@pythia-software/query-table-ui 0.7.0 → 0.7.1

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/index.js CHANGED
@@ -8251,7 +8251,7 @@ import {
8251
8251
  useLayoutEffect as useLayoutEffect6,
8252
8252
  useMemo as useMemo9,
8253
8253
  useRef as useRef18,
8254
- useState as useState25
8254
+ useState as useState26
8255
8255
  } from "react";
8256
8256
  import {
8257
8257
  MAX_AGGREGATIONS,
@@ -8266,7 +8266,7 @@ import {
8266
8266
  } from "@pythia-software/query-table-core";
8267
8267
 
8268
8268
  // src/MetricsPanel.tsx
8269
- import { useState as useState24, useMemo as useMemo8 } from "react";
8269
+ import { useState as useState25, useMemo as useMemo8 } from "react";
8270
8270
  import { EMPTY_QUERY as EMPTY_QUERY2 } from "@pythia-software/query-table-core";
8271
8271
 
8272
8272
  // src/MetricChart.tsx
@@ -8274,7 +8274,7 @@ import {
8274
8274
  useEffect as useEffect16,
8275
8275
  useId as useId7,
8276
8276
  useRef as useRef17,
8277
- useState as useState23
8277
+ useState as useState24
8278
8278
  } from "react";
8279
8279
 
8280
8280
  // src/metricChartHelpers.ts
@@ -8453,6 +8453,62 @@ function metricScale(values, options, zero = false) {
8453
8453
  omitted: values.length - valid.length
8454
8454
  };
8455
8455
  }
8456
+ function metricBoxWhiskers(summary) {
8457
+ return {
8458
+ low: Math.min(summary.low, summary.q1),
8459
+ high: Math.max(summary.high, summary.q3)
8460
+ };
8461
+ }
8462
+ function metricBoxOutliers(summary) {
8463
+ return [.../* @__PURE__ */ new Set([
8464
+ ...summary.outliers,
8465
+ ...summary.min < summary.low ? [summary.min] : [],
8466
+ ...summary.max > summary.high ? [summary.max] : []
8467
+ ])];
8468
+ }
8469
+
8470
+ // src/MetricTooltip.tsx
8471
+ import { useState as useState23 } from "react";
8472
+ import { jsx as jsx28, jsxs as jsxs24 } from "react/jsx-runtime";
8473
+ function MetricTooltip({ id, children }) {
8474
+ const [tooltip, setTooltip] = useState23(null);
8475
+ const show = (event) => {
8476
+ const target = event.target;
8477
+ const mark = target instanceof Element ? target.closest(".qt-metric-mark[aria-label]") : null;
8478
+ if (!mark || !event.currentTarget.contains(mark)) return;
8479
+ const label = mark.getAttribute("aria-label");
8480
+ const color = mark.getAttribute("data-qt-metric-color") ?? void 0;
8481
+ setTooltip((previous) => previous?.label === label && previous.color === color ? previous : { label, color });
8482
+ };
8483
+ return /* @__PURE__ */ jsxs24(
8484
+ "div",
8485
+ {
8486
+ className: "qt-metric-chart-body",
8487
+ onMouseOver: show,
8488
+ onMouseOut: (event) => {
8489
+ const target = event.target instanceof Element ? event.target.closest(".qt-metric-mark") : null;
8490
+ if (target && (!(event.relatedTarget instanceof Node) || !target.contains(event.relatedTarget))) setTooltip(null);
8491
+ },
8492
+ onMouseLeave: () => setTooltip(null),
8493
+ onFocus: show,
8494
+ onBlur: () => setTooltip(null),
8495
+ onKeyDown: (event) => {
8496
+ if (event.key === "Escape" && tooltip) {
8497
+ event.preventDefault();
8498
+ event.stopPropagation();
8499
+ setTooltip(null);
8500
+ }
8501
+ },
8502
+ children: [
8503
+ children,
8504
+ tooltip && /* @__PURE__ */ jsxs24("div", { id, role: "tooltip", className: "qt-metric-tooltip", children: [
8505
+ tooltip.color && /* @__PURE__ */ jsx28("span", { "aria-hidden": "true", className: "qt-metric-swatch", style: { background: tooltip.color } }),
8506
+ /* @__PURE__ */ jsx28("span", { children: tooltip.label })
8507
+ ] })
8508
+ ]
8509
+ }
8510
+ );
8511
+ }
8456
8512
 
8457
8513
  // src/compactMetricChart.ts
8458
8514
  var durationUnits2 = {
@@ -8565,19 +8621,19 @@ function compactCalendarLabels(points, clause, locale) {
8565
8621
  }
8566
8622
 
8567
8623
  // src/MetricChart.tsx
8568
- import { Fragment as Fragment18, jsx as jsx28, jsxs as jsxs24 } from "react/jsx-runtime";
8624
+ import { Fragment as Fragment18, jsx as jsx29, jsxs as jsxs25 } from "react/jsx-runtime";
8569
8625
  function usePlotSize() {
8570
8626
  const ref = useRef17(null);
8571
- const [size3, setSize] = useState23({ width: 400, height: 220 });
8627
+ const [size3, setSize] = useState24({ width: 400, height: 220 });
8572
8628
  useEffect16(() => {
8573
8629
  const element = ref.current;
8574
8630
  if (!element || typeof ResizeObserver === "undefined") return;
8575
8631
  const observer = new ResizeObserver((entries) => {
8576
8632
  const rect = entries[0]?.contentRect;
8577
8633
  if (rect && rect.width > 0 && rect.height > 0)
8578
- setSize({
8579
- width: Math.max(160, rect.width),
8580
- height: Math.max(100, rect.height)
8634
+ setSize((previous) => {
8635
+ const width = Math.max(160, rect.width), height = Math.max(100, rect.height);
8636
+ return previous.width === width && previous.height === height ? previous : { width, height };
8581
8637
  });
8582
8638
  });
8583
8639
  observer.observe(element);
@@ -8595,7 +8651,7 @@ function MetricChart({
8595
8651
  classNames,
8596
8652
  onInspect
8597
8653
  }) {
8598
- const { ref, width: W, height: H } = usePlotSize(), tooltipId = useId7(), clipId = useId7(), [tooltip, setTooltip] = useState23(null);
8654
+ const { ref, width: W, height: H } = usePlotSize(), tooltipId = useId7(), clipId = useId7();
8599
8655
  let buckets = inputBuckets;
8600
8656
  if (compact && clause.dateGrouping && ["line", "bar-vertical"].includes(clause.display?.kind ?? "")) {
8601
8657
  try {
@@ -8620,26 +8676,17 @@ function MetricChart({
8620
8676
  const detail = (b) => `${metricGroupLabel(b, clause, locale, true)}
8621
8677
  ${b.error ?? fmt(b.value, kind === "scatter" ? display2.xFormat : display2.format)}${kind === "scatter" ? ` / ${b.yError ?? fmt(b.y, display2.yFormat)}` : ""}
8622
8678
  ${b.count.toLocaleString(locale)} rows`;
8623
- const interaction = (b, label = detail(b), inspectable = true) => ({
8679
+ const interaction = (b, label = detail(b), inspectable = true, color = shade(b)) => ({
8624
8680
  clipPath: ["pie", "donut"].includes(kind) ? void 0 : `url(#${clipId})`,
8625
8681
  tabIndex: 0,
8626
8682
  role: onInspect && inspectable ? "button" : "img",
8627
8683
  "aria-label": label,
8628
- "aria-describedby": tooltip === label ? tooltipId : void 0,
8684
+ "data-qt-metric-color": color,
8629
8685
  className: `qt-metric-mark ${classNames?.mark ?? ""}`,
8630
- onMouseEnter: () => setTooltip(label),
8631
- onMouseLeave: () => setTooltip(null),
8632
- onFocus: () => setTooltip(label),
8633
- onBlur: () => setTooltip(null),
8634
8686
  onClick: () => {
8635
8687
  if (inspectable) onInspect?.(b);
8636
8688
  },
8637
8689
  onKeyDown: (e) => {
8638
- if (e.key === "Escape" && tooltip) {
8639
- e.preventDefault();
8640
- e.stopPropagation();
8641
- setTooltip(null);
8642
- }
8643
8690
  if (onInspect && inspectable && (e.key === "Enter" || e.key === " ")) {
8644
8691
  e.preventDefault();
8645
8692
  onInspect(b);
@@ -8647,8 +8694,8 @@ ${b.count.toLocaleString(locale)} rows`;
8647
8694
  }
8648
8695
  });
8649
8696
  const compactBox = compact && kind === "box";
8650
- const left = compactBox ? 8 : compact ? 28 : Math.min(78, W * 0.24), right = W - (compactBox ? 8 : compact ? 8 : 32), top = compactBox ? 0 : 12, bottom = H - (compactBox ? 5 : compact ? 20 : 42), plotW = right - left, plotH = bottom - top;
8651
- const text = (x, y, label, anchor = "middle") => /* @__PURE__ */ jsx28(
8697
+ const left = compactBox ? 8 : compact ? 44 : Math.min(78, W * 0.24), right = W - (compactBox ? 8 : compact ? 8 : 32), top = compactBox ? 0 : 12, bottom = H - (compact ? 20 : 42), plotW = right - left, plotH = bottom - top;
8698
+ const text = (x, y, label, anchor = "middle") => /* @__PURE__ */ jsx29(
8652
8699
  "text",
8653
8700
  {
8654
8701
  x: compact && anchor === "middle" ? Math.max(label.length * 2.7 + 2, Math.min(W - label.length * 2.7 - 2, x)) : x,
@@ -8658,7 +8705,7 @@ ${b.count.toLocaleString(locale)} rows`;
8658
8705
  children: label
8659
8706
  }
8660
8707
  );
8661
- const grid = (x1, y1, x2, y2) => /* @__PURE__ */ jsx28(
8708
+ const grid = (x1, y1, x2, y2) => /* @__PURE__ */ jsx29(
8662
8709
  "line",
8663
8710
  {
8664
8711
  x1,
@@ -8708,7 +8755,7 @@ ${b.count.toLocaleString(locale)} rows`;
8708
8755
  const start = angle;
8709
8756
  angle += s.value / pie.total * Math.PI * 2;
8710
8757
  const end = angle, large = end - start > Math.PI ? 1 : 0, color = s.other ? colors.token("other") : shade(s.bucket), label = `${s.other ? "Other (combined remainder)" : groupLabel(s.bucket)}: ${fmt(s.value, display2.format)} (${percent(s.value / pie.total)} of ${fmt(pie.total, display2.format)})`;
8711
- return /* @__PURE__ */ jsx28("g", { ...interaction(s.bucket, label, !s.other), children: s.value === pie.total ? /* @__PURE__ */ jsx28(
8758
+ return /* @__PURE__ */ jsx29("g", { ...interaction(s.bucket, label, !s.other, color), children: s.value === pie.total ? /* @__PURE__ */ jsx29(
8712
8759
  "circle",
8713
8760
  {
8714
8761
  cx: cx7,
@@ -8718,7 +8765,7 @@ ${b.count.toLocaleString(locale)} rows`;
8718
8765
  stroke: inner ? color : "none",
8719
8766
  strokeWidth: r - inner
8720
8767
  }
8721
- ) : /* @__PURE__ */ jsx28(
8768
+ ) : /* @__PURE__ */ jsx29(
8722
8769
  "path",
8723
8770
  {
8724
8771
  fill: color,
@@ -8728,48 +8775,52 @@ ${b.count.toLocaleString(locale)} rows`;
8728
8775
  });
8729
8776
  legend = pie.slices.map((s, i) => ({
8730
8777
  key: String(i),
8731
- label: `${s.other ? "Other (remainder)" : groupLabel(s.bucket)} \xB7 ${fmt(s.value, display2.format)} \xB7 ${percent(s.value / pie.total)}`,
8778
+ label: compact ? s.other ? "Other" : groupLabel(s.bucket) : `${s.other ? "Other (remainder)" : groupLabel(s.bucket)} \xB7 ${fmt(s.value, display2.format)} \xB7 ${percent(s.value / pie.total)}`,
8779
+ ...compact ? { value: fmt(s.value, display2.format), share: percent(s.value / pie.total) } : {},
8732
8780
  color: s.other ? colors.token("other") : shade(s.bucket)
8733
8781
  }));
8734
8782
  note = `Exact additive denominator: ${fmt(pie.total, display2.format)}. ${display2.showOther === false ? "Hidden remainder retains its share of the full denominator." : "Other combines remaining groups."} Hover a slice for its value.`;
8735
8783
  } else if (compactBox) {
8736
- const step = 52, visible = buckets.slice(0, Math.max(1, Math.floor(plotH / step)));
8784
+ const step = 30, visible = buckets.slice(0, Math.max(1, Math.floor(plotH / step)));
8785
+ const summaries = visible.flatMap((b) => !b.error && b.distribution?.kind === "box" && b.distribution.summary ? [b.distribution.summary] : []);
8786
+ const axis = scale(summaries.flatMap((s) => [s.min, s.max]), display2.xScale, false, display2.format);
8787
+ const x = (v) => left + axis.fraction(v) * plotW;
8788
+ axes = axis.ticks.map((v, i) => /* @__PURE__ */ jsxs25("g", { className: "qt-metric-box-axis-tick", children: [
8789
+ grid(x(v), top, x(v), bottom),
8790
+ text(x(v), bottom + 16, tickFmt(v, display2.format, axis.ticks), i === 0 ? "start" : i === axis.ticks.length - 1 ? "end" : "middle")
8791
+ ] }, i));
8737
8792
  marks = visible.map((b, i) => {
8738
8793
  const s = b.distribution?.kind === "box" ? b.distribution.summary : null;
8739
- const y = top + i * step + 27, color = shade(b);
8740
- const median = s ? `med ${fmt(s.median, display2.format)}` : "";
8794
+ const y = top + i * step + 22, color = shade(b);
8795
+ const median = s ? `Median ${fmt(s.median, display2.format)}` : "";
8741
8796
  const fullLabel = groupLabel(b);
8742
8797
  const chars = Math.max(4, Math.floor((plotW - median.length * 5.5 - 12) / 5.5));
8743
8798
  const shortLabel = fullLabel.length > chars ? `${fullLabel.slice(0, chars - 1)}\u2026` : fullLabel;
8744
- const axis = s ? scale([s.low, s.high], { ...display2.xScale, mode: "linear" }, false, display2.format) : void 0;
8745
- const x = (v) => left + axis.fraction(v) * plotW;
8799
+ const whisker = s ? metricBoxWhiskers(s) : null;
8800
+ const outliers = s ? metricBoxOutliers(s) : [];
8746
8801
  const detailLabel = s ? `${fullLabel}
8747
8802
  Min ${fmt(s.min, display2.format)} \xB7 Q1 ${fmt(s.q1, display2.format)} \xB7 Median ${fmt(s.median, display2.format)} \xB7 Q3 ${fmt(s.q3, display2.format)} \xB7 Max ${fmt(s.max, display2.format)} \xB7 Mean ${fmt(s.mean, display2.format)}
8748
- Whiskers ${fmt(s.low, display2.format)} \u2013 ${fmt(s.high, display2.format)}
8749
- ${s.n} samples \xB7 ${b.nullCount ?? 0} NULL \xB7 ${s.outlierCount} outliers (omitted from cover). Independent whisker scale.` : detail(b);
8750
- return /* @__PURE__ */ jsxs24("g", { className: "qt-metric-box-row", children: [
8751
- /* @__PURE__ */ jsxs24("text", { x: left, y: y - 17, textAnchor: "start", className: "qt-metric-axis qt-metric-box-label", children: [
8752
- /* @__PURE__ */ jsx28("title", { children: fullLabel }),
8803
+ Observed whiskers ${fmt(s.low, display2.format)} \u2013 ${fmt(s.high, display2.format)}${s.low > s.q1 || s.high < s.q3 ? "\nInterpolated quartile extends beyond observed inliers; whisker meets the box edge." : ""}
8804
+ ${s.n} samples \xB7 ${b.nullCount ?? 0} NULL \xB7 ${s.outlierCount} outliers (${outliers.length} retained markers). Shared ${display2.xScale?.mode === "log" ? "logarithmic" : "linear"} axis.` : detail(b);
8805
+ return /* @__PURE__ */ jsxs25("g", { className: "qt-metric-box-row", children: [
8806
+ /* @__PURE__ */ jsxs25("text", { x: left, y: y - 12, textAnchor: "start", className: "qt-metric-axis qt-metric-box-label", children: [
8807
+ /* @__PURE__ */ jsx29("title", { children: fullLabel }),
8753
8808
  shortLabel
8754
8809
  ] }),
8755
- text(right, y - 17, median, "end"),
8756
- s && axis && !b.error && axis.accepts(s.low) ? /* @__PURE__ */ jsxs24(Fragment18, { children: [
8757
- axis.ticks.map((v, j) => /* @__PURE__ */ jsxs24("g", { children: [
8758
- grid(x(v), y - 9, x(v), y + 9),
8759
- text(x(v), y + 21, tickFmt(v, display2.format, axis.ticks), j === 0 ? "start" : j === axis.ticks.length - 1 ? "end" : "middle")
8760
- ] }, j)),
8761
- /* @__PURE__ */ jsxs24("g", { ...interaction(b, detailLabel), children: [
8762
- /* @__PURE__ */ jsx28("line", { x1: x(s.low), x2: x(s.high), y1: y, y2: y, stroke: color, strokeWidth: 2 }),
8763
- [s.low, s.high].map((v, j) => /* @__PURE__ */ jsx28("line", { x1: x(v), x2: x(v), y1: y - 6, y2: y + 6, stroke: color }, j)),
8764
- /* @__PURE__ */ jsx28("rect", { x: x(s.q1), y: y - 8, width: Math.max(1, x(s.q3) - x(s.q1)), height: 16, fill: color, fillOpacity: 0.25, stroke: color }),
8765
- /* @__PURE__ */ jsx28("line", { x1: x(s.median), x2: x(s.median), y1: y - 8, y2: y + 8, stroke: color, strokeWidth: 2 }),
8766
- /* @__PURE__ */ jsx28("rect", { x: left, y: y - 11, width: plotW, height: 22, fill: "transparent" })
8767
- ] })
8768
- ] }) : text((left + right) / 2, y + 4, b.error ? "Error" : "No samples")
8810
+ text(right, y - 12, median, "end"),
8811
+ s && whisker && !b.error && axis.accepts(s.min) ? /* @__PURE__ */ jsxs25("g", { ...interaction(b, detailLabel), children: [
8812
+ /* @__PURE__ */ jsx29("line", { className: "qt-metric-box-whisker", x1: x(whisker.low), x2: x(whisker.high), y1: y, y2: y, stroke: color, strokeWidth: 2 }),
8813
+ [whisker.low, whisker.high].map((v, j) => /* @__PURE__ */ jsx29("line", { className: "qt-metric-box-cap", x1: x(v), x2: x(v), y1: y - 4, y2: y + 4, stroke: color }, j)),
8814
+ /* @__PURE__ */ jsx29("rect", { className: "qt-metric-box-quartiles", x: x(s.q1), y: y - 5, width: Math.max(1, x(s.q3) - x(s.q1)), height: 10, fill: color, fillOpacity: 0.25, stroke: color }),
8815
+ /* @__PURE__ */ jsx29("line", { x1: x(s.median), x2: x(s.median), y1: y - 5, y2: y + 5, stroke: color, strokeWidth: 2 }),
8816
+ display2.boxMean === true && /* @__PURE__ */ jsx29("circle", { cx: x(s.mean), cy: y, r: 2, fill: colors.token("surface"), stroke: color }),
8817
+ outliers.map((v, j) => /* @__PURE__ */ jsx29("circle", { className: "qt-metric-box-outlier", cx: x(v), cy: y, r: 2.5, fill: color }, j)),
8818
+ /* @__PURE__ */ jsx29("rect", { x: left, y: y - 7, width: plotW, height: 14, fill: "transparent" })
8819
+ ] }) : text((left + right) / 2, y + 4, b.error ? "Error" : s ? "Nonpositive samples" : "No samples")
8769
8820
  ] }, i);
8770
8821
  });
8771
8822
  if (visible.length < buckets.length) disclosure = `${visible.length} of ${buckets.length} returned groups drawn.`;
8772
- note = "Independent linear scales focus on each row's whiskers. Outlier markers are omitted; full summaries remain available in the data table.";
8823
+ note = `Shared ${display2.xScale?.mode === "log" ? "logarithmic" : "linear"} axis includes the visible cohorts\u2019 full observed range. Hover a box for exact summaries and observed whiskers. Dots retain sampled outliers and true extremes.`;
8773
8824
  } else if (kind === "box") {
8774
8825
  const summaries = buckets.flatMap(
8775
8826
  (b) => !b.error && b.distribution?.kind === "box" && b.distribution.summary ? [b.distribution.summary] : []
@@ -8778,35 +8829,36 @@ ${s.n} samples \xB7 ${b.nullCount ?? 0} NULL \xB7 ${s.outlierCount} outliers (om
8778
8829
  display2.xScale
8779
8830
  ), x = (v) => left + axis.fraction(v) * plotW;
8780
8831
  const visible = buckets.slice(0, Math.max(1, Math.floor(plotH / 22))), step = plotH / Math.max(1, visible.length);
8781
- axes = axis.ticks.map((v, i) => /* @__PURE__ */ jsxs24("g", { children: [
8832
+ axes = axis.ticks.map((v, i) => /* @__PURE__ */ jsxs25("g", { children: [
8782
8833
  grid(x(v), top, x(v), bottom),
8783
8834
  text(x(v), bottom + 18, tickFmt(v, display2.format, axis.ticks))
8784
8835
  ] }, i));
8785
8836
  marks = visible.map((b, i) => {
8786
8837
  const s = b.distribution?.kind === "box" ? b.distribution.summary : null, y = top + step * (i + 0.5), color = shade(b);
8838
+ const whisker = s ? metricBoxWhiskers(s) : null, outliers = s ? metricBoxOutliers(s) : [];
8787
8839
  const label = s ? `${groupLabel(b)}
8788
8840
  Min ${fmt(s.min, display2.format)} \xB7 Q1 ${fmt(s.q1, display2.format)} \xB7 Median ${fmt(s.median, display2.format)} \xB7 Q3 ${fmt(s.q3, display2.format)} \xB7 Max ${fmt(s.max, display2.format)} \xB7 Mean ${fmt(s.mean, display2.format)}
8789
- Whiskers ${fmt(s.low, display2.format)} \u2013 ${fmt(s.high, display2.format)}
8790
- ${s.n} samples \xB7 ${b.nullCount ?? 0} NULL \xB7 ${s.outlierCount} outliers (${s.outliers.length} markers returned)` : detail(b);
8791
- return /* @__PURE__ */ jsxs24("g", { children: [
8841
+ Observed whiskers ${fmt(s.low, display2.format)} \u2013 ${fmt(s.high, display2.format)}${s.low > s.q1 || s.high < s.q3 ? "\nInterpolated quartile extends beyond observed inliers; whisker meets the box edge." : ""}
8842
+ ${s.n} samples \xB7 ${b.nullCount ?? 0} NULL \xB7 ${s.outlierCount} outliers (${outliers.length} retained markers)` : detail(b);
8843
+ return /* @__PURE__ */ jsxs25("g", { children: [
8792
8844
  text(left - 8, y + 4, groupLabel(b), "end"),
8793
8845
  !s || b.error || !axis.accepts(s.min) ? text(
8794
8846
  (left + right) / 2,
8795
8847
  y + 4,
8796
8848
  b.error ? "Error" : s ? "Nonpositive samples" : "No samples"
8797
- ) : /* @__PURE__ */ jsxs24("g", { ...interaction(b, label), children: [
8798
- /* @__PURE__ */ jsx28(
8849
+ ) : /* @__PURE__ */ jsxs25("g", { ...interaction(b, label), children: [
8850
+ /* @__PURE__ */ jsx29(
8799
8851
  "line",
8800
8852
  {
8801
- x1: x(s.low),
8802
- x2: x(s.high),
8853
+ x1: x(whisker.low),
8854
+ x2: x(whisker.high),
8803
8855
  y1: y,
8804
8856
  y2: y,
8805
8857
  stroke: color,
8806
8858
  strokeWidth: 2
8807
8859
  }
8808
8860
  ),
8809
- [s.low, s.high].map((v, j) => /* @__PURE__ */ jsx28(
8861
+ [whisker.low, whisker.high].map((v, j) => /* @__PURE__ */ jsx29(
8810
8862
  "line",
8811
8863
  {
8812
8864
  x1: x(v),
@@ -8817,7 +8869,7 @@ ${s.n} samples \xB7 ${b.nullCount ?? 0} NULL \xB7 ${s.outlierCount} outliers (${
8817
8869
  },
8818
8870
  j
8819
8871
  )),
8820
- /* @__PURE__ */ jsx28(
8872
+ /* @__PURE__ */ jsx29(
8821
8873
  "rect",
8822
8874
  {
8823
8875
  x: x(s.q1),
@@ -8829,7 +8881,7 @@ ${s.n} samples \xB7 ${b.nullCount ?? 0} NULL \xB7 ${s.outlierCount} outliers (${
8829
8881
  stroke: color
8830
8882
  }
8831
8883
  ),
8832
- /* @__PURE__ */ jsx28(
8884
+ /* @__PURE__ */ jsx29(
8833
8885
  "line",
8834
8886
  {
8835
8887
  x1: x(s.median),
@@ -8840,7 +8892,7 @@ ${s.n} samples \xB7 ${b.nullCount ?? 0} NULL \xB7 ${s.outlierCount} outliers (${
8840
8892
  strokeWidth: 2
8841
8893
  }
8842
8894
  ),
8843
- display2.boxMean !== false && /* @__PURE__ */ jsx28(
8895
+ display2.boxMean !== false && /* @__PURE__ */ jsx29(
8844
8896
  "circle",
8845
8897
  {
8846
8898
  cx: x(s.mean),
@@ -8850,7 +8902,7 @@ ${s.n} samples \xB7 ${b.nullCount ?? 0} NULL \xB7 ${s.outlierCount} outliers (${
8850
8902
  stroke: color
8851
8903
  }
8852
8904
  ),
8853
- /* @__PURE__ */ jsx28(
8905
+ /* @__PURE__ */ jsx29(
8854
8906
  "rect",
8855
8907
  {
8856
8908
  x: left,
@@ -8860,7 +8912,7 @@ ${s.n} samples \xB7 ${b.nullCount ?? 0} NULL \xB7 ${s.outlierCount} outliers (${
8860
8912
  fill: "transparent"
8861
8913
  }
8862
8914
  ),
8863
- s.outliers.map((v, j) => /* @__PURE__ */ jsx28("circle", { cx: x(v), cy: y, r: 3, fill: color }, j))
8915
+ outliers.map((v, j) => /* @__PURE__ */ jsx29("circle", { cx: x(v), cy: y, r: 3, fill: color }, j))
8864
8916
  ] })
8865
8917
  ] }, i);
8866
8918
  });
@@ -8870,7 +8922,7 @@ ${s.n} samples \xB7 ${b.nullCount ?? 0} NULL \xB7 ${s.outlierCount} outliers (${
8870
8922
  (b) => b.error || b.distribution?.kind !== "box" || !b.distribution.summary
8871
8923
  ).length;
8872
8924
  const omittedOutliers = summaries.reduce(
8873
- (n, s) => n + s.outlierCount - s.outliers.length,
8925
+ (n, s) => n + Math.max(0, s.outlierCount - metricBoxOutliers(s).length),
8874
8926
  0
8875
8927
  );
8876
8928
  if (missing)
@@ -8898,12 +8950,12 @@ ${s.n} samples \xB7 ${b.nullCount ?? 0} NULL \xB7 ${s.outlierCount} outliers (${
8898
8950
  );
8899
8951
  const ya = scale(counts, display2.yScale, true), xa = scale(edges, display2.xScale, false, display2.xFormat);
8900
8952
  const y = (v) => bottom - ya.fraction(v) * plotH;
8901
- axes = /* @__PURE__ */ jsxs24(Fragment18, { children: [
8902
- ya.ticks.map((v, i) => /* @__PURE__ */ jsxs24("g", { children: [
8953
+ axes = /* @__PURE__ */ jsxs25(Fragment18, { children: [
8954
+ ya.ticks.map((v, i) => /* @__PURE__ */ jsxs25("g", { children: [
8903
8955
  grid(left, y(v), right, y(v)),
8904
8956
  text(left - 7, y(v) + 4, compact ? tickFmt(v, void 0, ya.ticks) : v.toLocaleString(locale), "end")
8905
8957
  ] }, i)),
8906
- xa.ticks.map((v, i) => /* @__PURE__ */ jsx28("g", { children: text(
8958
+ xa.ticks.map((v, i) => /* @__PURE__ */ jsx29("g", { children: text(
8907
8959
  left + xa.fraction(v) * plotW,
8908
8960
  bottom + 18,
8909
8961
  tickFmt(v, display2.xFormat, xa.ticks)
@@ -8919,9 +8971,9 @@ ${s.n} samples \xB7 ${b.nullCount ?? 0} NULL \xB7 ${s.outlierCount} outliers (${
8919
8971
  const binLeft = pointInterval ? center - pointWidth / 2 : center, binRight = pointInterval ? center + pointWidth / 2 : left + xa.fraction(edges[i + 1]) * plotW, binWidth = Math.max(1, binRight - binLeft), x = binLeft + j * binWidth / series.length, w = binWidth / series.length;
8920
8972
  const label = `${groupLabel(b)}
8921
8973
  ${fmt(edges[i], display2.xFormat)} \u2264 value ${i === bins - 1 ? "\u2264" : "<"} ${fmt(edges[i + 1], display2.xFormat)}
8922
- ${n} rows \xB7 ${b.distribution?.kind === "histogram" ? b.distribution.n : 0} numeric samples \xB7 ${b.nullCount ?? 0} NULL`;
8923
- return /* @__PURE__ */ jsxs24("g", { ...interaction(b, label), children: [
8924
- /* @__PURE__ */ jsx28(
8974
+ ${n} rows${compact ? "" : ` \xB7 ${b.distribution?.kind === "histogram" ? b.distribution.n : 0} numeric samples \xB7 ${b.nullCount ?? 0} NULL`}`;
8975
+ return /* @__PURE__ */ jsxs25("g", { ...interaction(b, label), children: [
8976
+ /* @__PURE__ */ jsx29(
8925
8977
  "rect",
8926
8978
  {
8927
8979
  x,
@@ -8931,7 +8983,7 @@ ${n} rows \xB7 ${b.distribution?.kind === "histogram" ? b.distribution.n : 0} nu
8931
8983
  fill: shade(b)
8932
8984
  }
8933
8985
  ),
8934
- /* @__PURE__ */ jsx28(
8986
+ /* @__PURE__ */ jsx29(
8935
8987
  "rect",
8936
8988
  {
8937
8989
  x,
@@ -8967,18 +9019,18 @@ ${n} rows \xB7 ${b.distribution?.kind === "histogram" ? b.distribution.n : 0} nu
8967
9019
  false,
8968
9020
  display2.yFormat
8969
9021
  ), x = (v) => left + xa.fraction(v) * plotW, y = (v) => bottom - ya.fraction(v) * plotH;
8970
- axes = /* @__PURE__ */ jsxs24(Fragment18, { children: [
8971
- xa.ticks.map((v, i) => /* @__PURE__ */ jsxs24("g", { children: [
9022
+ axes = /* @__PURE__ */ jsxs25(Fragment18, { children: [
9023
+ xa.ticks.map((v, i) => /* @__PURE__ */ jsxs25("g", { children: [
8972
9024
  grid(x(v), top, x(v), bottom),
8973
9025
  text(x(v), bottom + 18, tickFmt(v, display2.xFormat, xa.ticks))
8974
9026
  ] }, `x${i}`)),
8975
- ya.ticks.map((v, i) => /* @__PURE__ */ jsxs24("g", { children: [
9027
+ ya.ticks.map((v, i) => /* @__PURE__ */ jsxs25("g", { children: [
8976
9028
  grid(left, y(v), right, y(v)),
8977
9029
  text(left - 7, y(v) + 4, tickFmt(v, display2.yFormat, ya.ticks), "end")
8978
9030
  ] }, `y${i}`))
8979
9031
  ] });
8980
- marks = points.filter((b) => xa.accepts(b.value) && ya.accepts(b.y)).map((b, i) => /* @__PURE__ */ jsxs24("g", { ...interaction(b), children: [
8981
- /* @__PURE__ */ jsx28(
9032
+ marks = points.filter((b) => xa.accepts(b.value) && ya.accepts(b.y)).map((b, i) => /* @__PURE__ */ jsxs25("g", { ...interaction(b), children: [
9033
+ /* @__PURE__ */ jsx29(
8982
9034
  "circle",
8983
9035
  {
8984
9036
  cx: x(b.value),
@@ -8987,7 +9039,7 @@ ${n} rows \xB7 ${b.distribution?.kind === "histogram" ? b.distribution.n : 0} nu
8987
9039
  fill: shade(b)
8988
9040
  }
8989
9041
  ),
8990
- /* @__PURE__ */ jsx28(
9042
+ /* @__PURE__ */ jsx29(
8991
9043
  "circle",
8992
9044
  {
8993
9045
  cx: x(b.value),
@@ -9051,8 +9103,8 @@ ${n} rows \xB7 ${b.distribution?.kind === "histogram" ? b.distribution.n : 0} nu
9051
9103
  label: metricGroupLabel({ ...first, keys: first.keys.slice(1) })
9052
9104
  };
9053
9105
  });
9054
- marks = /* @__PURE__ */ jsxs24(Fragment18, { children: [
9055
- paths.map((series2) => /* @__PURE__ */ jsx28(
9106
+ marks = /* @__PURE__ */ jsxs25(Fragment18, { children: [
9107
+ paths.map((series2) => /* @__PURE__ */ jsx29(
9056
9108
  "path",
9057
9109
  {
9058
9110
  clipPath: `url(#${clipId})`,
@@ -9064,8 +9116,8 @@ ${n} rows \xB7 ${b.distribution?.kind === "histogram" ? b.distribution.n : 0} nu
9064
9116
  series2.key
9065
9117
  )),
9066
9118
  ordered.map(
9067
- ({ bucket: b, time }, i) => !b.error && finiteMetricNumber(b.value) && axis.accepts(b.value) && timeAxis.accepts(time) ? /* @__PURE__ */ jsxs24("g", { ...interaction(b), children: [
9068
- /* @__PURE__ */ jsx28(
9119
+ ({ bucket: b, time }, i) => !b.error && finiteMetricNumber(b.value) && axis.accepts(b.value) && timeAxis.accepts(time) ? /* @__PURE__ */ jsxs25("g", { ...interaction(b, detail(b), true, clause.groupBy.length > 1 ? colors.color(clause.groupBy[1], b.keys[1] ?? null) : colors.token("accent")), children: [
9120
+ /* @__PURE__ */ jsx29(
9069
9121
  "circle",
9070
9122
  {
9071
9123
  cx: tx(time),
@@ -9074,7 +9126,7 @@ ${n} rows \xB7 ${b.distribution?.kind === "histogram" ? b.distribution.n : 0} nu
9074
9126
  fill: clause.groupBy.length > 1 ? colors.color(clause.groupBy[1], b.keys[1] ?? null) : colors.token("accent")
9075
9127
  }
9076
9128
  ),
9077
- /* @__PURE__ */ jsx28(
9129
+ /* @__PURE__ */ jsx29(
9078
9130
  "circle",
9079
9131
  {
9080
9132
  cx: tx(time),
@@ -9090,7 +9142,7 @@ ${n} rows \xB7 ${b.distribution?.kind === "histogram" ? b.distribution.n : 0} nu
9090
9142
  ).filter(({ time }) => timeAxis.accepts(time)).filter(({ bucket, time }, i, points) => {
9091
9143
  const last = points[points.length - 1];
9092
9144
  return i === points.length - 1 || tx(last.time) - tx(time) > (timeLabel(bucket).length + timeLabel(last.bucket).length) * 3 + 12;
9093
- }).map(({ bucket: b, time }, i) => /* @__PURE__ */ jsx28("g", { children: text(tx(time), bottom + 18, timeLabel(b)) }, i))
9145
+ }).map(({ bucket: b, time }, i) => /* @__PURE__ */ jsx29("g", { children: text(tx(time), bottom + 18, timeLabel(b)) }, i))
9094
9146
  ] });
9095
9147
  const missing = buckets.filter(
9096
9148
  (b) => b.error || !finiteMetricNumber(b.value)
@@ -9107,14 +9159,14 @@ ${n} rows \xB7 ${b.distribution?.kind === "histogram" ? b.distribution.n : 0} nu
9107
9159
  const calendarLabels = compactCalendarLabels(compact && !horizontal ? visible.map((bucket, i) => ({ bucket, x: left + step * (i + 0.5) })) : [], clause, locale);
9108
9160
  marks = visible.map((b, i) => {
9109
9161
  const center = (horizontal ? top : left) + step * (i + 0.5), valid = !b.error && finiteMetricNumber(b.value) && axis.accepts(b.value), value = valid ? b.value : 0;
9110
- return /* @__PURE__ */ jsxs24("g", { children: [
9162
+ return /* @__PURE__ */ jsxs25("g", { children: [
9111
9163
  (compact && clause.dateGrouping && !horizontal ? calendarLabels.has(b) : horizontal || step > 42 || i % Math.ceil(42 / step) === 0) && text(
9112
9164
  horizontal ? left - 7 : center,
9113
9165
  horizontal ? center + 4 : bottom + 18,
9114
9166
  compact && clause.dateGrouping && !horizontal ? calendarLabels.get(b) : !horizontal && groupFormat && b.keys.length === 1 ? formatMetricOutput(b.keys[0], groupFormat, locale).text : groupLabel(b),
9115
9167
  horizontal ? "end" : "middle"
9116
9168
  ),
9117
- valid ? /* @__PURE__ */ jsx28("g", { ...interaction(b), children: /* @__PURE__ */ jsx28(
9169
+ valid ? /* @__PURE__ */ jsx29("g", { ...interaction(b), children: /* @__PURE__ */ jsx29(
9118
9170
  "rect",
9119
9171
  {
9120
9172
  x: horizontal ? Math.min(x(axis.baseline), x(value)) : center - step * 0.32,
@@ -9134,13 +9186,13 @@ ${n} rows \xB7 ${b.distribution?.kind === "histogram" ? b.distribution.n : 0} nu
9134
9186
  if (missing) disclosure += ` ${missing} missing/error values.`;
9135
9187
  note = `${axis.accepts(0) ? "Signed values use a zero baseline." : "Logarithmic values use the positive domain minimum as baseline."} ${visible.length} of ${result?.groupCount ?? buckets.length} groups drawn; Hover a mark for its value.`;
9136
9188
  }
9137
- axes = axis.ticks.map((v, i) => /* @__PURE__ */ jsxs24("g", { children: [
9189
+ axes = axis.ticks.map((v, i) => /* @__PURE__ */ jsxs25("g", { children: [
9138
9190
  horizontal ? grid(x(v), top, x(v), bottom) : grid(left, y(v), right, y(v)),
9139
9191
  horizontal ? text(x(v), bottom + 18, compact ? tickFmt(v, display2.format, axis.ticks) : fmt(v, display2.format)) : text(left - 7, y(v) + 4, tickFmt(v, display2.format, axis.ticks), "end")
9140
9192
  ] }, i));
9141
- axes = /* @__PURE__ */ jsxs24(Fragment18, { children: [
9193
+ axes = /* @__PURE__ */ jsxs25(Fragment18, { children: [
9142
9194
  axes,
9143
- horizontal ? /* @__PURE__ */ jsx28(
9195
+ horizontal ? /* @__PURE__ */ jsx29(
9144
9196
  "line",
9145
9197
  {
9146
9198
  x1: x(axis.baseline),
@@ -9149,7 +9201,7 @@ ${n} rows \xB7 ${b.distribution?.kind === "histogram" ? b.distribution.n : 0} nu
9149
9201
  y2: bottom,
9150
9202
  stroke: colors.token("muted")
9151
9203
  }
9152
- ) : /* @__PURE__ */ jsx28(
9204
+ ) : /* @__PURE__ */ jsx29(
9153
9205
  "line",
9154
9206
  {
9155
9207
  x1: left,
@@ -9166,33 +9218,33 @@ ${n} rows \xB7 ${b.distribution?.kind === "histogram" ? b.distribution.n : 0} nu
9166
9218
  const position = display2.legendPosition ?? (["pie", "donut", "scatter", "histogram"].includes(kind) ? "right" : "none");
9167
9219
  const xAxisLabel = display2.xLabel ?? (kind === "scatter" ? "X value" : kind === "histogram" ? display2.valueLabel ?? "Value" : horizontalLabel(kind, clause));
9168
9220
  const yAxisLabel = display2.yLabel ?? (kind === "scatter" ? "Y value" : kind === "histogram" ? "Count" : kind === "bar-horizontal" ? clause.groupBy.join(" / ") : display2.valueLabel ?? "Value");
9169
- return /* @__PURE__ */ jsxs24(Fragment18, { children: [
9170
- /* @__PURE__ */ jsxs24(
9221
+ return /* @__PURE__ */ jsxs25(MetricTooltip, { id: tooltipId, children: [
9222
+ /* @__PURE__ */ jsxs25(
9171
9223
  "div",
9172
9224
  {
9173
9225
  className: `qt-metric-chart-layout qt-metric-legend-${position}`,
9174
9226
  style: kind === "bar-horizontal" || kind === "box" ? {
9175
- minHeight: Math.min(8, buckets.length) * (compactBox ? 52 : kind === "box" ? 22 : 20) + (compactBox ? 5 : 54)
9227
+ minHeight: Math.min(8, buckets.length) * (compactBox ? 30 : kind === "box" ? 22 : 20) + (compactBox ? 20 : 54)
9176
9228
  } : void 0,
9177
9229
  children: [
9178
- /* @__PURE__ */ jsx28("div", { ref, className: `qt-metric-plot ${classNames?.plot ?? ""}`, children: problem ? /* @__PURE__ */ jsx28("p", { className: "qt-metric-message", role: "status", children: problem }) : /* @__PURE__ */ jsxs24(
9230
+ /* @__PURE__ */ jsx29("div", { ref, className: `qt-metric-plot ${classNames?.plot ?? ""}`, children: problem ? /* @__PURE__ */ jsx29("p", { className: "qt-metric-message", role: "status", children: problem }) : /* @__PURE__ */ jsxs25(
9179
9231
  "svg",
9180
9232
  {
9181
9233
  viewBox: `0 0 ${W} ${H}`,
9182
9234
  "aria-label": clause.label ?? "Metric chart",
9183
9235
  role: "group",
9184
9236
  children: [
9185
- /* @__PURE__ */ jsx28("title", { children: clause.label ?? "Metric chart" }),
9186
- /* @__PURE__ */ jsx28("defs", { children: /* @__PURE__ */ jsx28("clipPath", { id: clipId, children: /* @__PURE__ */ jsx28("rect", { x: left, y: top, width: plotW, height: plotH }) }) }),
9237
+ /* @__PURE__ */ jsx29("title", { children: clause.label ?? "Metric chart" }),
9238
+ /* @__PURE__ */ jsx29("defs", { children: /* @__PURE__ */ jsx29("clipPath", { id: clipId, children: /* @__PURE__ */ jsx29("rect", { x: left, y: top, width: plotW, height: plotH }) }) }),
9187
9239
  axes,
9188
9240
  marks,
9189
- !compact && !["pie", "donut"].includes(kind) && /* @__PURE__ */ jsxs24(Fragment18, { children: [
9241
+ !compact && !["pie", "donut"].includes(kind) && /* @__PURE__ */ jsxs25(Fragment18, { children: [
9190
9242
  text(
9191
9243
  (left + right) / 2,
9192
9244
  H - 5,
9193
9245
  display2.xLabel ?? (kind === "scatter" ? "X value" : kind === "box" || kind === "histogram" ? display2.valueLabel ?? "Value" : horizontalLabel(kind, clause))
9194
9246
  ),
9195
- display2.yLabel && /* @__PURE__ */ jsx28(
9247
+ display2.yLabel && /* @__PURE__ */ jsx29(
9196
9248
  "text",
9197
9249
  {
9198
9250
  transform: `translate(12 ${(top + bottom) / 2}) rotate(-90)`,
@@ -9205,45 +9257,46 @@ ${n} rows \xB7 ${b.distribution?.kind === "histogram" ? b.distribution.n : 0} nu
9205
9257
  ]
9206
9258
  }
9207
9259
  ) }),
9208
- position !== "none" && legend.length > 0 && /* @__PURE__ */ jsx28(
9260
+ position !== "none" && legend.length > 0 && /* @__PURE__ */ jsx29(
9209
9261
  "ul",
9210
9262
  {
9211
- className: `qt-metric-legend ${classNames?.legend ?? ""}`,
9263
+ className: `qt-metric-legend ${legend.some((e) => e.value !== void 0) ? "qt-metric-legend--composition" : ""} ${classNames?.legend ?? ""}`,
9212
9264
  "aria-label": "Legend",
9213
- children: legend.map((e) => /* @__PURE__ */ jsxs24("li", { children: [
9214
- /* @__PURE__ */ jsx28(
9265
+ children: legend.map((e) => /* @__PURE__ */ jsxs25("li", { title: [e.label, e.value, e.share].filter(Boolean).join(" \xB7 "), children: [
9266
+ /* @__PURE__ */ jsx29(
9215
9267
  "span",
9216
9268
  {
9217
9269
  className: "qt-metric-swatch",
9218
9270
  style: { background: e.color }
9219
9271
  }
9220
9272
  ),
9221
- /* @__PURE__ */ jsx28("span", { children: e.label })
9273
+ /* @__PURE__ */ jsx29("span", { className: "qt-metric-legend-label", children: e.label }),
9274
+ e.value !== void 0 && /* @__PURE__ */ jsx29("span", { className: "qt-metric-legend-value", children: e.value }),
9275
+ e.share !== void 0 && /* @__PURE__ */ jsx29("span", { className: "qt-metric-legend-share", children: e.share })
9222
9276
  ] }, e.key))
9223
9277
  }
9224
9278
  )
9225
9279
  ]
9226
9280
  }
9227
9281
  ),
9228
- compact && !compactBox && !["pie", "donut"].includes(kind) && /* @__PURE__ */ jsxs24("div", { className: "qt-metric-axis-labels", children: [
9229
- /* @__PURE__ */ jsxs24("span", { title: yAxisLabel, children: [
9230
- /* @__PURE__ */ jsx28("span", { "aria-hidden": "true", children: "\u2191 " }),
9282
+ compact && !compactBox && !["pie", "donut"].includes(kind) && /* @__PURE__ */ jsxs25("div", { className: "qt-metric-axis-labels", children: [
9283
+ /* @__PURE__ */ jsxs25("span", { title: yAxisLabel, children: [
9284
+ /* @__PURE__ */ jsx29("span", { "aria-hidden": "true", children: "\u2191 " }),
9231
9285
  yAxisLabel
9232
9286
  ] }),
9233
- /* @__PURE__ */ jsxs24("span", { title: xAxisLabel, children: [
9234
- /* @__PURE__ */ jsx28("span", { "aria-hidden": "true", children: "\u2192 " }),
9287
+ /* @__PURE__ */ jsxs25("span", { title: xAxisLabel, children: [
9288
+ /* @__PURE__ */ jsx29("span", { "aria-hidden": "true", children: "\u2192 " }),
9235
9289
  xAxisLabel
9236
9290
  ] })
9237
9291
  ] }),
9238
- compactBox && /* @__PURE__ */ jsxs24("p", { className: "qt-metric-compact-guide", children: [
9239
- "Box: middle 50% \xB7 line: median",
9240
- /* @__PURE__ */ jsx28("br", {}),
9241
- "Per-row scales \xB7 outliers omitted"
9292
+ compactBox && /* @__PURE__ */ jsxs25("p", { className: "qt-metric-compact-guide", children: [
9293
+ "Shared ",
9294
+ display2.xScale?.mode === "log" ? "log " : "",
9295
+ "axis \xB7 Box: middle 50% \xB7 line: median \xB7 dots: outliers and extremes"
9242
9296
  ] }),
9243
- tooltip && /* @__PURE__ */ jsx28("div", { id: tooltipId, role: "tooltip", className: "qt-metric-tooltip", children: tooltip }),
9244
- !problem && scaleNotes.length > 0 && /* @__PURE__ */ jsx28("p", { className: "qt-metric-note", role: "status", children: [...new Set(scaleNotes)].join(" ") }),
9245
- !problem && disclosure && /* @__PURE__ */ jsx28("p", { className: "qt-metric-note", role: "status", children: disclosure.trim() }),
9246
- /* @__PURE__ */ jsx28("p", { className: "qt-metric-note qt-sr-only", children: note })
9297
+ !problem && scaleNotes.length > 0 && /* @__PURE__ */ jsx29("p", { className: "qt-metric-note", role: "status", children: [...new Set(scaleNotes)].join(" ") }),
9298
+ !problem && disclosure && /* @__PURE__ */ jsx29("p", { className: "qt-metric-note", role: "status", children: disclosure.trim() }),
9299
+ /* @__PURE__ */ jsx29("p", { className: "qt-metric-note qt-sr-only", children: note })
9247
9300
  ] });
9248
9301
  }
9249
9302
  function horizontalLabel(kind, clause) {
@@ -9251,7 +9304,7 @@ function horizontalLabel(kind, clause) {
9251
9304
  }
9252
9305
 
9253
9306
  // src/MetricsPanel.tsx
9254
- import { jsx as jsx29, jsxs as jsxs25 } from "react/jsx-runtime";
9307
+ import { jsx as jsx30, jsxs as jsxs26 } from "react/jsx-runtime";
9255
9308
  var cx4 = (...parts) => parts.filter((p) => Boolean(p)).join(" ");
9256
9309
  var OP_LABELS = {
9257
9310
  count: "Count",
@@ -9277,11 +9330,11 @@ function MetricsPanel({
9277
9330
  }) {
9278
9331
  if (api?.query.grouping && api.schema) fields = api.schema.fields;
9279
9332
  const { clauses, results, loading, error } = aggregations;
9280
- const [editing, setEditing] = useState24(null);
9333
+ const [editing, setEditing] = useState25(null);
9281
9334
  const editMetric = onEditMetric ?? (api ? (id) => setEditing({ id, view: "editor" }) : void 0);
9282
9335
  const editDashboard = onEditDashboard ?? (api ? () => setEditing({ view: "editor" }) : void 0);
9283
9336
  if (clauses.length === 0) {
9284
- return emptyMessage ? /* @__PURE__ */ jsx29(
9337
+ return emptyMessage ? /* @__PURE__ */ jsx30(
9285
9338
  "div",
9286
9339
  {
9287
9340
  className: cx4("qt-metrics", classNames?.root),
@@ -9291,13 +9344,13 @@ function MetricsPanel({
9291
9344
  ) : null;
9292
9345
  }
9293
9346
  const resultById = new Map((results?.metrics ?? []).map((m) => [m.id, m]));
9294
- return /* @__PURE__ */ jsxs25(
9347
+ return /* @__PURE__ */ jsxs26(
9295
9348
  "div",
9296
9349
  {
9297
9350
  className: cx4("qt-metrics", classNames?.root),
9298
9351
  style: metricThemeStyle(theme),
9299
9352
  children: [
9300
- editDashboard && /* @__PURE__ */ jsx29("div", { className: "qt-metrics-toolbar", children: /* @__PURE__ */ jsxs25(
9353
+ editDashboard && /* @__PURE__ */ jsx30("div", { className: "qt-metrics-toolbar", children: /* @__PURE__ */ jsxs26(
9301
9354
  "button",
9302
9355
  {
9303
9356
  type: "button",
@@ -9307,13 +9360,13 @@ function MetricsPanel({
9307
9360
  title: "Edit metrics",
9308
9361
  onClick: editDashboard,
9309
9362
  children: [
9310
- /* @__PURE__ */ jsx29(Icon, { name: "pencil" }),
9363
+ /* @__PURE__ */ jsx30(Icon, { name: "pencil" }),
9311
9364
  "Edit",
9312
- /* @__PURE__ */ jsx29(Icon, { name: "chevronRight", size: 14 })
9365
+ /* @__PURE__ */ jsx30(Icon, { name: "chevronRight", size: 14 })
9313
9366
  ]
9314
9367
  }
9315
9368
  ) }),
9316
- editing && api && /* @__PURE__ */ jsx29(
9369
+ editing && api && /* @__PURE__ */ jsx30(
9317
9370
  MetricsEditor,
9318
9371
  {
9319
9372
  api,
@@ -9325,11 +9378,11 @@ function MetricsPanel({
9325
9378
  onClose: () => setEditing(null)
9326
9379
  }
9327
9380
  ),
9328
- error ? /* @__PURE__ */ jsxs25("div", { className: "qt-metrics-error", children: [
9381
+ error ? /* @__PURE__ */ jsxs26("div", { className: "qt-metrics-error", children: [
9329
9382
  "Metrics failed: ",
9330
9383
  error.message
9331
9384
  ] }) : null,
9332
- clauses.map((clause) => /* @__PURE__ */ jsx29(
9385
+ clauses.map((clause) => /* @__PURE__ */ jsx30(
9333
9386
  MetricCard,
9334
9387
  {
9335
9388
  clause,
@@ -9378,7 +9431,7 @@ function MetricCard({
9378
9431
  const fmt = (v) => {
9379
9432
  if (clause.display?.format) {
9380
9433
  const out = formatMetricOutput(v, clause.display.format, locale);
9381
- return /* @__PURE__ */ jsx29(
9434
+ return /* @__PURE__ */ jsx30(
9382
9435
  "span",
9383
9436
  {
9384
9437
  title: out.error,
@@ -9422,16 +9475,16 @@ function MetricCard({
9422
9475
  const problem = result?.error ?? metricPresentationProblem(clause) ?? invalidDistribution ?? ((kind === "value" || kind === "auto" && !clause.groupBy.length) && (buckets.length > 1 || buckets.some((b) => b.keys.length > 0)) ? "Value display requires one ungrouped result. Choose Table or List, or correct the result grouping." : void 0);
9423
9476
  let body;
9424
9477
  if (problem)
9425
- body = /* @__PURE__ */ jsx29("div", { className: "qt-metrics-error", role: "status", children: problem });
9478
+ body = /* @__PURE__ */ jsx30("div", { className: "qt-metrics-error", role: "status", children: problem });
9426
9479
  else if (loading && buckets.length === 0)
9427
- body = /* @__PURE__ */ jsxs25("div", { className: "qt-metric-loading", role: "status", children: [
9428
- /* @__PURE__ */ jsx29("span", { className: "qt-metric-spinner", "aria-hidden": "true" }),
9429
- /* @__PURE__ */ jsx29("span", { className: "qt-sr-only", children: "Loading metric" })
9480
+ body = /* @__PURE__ */ jsxs26("div", { className: "qt-metric-loading", role: "status", children: [
9481
+ /* @__PURE__ */ jsx30("span", { className: "qt-metric-spinner", "aria-hidden": "true" }),
9482
+ /* @__PURE__ */ jsx30("span", { className: "qt-sr-only", children: "Loading metric" })
9430
9483
  ] });
9431
9484
  else if (!buckets.length)
9432
- body = /* @__PURE__ */ jsx29("div", { className: "qt-metric-empty", children: "no data" });
9485
+ body = /* @__PURE__ */ jsx30("div", { className: "qt-metric-empty", children: "no data" });
9433
9486
  else if (chart)
9434
- body = /* @__PURE__ */ jsx29(
9487
+ body = /* @__PURE__ */ jsx30(
9435
9488
  MetricChart,
9436
9489
  {
9437
9490
  compact,
@@ -9445,9 +9498,9 @@ function MetricCard({
9445
9498
  }
9446
9499
  );
9447
9500
  else if (kind === "value" || kind === "auto" && clause.groupBy.length === 0)
9448
- body = /* @__PURE__ */ jsx29(BigNumber, { bucket: buckets[0], fmt });
9501
+ body = /* @__PURE__ */ jsx30(BigNumber, { bucket: buckets[0], fmt });
9449
9502
  else if (kind === "list" || kind === "auto" && clause.groupBy.length === 1)
9450
- body = /* @__PURE__ */ jsx29(
9503
+ body = /* @__PURE__ */ jsx30(
9451
9504
  BarList,
9452
9505
  {
9453
9506
  clause,
@@ -9458,7 +9511,7 @@ function MetricCard({
9458
9511
  }
9459
9512
  );
9460
9513
  else if (clause.groupBy.length === 2)
9461
- body = /* @__PURE__ */ jsx29(
9514
+ body = /* @__PURE__ */ jsx30(
9462
9515
  Pivot,
9463
9516
  {
9464
9517
  clause,
@@ -9470,7 +9523,7 @@ function MetricCard({
9470
9523
  }
9471
9524
  );
9472
9525
  else
9473
- body = /* @__PURE__ */ jsx29(
9526
+ body = /* @__PURE__ */ jsx30(
9474
9527
  FlatTable,
9475
9528
  {
9476
9529
  clause,
@@ -9481,19 +9534,20 @@ function MetricCard({
9481
9534
  valueLabel: clause.display?.valueLabel ?? metricTitle(clause, measure)
9482
9535
  }
9483
9536
  );
9484
- return /* @__PURE__ */ jsxs25(
9537
+ return /* @__PURE__ */ jsxs26(
9485
9538
  "div",
9486
9539
  {
9487
9540
  className: cx4(
9488
9541
  "qt-metric",
9489
9542
  `qt-metric--gb${Math.min(clause.groupBy.length, 3)}`,
9490
9543
  chart && "qt-metric--chart",
9544
+ compact && "qt-metric--compact",
9491
9545
  className,
9492
9546
  classNames?.metric
9493
9547
  ),
9494
9548
  style: { ...metricThemeStyle(theme), ...size3 },
9495
9549
  children: [
9496
- onEdit && /* @__PURE__ */ jsx29(
9550
+ onEdit && /* @__PURE__ */ jsx30(
9497
9551
  "button",
9498
9552
  {
9499
9553
  type: "button",
@@ -9501,32 +9555,32 @@ function MetricCard({
9501
9555
  "aria-label": `Edit metric ${metricTitle(clause, measure)}`,
9502
9556
  title: "Edit metric",
9503
9557
  onClick: onEdit,
9504
- children: /* @__PURE__ */ jsx29(Icon, { name: "pencil" })
9558
+ children: /* @__PURE__ */ jsx30(Icon, { name: "pencil" })
9505
9559
  }
9506
9560
  ),
9507
- /* @__PURE__ */ jsxs25("div", { className: "qt-metric-head", children: [
9508
- /* @__PURE__ */ jsx29("span", { className: cx4("qt-metric-title", classNames?.title), children: metricTitle(clause, measure) }),
9509
- groupLabels.length > 0 && /* @__PURE__ */ jsxs25("span", { className: "qt-metric-by", children: [
9561
+ /* @__PURE__ */ jsxs26("div", { className: "qt-metric-head", children: [
9562
+ /* @__PURE__ */ jsx30("span", { className: cx4("qt-metric-title", classNames?.title), children: metricTitle(clause, measure) }),
9563
+ groupLabels.length > 0 && /* @__PURE__ */ jsxs26("span", { className: "qt-metric-by", children: [
9510
9564
  "by ",
9511
9565
  groupLabels.join(" \xD7 ")
9512
9566
  ] })
9513
9567
  ] }),
9514
- result?.coverage === "partial" && /* @__PURE__ */ jsx29("p", { className: "qt-metric-note", role: "status", children: "Partial results" }),
9568
+ result?.coverage === "partial" && /* @__PURE__ */ jsx30("p", { className: "qt-metric-note", role: "status", children: "Partial results" }),
9515
9569
  body,
9516
- keyedLimit ? buckets !== allBuckets && /* @__PURE__ */ jsxs25("p", { className: "qt-metric-note", children: [
9570
+ keyedLimit ? buckets !== allBuckets && /* @__PURE__ */ jsxs26("p", { className: "qt-metric-note", children: [
9517
9571
  "Showing the first ",
9518
9572
  clause.display?.maxGroups,
9519
9573
  " ",
9520
9574
  keyedLimit.unit,
9521
9575
  " in result order."
9522
- ] }) : buckets !== allBuckets && allBuckets.length > (clause.display?.maxGroups ?? allBuckets.length) && /* @__PURE__ */ jsxs25("p", { className: "qt-metric-note", children: [
9576
+ ] }) : buckets !== allBuckets && allBuckets.length > (clause.display?.maxGroups ?? allBuckets.length) && /* @__PURE__ */ jsxs26("p", { className: "qt-metric-note", children: [
9523
9577
  "Showing the first ",
9524
9578
  clause.display?.maxGroups,
9525
9579
  " groups in result order",
9526
9580
  buckets.length > clause.display.maxGroups ? " plus Other" : "",
9527
9581
  "."
9528
9582
  ] }),
9529
- result?.groupCount !== void 0 && result.groupCount > allBuckets.length && /* @__PURE__ */ jsxs25("p", { className: "qt-metric-note", children: [
9583
+ result?.groupCount !== void 0 && result.groupCount > allBuckets.length && /* @__PURE__ */ jsxs26("p", { className: "qt-metric-note", children: [
9530
9584
  allBuckets.length,
9531
9585
  " of ",
9532
9586
  result.groupCount,
@@ -9540,9 +9594,9 @@ function BigNumber({
9540
9594
  bucket,
9541
9595
  fmt
9542
9596
  }) {
9543
- return /* @__PURE__ */ jsxs25("div", { className: "qt-metric-big", children: [
9544
- /* @__PURE__ */ jsx29("span", { className: "qt-metric-big-value", children: bucket.error ?? fmt(bucket.value) }),
9545
- /* @__PURE__ */ jsxs25("span", { className: "qt-metric-big-sub", children: [
9597
+ return /* @__PURE__ */ jsxs26("div", { className: "qt-metric-big", children: [
9598
+ /* @__PURE__ */ jsx30("span", { className: "qt-metric-big-value", children: bucket.error ?? fmt(bucket.value) }),
9599
+ /* @__PURE__ */ jsxs26("span", { className: "qt-metric-big-sub", children: [
9546
9600
  bucket.count.toLocaleString(),
9547
9601
  " rows"
9548
9602
  ] })
@@ -9565,9 +9619,9 @@ function BarList({
9565
9619
  clause.display?.xScale,
9566
9620
  true
9567
9621
  );
9568
- return /* @__PURE__ */ jsx29("div", { className: "qt-metric-bars", children: buckets.map((b, i) => {
9622
+ return /* @__PURE__ */ jsx30("div", { className: "qt-metric-bars", children: buckets.map((b, i) => {
9569
9623
  const pct = typeof b.value === "number" && !b.error && axis.accepts(b.value) ? Math.max(0, Math.min(1, axis.fraction(b.value))) * 100 : 0;
9570
- return /* @__PURE__ */ jsxs25(
9624
+ return /* @__PURE__ */ jsxs26(
9571
9625
  "div",
9572
9626
  {
9573
9627
  className: `qt-metric-bar-row${below ? " qt-metric-bar-row--below" : ""}`,
@@ -9575,14 +9629,14 @@ function BarList({
9575
9629
  gridTemplateColumns: below ? `minmax(0, 1fr)${showValues ? " auto" : ""}` : `minmax(3.375rem, 38%) ${showBars ? "1fr " : ""}${showValues ? "auto" : ""}`
9576
9630
  },
9577
9631
  children: [
9578
- /* @__PURE__ */ jsxs25(
9632
+ /* @__PURE__ */ jsxs26(
9579
9633
  "span",
9580
9634
  {
9581
9635
  className: `qt-metric-bar-label${maxLabelLines ? " qt-metric-bar-label--clamped" : ""}`,
9582
9636
  style: maxLabelLines ? { WebkitLineClamp: maxLabelLines } : void 0,
9583
9637
  title: metricGroupLabel(b, clause, locale, true),
9584
9638
  children: [
9585
- options?.useGroupColors && /* @__PURE__ */ jsx29(
9639
+ options?.useGroupColors && /* @__PURE__ */ jsx30(
9586
9640
  "span",
9587
9641
  {
9588
9642
  className: "qt-metric-swatch",
@@ -9596,7 +9650,7 @@ function BarList({
9596
9650
  ]
9597
9651
  }
9598
9652
  ),
9599
- showBars && /* @__PURE__ */ jsx29("span", { className: "qt-metric-bar-track", children: /* @__PURE__ */ jsx29(
9653
+ showBars && /* @__PURE__ */ jsx30("span", { className: "qt-metric-bar-track", children: /* @__PURE__ */ jsx30(
9600
9654
  "span",
9601
9655
  {
9602
9656
  className: "qt-metric-bar-fill",
@@ -9608,7 +9662,7 @@ function BarList({
9608
9662
  }
9609
9663
  }
9610
9664
  ) }),
9611
- showValues && /* @__PURE__ */ jsx29("span", { className: "qt-metric-bar-value", children: b.error ?? fmt(b.value) })
9665
+ showValues && /* @__PURE__ */ jsx30("span", { className: "qt-metric-bar-value", children: b.error ?? fmt(b.value) })
9612
9666
  ]
9613
9667
  },
9614
9668
  `${keyText(b.keys[0])}-${i}`
@@ -9641,22 +9695,22 @@ function Pivot({
9641
9695
  metricTupleKey([b.keys[rowAxis] ?? null, b.keys[colAxis] ?? null]),
9642
9696
  b
9643
9697
  );
9644
- return /* @__PURE__ */ jsx29("div", { className: "qt-metric-pivot-wrap", children: /* @__PURE__ */ jsxs25("table", { className: "qt-metric-pivot", children: [
9645
- /* @__PURE__ */ jsx29("thead", { children: /* @__PURE__ */ jsxs25("tr", { children: [
9646
- /* @__PURE__ */ jsx29("th", { className: "qt-metric-pivot-corner", children: /* @__PURE__ */ jsxs25("span", { className: "qt-metric-pivot-axes", children: [
9698
+ return /* @__PURE__ */ jsx30("div", { className: "qt-metric-pivot-wrap", children: /* @__PURE__ */ jsxs26("table", { className: "qt-metric-pivot", children: [
9699
+ /* @__PURE__ */ jsx30("thead", { children: /* @__PURE__ */ jsxs26("tr", { children: [
9700
+ /* @__PURE__ */ jsx30("th", { className: "qt-metric-pivot-corner", children: /* @__PURE__ */ jsxs26("span", { className: "qt-metric-pivot-axes", children: [
9647
9701
  rowLabel,
9648
9702
  " ",
9649
- /* @__PURE__ */ jsx29("span", { className: "qt-muted", children: "\\" }),
9703
+ /* @__PURE__ */ jsx30("span", { className: "qt-muted", children: "\\" }),
9650
9704
  " ",
9651
9705
  colLabel
9652
9706
  ] }) }),
9653
- colKeys.map((c) => /* @__PURE__ */ jsx29("th", { className: "qt-metric-pivot-col", children: keyNode(c, colAxis, clause, locale) }, typedMetricKey(c)))
9707
+ colKeys.map((c) => /* @__PURE__ */ jsx30("th", { className: "qt-metric-pivot-col", children: keyNode(c, colAxis, clause, locale) }, typedMetricKey(c)))
9654
9708
  ] }) }),
9655
- /* @__PURE__ */ jsx29("tbody", { children: rowKeys.map((r) => /* @__PURE__ */ jsxs25("tr", { children: [
9656
- /* @__PURE__ */ jsx29("th", { className: "qt-metric-pivot-row", children: keyNode(r, rowAxis, clause, locale) }),
9709
+ /* @__PURE__ */ jsx30("tbody", { children: rowKeys.map((r) => /* @__PURE__ */ jsxs26("tr", { children: [
9710
+ /* @__PURE__ */ jsx30("th", { className: "qt-metric-pivot-row", children: keyNode(r, rowAxis, clause, locale) }),
9657
9711
  colKeys.map((c) => {
9658
9712
  const v = cell.get(metricTupleKey([r, c]));
9659
- return /* @__PURE__ */ jsx29("td", { className: "qt-metric-pivot-cell", children: v === void 0 ? /* @__PURE__ */ jsx29("span", { className: "qt-muted", children: "\xB7" }) : v.error ?? fmt(v.value) }, typedMetricKey(c));
9713
+ return /* @__PURE__ */ jsx30("td", { className: "qt-metric-pivot-cell", children: v === void 0 ? /* @__PURE__ */ jsx30("span", { className: "qt-muted", children: "\xB7" }) : v.error ?? fmt(v.value) }, typedMetricKey(c));
9660
9714
  })
9661
9715
  ] }, typedMetricKey(r))) })
9662
9716
  ] }) });
@@ -9669,14 +9723,14 @@ function FlatTable({
9669
9723
  clause,
9670
9724
  locale
9671
9725
  }) {
9672
- return /* @__PURE__ */ jsx29("div", { className: "qt-metric-pivot-wrap", children: /* @__PURE__ */ jsxs25("table", { className: "qt-metric-flat", children: [
9673
- /* @__PURE__ */ jsx29("thead", { children: /* @__PURE__ */ jsxs25("tr", { children: [
9674
- groupLabels.map((g) => /* @__PURE__ */ jsx29("th", { children: g }, g)),
9675
- /* @__PURE__ */ jsx29("th", { className: "qt-metric-flat-value", children: valueLabel2 })
9726
+ return /* @__PURE__ */ jsx30("div", { className: "qt-metric-pivot-wrap", children: /* @__PURE__ */ jsxs26("table", { className: "qt-metric-flat", children: [
9727
+ /* @__PURE__ */ jsx30("thead", { children: /* @__PURE__ */ jsxs26("tr", { children: [
9728
+ groupLabels.map((g) => /* @__PURE__ */ jsx30("th", { children: g }, g)),
9729
+ /* @__PURE__ */ jsx30("th", { className: "qt-metric-flat-value", children: valueLabel2 })
9676
9730
  ] }) }),
9677
- /* @__PURE__ */ jsx29("tbody", { children: buckets.map((b, i) => /* @__PURE__ */ jsxs25("tr", { children: [
9678
- groupLabels.map((_, j) => /* @__PURE__ */ jsx29("td", { children: keyNode(b.keys[j], j, clause, locale) }, j)),
9679
- /* @__PURE__ */ jsx29("td", { className: "qt-metric-flat-value", children: b.error ?? fmt(b.value) })
9731
+ /* @__PURE__ */ jsx30("tbody", { children: buckets.map((b, i) => /* @__PURE__ */ jsxs26("tr", { children: [
9732
+ groupLabels.map((_, j) => /* @__PURE__ */ jsx30("td", { children: keyNode(b.keys[j], j, clause, locale) }, j)),
9733
+ /* @__PURE__ */ jsx30("td", { className: "qt-metric-flat-value", children: b.error ?? fmt(b.value) })
9680
9734
  ] }, i)) })
9681
9735
  ] }) });
9682
9736
  }
@@ -9691,7 +9745,7 @@ var UNIT_RENDER_KEYS = /* @__PURE__ */ new Set([
9691
9745
  "byte_size"
9692
9746
  ]);
9693
9747
  function formatMetricValue(value, op, measure, renderers, decimals) {
9694
- if (value == null) return /* @__PURE__ */ jsx29("span", { className: "qt-muted", children: "\u2014" });
9748
+ if (value == null) return /* @__PURE__ */ jsx30("span", { className: "qt-muted", children: "\u2014" });
9695
9749
  if (op === "count" || op === "count_distinct") {
9696
9750
  return typeof value === "number" ? formatNumber(value, 0) : String(value);
9697
9751
  }
@@ -9757,7 +9811,7 @@ function keyText(k) {
9757
9811
  return k == null ? NULL_KEY : String(k);
9758
9812
  }
9759
9813
  function keyNode(k, axis, clause, locale) {
9760
- return k == null ? /* @__PURE__ */ jsx29("span", { className: "qt-muted", children: NULL_KEY }) : metricGroupKeyLabel(k, axis, clause, locale);
9814
+ return k == null ? /* @__PURE__ */ jsx30("span", { className: "qt-muted", children: NULL_KEY }) : metricGroupKeyLabel(k, axis, clause, locale);
9761
9815
  }
9762
9816
 
9763
9817
  // src/useMetricWorkbench.ts
@@ -9773,7 +9827,7 @@ function useMetricWorkbench(isEditor = true) {
9773
9827
 
9774
9828
  // src/MetricsEditor.tsx
9775
9829
  import { FORMULA_FUNCTIONS as FORMULA_FUNCTIONS2 } from "@pythia-software/query-table-core";
9776
- import { Fragment as Fragment19, jsx as jsx30, jsxs as jsxs26 } from "react/jsx-runtime";
9830
+ import { Fragment as Fragment19, jsx as jsx31, jsxs as jsxs27 } from "react/jsx-runtime";
9777
9831
  var FormulaEditor3 = lazy2(() => import("./FormulaEditor-NZWSPFJQ.js"));
9778
9832
  var clone = (value) => JSON.parse(JSON.stringify(value));
9779
9833
  var fieldSource = (name) => `[${name.replace(/\]/g, "]]")}]`;
@@ -9817,21 +9871,21 @@ function MetricsEditor({
9817
9871
  const titleId = useId8();
9818
9872
  const initial = useRef18(clone(api.aggregations.clauses));
9819
9873
  const initialKey = useRef18(JSON.stringify(initial.current));
9820
- const [drafts, setDrafts] = useState25(initial.current);
9821
- const [active, setActive] = useState25(
9874
+ const [drafts, setDrafts] = useState26(initial.current);
9875
+ const [active, setActive] = useState26(
9822
9876
  initialMetricId ?? initial.current[0]?.id ?? ""
9823
9877
  );
9824
- const [view, setView] = useState25(initialView);
9825
- const [discard, setDiscard] = useState25(false);
9826
- const [error, setError] = useState25(null);
9827
- const [announcement, setAnnouncement] = useState25("");
9828
- const [preview, setPreview] = useState25(null);
9829
- const [previewLoading, setPreviewLoading] = useState25(false);
9830
- const [retry, setRetry] = useState25(0);
9831
- const [canvas, setCanvas] = useState25(1120);
9832
- const [returnMetric, setReturnMetric] = useState25(null);
9833
- const [removed, setRemoved] = useState25(null);
9834
- const [openSettings, setOpenSettings] = useState25({});
9878
+ const [view, setView] = useState26(initialView);
9879
+ const [discard, setDiscard] = useState26(false);
9880
+ const [error, setError] = useState26(null);
9881
+ const [announcement, setAnnouncement] = useState26("");
9882
+ const [preview, setPreview] = useState26(null);
9883
+ const [previewLoading, setPreviewLoading] = useState26(false);
9884
+ const [retry, setRetry] = useState26(0);
9885
+ const [canvas, setCanvas] = useState26(1120);
9886
+ const [returnMetric, setReturnMetric] = useState26(null);
9887
+ const [removed, setRemoved] = useState26(null);
9888
+ const [openSettings, setOpenSettings] = useState26({});
9835
9889
  const settingsState = (title) => ({
9836
9890
  open: openSettings[title] ?? false,
9837
9891
  onOpenChange: (open) => setOpenSettings(
@@ -9841,23 +9895,23 @@ function MetricsEditor({
9841
9895
  const geometryDrag = useMetricResize();
9842
9896
  const canvasElement = useRef18(null);
9843
9897
  const focusDestination = useRef18(false);
9844
- const [navigation, setNavigation] = useState25(0);
9898
+ const [navigation, setNavigation] = useState26(0);
9845
9899
  const paneScroll = useRef18([0, 0, 0, 0]);
9846
- const [previewSize, setPreviewSize] = useState25({ width: 320, height: 200 });
9847
- const [formatTarget, setFormatTarget] = useState25(
9900
+ const [previewSize, setPreviewSize] = useState26({ width: 320, height: 200 });
9901
+ const [formatTarget, setFormatTarget] = useState26(
9848
9902
  "value"
9849
9903
  );
9850
- const [reference, setReference] = useState25("fields");
9851
- const [referenceSearch, setReferenceSearch] = useState25({
9904
+ const [reference, setReference] = useState26("fields");
9905
+ const [referenceSearch, setReferenceSearch] = useState26({
9852
9906
  fields: "",
9853
9907
  functions: ""
9854
9908
  });
9855
9909
  const search = referenceSearch[reference];
9856
9910
  const setSearch = (value) => setReferenceSearch((previous) => ({ ...previous, [reference]: value }));
9857
- const [concept, setConcept] = useState25("all");
9858
- const [inspectOpen, setInspectOpen] = useState25(false);
9859
- const [inspectedKey, setInspectedKey] = useState25(null);
9860
- const [inputTarget, setInputTarget] = useState25(
9911
+ const [concept, setConcept] = useState26("all");
9912
+ const [inspectOpen, setInspectOpen] = useState26(false);
9913
+ const [inspectedKey, setInspectedKey] = useState26(null);
9914
+ const [inputTarget, setInputTarget] = useState26(
9861
9915
  "primary"
9862
9916
  );
9863
9917
  const pendingInsertion = useRef18(null);
@@ -10067,7 +10121,7 @@ function MetricsEditor({
10067
10121
  }
10068
10122
  function panelToggle(index, collapse = false) {
10069
10123
  const pane = panes4[index];
10070
- return /* @__PURE__ */ jsx30(
10124
+ return /* @__PURE__ */ jsx31(
10071
10125
  EditorPanelToggle,
10072
10126
  {
10073
10127
  workbench,
@@ -10080,8 +10134,8 @@ function MetricsEditor({
10080
10134
  );
10081
10135
  }
10082
10136
  function paneHeading(index, label) {
10083
- return /* @__PURE__ */ jsxs26("div", { className: "qt-metric-pane-heading", children: [
10084
- /* @__PURE__ */ jsx30("h3", { children: label }),
10137
+ return /* @__PURE__ */ jsxs27("div", { className: "qt-metric-pane-heading", children: [
10138
+ /* @__PURE__ */ jsx31("h3", { children: label }),
10085
10139
  panelToggle(index, true)
10086
10140
  ] });
10087
10141
  }
@@ -10290,16 +10344,16 @@ function MetricsEditor({
10290
10344
  const setFormat = (format) => displayPatch(
10291
10345
  formatTarget === "x" ? { xFormat: format } : formatTarget === "y" ? { yFormat: format } : { format }
10292
10346
  );
10293
- const menu = (c, index) => /* @__PURE__ */ jsx30("span", { className: "qt-metric-actions", children: /* @__PURE__ */ jsxs26(MenuButton, { label: `Actions for ${titleOf(c, fields)}`, width: 200, trigger: /* @__PURE__ */ jsx30("span", { "aria-hidden": true, children: "\u22EF" }), children: [
10294
- view === "dashboard" && /* @__PURE__ */ jsx30(MenuItem, { onSelect: () => navigate("editor", c.id), children: "Edit metric" }),
10295
- /* @__PURE__ */ jsx30(MenuItem, { disabled: drafts.length >= MAX_AGGREGATIONS, onSelect: () => duplicate(c), children: "Duplicate" }),
10296
- /* @__PURE__ */ jsx30(MenuItem, { disabled: index === 0, onSelect: () => move(c.id, index - 1), children: "Move up" }),
10297
- /* @__PURE__ */ jsx30(MenuItem, { disabled: index === drafts.length - 1, onSelect: () => move(c.id, index + 1), children: "Move down" }),
10298
- /* @__PURE__ */ jsx30(MenuSeparator, {}),
10299
- /* @__PURE__ */ jsx30(MenuItem, { tone: "danger", onSelect: () => remove(c.id), children: "Remove" })
10347
+ const menu = (c, index) => /* @__PURE__ */ jsx31("span", { className: "qt-metric-actions", children: /* @__PURE__ */ jsxs27(MenuButton, { label: `Actions for ${titleOf(c, fields)}`, width: 200, trigger: /* @__PURE__ */ jsx31("span", { "aria-hidden": true, children: "\u22EF" }), children: [
10348
+ view === "dashboard" && /* @__PURE__ */ jsx31(MenuItem, { onSelect: () => navigate("editor", c.id), children: "Edit metric" }),
10349
+ /* @__PURE__ */ jsx31(MenuItem, { disabled: drafts.length >= MAX_AGGREGATIONS, onSelect: () => duplicate(c), children: "Duplicate" }),
10350
+ /* @__PURE__ */ jsx31(MenuItem, { disabled: index === 0, onSelect: () => move(c.id, index - 1), children: "Move up" }),
10351
+ /* @__PURE__ */ jsx31(MenuItem, { disabled: index === drafts.length - 1, onSelect: () => move(c.id, index + 1), children: "Move down" }),
10352
+ /* @__PURE__ */ jsx31(MenuSeparator, {}),
10353
+ /* @__PURE__ */ jsx31(MenuItem, { tone: "danger", onSelect: () => remove(c.id), children: "Remove" })
10300
10354
  ] }) });
10301
- const sizeControls = selected && /* @__PURE__ */ jsx30("div", { className: "qt-metric-size-controls", children: ["widthRem", "heightRem", "minWidthRem", "minHeightRem"].map(
10302
- (key) => /* @__PURE__ */ jsxs26("label", { children: [
10355
+ const sizeControls = selected && /* @__PURE__ */ jsx31("div", { className: "qt-metric-size-controls", children: ["widthRem", "heightRem", "minWidthRem", "minHeightRem"].map(
10356
+ (key) => /* @__PURE__ */ jsxs27("label", { children: [
10303
10357
  {
10304
10358
  widthRem: "Width",
10305
10359
  heightRem: "Height",
@@ -10308,7 +10362,7 @@ function MetricsEditor({
10308
10362
  }[key],
10309
10363
  " ",
10310
10364
  "(rem)",
10311
- /* @__PURE__ */ jsx30(
10365
+ /* @__PURE__ */ jsx31(
10312
10366
  MetricNumberInput,
10313
10367
  {
10314
10368
  "aria-label": `${{ widthRem: "Width", heightRem: "Height", minWidthRem: "Min width", minHeightRem: "Min height" }[key]} in rem`,
@@ -10322,7 +10376,7 @@ function MetricsEditor({
10322
10376
  )
10323
10377
  ] }, key)
10324
10378
  ) });
10325
- const card = (c) => /* @__PURE__ */ jsx30(
10379
+ const card = (c) => /* @__PURE__ */ jsx31(
10326
10380
  MetricCard,
10327
10381
  {
10328
10382
  clause: c,
@@ -10337,7 +10391,7 @@ function MetricsEditor({
10337
10391
  } : void 0
10338
10392
  }
10339
10393
  );
10340
- return /* @__PURE__ */ jsxs26(
10394
+ return /* @__PURE__ */ jsxs27(
10341
10395
  EditorModal,
10342
10396
  {
10343
10397
  title: "Edit metrics",
@@ -10345,9 +10399,9 @@ function MetricsEditor({
10345
10399
  closeLabel: "Close metric editor",
10346
10400
  onClose: close,
10347
10401
  workbench,
10348
- headerActions: /* @__PURE__ */ jsxs26("label", { children: [
10349
- /* @__PURE__ */ jsx30("span", { className: "qt-sr-only", children: "Workbench view" }),
10350
- /* @__PURE__ */ jsxs26(
10402
+ headerActions: /* @__PURE__ */ jsxs27("label", { children: [
10403
+ /* @__PURE__ */ jsx31("span", { className: "qt-sr-only", children: "Workbench view" }),
10404
+ /* @__PURE__ */ jsxs27(
10351
10405
  "select",
10352
10406
  {
10353
10407
  "aria-label": "Workbench view",
@@ -10357,26 +10411,26 @@ function MetricsEditor({
10357
10411
  setView(e.target.value);
10358
10412
  },
10359
10413
  children: [
10360
- /* @__PURE__ */ jsx30("option", { value: "editor", children: "Metric editor" }),
10361
- /* @__PURE__ */ jsx30("option", { value: "dashboard", children: "Dashboard layout" })
10414
+ /* @__PURE__ */ jsx31("option", { value: "editor", children: "Metric editor" }),
10415
+ /* @__PURE__ */ jsx31("option", { value: "dashboard", children: "Dashboard layout" })
10362
10416
  ]
10363
10417
  }
10364
10418
  )
10365
10419
  ] }),
10366
- panelControls: view === "editor" && /* @__PURE__ */ jsxs26(
10420
+ panelControls: view === "editor" && /* @__PURE__ */ jsxs27(
10367
10421
  "div",
10368
10422
  {
10369
10423
  className: "qt-metric-panel-tools",
10370
10424
  role: "group",
10371
10425
  "aria-label": "Visible editor panels",
10372
10426
  children: [
10373
- /* @__PURE__ */ jsx30("span", { children: "Panels" }),
10374
- panes4.map((pane, i) => /* @__PURE__ */ jsx30("span", { children: panelToggle(i) }, pane.label))
10427
+ /* @__PURE__ */ jsx31("span", { children: "Panels" }),
10428
+ panes4.map((pane, i) => /* @__PURE__ */ jsx31("span", { children: panelToggle(i) }, pane.label))
10375
10429
  ]
10376
10430
  }
10377
10431
  ),
10378
10432
  children: [
10379
- /* @__PURE__ */ jsx30(
10433
+ /* @__PURE__ */ jsx31(
10380
10434
  EditorContext,
10381
10435
  {
10382
10436
  shown: api.rows.length,
@@ -10385,9 +10439,9 @@ function MetricsEditor({
10385
10439
  locale
10386
10440
  }
10387
10441
  ),
10388
- view === "editor" && /* @__PURE__ */ jsxs26("div", { className: "qt-metric-workbench-tools", children: [
10389
- /* @__PURE__ */ jsxs26("div", { className: "qt-metric-selection-tools", children: [
10390
- /* @__PURE__ */ jsxs26(
10442
+ view === "editor" && /* @__PURE__ */ jsxs27("div", { className: "qt-metric-workbench-tools", children: [
10443
+ /* @__PURE__ */ jsxs27("div", { className: "qt-metric-selection-tools", children: [
10444
+ /* @__PURE__ */ jsxs27(
10391
10445
  "select",
10392
10446
  {
10393
10447
  "aria-label": "Editing metric",
@@ -10395,12 +10449,12 @@ function MetricsEditor({
10395
10449
  onChange: (e) => setActive(e.target.value),
10396
10450
  disabled: !drafts.length,
10397
10451
  children: [
10398
- !drafts.length && /* @__PURE__ */ jsx30("option", { value: "", children: "No metrics yet" }),
10399
- orderItems.map((item) => /* @__PURE__ */ jsx30("option", { value: item.id, children: item.label }, item.id))
10452
+ !drafts.length && /* @__PURE__ */ jsx31("option", { value: "", children: "No metrics yet" }),
10453
+ orderItems.map((item) => /* @__PURE__ */ jsx31("option", { value: item.id, children: item.label }, item.id))
10400
10454
  ]
10401
10455
  }
10402
10456
  ),
10403
- /* @__PURE__ */ jsx30(
10457
+ /* @__PURE__ */ jsx31(
10404
10458
  "button",
10405
10459
  {
10406
10460
  type: "button",
@@ -10409,10 +10463,10 @@ function MetricsEditor({
10409
10463
  title: "Previous metric",
10410
10464
  disabled: selectedPosition <= 0,
10411
10465
  onClick: () => setActive(drafts[selectedPosition - 1].id),
10412
- children: /* @__PURE__ */ jsx30(Icon, { name: "arrowUp" })
10466
+ children: /* @__PURE__ */ jsx31(Icon, { name: "arrowUp" })
10413
10467
  }
10414
10468
  ),
10415
- /* @__PURE__ */ jsx30(
10469
+ /* @__PURE__ */ jsx31(
10416
10470
  "button",
10417
10471
  {
10418
10472
  type: "button",
@@ -10421,11 +10475,11 @@ function MetricsEditor({
10421
10475
  title: "Next metric",
10422
10476
  disabled: selectedPosition < 0 || selectedPosition >= drafts.length - 1,
10423
10477
  onClick: () => setActive(drafts[selectedPosition + 1].id),
10424
- children: /* @__PURE__ */ jsx30(Icon, { name: "arrowDown" })
10478
+ children: /* @__PURE__ */ jsx31(Icon, { name: "arrowDown" })
10425
10479
  }
10426
10480
  )
10427
10481
  ] }),
10428
- /* @__PURE__ */ jsxs26(
10482
+ /* @__PURE__ */ jsxs27(
10429
10483
  "button",
10430
10484
  {
10431
10485
  type: "button",
@@ -10433,20 +10487,20 @@ function MetricsEditor({
10433
10487
  disabled: !selected,
10434
10488
  onClick: seeInDashboard,
10435
10489
  children: [
10436
- /* @__PURE__ */ jsx30(Icon, { name: "dashboard" }),
10490
+ /* @__PURE__ */ jsx31(Icon, { name: "dashboard" }),
10437
10491
  "See in dashboard",
10438
- /* @__PURE__ */ jsx30(Icon, { name: "arrowRight", size: 14 })
10492
+ /* @__PURE__ */ jsx31(Icon, { name: "arrowRight", size: 14 })
10439
10493
  ]
10440
10494
  }
10441
10495
  )
10442
10496
  ] }),
10443
- view === "dashboard" ? /* @__PURE__ */ jsxs26("section", { className: "qt-metric-layout-editor", children: [
10444
- /* @__PURE__ */ jsxs26("div", { className: "qt-metric-canvas-controls", children: [
10445
- /* @__PURE__ */ jsxs26("div", { className: "qt-metric-canvas-heading", children: [
10446
- /* @__PURE__ */ jsx30("strong", { children: "Dashboard layout" }),
10447
- /* @__PURE__ */ jsx30("p", { className: "qt-metric-help", children: "Select a card to adjust it. Drag handles to reorder, corners to resize." })
10497
+ view === "dashboard" ? /* @__PURE__ */ jsxs27("section", { className: "qt-metric-layout-editor", children: [
10498
+ /* @__PURE__ */ jsxs27("div", { className: "qt-metric-canvas-controls", children: [
10499
+ /* @__PURE__ */ jsxs27("div", { className: "qt-metric-canvas-heading", children: [
10500
+ /* @__PURE__ */ jsx31("strong", { children: "Dashboard layout" }),
10501
+ /* @__PURE__ */ jsx31("p", { className: "qt-metric-help", children: "Select a card to adjust it. Drag handles to reorder, corners to resize." })
10448
10502
  ] }),
10449
- returnMetric && drafts.some((c) => c.id === returnMetric) && /* @__PURE__ */ jsxs26(
10503
+ returnMetric && drafts.some((c) => c.id === returnMetric) && /* @__PURE__ */ jsxs27(
10450
10504
  "button",
10451
10505
  {
10452
10506
  type: "button",
@@ -10457,12 +10511,12 @@ function MetricsEditor({
10457
10511
  )}`,
10458
10512
  onClick: () => navigate("editor", returnMetric),
10459
10513
  children: [
10460
- /* @__PURE__ */ jsx30(Icon, { name: "arrowLeft" }),
10514
+ /* @__PURE__ */ jsx31(Icon, { name: "arrowLeft" }),
10461
10515
  "Back to metric"
10462
10516
  ]
10463
10517
  }
10464
10518
  ),
10465
- /* @__PURE__ */ jsxs26(
10519
+ /* @__PURE__ */ jsxs27(
10466
10520
  "button",
10467
10521
  {
10468
10522
  type: "button",
@@ -10470,21 +10524,21 @@ function MetricsEditor({
10470
10524
  disabled: drafts.length >= MAX_AGGREGATIONS,
10471
10525
  onClick: createMetric,
10472
10526
  children: [
10473
- /* @__PURE__ */ jsx30(Icon, { name: "add" }),
10527
+ /* @__PURE__ */ jsx31(Icon, { name: "add" }),
10474
10528
  "Create metric"
10475
10529
  ]
10476
10530
  }
10477
10531
  ),
10478
- /* @__PURE__ */ jsxs26(
10532
+ /* @__PURE__ */ jsxs27(
10479
10533
  "div",
10480
10534
  {
10481
10535
  className: "qt-metric-canvas-presets",
10482
10536
  role: "group",
10483
10537
  "aria-label": "Viewport presets",
10484
10538
  children: [
10485
- /* @__PURE__ */ jsxs26("label", { children: [
10539
+ /* @__PURE__ */ jsxs27("label", { children: [
10486
10540
  "Canvas width (px)",
10487
- /* @__PURE__ */ jsx30(
10541
+ /* @__PURE__ */ jsx31(
10488
10542
  MetricNumberInput,
10489
10543
  {
10490
10544
  "aria-label": "Canvas width",
@@ -10496,8 +10550,8 @@ function MetricsEditor({
10496
10550
  }
10497
10551
  )
10498
10552
  ] }),
10499
- /* @__PURE__ */ jsx30("span", { children: "or preset" }),
10500
- [360, 768, 1200].map((width) => /* @__PURE__ */ jsxs26(
10553
+ /* @__PURE__ */ jsx31("span", { children: "or preset" }),
10554
+ [360, 768, 1200].map((width) => /* @__PURE__ */ jsxs27(
10501
10555
  "button",
10502
10556
  {
10503
10557
  type: "button",
@@ -10517,22 +10571,22 @@ function MetricsEditor({
10517
10571
  }
10518
10572
  )
10519
10573
  ] }),
10520
- /* @__PURE__ */ jsxs26("div", { className: "qt-metric-layout-controls", children: [
10521
- /* @__PURE__ */ jsxs26("label", { className: "qt-metric-layout-picker", children: [
10574
+ /* @__PURE__ */ jsxs27("div", { className: "qt-metric-layout-controls", children: [
10575
+ /* @__PURE__ */ jsxs27("label", { className: "qt-metric-layout-picker", children: [
10522
10576
  "Selected metric",
10523
- /* @__PURE__ */ jsx30(
10577
+ /* @__PURE__ */ jsx31(
10524
10578
  "select",
10525
10579
  {
10526
10580
  "aria-label": "Selected metric",
10527
10581
  value: active,
10528
10582
  onChange: (e) => setActive(e.target.value),
10529
- children: orderItems.map((item) => /* @__PURE__ */ jsx30("option", { value: item.id, children: item.label }, item.id))
10583
+ children: orderItems.map((item) => /* @__PURE__ */ jsx31("option", { value: item.id, children: item.label }, item.id))
10530
10584
  }
10531
10585
  )
10532
10586
  ] }),
10533
- selected && /* @__PURE__ */ jsxs26("label", { className: "qt-metric-layout-name", children: [
10587
+ selected && /* @__PURE__ */ jsxs27("label", { className: "qt-metric-layout-name", children: [
10534
10588
  "Name",
10535
- /* @__PURE__ */ jsx30(
10589
+ /* @__PURE__ */ jsx31(
10536
10590
  "input",
10537
10591
  {
10538
10592
  "aria-label": "Layout metric name",
@@ -10543,7 +10597,7 @@ function MetricsEditor({
10543
10597
  )
10544
10598
  ] }),
10545
10599
  sizeControls,
10546
- /* @__PURE__ */ jsx30(
10600
+ /* @__PURE__ */ jsx31(
10547
10601
  "button",
10548
10602
  {
10549
10603
  type: "button",
@@ -10554,20 +10608,20 @@ function MetricsEditor({
10554
10608
  }
10555
10609
  )
10556
10610
  ] }),
10557
- /* @__PURE__ */ jsx30("div", { className: "qt-metric-canvas-scroll", children: /* @__PURE__ */ jsxs26(
10611
+ /* @__PURE__ */ jsx31("div", { className: "qt-metric-canvas-scroll", children: /* @__PURE__ */ jsxs27(
10558
10612
  "div",
10559
10613
  {
10560
10614
  className: "qt-metric-canvas-frame",
10561
10615
  style: { width: canvas + 18 },
10562
10616
  children: [
10563
- /* @__PURE__ */ jsxs26(
10617
+ /* @__PURE__ */ jsxs27(
10564
10618
  "div",
10565
10619
  {
10566
10620
  ref: canvasElement,
10567
10621
  className: "qt-metric-layout-canvas",
10568
10622
  style: { width: canvas },
10569
10623
  children: [
10570
- /* @__PURE__ */ jsx30(
10624
+ /* @__PURE__ */ jsx31(
10571
10625
  ReorderList,
10572
10626
  {
10573
10627
  items: orderItems,
@@ -10588,7 +10642,7 @@ function MetricsEditor({
10588
10642
  },
10589
10643
  renderItem: (item, index) => {
10590
10644
  const c = drafts.find((d) => d.id === item.id);
10591
- return /* @__PURE__ */ jsxs26(
10645
+ return /* @__PURE__ */ jsxs27(
10592
10646
  "div",
10593
10647
  {
10594
10648
  className: "qt-metric-layout-card",
@@ -10617,7 +10671,7 @@ function MetricsEditor({
10617
10671
  }
10618
10672
  },
10619
10673
  children: [
10620
- /* @__PURE__ */ jsx30(
10674
+ /* @__PURE__ */ jsx31(
10621
10675
  "button",
10622
10676
  {
10623
10677
  type: "button",
@@ -10625,12 +10679,12 @@ function MetricsEditor({
10625
10679
  "aria-label": `Edit ${item.label}`,
10626
10680
  title: "Edit metric",
10627
10681
  onClick: () => navigate("editor", item.id),
10628
- children: /* @__PURE__ */ jsx30(Icon, { name: "pencil", size: 14 })
10682
+ children: /* @__PURE__ */ jsx31(Icon, { name: "pencil", size: 14 })
10629
10683
  }
10630
10684
  ),
10631
10685
  menu(c, index),
10632
10686
  card(c),
10633
- /* @__PURE__ */ jsx30(
10687
+ /* @__PURE__ */ jsx31(
10634
10688
  "button",
10635
10689
  {
10636
10690
  type: "button",
@@ -10700,7 +10754,7 @@ function MetricsEditor({
10700
10754
  if (layout.widthRem !== base.widthRem || layout.heightRem !== base.heightRem)
10701
10755
  patch(c.id, { layout });
10702
10756
  },
10703
- children: /* @__PURE__ */ jsx30(Icon, { name: "resize", size: 14 })
10757
+ children: /* @__PURE__ */ jsx31(Icon, { name: "resize", size: 14 })
10704
10758
  }
10705
10759
  )
10706
10760
  ]
@@ -10709,18 +10763,18 @@ function MetricsEditor({
10709
10763
  }
10710
10764
  }
10711
10765
  ),
10712
- !drafts.length && /* @__PURE__ */ jsxs26("div", { className: "qt-metric-authoring-empty", children: [
10713
- /* @__PURE__ */ jsx30(Icon, { name: "dashboard", size: 28 }),
10714
- /* @__PURE__ */ jsx30("strong", { children: "Your dashboard is empty" }),
10715
- /* @__PURE__ */ jsx30("p", { children: "Create a metric to start arranging your dashboard." }),
10716
- /* @__PURE__ */ jsxs26(
10766
+ !drafts.length && /* @__PURE__ */ jsxs27("div", { className: "qt-metric-authoring-empty", children: [
10767
+ /* @__PURE__ */ jsx31(Icon, { name: "dashboard", size: 28 }),
10768
+ /* @__PURE__ */ jsx31("strong", { children: "Your dashboard is empty" }),
10769
+ /* @__PURE__ */ jsx31("p", { children: "Create a metric to start arranging your dashboard." }),
10770
+ /* @__PURE__ */ jsxs27(
10717
10771
  "button",
10718
10772
  {
10719
10773
  type: "button",
10720
10774
  className: "qt-btn",
10721
10775
  onClick: createMetric,
10722
10776
  children: [
10723
- /* @__PURE__ */ jsx30(Icon, { name: "add" }),
10777
+ /* @__PURE__ */ jsx31(Icon, { name: "add" }),
10724
10778
  "Create your first metric"
10725
10779
  ]
10726
10780
  }
@@ -10729,7 +10783,7 @@ function MetricsEditor({
10729
10783
  ]
10730
10784
  }
10731
10785
  ),
10732
- /* @__PURE__ */ jsx30(
10786
+ /* @__PURE__ */ jsx31(
10733
10787
  "div",
10734
10788
  {
10735
10789
  className: "qt-metric-canvas-resize",
@@ -10763,17 +10817,17 @@ function MetricsEditor({
10763
10817
  );
10764
10818
  }
10765
10819
  },
10766
- children: /* @__PURE__ */ jsx30(Icon, { name: "grip", size: 14 })
10820
+ children: /* @__PURE__ */ jsx31(Icon, { name: "grip", size: 14 })
10767
10821
  }
10768
10822
  )
10769
10823
  ]
10770
10824
  }
10771
10825
  ) }),
10772
- /* @__PURE__ */ jsxs26("p", { className: "qt-metric-canvas-note qt-metric-help", children: [
10826
+ /* @__PURE__ */ jsxs27("p", { className: "qt-metric-canvas-note qt-metric-help", children: [
10773
10827
  canvas,
10774
10828
  " px canvas \xB7 Drag the right edge to test wrapping. Card widths are preferred sizes; cards expand to fill each row."
10775
10829
  ] })
10776
- ] }) : /* @__PURE__ */ jsxs26(
10830
+ ] }) : /* @__PURE__ */ jsxs27(
10777
10831
  "div",
10778
10832
  {
10779
10833
  ref: workbench.root,
@@ -10782,7 +10836,7 @@ function MetricsEditor({
10782
10836
  gridTemplateColumns: workbench.visibleIndices.map((i) => `${workbench.widths[i]}px`).join(" 6px ")
10783
10837
  },
10784
10838
  children: [
10785
- /* @__PURE__ */ jsxs26(
10839
+ /* @__PURE__ */ jsxs27(
10786
10840
  "aside",
10787
10841
  {
10788
10842
  className: "qt-metric-library",
@@ -10791,15 +10845,15 @@ function MetricsEditor({
10791
10845
  children: [
10792
10846
  paneHeading(
10793
10847
  0,
10794
- /* @__PURE__ */ jsxs26(Fragment19, { children: [
10848
+ /* @__PURE__ */ jsxs27(Fragment19, { children: [
10795
10849
  "In this query ",
10796
- /* @__PURE__ */ jsxs26("span", { children: [
10850
+ /* @__PURE__ */ jsxs27("span", { children: [
10797
10851
  "\xB7 ",
10798
10852
  drafts.length
10799
10853
  ] })
10800
10854
  ] })
10801
10855
  ),
10802
- /* @__PURE__ */ jsx30(
10856
+ /* @__PURE__ */ jsx31(
10803
10857
  ReorderList,
10804
10858
  {
10805
10859
  items: orderItems,
@@ -10808,8 +10862,8 @@ function MetricsEditor({
10808
10862
  itemClassName: (item) => item.id === active ? "qt-metric-library-selected" : "",
10809
10863
  renderItem: (item, index) => {
10810
10864
  const c = drafts.find((d) => d.id === item.id);
10811
- return /* @__PURE__ */ jsxs26(Fragment19, { children: [
10812
- /* @__PURE__ */ jsxs26(
10865
+ return /* @__PURE__ */ jsxs27(Fragment19, { children: [
10866
+ /* @__PURE__ */ jsxs27(
10813
10867
  "button",
10814
10868
  {
10815
10869
  type: "button",
@@ -10817,20 +10871,20 @@ function MetricsEditor({
10817
10871
  "aria-current": item.id === active,
10818
10872
  onClick: () => setActive(item.id),
10819
10873
  children: [
10820
- /* @__PURE__ */ jsxs26("strong", { children: [
10874
+ /* @__PURE__ */ jsxs27("strong", { children: [
10821
10875
  item.label,
10822
- issues.has(c.id) && /* @__PURE__ */ jsx30(
10876
+ issues.has(c.id) && /* @__PURE__ */ jsx31(
10823
10877
  "span",
10824
10878
  {
10825
10879
  className: "qt-metric-needs-attention",
10826
10880
  "aria-label": "Needs attention",
10827
10881
  title: issues.get(c.id),
10828
- children: /* @__PURE__ */ jsx30(Icon, { name: "alert", size: 12 })
10882
+ children: /* @__PURE__ */ jsx31(Icon, { name: "alert", size: 12 })
10829
10883
  }
10830
10884
  ),
10831
10885
  JSON.stringify(c) !== JSON.stringify(
10832
10886
  initial.current.find((m) => m.id === c.id)
10833
- ) && /* @__PURE__ */ jsx30(
10887
+ ) && /* @__PURE__ */ jsx31(
10834
10888
  "i",
10835
10889
  {
10836
10890
  className: "qt-metric-dirty-dot",
@@ -10838,7 +10892,7 @@ function MetricsEditor({
10838
10892
  }
10839
10893
  )
10840
10894
  ] }),
10841
- /* @__PURE__ */ jsxs26("span", { children: [
10895
+ /* @__PURE__ */ jsxs27("span", { children: [
10842
10896
  c.groupBy.map(
10843
10897
  (g) => fields.find((f) => f.name === g)?.label ?? g
10844
10898
  ).join(" \xD7 ") || "One value",
@@ -10855,7 +10909,7 @@ function MetricsEditor({
10855
10909
  }
10856
10910
  }
10857
10911
  ),
10858
- /* @__PURE__ */ jsx30(
10912
+ /* @__PURE__ */ jsx31(
10859
10913
  "button",
10860
10914
  {
10861
10915
  type: "button",
@@ -10869,12 +10923,12 @@ function MetricsEditor({
10869
10923
  }
10870
10924
  ),
10871
10925
  separator(0),
10872
- /* @__PURE__ */ jsxs26("section", { className: "qt-metric-definition", ...paneProps(1), children: [
10926
+ /* @__PURE__ */ jsxs27("section", { className: "qt-metric-definition", ...paneProps(1), children: [
10873
10927
  paneHeading(1, "Metric definition"),
10874
- selected ? /* @__PURE__ */ jsxs26(Fragment19, { children: [
10875
- /* @__PURE__ */ jsxs26("label", { children: [
10928
+ selected ? /* @__PURE__ */ jsxs27(Fragment19, { children: [
10929
+ /* @__PURE__ */ jsxs27("label", { children: [
10876
10930
  "Metric name",
10877
- /* @__PURE__ */ jsx30(
10931
+ /* @__PURE__ */ jsx31(
10878
10932
  "input",
10879
10933
  {
10880
10934
  "aria-label": "Metric name",
@@ -10884,16 +10938,16 @@ function MetricsEditor({
10884
10938
  }
10885
10939
  )
10886
10940
  ] }),
10887
- /* @__PURE__ */ jsxs26("div", { className: "qt-metric-expression-heading", children: [
10888
- /* @__PURE__ */ jsx30("strong", { children: ["box", "histogram"].includes(chosen.kind) ? "Values to summarize" : chosen.kind === "scatter" ? "X expression" : "Expression" }),
10889
- !["box", "histogram", "scatter"].includes(chosen.kind) && /* @__PURE__ */ jsxs26(
10941
+ /* @__PURE__ */ jsxs27("div", { className: "qt-metric-expression-heading", children: [
10942
+ /* @__PURE__ */ jsx31("strong", { children: ["box", "histogram"].includes(chosen.kind) ? "Values to summarize" : chosen.kind === "scatter" ? "X expression" : "Expression" }),
10943
+ !["box", "histogram", "scatter"].includes(chosen.kind) && /* @__PURE__ */ jsxs27(
10890
10944
  "div",
10891
10945
  {
10892
10946
  className: "qt-metric-mode",
10893
10947
  role: "group",
10894
10948
  "aria-label": "Expression mode",
10895
10949
  children: [
10896
- /* @__PURE__ */ jsx30(
10950
+ /* @__PURE__ */ jsx31(
10897
10951
  "button",
10898
10952
  {
10899
10953
  type: "button",
@@ -10912,7 +10966,7 @@ function MetricsEditor({
10912
10966
  children: "Basic"
10913
10967
  }
10914
10968
  ),
10915
- /* @__PURE__ */ jsx30(
10969
+ /* @__PURE__ */ jsx31(
10916
10970
  "button",
10917
10971
  {
10918
10972
  type: "button",
@@ -10927,8 +10981,8 @@ function MetricsEditor({
10927
10981
  }
10928
10982
  )
10929
10983
  ] }),
10930
- selected.expression === void 0 && !["box", "histogram", "scatter"].includes(chosen.kind) ? /* @__PURE__ */ jsxs26("div", { className: "qt-metric-basic", children: [
10931
- /* @__PURE__ */ jsx30(
10984
+ selected.expression === void 0 && !["box", "histogram", "scatter"].includes(chosen.kind) ? /* @__PURE__ */ jsxs27("div", { className: "qt-metric-basic", children: [
10985
+ /* @__PURE__ */ jsx31(
10932
10986
  "select",
10933
10987
  {
10934
10988
  "aria-label": "Aggregation function",
@@ -10938,10 +10992,10 @@ function MetricsEditor({
10938
10992
  }),
10939
10993
  children: (selected.field && fields.find((f) => f.name === selected.field) ? aggOpsForField(
10940
10994
  fields.find((f) => f.name === selected.field)
10941
- ) : ["count"]).map((op) => /* @__PURE__ */ jsx30("option", { value: op, children: op.toUpperCase() }, op))
10995
+ ) : ["count"]).map((op) => /* @__PURE__ */ jsx31("option", { value: op, children: op.toUpperCase() }, op))
10942
10996
  }
10943
10997
  ),
10944
- /* @__PURE__ */ jsxs26(
10998
+ /* @__PURE__ */ jsxs27(
10945
10999
  "select",
10946
11000
  {
10947
11001
  "aria-label": "Measure field",
@@ -10955,12 +11009,12 @@ function MetricsEditor({
10955
11009
  });
10956
11010
  },
10957
11011
  children: [
10958
- /* @__PURE__ */ jsx30("option", { value: "", children: "All rows" }),
10959
- measurable.map((f) => /* @__PURE__ */ jsx30("option", { value: f.name, children: f.label }, f.name))
11012
+ /* @__PURE__ */ jsx31("option", { value: "", children: "All rows" }),
11013
+ measurable.map((f) => /* @__PURE__ */ jsx31("option", { value: f.name, children: f.label }, f.name))
10960
11014
  ]
10961
11015
  }
10962
11016
  )
10963
- ] }) : /* @__PURE__ */ jsx30(Suspense2, { fallback: /* @__PURE__ */ jsx30("p", { children: "Loading expression editor\u2026" }), children: /* @__PURE__ */ jsx30(
11017
+ ] }) : /* @__PURE__ */ jsx31(Suspense2, { fallback: /* @__PURE__ */ jsx31("p", { children: "Loading expression editor\u2026" }), children: /* @__PURE__ */ jsx31(
10964
11018
  FormulaEditor3,
10965
11019
  {
10966
11020
  value: ["box", "histogram"].includes(chosen.kind) ? selected.distribution?.input ?? "NULL" : metricExpression(selected),
@@ -10985,9 +11039,9 @@ function MetricsEditor({
10985
11039
  },
10986
11040
  `${selected.id}-x`
10987
11041
  ) }),
10988
- chosen.kind === "scatter" && /* @__PURE__ */ jsxs26(Fragment19, { children: [
10989
- /* @__PURE__ */ jsx30("strong", { children: "Y expression" }),
10990
- /* @__PURE__ */ jsx30(Suspense2, { fallback: /* @__PURE__ */ jsx30("p", { children: "Loading expression editor\u2026" }), children: /* @__PURE__ */ jsx30(
11042
+ chosen.kind === "scatter" && /* @__PURE__ */ jsxs27(Fragment19, { children: [
11043
+ /* @__PURE__ */ jsx31("strong", { children: "Y expression" }),
11044
+ /* @__PURE__ */ jsx31(Suspense2, { fallback: /* @__PURE__ */ jsx31("p", { children: "Loading expression editor\u2026" }), children: /* @__PURE__ */ jsx31(
10991
11045
  FormulaEditor3,
10992
11046
  {
10993
11047
  value: selected.expressionY ?? "COUNT()",
@@ -11009,22 +11063,22 @@ function MetricsEditor({
11009
11063
  ] }),
11010
11064
  diagnostics.get(selected.id) && (!computationDiagnostics.has(selected.id) || selected.expression === void 0 && !["box", "histogram", "scatter"].includes(
11011
11065
  chosen.kind
11012
- )) && /* @__PURE__ */ jsx30("p", { className: "qt-metric-editor-error", role: "status", children: diagnostics.get(selected.id) }),
11013
- !diagnostics.has(selected.id) && /* @__PURE__ */ jsx30("p", { className: "qt-metric-validation", children: "\u2713 Valid expression" }),
11014
- /* @__PURE__ */ jsxs26(
11066
+ )) && /* @__PURE__ */ jsx31("p", { className: "qt-metric-editor-error", role: "status", children: diagnostics.get(selected.id) }),
11067
+ !diagnostics.has(selected.id) && /* @__PURE__ */ jsx31("p", { className: "qt-metric-validation", children: "\u2713 Valid expression" }),
11068
+ /* @__PURE__ */ jsxs27(
11015
11069
  Settings,
11016
11070
  {
11017
11071
  title: "Data scope",
11018
11072
  ...settingsState("Data scope"),
11019
11073
  summary: selected.scope === "shownRows" ? "Shown rows" : "All matching rows",
11020
11074
  children: [
11021
- /* @__PURE__ */ jsx30(
11075
+ /* @__PURE__ */ jsx31(
11022
11076
  "div",
11023
11077
  {
11024
11078
  className: "qt-metric-scope",
11025
11079
  role: "group",
11026
11080
  "aria-label": "Calculate over",
11027
- children: ["allMatching", "shownRows"].map((scope) => /* @__PURE__ */ jsx30(
11081
+ children: ["allMatching", "shownRows"].map((scope) => /* @__PURE__ */ jsx31(
11028
11082
  "button",
11029
11083
  {
11030
11084
  type: "button",
@@ -11036,11 +11090,11 @@ function MetricsEditor({
11036
11090
  ))
11037
11091
  }
11038
11092
  ),
11039
- /* @__PURE__ */ jsx30("p", { className: "qt-metric-help", children: selected.scope === "shownRows" ? "Uses only rows on the current page, after sorting and paging." : "Uses every matching row; ignores the table\u2019s limit and offset." })
11093
+ /* @__PURE__ */ jsx31("p", { className: "qt-metric-help", children: selected.scope === "shownRows" ? "Uses only rows on the current page, after sorting and paging." : "Uses every matching row; ignores the table\u2019s limit and offset." })
11040
11094
  ]
11041
11095
  }
11042
11096
  ),
11043
- /* @__PURE__ */ jsxs26(
11097
+ /* @__PURE__ */ jsxs27(
11044
11098
  Settings,
11045
11099
  {
11046
11100
  title: "Grouping",
@@ -11049,12 +11103,12 @@ function MetricsEditor({
11049
11103
  (g) => fields.find((f) => f.name === g)?.label ?? g
11050
11104
  ).join(" \xD7 ") + (selected.dateGrouping ? ` \xB7 ${selected.dateGrouping.interval} \xB7 ${selected.dateGrouping.timeZone ?? "UTC"}${selected.dateGrouping.includeEmpty ? " \xB7 empty dates" : ""}` : "") : "One value",
11051
11105
  children: [
11052
- selected.groupBy.map((group, index) => /* @__PURE__ */ jsxs26(
11106
+ selected.groupBy.map((group, index) => /* @__PURE__ */ jsxs27(
11053
11107
  "div",
11054
11108
  {
11055
11109
  className: "qt-metric-group-row",
11056
11110
  children: [
11057
- /* @__PURE__ */ jsx30(
11111
+ /* @__PURE__ */ jsx31(
11058
11112
  "select",
11059
11113
  {
11060
11114
  "aria-label": `Grouping ${index + 1}`,
@@ -11064,7 +11118,7 @@ function MetricsEditor({
11064
11118
  groupBy[index] = e.target.value;
11065
11119
  regroup(groupBy);
11066
11120
  },
11067
- children: groupable.map((f) => /* @__PURE__ */ jsx30(
11121
+ children: groupable.map((f) => /* @__PURE__ */ jsx31(
11068
11122
  "option",
11069
11123
  {
11070
11124
  value: f.name,
@@ -11075,7 +11129,7 @@ function MetricsEditor({
11075
11129
  ))
11076
11130
  }
11077
11131
  ),
11078
- /* @__PURE__ */ jsx30(
11132
+ /* @__PURE__ */ jsx31(
11079
11133
  "button",
11080
11134
  {
11081
11135
  type: "button",
@@ -11086,7 +11140,7 @@ function MetricsEditor({
11086
11140
  children: "\xD7"
11087
11141
  }
11088
11142
  ),
11089
- index > 0 && /* @__PURE__ */ jsx30(
11143
+ index > 0 && /* @__PURE__ */ jsx31(
11090
11144
  "button",
11091
11145
  {
11092
11146
  type: "button",
@@ -11106,10 +11160,10 @@ function MetricsEditor({
11106
11160
  },
11107
11161
  `${group}-${index}`
11108
11162
  )),
11109
- dateField && /* @__PURE__ */ jsxs26("div", { className: "qt-metric-date-grouping", children: [
11110
- /* @__PURE__ */ jsxs26("label", { children: [
11163
+ dateField && /* @__PURE__ */ jsxs27("div", { className: "qt-metric-date-grouping", children: [
11164
+ /* @__PURE__ */ jsxs27("label", { children: [
11111
11165
  "Date interval",
11112
- /* @__PURE__ */ jsxs26(
11166
+ /* @__PURE__ */ jsxs27(
11113
11167
  "select",
11114
11168
  {
11115
11169
  "aria-label": "Date interval",
@@ -11131,19 +11185,19 @@ function MetricsEditor({
11131
11185
  });
11132
11186
  },
11133
11187
  children: [
11134
- /* @__PURE__ */ jsx30("option", { value: "exact", children: "Exact timestamp" }),
11135
- /* @__PURE__ */ jsx30("option", { value: "hour", children: "Hour" }),
11136
- /* @__PURE__ */ jsx30("option", { value: "day", children: "Day" }),
11137
- /* @__PURE__ */ jsx30("option", { value: "week", children: "Week" }),
11138
- /* @__PURE__ */ jsx30("option", { value: "month", children: "Month" }),
11139
- /* @__PURE__ */ jsx30("option", { value: "year", children: "Year" })
11188
+ /* @__PURE__ */ jsx31("option", { value: "exact", children: "Exact timestamp" }),
11189
+ /* @__PURE__ */ jsx31("option", { value: "hour", children: "Hour" }),
11190
+ /* @__PURE__ */ jsx31("option", { value: "day", children: "Day" }),
11191
+ /* @__PURE__ */ jsx31("option", { value: "week", children: "Week" }),
11192
+ /* @__PURE__ */ jsx31("option", { value: "month", children: "Month" }),
11193
+ /* @__PURE__ */ jsx31("option", { value: "year", children: "Year" })
11140
11194
  ]
11141
11195
  }
11142
11196
  )
11143
11197
  ] }),
11144
- selected.dateGrouping && /* @__PURE__ */ jsxs26("label", { children: [
11198
+ selected.dateGrouping && /* @__PURE__ */ jsxs27("label", { children: [
11145
11199
  "Grouping timezone",
11146
- /* @__PURE__ */ jsx30(
11200
+ /* @__PURE__ */ jsx31(
11147
11201
  "input",
11148
11202
  {
11149
11203
  "aria-label": "Grouping timezone",
@@ -11159,7 +11213,7 @@ function MetricsEditor({
11159
11213
  })
11160
11214
  }
11161
11215
  ),
11162
- /* @__PURE__ */ jsx30("datalist", { id: `${titleId}-grouping-timezones`, children: [
11216
+ /* @__PURE__ */ jsx31("datalist", { id: `${titleId}-grouping-timezones`, children: [
11163
11217
  "UTC",
11164
11218
  "America/Denver",
11165
11219
  "America/Los_Angeles",
@@ -11170,10 +11224,10 @@ function MetricsEditor({
11170
11224
  "Asia/Tokyo",
11171
11225
  "Australia/Sydney",
11172
11226
  "Pacific/Auckland"
11173
- ].map((zone2) => /* @__PURE__ */ jsx30("option", { value: zone2 }, zone2)) })
11227
+ ].map((zone2) => /* @__PURE__ */ jsx31("option", { value: zone2 }, zone2)) })
11174
11228
  ] }),
11175
- /* @__PURE__ */ jsxs26("label", { className: "qt-metric-date-toggle", children: [
11176
- /* @__PURE__ */ jsx30(
11229
+ /* @__PURE__ */ jsxs27("label", { className: "qt-metric-date-toggle", children: [
11230
+ /* @__PURE__ */ jsx31(
11177
11231
  "input",
11178
11232
  {
11179
11233
  type: "checkbox",
@@ -11190,11 +11244,11 @@ function MetricsEditor({
11190
11244
  ),
11191
11245
  "Include empty dates"
11192
11246
  ] }),
11193
- /* @__PURE__ */ jsx30("p", { className: "qt-metric-help", children: "Add a bucket for every interval, even when no rows match." }),
11194
- selected.dateGrouping?.includeEmpty && /* @__PURE__ */ jsxs26(Fragment19, { children: [
11195
- /* @__PURE__ */ jsxs26("label", { children: [
11247
+ /* @__PURE__ */ jsx31("p", { className: "qt-metric-help", children: "Add a bucket for every interval, even when no rows match." }),
11248
+ selected.dateGrouping?.includeEmpty && /* @__PURE__ */ jsxs27(Fragment19, { children: [
11249
+ /* @__PURE__ */ jsxs27("label", { children: [
11196
11250
  "Complete dates across",
11197
- /* @__PURE__ */ jsxs26(
11251
+ /* @__PURE__ */ jsxs27(
11198
11252
  "select",
11199
11253
  {
11200
11254
  "aria-label": "Complete dates across",
@@ -11206,17 +11260,17 @@ function MetricsEditor({
11206
11260
  }
11207
11261
  }),
11208
11262
  children: [
11209
- /* @__PURE__ */ jsx30("option", { value: "query", children: "Query date range" }),
11210
- /* @__PURE__ */ jsx30("option", { value: "observed", children: "First to last observed date" }),
11211
- /* @__PURE__ */ jsx30("option", { value: "custom", children: "Custom date range" })
11263
+ /* @__PURE__ */ jsx31("option", { value: "query", children: "Query date range" }),
11264
+ /* @__PURE__ */ jsx31("option", { value: "observed", children: "First to last observed date" }),
11265
+ /* @__PURE__ */ jsx31("option", { value: "custom", children: "Custom date range" })
11212
11266
  ]
11213
11267
  }
11214
11268
  )
11215
11269
  ] }),
11216
- selected.dateGrouping.range === "custom" && /* @__PURE__ */ jsxs26("div", { className: "qt-metric-date-bounds", children: [
11217
- /* @__PURE__ */ jsxs26("label", { children: [
11270
+ selected.dateGrouping.range === "custom" && /* @__PURE__ */ jsxs27("div", { className: "qt-metric-date-bounds", children: [
11271
+ /* @__PURE__ */ jsxs27("label", { children: [
11218
11272
  "From",
11219
- /* @__PURE__ */ jsx30(
11273
+ /* @__PURE__ */ jsx31(
11220
11274
  "input",
11221
11275
  {
11222
11276
  type: "date",
@@ -11231,9 +11285,9 @@ function MetricsEditor({
11231
11285
  }
11232
11286
  )
11233
11287
  ] }),
11234
- /* @__PURE__ */ jsxs26("label", { children: [
11288
+ /* @__PURE__ */ jsxs27("label", { children: [
11235
11289
  "Through",
11236
- /* @__PURE__ */ jsx30(
11290
+ /* @__PURE__ */ jsx31(
11237
11291
  "input",
11238
11292
  {
11239
11293
  type: "date",
@@ -11249,11 +11303,11 @@ function MetricsEditor({
11249
11303
  )
11250
11304
  ] })
11251
11305
  ] }),
11252
- /* @__PURE__ */ jsx30("p", { className: "qt-metric-help", children: "Direct counts and sums use 0 for empty dates. Averages, ratios, and other expressions have no value." })
11306
+ /* @__PURE__ */ jsx31("p", { className: "qt-metric-help", children: "Direct counts and sums use 0 for empty dates. Averages, ratios, and other expressions have no value." })
11253
11307
  ] }),
11254
- /* @__PURE__ */ jsx30("p", { className: "qt-metric-help", children: "Calendar boundaries and custom dates use the grouping timezone. Weeks begin Monday." })
11308
+ /* @__PURE__ */ jsx31("p", { className: "qt-metric-help", children: "Calendar boundaries and custom dates use the grouping timezone. Weeks begin Monday." })
11255
11309
  ] }),
11256
- /* @__PURE__ */ jsxs26(
11310
+ /* @__PURE__ */ jsxs27(
11257
11311
  "select",
11258
11312
  {
11259
11313
  "aria-label": "Add grouping",
@@ -11265,23 +11319,23 @@ function MetricsEditor({
11265
11319
  });
11266
11320
  },
11267
11321
  children: [
11268
- /* @__PURE__ */ jsx30("option", { value: "", children: "+ Add grouping" }),
11269
- groupable.filter((f) => !selected.groupBy.includes(f.name)).map((f) => /* @__PURE__ */ jsx30("option", { value: f.name, children: f.label }, f.name))
11322
+ /* @__PURE__ */ jsx31("option", { value: "", children: "+ Add grouping" }),
11323
+ groupable.filter((f) => !selected.groupBy.includes(f.name)).map((f) => /* @__PURE__ */ jsx31("option", { value: f.name, children: f.label }, f.name))
11270
11324
  ]
11271
11325
  }
11272
11326
  )
11273
11327
  ]
11274
11328
  }
11275
11329
  ),
11276
- /* @__PURE__ */ jsxs26(
11330
+ /* @__PURE__ */ jsxs27(
11277
11331
  Settings,
11278
11332
  {
11279
11333
  title: "Ordering & limits",
11280
11334
  ...settingsState("Ordering & limits"),
11281
11335
  summary: selected.sort?.length ? `${selected.sort.length} sort ${selected.sort.length === 1 ? "rule" : "rules"}${selected.groupLimit ? ` \xB7 first ${selected.groupLimit}` : ""}` : `Default ordering${selected.groupLimit ? ` \xB7 first ${selected.groupLimit}` : ""}`,
11282
11336
  children: [
11283
- (selected.sort ?? []).map((sort, index) => /* @__PURE__ */ jsxs26("div", { className: "qt-metric-sort-row", children: [
11284
- /* @__PURE__ */ jsxs26(
11337
+ (selected.sort ?? []).map((sort, index) => /* @__PURE__ */ jsxs27("div", { className: "qt-metric-sort-row", children: [
11338
+ /* @__PURE__ */ jsxs27(
11285
11339
  "select",
11286
11340
  {
11287
11341
  "aria-label": `Sort result ${index + 1}`,
@@ -11292,15 +11346,15 @@ function MetricsEditor({
11292
11346
  )
11293
11347
  }),
11294
11348
  children: [
11295
- /* @__PURE__ */ jsx30("option", { value: "value", children: chosen.kind === "box" ? "Median" : chosen.kind === "scatter" ? "X value" : "Value" }),
11296
- chosen.kind === "scatter" && /* @__PURE__ */ jsx30("option", { value: "y", children: "Y value" }),
11297
- /* @__PURE__ */ jsx30("option", { value: "count", children: "Rows" }),
11298
- ["box", "histogram"].includes(chosen.kind) && /* @__PURE__ */ jsx30("option", { value: "samples", children: "Numeric samples" }),
11299
- selected.groupBy.map((g, i) => /* @__PURE__ */ jsx30("option", { value: `group${i}`, children: fields.find((f) => f.name === g)?.label ?? g }, g))
11349
+ /* @__PURE__ */ jsx31("option", { value: "value", children: chosen.kind === "box" ? "Median" : chosen.kind === "scatter" ? "X value" : "Value" }),
11350
+ chosen.kind === "scatter" && /* @__PURE__ */ jsx31("option", { value: "y", children: "Y value" }),
11351
+ /* @__PURE__ */ jsx31("option", { value: "count", children: "Rows" }),
11352
+ ["box", "histogram"].includes(chosen.kind) && /* @__PURE__ */ jsx31("option", { value: "samples", children: "Numeric samples" }),
11353
+ selected.groupBy.map((g, i) => /* @__PURE__ */ jsx31("option", { value: `group${i}`, children: fields.find((f) => f.name === g)?.label ?? g }, g))
11300
11354
  ]
11301
11355
  }
11302
11356
  ),
11303
- /* @__PURE__ */ jsxs26(
11357
+ /* @__PURE__ */ jsxs27(
11304
11358
  "select",
11305
11359
  {
11306
11360
  "aria-label": `Sort direction ${index + 1}`,
@@ -11314,12 +11368,12 @@ function MetricsEditor({
11314
11368
  )
11315
11369
  }),
11316
11370
  children: [
11317
- /* @__PURE__ */ jsx30("option", { value: "asc", children: "Ascending" }),
11318
- /* @__PURE__ */ jsx30("option", { value: "desc", children: "Descending" })
11371
+ /* @__PURE__ */ jsx31("option", { value: "asc", children: "Ascending" }),
11372
+ /* @__PURE__ */ jsx31("option", { value: "desc", children: "Descending" })
11319
11373
  ]
11320
11374
  }
11321
11375
  ),
11322
- /* @__PURE__ */ jsxs26(
11376
+ /* @__PURE__ */ jsxs27(
11323
11377
  "select",
11324
11378
  {
11325
11379
  "aria-label": `Null placement ${index + 1}`,
@@ -11333,12 +11387,12 @@ function MetricsEditor({
11333
11387
  )
11334
11388
  }),
11335
11389
  children: [
11336
- /* @__PURE__ */ jsx30("option", { value: "last", children: "NULL last" }),
11337
- /* @__PURE__ */ jsx30("option", { value: "first", children: "NULL first" })
11390
+ /* @__PURE__ */ jsx31("option", { value: "last", children: "NULL last" }),
11391
+ /* @__PURE__ */ jsx31("option", { value: "first", children: "NULL first" })
11338
11392
  ]
11339
11393
  }
11340
11394
  ),
11341
- /* @__PURE__ */ jsx30(
11395
+ /* @__PURE__ */ jsx31(
11342
11396
  "button",
11343
11397
  {
11344
11398
  type: "button",
@@ -11350,7 +11404,7 @@ function MetricsEditor({
11350
11404
  }
11351
11405
  )
11352
11406
  ] }, index)),
11353
- /* @__PURE__ */ jsx30(
11407
+ /* @__PURE__ */ jsx31(
11354
11408
  "button",
11355
11409
  {
11356
11410
  type: "button",
@@ -11365,9 +11419,9 @@ function MetricsEditor({
11365
11419
  children: "+ Add sort"
11366
11420
  }
11367
11421
  ),
11368
- /* @__PURE__ */ jsxs26("label", { children: [
11422
+ /* @__PURE__ */ jsxs27("label", { children: [
11369
11423
  "Show first groups",
11370
- /* @__PURE__ */ jsx30(
11424
+ /* @__PURE__ */ jsx31(
11371
11425
  "input",
11372
11426
  {
11373
11427
  "aria-label": "Metric group limit",
@@ -11389,34 +11443,34 @@ function MetricsEditor({
11389
11443
  ]
11390
11444
  }
11391
11445
  ),
11392
- /* @__PURE__ */ jsxs26(
11446
+ /* @__PURE__ */ jsxs27(
11393
11447
  Settings,
11394
11448
  {
11395
11449
  title: "Display",
11396
11450
  ...settingsState("Display"),
11397
11451
  summary: `${kinds.find(([kind]) => kind === chosen.kind)?.[1] ?? chosen.kind}${chosen.format ? ` \xB7 ${chosen.format.kind}` : ""}`,
11398
11452
  children: [
11399
- chosen.kind === "scatter" && /* @__PURE__ */ jsxs26("label", { children: [
11453
+ chosen.kind === "scatter" && /* @__PURE__ */ jsxs27("label", { children: [
11400
11454
  "Format measure",
11401
- /* @__PURE__ */ jsxs26(
11455
+ /* @__PURE__ */ jsxs27(
11402
11456
  "select",
11403
11457
  {
11404
11458
  "aria-label": "Format measure",
11405
11459
  value: formatTarget,
11406
11460
  onChange: (e) => setFormatTarget(e.target.value),
11407
11461
  children: [
11408
- /* @__PURE__ */ jsx30("option", { value: "x", children: "X output" }),
11409
- /* @__PURE__ */ jsx30("option", { value: "y", children: "Y output" })
11462
+ /* @__PURE__ */ jsx31("option", { value: "x", children: "X output" }),
11463
+ /* @__PURE__ */ jsx31("option", { value: "y", children: "Y output" })
11410
11464
  ]
11411
11465
  }
11412
11466
  )
11413
11467
  ] }),
11414
- /* @__PURE__ */ jsx30(
11468
+ /* @__PURE__ */ jsx31(
11415
11469
  MetricFormatControls,
11416
11470
  {
11417
- displayControl: /* @__PURE__ */ jsxs26("label", { children: [
11471
+ displayControl: /* @__PURE__ */ jsxs27("label", { children: [
11418
11472
  "Display",
11419
- /* @__PURE__ */ jsx30(
11473
+ /* @__PURE__ */ jsx31(
11420
11474
  "select",
11421
11475
  {
11422
11476
  "aria-label": "Metric display",
@@ -11424,7 +11478,7 @@ function MetricsEditor({
11424
11478
  onChange: (e) => changeDisplay(
11425
11479
  e.target.value
11426
11480
  ),
11427
- children: kinds.map(([kind, label]) => /* @__PURE__ */ jsx30("option", { value: kind, children: label }, kind))
11481
+ children: kinds.map(([kind, label]) => /* @__PURE__ */ jsx31("option", { value: kind, children: label }, kind))
11428
11482
  }
11429
11483
  )
11430
11484
  ] }),
@@ -11442,15 +11496,15 @@ function MetricsEditor({
11442
11496
  "box",
11443
11497
  "histogram",
11444
11498
  "list"
11445
- ].includes(chosen.kind) && /* @__PURE__ */ jsxs26("details", { className: "qt-metric-settings", children: [
11446
- /* @__PURE__ */ jsx30("summary", { children: "Scale & bounds" }),
11499
+ ].includes(chosen.kind) && /* @__PURE__ */ jsxs27("details", { className: "qt-metric-settings", children: [
11500
+ /* @__PURE__ */ jsx31("summary", { children: "Scale & bounds" }),
11447
11501
  (chosen.kind === "scatter" || chosen.kind === "histogram" || chosen.kind === "line" ? ["xScale", "yScale"] : [
11448
11502
  chosen.kind === "box" || chosen.kind === "bar-horizontal" || chosen.kind === "list" ? "xScale" : "yScale"
11449
- ]).map((key) => /* @__PURE__ */ jsxs26("fieldset", { className: "qt-metric-axis-settings", children: [
11450
- /* @__PURE__ */ jsx30("legend", { children: key === "xScale" ? "X / horizontal axis" : "Y / vertical axis" }),
11451
- /* @__PURE__ */ jsxs26("label", { children: [
11503
+ ]).map((key) => /* @__PURE__ */ jsxs27("fieldset", { className: "qt-metric-axis-settings", children: [
11504
+ /* @__PURE__ */ jsx31("legend", { children: key === "xScale" ? "X / horizontal axis" : "Y / vertical axis" }),
11505
+ /* @__PURE__ */ jsxs27("label", { children: [
11452
11506
  "Scale",
11453
- /* @__PURE__ */ jsxs26(
11507
+ /* @__PURE__ */ jsxs27(
11454
11508
  "select",
11455
11509
  {
11456
11510
  "aria-label": `${key === "xScale" ? "X" : "Y"} axis scale`,
@@ -11462,15 +11516,15 @@ function MetricsEditor({
11462
11516
  }
11463
11517
  }),
11464
11518
  children: [
11465
- /* @__PURE__ */ jsx30("option", { value: "linear", children: "Linear" }),
11466
- /* @__PURE__ */ jsx30("option", { value: "log", children: "Logarithmic" })
11519
+ /* @__PURE__ */ jsx31("option", { value: "linear", children: "Linear" }),
11520
+ /* @__PURE__ */ jsx31("option", { value: "log", children: "Logarithmic" })
11467
11521
  ]
11468
11522
  }
11469
11523
  )
11470
11524
  ] }),
11471
- ["min", "max"].map((bound) => /* @__PURE__ */ jsxs26("label", { children: [
11525
+ ["min", "max"].map((bound) => /* @__PURE__ */ jsxs27("label", { children: [
11472
11526
  bound === "min" ? "Minimum" : "Maximum",
11473
- /* @__PURE__ */ jsx30(
11527
+ /* @__PURE__ */ jsx31(
11474
11528
  "input",
11475
11529
  {
11476
11530
  type: "number",
@@ -11489,13 +11543,13 @@ function MetricsEditor({
11489
11543
  )
11490
11544
  ] }, bound))
11491
11545
  ] }, key)),
11492
- /* @__PURE__ */ jsx30("p", { className: "qt-muted", children: "Bounds use raw result units. Logarithmic axes omit zero and negative values. Pie and ring charts use proportional areas." })
11546
+ /* @__PURE__ */ jsx31("p", { className: "qt-muted", children: "Bounds use raw result units. Logarithmic axes omit zero and negative values. Pie and ring charts use proportional areas." })
11493
11547
  ] }),
11494
11548
  ["pie", "donut", "scatter", "histogram"].includes(
11495
11549
  chosen.kind
11496
- ) && /* @__PURE__ */ jsxs26("label", { children: [
11550
+ ) && /* @__PURE__ */ jsxs27("label", { children: [
11497
11551
  "Legend placement",
11498
- /* @__PURE__ */ jsx30(
11552
+ /* @__PURE__ */ jsx31(
11499
11553
  "select",
11500
11554
  {
11501
11555
  "aria-label": "Legend placement",
@@ -11503,7 +11557,7 @@ function MetricsEditor({
11503
11557
  onChange: (e) => displayPatch({
11504
11558
  legendPosition: e.target.value
11505
11559
  }),
11506
- children: ["left", "right", "bottom", "top", "none"].map((position) => /* @__PURE__ */ jsx30("option", { value: position, children: {
11560
+ children: ["left", "right", "bottom", "top", "none"].map((position) => /* @__PURE__ */ jsx31("option", { value: position, children: {
11507
11561
  left: "Left",
11508
11562
  right: "Right",
11509
11563
  bottom: "Below",
@@ -11513,9 +11567,9 @@ function MetricsEditor({
11513
11567
  }
11514
11568
  )
11515
11569
  ] }),
11516
- chosen.kind !== "value" && /* @__PURE__ */ jsxs26("label", { children: [
11570
+ chosen.kind !== "value" && /* @__PURE__ */ jsxs27("label", { children: [
11517
11571
  "Maximum displayed groups",
11518
- /* @__PURE__ */ jsx30(
11572
+ /* @__PURE__ */ jsx31(
11519
11573
  MetricNumberInput,
11520
11574
  {
11521
11575
  "aria-label": "Maximum displayed groups",
@@ -11535,8 +11589,8 @@ function MetricsEditor({
11535
11589
  selected.id
11536
11590
  )
11537
11591
  ] }),
11538
- ["list", "pie", "donut"].includes(chosen.kind) && /* @__PURE__ */ jsxs26("label", { children: [
11539
- /* @__PURE__ */ jsx30(
11592
+ ["list", "pie", "donut"].includes(chosen.kind) && /* @__PURE__ */ jsxs27("label", { children: [
11593
+ /* @__PURE__ */ jsx31(
11540
11594
  "input",
11541
11595
  {
11542
11596
  type: "checkbox",
@@ -11547,25 +11601,25 @@ function MetricsEditor({
11547
11601
  ),
11548
11602
  "Show Other remainder (additive values only)"
11549
11603
  ] }),
11550
- chosen.kind === "list" && /* @__PURE__ */ jsxs26("div", { className: "qt-metric-list-controls", children: [
11551
- /* @__PURE__ */ jsxs26("label", { children: [
11604
+ chosen.kind === "list" && /* @__PURE__ */ jsxs27("div", { className: "qt-metric-list-controls", children: [
11605
+ /* @__PURE__ */ jsxs27("label", { children: [
11552
11606
  "Bar placement",
11553
- /* @__PURE__ */ jsxs26(
11607
+ /* @__PURE__ */ jsxs27(
11554
11608
  "select",
11555
11609
  {
11556
11610
  "aria-label": "List bar placement",
11557
11611
  value: chosen.list?.barPosition ?? "inline",
11558
11612
  onChange: (event) => displayPatch({ list: { ...chosen.list, barPosition: event.target.value } }),
11559
11613
  children: [
11560
- /* @__PURE__ */ jsx30("option", { value: "inline", children: "Beside label" }),
11561
- /* @__PURE__ */ jsx30("option", { value: "below", children: "Under label" })
11614
+ /* @__PURE__ */ jsx31("option", { value: "inline", children: "Beside label" }),
11615
+ /* @__PURE__ */ jsx31("option", { value: "below", children: "Under label" })
11562
11616
  ]
11563
11617
  }
11564
11618
  )
11565
11619
  ] }),
11566
- chosen.list?.barPosition === "below" && /* @__PURE__ */ jsxs26("label", { children: [
11620
+ chosen.list?.barPosition === "below" && /* @__PURE__ */ jsxs27("label", { children: [
11567
11621
  "Maximum label lines",
11568
- /* @__PURE__ */ jsx30(
11622
+ /* @__PURE__ */ jsx31(
11569
11623
  MetricNumberInput,
11570
11624
  {
11571
11625
  "aria-label": "Maximum label lines",
@@ -11585,8 +11639,8 @@ function MetricsEditor({
11585
11639
  selected.id
11586
11640
  )
11587
11641
  ] }),
11588
- ["showBars", "useGroupColors", "showValues"].map((key) => /* @__PURE__ */ jsxs26("label", { children: [
11589
- /* @__PURE__ */ jsx30(
11642
+ ["showBars", "useGroupColors", "showValues"].map((key) => /* @__PURE__ */ jsxs27("label", { children: [
11643
+ /* @__PURE__ */ jsx31(
11590
11644
  "input",
11591
11645
  {
11592
11646
  type: "checkbox",
@@ -11606,9 +11660,9 @@ function MetricsEditor({
11606
11660
  }[key]
11607
11661
  ] }, key))
11608
11662
  ] }),
11609
- chosen.kind === "table" && selected.groupBy.length === 2 && /* @__PURE__ */ jsxs26(Fragment19, { children: [
11610
- /* @__PURE__ */ jsxs26("label", { children: [
11611
- /* @__PURE__ */ jsx30(
11663
+ chosen.kind === "table" && selected.groupBy.length === 2 && /* @__PURE__ */ jsxs27(Fragment19, { children: [
11664
+ /* @__PURE__ */ jsxs27("label", { children: [
11665
+ /* @__PURE__ */ jsx31(
11612
11666
  "input",
11613
11667
  {
11614
11668
  type: "checkbox",
@@ -11623,9 +11677,9 @@ function MetricsEditor({
11623
11677
  ),
11624
11678
  "Swap X/Y axes"
11625
11679
  ] }),
11626
- ["rowDir", "columnDir"].map((key) => /* @__PURE__ */ jsxs26("label", { children: [
11680
+ ["rowDir", "columnDir"].map((key) => /* @__PURE__ */ jsxs27("label", { children: [
11627
11681
  key === "rowDir" ? "Row keys" : "Column keys",
11628
- /* @__PURE__ */ jsxs26(
11682
+ /* @__PURE__ */ jsxs27(
11629
11683
  "select",
11630
11684
  {
11631
11685
  value: chosen.pivot?.[key] ?? "asc",
@@ -11636,17 +11690,17 @@ function MetricsEditor({
11636
11690
  }
11637
11691
  }),
11638
11692
  children: [
11639
- /* @__PURE__ */ jsx30("option", { value: "asc", children: "Ascending" }),
11640
- /* @__PURE__ */ jsx30("option", { value: "desc", children: "Descending" })
11693
+ /* @__PURE__ */ jsx31("option", { value: "asc", children: "Ascending" }),
11694
+ /* @__PURE__ */ jsx31("option", { value: "desc", children: "Descending" })
11641
11695
  ]
11642
11696
  }
11643
11697
  )
11644
11698
  ] }, key))
11645
11699
  ] }),
11646
- chosen.kind === "box" && selected.distribution && /* @__PURE__ */ jsxs26(Fragment19, { children: [
11647
- /* @__PURE__ */ jsxs26("label", { children: [
11700
+ chosen.kind === "box" && selected.distribution && /* @__PURE__ */ jsxs27(Fragment19, { children: [
11701
+ /* @__PURE__ */ jsxs27("label", { children: [
11648
11702
  "Whiskers",
11649
- /* @__PURE__ */ jsxs26(
11703
+ /* @__PURE__ */ jsxs27(
11650
11704
  "select",
11651
11705
  {
11652
11706
  "aria-label": "Box whiskers",
@@ -11658,14 +11712,14 @@ function MetricsEditor({
11658
11712
  }
11659
11713
  }),
11660
11714
  children: [
11661
- /* @__PURE__ */ jsx30("option", { value: "minmax", children: "Minimum / maximum" }),
11662
- /* @__PURE__ */ jsx30("option", { value: "tukey", children: "1.5 \xD7 IQR \xB7 show outliers" })
11715
+ /* @__PURE__ */ jsx31("option", { value: "minmax", children: "Minimum / maximum" }),
11716
+ /* @__PURE__ */ jsx31("option", { value: "tukey", children: "1.5 \xD7 IQR \xB7 show outliers" })
11663
11717
  ]
11664
11718
  }
11665
11719
  )
11666
11720
  ] }),
11667
- /* @__PURE__ */ jsxs26("label", { children: [
11668
- /* @__PURE__ */ jsx30(
11721
+ /* @__PURE__ */ jsxs27("label", { children: [
11722
+ /* @__PURE__ */ jsx31(
11669
11723
  "input",
11670
11724
  {
11671
11725
  type: "checkbox",
@@ -11676,9 +11730,9 @@ function MetricsEditor({
11676
11730
  "Show mean marker"
11677
11731
  ] })
11678
11732
  ] }),
11679
- chosen.kind === "histogram" && selected.distribution && /* @__PURE__ */ jsxs26("label", { children: [
11733
+ chosen.kind === "histogram" && selected.distribution && /* @__PURE__ */ jsxs27("label", { children: [
11680
11734
  "Equal-width bins",
11681
- /* @__PURE__ */ jsx30(
11735
+ /* @__PURE__ */ jsx31(
11682
11736
  MetricNumberInput,
11683
11737
  {
11684
11738
  "aria-label": "Histogram bins",
@@ -11702,7 +11756,7 @@ function MetricsEditor({
11702
11756
  ]
11703
11757
  }
11704
11758
  ),
11705
- /* @__PURE__ */ jsx30(
11759
+ /* @__PURE__ */ jsx31(
11706
11760
  Settings,
11707
11761
  {
11708
11762
  title: "Labels",
@@ -11710,13 +11764,13 @@ function MetricsEditor({
11710
11764
  summary: [chosen.valueLabel, chosen.xLabel, chosen.yLabel].some(
11711
11765
  Boolean
11712
11766
  ) ? "Custom" : "Automatic",
11713
- children: ["valueLabel", "xLabel", "yLabel"].map((key) => /* @__PURE__ */ jsxs26("label", { children: [
11767
+ children: ["valueLabel", "xLabel", "yLabel"].map((key) => /* @__PURE__ */ jsxs27("label", { children: [
11714
11768
  {
11715
11769
  valueLabel: "Value label",
11716
11770
  xLabel: "X axis label",
11717
11771
  yLabel: "Y axis label"
11718
11772
  }[key],
11719
- /* @__PURE__ */ jsx30(
11773
+ /* @__PURE__ */ jsx31(
11720
11774
  "input",
11721
11775
  {
11722
11776
  maxLength: 1e3,
@@ -11727,7 +11781,7 @@ function MetricsEditor({
11727
11781
  ] }, key))
11728
11782
  }
11729
11783
  ),
11730
- /* @__PURE__ */ jsx30(
11784
+ /* @__PURE__ */ jsx31(
11731
11785
  Settings,
11732
11786
  {
11733
11787
  title: "Card size",
@@ -11736,18 +11790,18 @@ function MetricsEditor({
11736
11790
  children: sizeControls
11737
11791
  }
11738
11792
  )
11739
- ] }) : /* @__PURE__ */ jsxs26("div", { className: "qt-metric-authoring-empty", children: [
11740
- /* @__PURE__ */ jsx30(Icon, { name: "panelDefinition", size: 28 }),
11741
- /* @__PURE__ */ jsx30("strong", { children: "No metric selected" }),
11742
- /* @__PURE__ */ jsx30("p", { children: "Create a metric to define what you want to measure." }),
11743
- /* @__PURE__ */ jsxs26("button", { type: "button", className: "qt-btn", onClick: createMetric, children: [
11744
- /* @__PURE__ */ jsx30(Icon, { name: "add" }),
11793
+ ] }) : /* @__PURE__ */ jsxs27("div", { className: "qt-metric-authoring-empty", children: [
11794
+ /* @__PURE__ */ jsx31(Icon, { name: "panelDefinition", size: 28 }),
11795
+ /* @__PURE__ */ jsx31("strong", { children: "No metric selected" }),
11796
+ /* @__PURE__ */ jsx31("p", { children: "Create a metric to define what you want to measure." }),
11797
+ /* @__PURE__ */ jsxs27("button", { type: "button", className: "qt-btn", onClick: createMetric, children: [
11798
+ /* @__PURE__ */ jsx31(Icon, { name: "add" }),
11745
11799
  "Create metric"
11746
11800
  ] })
11747
11801
  ] })
11748
11802
  ] }),
11749
11803
  separator(1),
11750
- /* @__PURE__ */ jsxs26(
11804
+ /* @__PURE__ */ jsxs27(
11751
11805
  "aside",
11752
11806
  {
11753
11807
  className: "qt-metric-reference",
@@ -11755,22 +11809,22 @@ function MetricsEditor({
11755
11809
  "aria-label": "Field and function library",
11756
11810
  children: [
11757
11811
  paneHeading(2, "Fields & functions"),
11758
- /* @__PURE__ */ jsxs26(
11812
+ /* @__PURE__ */ jsxs27(
11759
11813
  "select",
11760
11814
  {
11761
11815
  "aria-label": "Reference library",
11762
11816
  value: reference,
11763
11817
  onChange: (e) => setReference(e.target.value),
11764
11818
  children: [
11765
- /* @__PURE__ */ jsx30("option", { value: "fields", children: "Fields" }),
11766
- /* @__PURE__ */ jsx30("option", { value: "functions", children: "Functions" })
11819
+ /* @__PURE__ */ jsx31("option", { value: "fields", children: "Fields" }),
11820
+ /* @__PURE__ */ jsx31("option", { value: "functions", children: "Functions" })
11767
11821
  ]
11768
11822
  }
11769
11823
  ),
11770
- /* @__PURE__ */ jsxs26("label", { children: [
11824
+ /* @__PURE__ */ jsxs27("label", { children: [
11771
11825
  "Search ",
11772
11826
  reference,
11773
- /* @__PURE__ */ jsx30(
11827
+ /* @__PURE__ */ jsx31(
11774
11828
  "input",
11775
11829
  {
11776
11830
  "aria-label": "Search metric reference",
@@ -11781,29 +11835,29 @@ function MetricsEditor({
11781
11835
  }
11782
11836
  )
11783
11837
  ] }),
11784
- reference === "functions" && /* @__PURE__ */ jsxs26("label", { children: [
11838
+ reference === "functions" && /* @__PURE__ */ jsxs27("label", { children: [
11785
11839
  "Concept",
11786
- /* @__PURE__ */ jsxs26(
11840
+ /* @__PURE__ */ jsxs27(
11787
11841
  "select",
11788
11842
  {
11789
11843
  "aria-label": "Function concept",
11790
11844
  value: concept,
11791
11845
  onChange: (e) => setConcept(e.target.value),
11792
11846
  children: [
11793
- /* @__PURE__ */ jsx30("option", { value: "all", children: "All functions" }),
11794
- /* @__PURE__ */ jsx30("option", { value: "aggregate", children: "Aggregation" }),
11795
- /* @__PURE__ */ jsx30("option", { value: "row", children: "Row arithmetic & conditions" })
11847
+ /* @__PURE__ */ jsx31("option", { value: "all", children: "All functions" }),
11848
+ /* @__PURE__ */ jsx31("option", { value: "aggregate", children: "Aggregation" }),
11849
+ /* @__PURE__ */ jsx31("option", { value: "row", children: "Row arithmetic & conditions" })
11796
11850
  ]
11797
11851
  }
11798
11852
  )
11799
11853
  ] }),
11800
- /* @__PURE__ */ jsxs26("div", { className: "qt-metric-reference-columns", "aria-hidden": "true", children: [
11801
- /* @__PURE__ */ jsx30("span", { children: "Type" }),
11802
- /* @__PURE__ */ jsx30("span", { children: "Name" }),
11803
- /* @__PURE__ */ jsx30("span", { children: reference === "fields" ? "ID" : "Signature" })
11854
+ /* @__PURE__ */ jsxs27("div", { className: "qt-metric-reference-columns", "aria-hidden": "true", children: [
11855
+ /* @__PURE__ */ jsx31("span", { children: "Type" }),
11856
+ /* @__PURE__ */ jsx31("span", { children: "Name" }),
11857
+ /* @__PURE__ */ jsx31("span", { children: reference === "fields" ? "ID" : "Signature" })
11804
11858
  ] }),
11805
- /* @__PURE__ */ jsxs26("div", { className: "qt-metric-reference-list", children: [
11806
- referenceItems.map((item) => /* @__PURE__ */ jsxs26(
11859
+ /* @__PURE__ */ jsxs27("div", { className: "qt-metric-reference-list", children: [
11860
+ referenceItems.map((item) => /* @__PURE__ */ jsxs27(
11807
11861
  "button",
11808
11862
  {
11809
11863
  type: "button",
@@ -11813,14 +11867,14 @@ ${item.description}`,
11813
11867
  onMouseDown: (e) => e.preventDefault(),
11814
11868
  onClick: () => insert(item.wrap ? item.name : item.detail, item.wrap),
11815
11869
  children: [
11816
- /* @__PURE__ */ jsx30("span", { children: item.type }),
11817
- /* @__PURE__ */ jsx30("strong", { children: item.label }),
11818
- /* @__PURE__ */ jsx30("code", { children: reference === "fields" ? item.name : item.detail })
11870
+ /* @__PURE__ */ jsx31("span", { children: item.type }),
11871
+ /* @__PURE__ */ jsx31("strong", { children: item.label }),
11872
+ /* @__PURE__ */ jsx31("code", { children: reference === "fields" ? item.name : item.detail })
11819
11873
  ]
11820
11874
  },
11821
11875
  item.name
11822
11876
  )),
11823
- referenceItems.length === 0 && /* @__PURE__ */ jsxs26("p", { className: "qt-metric-help", role: "status", children: [
11877
+ referenceItems.length === 0 && /* @__PURE__ */ jsxs27("p", { className: "qt-metric-help", role: "status", children: [
11824
11878
  "No ",
11825
11879
  reference,
11826
11880
  " match \u201C",
@@ -11828,24 +11882,24 @@ ${item.description}`,
11828
11882
  "\u201D."
11829
11883
  ] })
11830
11884
  ] }),
11831
- /* @__PURE__ */ jsx30("p", { className: "qt-metric-help", children: "Insert at the cursor. Select expression text to wrap it in a function." })
11885
+ /* @__PURE__ */ jsx31("p", { className: "qt-metric-help", children: "Insert at the cursor. Select expression text to wrap it in a function." })
11832
11886
  ]
11833
11887
  }
11834
11888
  ),
11835
11889
  separator(2),
11836
- /* @__PURE__ */ jsxs26("section", { className: "qt-metric-live-preview", ...paneProps(3), children: [
11837
- /* @__PURE__ */ jsxs26("div", { className: "qt-metric-preview-heading", children: [
11838
- /* @__PURE__ */ jsx30("h3", { children: "Live preview" }),
11839
- /* @__PURE__ */ jsx30("span", { className: "qt-metric-preview-status", role: "status", children: previewLoading ? "Calculating\u2026" : selectedResult?.error || error || selected && diagnostics.has(selected.id) ? "Needs attention" : selectedResult?.coverage === "exact" ? "Complete results" : selectedResult?.coverage === "partial" ? "Partial results" : "Preview" }),
11890
+ /* @__PURE__ */ jsxs27("section", { className: "qt-metric-live-preview", ...paneProps(3), children: [
11891
+ /* @__PURE__ */ jsxs27("div", { className: "qt-metric-preview-heading", children: [
11892
+ /* @__PURE__ */ jsx31("h3", { children: "Live preview" }),
11893
+ /* @__PURE__ */ jsx31("span", { className: "qt-metric-preview-status", role: "status", children: previewLoading ? "Calculating\u2026" : selectedResult?.error || error || selected && diagnostics.has(selected.id) ? "Needs attention" : selectedResult?.coverage === "exact" ? "Complete results" : selectedResult?.coverage === "partial" ? "Partial results" : "Preview" }),
11840
11894
  panelToggle(3, true)
11841
11895
  ] }),
11842
- selected && /* @__PURE__ */ jsxs26(Fragment19, { children: [
11843
- /* @__PURE__ */ jsx30("p", { className: "qt-metric-preview-scope", children: selected.scope === "shownRows" ? "Shown rows on this page" : "All matching rows" }),
11844
- /* @__PURE__ */ jsx30("p", { className: "qt-metric-help", children: "Aggregate input rows, then apply result ordering and display." }),
11845
- /* @__PURE__ */ jsxs26("div", { className: "qt-metric-preview-controls", children: [
11846
- /* @__PURE__ */ jsxs26("label", { children: [
11896
+ selected && /* @__PURE__ */ jsxs27(Fragment19, { children: [
11897
+ /* @__PURE__ */ jsx31("p", { className: "qt-metric-preview-scope", children: selected.scope === "shownRows" ? "Shown rows on this page" : "All matching rows" }),
11898
+ /* @__PURE__ */ jsx31("p", { className: "qt-metric-help", children: "Aggregate input rows, then apply result ordering and display." }),
11899
+ /* @__PURE__ */ jsxs27("div", { className: "qt-metric-preview-controls", children: [
11900
+ /* @__PURE__ */ jsxs27("label", { children: [
11847
11901
  "Width (px)",
11848
- /* @__PURE__ */ jsx30(
11902
+ /* @__PURE__ */ jsx31(
11849
11903
  MetricNumberInput,
11850
11904
  {
11851
11905
  "aria-label": "Preview width",
@@ -11863,9 +11917,9 @@ ${item.description}`,
11863
11917
  selected.id
11864
11918
  )
11865
11919
  ] }),
11866
- /* @__PURE__ */ jsxs26("label", { children: [
11920
+ /* @__PURE__ */ jsxs27("label", { children: [
11867
11921
  "Height (px)",
11868
- /* @__PURE__ */ jsx30(
11922
+ /* @__PURE__ */ jsx31(
11869
11923
  MetricNumberInput,
11870
11924
  {
11871
11925
  "aria-label": "Preview height",
@@ -11883,7 +11937,7 @@ ${item.description}`,
11883
11937
  selected.id
11884
11938
  )
11885
11939
  ] }),
11886
- /* @__PURE__ */ jsx30(
11940
+ /* @__PURE__ */ jsx31(
11887
11941
  "button",
11888
11942
  {
11889
11943
  type: "button",
@@ -11901,7 +11955,7 @@ ${item.description}`,
11901
11955
  children: "Use card size"
11902
11956
  }
11903
11957
  ),
11904
- /* @__PURE__ */ jsx30(
11958
+ /* @__PURE__ */ jsx31(
11905
11959
  "button",
11906
11960
  {
11907
11961
  type: "button",
@@ -11909,11 +11963,11 @@ ${item.description}`,
11909
11963
  "aria-label": "Refresh preview",
11910
11964
  title: "Refresh preview",
11911
11965
  onClick: () => setRetry((value) => value + 1),
11912
- children: /* @__PURE__ */ jsx30(Icon, { name: "refresh", size: 14 })
11966
+ children: /* @__PURE__ */ jsx31(Icon, { name: "refresh", size: 14 })
11913
11967
  }
11914
11968
  )
11915
11969
  ] }),
11916
- /* @__PURE__ */ jsx30(
11970
+ /* @__PURE__ */ jsx31(
11917
11971
  "div",
11918
11972
  {
11919
11973
  ref: previewContainer,
@@ -11925,8 +11979,8 @@ ${item.description}`,
11925
11979
  children: card(selected)
11926
11980
  }
11927
11981
  ),
11928
- /* @__PURE__ */ jsx30("p", { className: "qt-metric-help", children: "Drag the lower-right corner to resize. Preview dimensions are temporary." }),
11929
- selectedResult?.processedRows !== void 0 && /* @__PURE__ */ jsxs26("p", { className: "qt-muted", children: [
11982
+ /* @__PURE__ */ jsx31("p", { className: "qt-metric-help", children: "Drag the lower-right corner to resize. Preview dimensions are temporary." }),
11983
+ selectedResult?.processedRows !== void 0 && /* @__PURE__ */ jsxs27("p", { className: "qt-muted", children: [
11930
11984
  selectedResult.processedRows.toLocaleString(locale),
11931
11985
  " input rows \xB7 ",
11932
11986
  selectedResult.buckets.length,
@@ -11936,27 +11990,27 @@ ${item.description}`,
11936
11990
  " ",
11937
11991
  "groups"
11938
11992
  ] }),
11939
- inspectedBucket && /* @__PURE__ */ jsxs26(
11993
+ inspectedBucket && /* @__PURE__ */ jsxs27(
11940
11994
  "details",
11941
11995
  {
11942
11996
  className: "qt-metric-settings qt-metric-inspection",
11943
11997
  open: inspectOpen,
11944
11998
  onToggle: (e) => setInspectOpen(e.currentTarget.open),
11945
11999
  children: [
11946
- /* @__PURE__ */ jsxs26("summary", { children: [
11947
- /* @__PURE__ */ jsx30("strong", { children: "Inspect result" }),
11948
- /* @__PURE__ */ jsx30("span", { children: inspectedBucket.keys.map((k) => k === null ? "NULL" : String(k)).join(" / ") || "One value" })
12000
+ /* @__PURE__ */ jsxs27("summary", { children: [
12001
+ /* @__PURE__ */ jsx31("strong", { children: "Inspect result" }),
12002
+ /* @__PURE__ */ jsx31("span", { children: inspectedBucket.keys.map((k) => k === null ? "NULL" : String(k)).join(" / ") || "One value" })
11949
12003
  ] }),
11950
- /* @__PURE__ */ jsxs26("div", { children: [
11951
- selectedResult && selectedResult.buckets.length > 1 && /* @__PURE__ */ jsxs26("label", { children: [
12004
+ /* @__PURE__ */ jsxs27("div", { children: [
12005
+ selectedResult && selectedResult.buckets.length > 1 && /* @__PURE__ */ jsxs27("label", { children: [
11952
12006
  "Result group",
11953
- /* @__PURE__ */ jsx30(
12007
+ /* @__PURE__ */ jsx31(
11954
12008
  "select",
11955
12009
  {
11956
12010
  "aria-label": "Inspect result group",
11957
12011
  value: JSON.stringify(inspectedBucket.keys),
11958
12012
  onChange: (e) => setInspectedKey(e.target.value),
11959
- children: selectedResult.buckets.map((b) => /* @__PURE__ */ jsx30(
12013
+ children: selectedResult.buckets.map((b) => /* @__PURE__ */ jsx31(
11960
12014
  "option",
11961
12015
  {
11962
12016
  value: JSON.stringify(b.keys),
@@ -11967,7 +12021,7 @@ ${item.description}`,
11967
12021
  }
11968
12022
  )
11969
12023
  ] }),
11970
- /* @__PURE__ */ jsx30(
12024
+ /* @__PURE__ */ jsx31(
11971
12025
  MetricInspection,
11972
12026
  {
11973
12027
  bucket: inspectedBucket,
@@ -11984,11 +12038,11 @@ ${item.description}`,
11984
12038
  ]
11985
12039
  }
11986
12040
  ),
11987
- error && /* @__PURE__ */ jsx30("p", { className: "qt-metric-editor-error", role: "alert", children: error }),
11988
- contextChanged && /* @__PURE__ */ jsx30("p", { className: "qt-metric-editor-error", role: "status", children: "The metric configuration changed outside this draft." }),
11989
- /* @__PURE__ */ jsxs26("footer", { className: "qt-metrics-editor-footer", children: [
11990
- /* @__PURE__ */ jsx30("span", { className: "qt-muted", children: dirty ? "Unsaved changes" : "Changes stay in this draft until applied." }),
11991
- removed && /* @__PURE__ */ jsxs26(
12041
+ error && /* @__PURE__ */ jsx31("p", { className: "qt-metric-editor-error", role: "alert", children: error }),
12042
+ contextChanged && /* @__PURE__ */ jsx31("p", { className: "qt-metric-editor-error", role: "status", children: "The metric configuration changed outside this draft." }),
12043
+ /* @__PURE__ */ jsxs27("footer", { className: "qt-metrics-editor-footer", children: [
12044
+ /* @__PURE__ */ jsx31("span", { className: "qt-muted", children: dirty ? "Unsaved changes" : "Changes stay in this draft until applied." }),
12045
+ removed && /* @__PURE__ */ jsxs27(
11992
12046
  "button",
11993
12047
  {
11994
12048
  type: "button",
@@ -12012,12 +12066,12 @@ ${item.description}`,
12012
12066
  setRemoved(null);
12013
12067
  },
12014
12068
  children: [
12015
- /* @__PURE__ */ jsx30(Icon, { name: "undo", size: 14 }),
12069
+ /* @__PURE__ */ jsx31(Icon, { name: "undo", size: 14 }),
12016
12070
  "Undo remove"
12017
12071
  ]
12018
12072
  }
12019
12073
  ),
12020
- issues.size > 0 && /* @__PURE__ */ jsxs26(
12074
+ issues.size > 0 && /* @__PURE__ */ jsxs27(
12021
12075
  "button",
12022
12076
  {
12023
12077
  type: "button",
@@ -12027,7 +12081,7 @@ ${item.description}`,
12027
12081
  navigate("editor", issues.keys().next().value);
12028
12082
  },
12029
12083
  children: [
12030
- /* @__PURE__ */ jsx30(Icon, { name: "alert", size: 14 }),
12084
+ /* @__PURE__ */ jsx31(Icon, { name: "alert", size: 14 }),
12031
12085
  "Review ",
12032
12086
  issues.size,
12033
12087
  " ",
@@ -12035,8 +12089,8 @@ ${item.description}`,
12035
12089
  ]
12036
12090
  }
12037
12091
  ),
12038
- /* @__PURE__ */ jsx30("button", { type: "button", className: "qt-btn", onClick: close, children: "Cancel" }),
12039
- /* @__PURE__ */ jsx30(
12092
+ /* @__PURE__ */ jsx31("button", { type: "button", className: "qt-btn", onClick: close, children: "Cancel" }),
12093
+ /* @__PURE__ */ jsx31(
12040
12094
  "button",
12041
12095
  {
12042
12096
  type: "button",
@@ -12047,20 +12101,20 @@ ${item.description}`,
12047
12101
  }
12048
12102
  )
12049
12103
  ] }),
12050
- /* @__PURE__ */ jsxs26("div", { className: "qt-sr-only", role: "status", "aria-live": "polite", children: [
12104
+ /* @__PURE__ */ jsxs27("div", { className: "qt-sr-only", role: "status", "aria-live": "polite", children: [
12051
12105
  announcement,
12052
12106
  selectedPosition >= 0 ? `Selected metric ${selectedPosition + 1} of ${drafts.length}` : ""
12053
12107
  ] }),
12054
- discard && /* @__PURE__ */ jsx30(
12108
+ discard && /* @__PURE__ */ jsx31(
12055
12109
  ModalSurface,
12056
12110
  {
12057
12111
  title: "Discard metric changes?",
12058
12112
  className: "qt-modal qt-metric-discard",
12059
12113
  onClose: () => setDiscard(false),
12060
- children: /* @__PURE__ */ jsxs26("div", { className: "qt-overlay-body", children: [
12061
- /* @__PURE__ */ jsx30("p", { children: "Your metric draft has not been applied." }),
12062
- /* @__PURE__ */ jsxs26("div", { className: "qt-metric-discard-actions", children: [
12063
- /* @__PURE__ */ jsx30(
12114
+ children: /* @__PURE__ */ jsxs27("div", { className: "qt-overlay-body", children: [
12115
+ /* @__PURE__ */ jsx31("p", { children: "Your metric draft has not been applied." }),
12116
+ /* @__PURE__ */ jsxs27("div", { className: "qt-metric-discard-actions", children: [
12117
+ /* @__PURE__ */ jsx31(
12064
12118
  "button",
12065
12119
  {
12066
12120
  type: "button",
@@ -12069,7 +12123,7 @@ ${item.description}`,
12069
12123
  children: "Keep editing"
12070
12124
  }
12071
12125
  ),
12072
- /* @__PURE__ */ jsx30("button", { type: "button", className: "qt-btn", onClick: onClose, children: "Discard changes" })
12126
+ /* @__PURE__ */ jsx31("button", { type: "button", className: "qt-btn", onClick: onClose, children: "Discard changes" })
12073
12127
  ] })
12074
12128
  ] })
12075
12129
  }
@@ -12078,7 +12132,7 @@ ${item.description}`,
12078
12132
  }
12079
12133
  );
12080
12134
  function separator(index) {
12081
- return /* @__PURE__ */ jsx30(
12135
+ return /* @__PURE__ */ jsx31(
12082
12136
  EditorPanelSeparator,
12083
12137
  {
12084
12138
  workbench,
@@ -12100,8 +12154,8 @@ function MetricNumberInput({
12100
12154
  max,
12101
12155
  ...props
12102
12156
  }) {
12103
- const [draft, setDraft] = useState25(null);
12104
- return /* @__PURE__ */ jsx30(
12157
+ const [draft, setDraft] = useState26(null);
12158
+ return /* @__PURE__ */ jsx31(
12105
12159
  "input",
12106
12160
  {
12107
12161
  ...props,
@@ -12137,18 +12191,18 @@ function Settings({
12137
12191
  open,
12138
12192
  onOpenChange
12139
12193
  }) {
12140
- return /* @__PURE__ */ jsxs26(
12194
+ return /* @__PURE__ */ jsxs27(
12141
12195
  "details",
12142
12196
  {
12143
12197
  className: "qt-metric-settings",
12144
12198
  open,
12145
12199
  onToggle: (e) => onOpenChange(e.currentTarget.open),
12146
12200
  children: [
12147
- /* @__PURE__ */ jsxs26("summary", { children: [
12148
- /* @__PURE__ */ jsx30("strong", { children: title }),
12149
- /* @__PURE__ */ jsx30("span", { children: summary })
12201
+ /* @__PURE__ */ jsxs27("summary", { children: [
12202
+ /* @__PURE__ */ jsx31("strong", { children: title }),
12203
+ /* @__PURE__ */ jsx31("span", { children: summary })
12150
12204
  ] }),
12151
- /* @__PURE__ */ jsx30("div", { children })
12205
+ /* @__PURE__ */ jsx31("div", { children })
12152
12206
  ]
12153
12207
  }
12154
12208
  );
@@ -12177,15 +12231,15 @@ function MetricFormatControls({
12177
12231
  ["millisecondsOfDay", "Milliseconds since midnight"]
12178
12232
  ] : []
12179
12233
  ];
12180
- return /* @__PURE__ */ jsxs26(
12234
+ return /* @__PURE__ */ jsxs27(
12181
12235
  "div",
12182
12236
  {
12183
12237
  className: `qt-metric-format-controls${temporal ? " qt-metric-format-controls--temporal" : ""}`,
12184
12238
  children: [
12185
12239
  displayControl,
12186
- /* @__PURE__ */ jsxs26("label", { children: [
12240
+ /* @__PURE__ */ jsxs27("label", { children: [
12187
12241
  "Output type",
12188
- /* @__PURE__ */ jsx30(
12242
+ /* @__PURE__ */ jsx31(
12189
12243
  "select",
12190
12244
  {
12191
12245
  "aria-label": "Metric output type",
@@ -12204,7 +12258,7 @@ function MetricFormatControls({
12204
12258
  "date",
12205
12259
  "time",
12206
12260
  "datetime"
12207
- ].map((kind) => /* @__PURE__ */ jsx30("option", { value: kind, children: {
12261
+ ].map((kind) => /* @__PURE__ */ jsx31("option", { value: kind, children: {
12208
12262
  number: "Number",
12209
12263
  percent: "Percent",
12210
12264
  duration: "Duration",
@@ -12215,9 +12269,9 @@ function MetricFormatControls({
12215
12269
  }
12216
12270
  )
12217
12271
  ] }),
12218
- !temporal && /* @__PURE__ */ jsxs26("label", { children: [
12272
+ !temporal && /* @__PURE__ */ jsxs27("label", { children: [
12219
12273
  "Decimals",
12220
- /* @__PURE__ */ jsx30(
12274
+ /* @__PURE__ */ jsx31(
12221
12275
  MetricNumberInput,
12222
12276
  {
12223
12277
  "aria-label": "Metric decimals",
@@ -12232,10 +12286,10 @@ function MetricFormatControls({
12232
12286
  }
12233
12287
  )
12234
12288
  ] }),
12235
- temporal && /* @__PURE__ */ jsxs26("div", { className: "qt-metric-temporal-controls", children: [
12236
- /* @__PURE__ */ jsxs26("label", { children: [
12289
+ temporal && /* @__PURE__ */ jsxs27("div", { className: "qt-metric-temporal-controls", children: [
12290
+ /* @__PURE__ */ jsxs27("label", { children: [
12237
12291
  "Source units / encoding",
12238
- /* @__PURE__ */ jsx30(
12292
+ /* @__PURE__ */ jsx31(
12239
12293
  "select",
12240
12294
  {
12241
12295
  "aria-label": "Source units",
@@ -12243,13 +12297,13 @@ function MetricFormatControls({
12243
12297
  onChange: (e) => patch({
12244
12298
  sourceUnit: e.target.value
12245
12299
  }),
12246
- children: units.map(([unit, label]) => /* @__PURE__ */ jsx30("option", { value: unit, children: label }, unit))
12300
+ children: units.map(([unit, label]) => /* @__PURE__ */ jsx31("option", { value: unit, children: label }, unit))
12247
12301
  }
12248
12302
  )
12249
12303
  ] }),
12250
- /* @__PURE__ */ jsxs26("label", { children: [
12304
+ /* @__PURE__ */ jsxs27("label", { children: [
12251
12305
  "Label format",
12252
- /* @__PURE__ */ jsxs26(
12306
+ /* @__PURE__ */ jsxs27(
12253
12307
  "select",
12254
12308
  {
12255
12309
  "aria-label": "Label format",
@@ -12259,19 +12313,19 @@ function MetricFormatControls({
12259
12313
  pattern: format.pattern ?? (duration ? "{h}h{m}m" : format.kind === "time" ? "HH:mm:ss" : format.kind === "date" ? "YYYY-MM-DD" : "YYYY-MM-DD HH:mm:ss")
12260
12314
  }),
12261
12315
  children: [
12262
- /* @__PURE__ */ jsx30("option", { value: "human", children: duration ? "Human readable" : format.kind === "time" ? "24-hour" : "Readable" }),
12263
- duration ? /* @__PURE__ */ jsxs26(Fragment19, { children: [
12264
- /* @__PURE__ */ jsx30("option", { value: "long", children: "Long" }),
12265
- /* @__PURE__ */ jsx30("option", { value: "clock", children: "Clock \xB7 total hours" })
12266
- ] }) : /* @__PURE__ */ jsx30("option", { value: "iso", children: "ISO-style" }),
12267
- /* @__PURE__ */ jsx30("option", { value: "custom", children: "Custom format string" })
12316
+ /* @__PURE__ */ jsx31("option", { value: "human", children: duration ? "Human readable" : format.kind === "time" ? "24-hour" : "Readable" }),
12317
+ duration ? /* @__PURE__ */ jsxs27(Fragment19, { children: [
12318
+ /* @__PURE__ */ jsx31("option", { value: "long", children: "Long" }),
12319
+ /* @__PURE__ */ jsx31("option", { value: "clock", children: "Clock \xB7 total hours" })
12320
+ ] }) : /* @__PURE__ */ jsx31("option", { value: "iso", children: "ISO-style" }),
12321
+ /* @__PURE__ */ jsx31("option", { value: "custom", children: "Custom format string" })
12268
12322
  ]
12269
12323
  }
12270
12324
  )
12271
12325
  ] }),
12272
- format.style === "custom" && /* @__PURE__ */ jsxs26("label", { children: [
12326
+ format.style === "custom" && /* @__PURE__ */ jsxs27("label", { children: [
12273
12327
  "Format string",
12274
- /* @__PURE__ */ jsx30(
12328
+ /* @__PURE__ */ jsx31(
12275
12329
  "input",
12276
12330
  {
12277
12331
  "aria-label": "Output format string",
@@ -12280,13 +12334,13 @@ function MetricFormatControls({
12280
12334
  onChange: (e) => patch({ pattern: e.target.value })
12281
12335
  }
12282
12336
  ),
12283
- /* @__PURE__ */ jsx30("span", { className: "qt-muted", children: duration ? "{d} {h} {hh} {m} {mm} {s} {ss} {ms}" : "YYYY MM DD MMM MMMM ddd HH hh mm ss SSS A Z; [literal text]" })
12337
+ /* @__PURE__ */ jsx31("span", { className: "qt-muted", children: duration ? "{d} {h} {hh} {m} {mm} {s} {ss} {ms}" : "YYYY MM DD MMM MMMM ddd HH hh mm ss SSS A Z; [literal text]" })
12284
12338
  ] }),
12285
12339
  !duration && !["secondsOfDay", "millisecondsOfDay"].includes(
12286
12340
  format.sourceUnit ?? ""
12287
- ) && /* @__PURE__ */ jsxs26("label", { children: [
12341
+ ) && /* @__PURE__ */ jsxs27("label", { children: [
12288
12342
  "Timezone",
12289
- /* @__PURE__ */ jsx30(
12343
+ /* @__PURE__ */ jsx31(
12290
12344
  "input",
12291
12345
  {
12292
12346
  "aria-label": "Output timezone",
@@ -12298,9 +12352,9 @@ function MetricFormatControls({
12298
12352
  )
12299
12353
  ] })
12300
12354
  ] }),
12301
- /* @__PURE__ */ jsxs26("div", { className: "qt-metric-format-example", children: [
12302
- /* @__PURE__ */ jsx30("span", { children: "Format example" }),
12303
- /* @__PURE__ */ jsx30("strong", { children: formatMetricOutput(
12355
+ /* @__PURE__ */ jsxs27("div", { className: "qt-metric-format-example", children: [
12356
+ /* @__PURE__ */ jsx31("span", { children: "Format example" }),
12357
+ /* @__PURE__ */ jsx31("strong", { children: formatMetricOutput(
12304
12358
  sample === void 0 ? format.kind === "date" || format.kind === "datetime" ? "2026-10-08T14:30:00Z" : format.kind === "time" ? "14:30:00" : format.kind === "duration" ? 83400 : 0.875 : sample,
12305
12359
  format,
12306
12360
  locale
@@ -12347,13 +12401,13 @@ function MetricInspection({
12347
12401
  ],
12348
12402
  ["NULL values", String(bucket.nullCount ?? 0)]
12349
12403
  );
12350
- return /* @__PURE__ */ jsxs26(Fragment19, { children: [
12351
- /* @__PURE__ */ jsx30("code", { className: "qt-metric-inspection-expression", children: clause.distribution && ["box", "histogram"].includes(clause.display?.kind ?? "") ? clause.distribution.input : metricExpression(clause) }),
12352
- /* @__PURE__ */ jsx30("dl", { className: "qt-metric-inspection-values", children: rows.map(([label, value]) => /* @__PURE__ */ jsxs26("div", { children: [
12353
- /* @__PURE__ */ jsx30("dt", { children: label }),
12354
- /* @__PURE__ */ jsx30("dd", { children: value })
12404
+ return /* @__PURE__ */ jsxs27(Fragment19, { children: [
12405
+ /* @__PURE__ */ jsx31("code", { className: "qt-metric-inspection-expression", children: clause.distribution && ["box", "histogram"].includes(clause.display?.kind ?? "") ? clause.distribution.input : metricExpression(clause) }),
12406
+ /* @__PURE__ */ jsx31("dl", { className: "qt-metric-inspection-values", children: rows.map(([label, value]) => /* @__PURE__ */ jsxs27("div", { children: [
12407
+ /* @__PURE__ */ jsx31("dt", { children: label }),
12408
+ /* @__PURE__ */ jsx31("dd", { children: value })
12355
12409
  ] }, label)) }),
12356
- bucket.error && /* @__PURE__ */ jsx30("p", { className: "qt-metric-editor-error", children: bucket.error })
12410
+ bucket.error && /* @__PURE__ */ jsx31("p", { className: "qt-metric-editor-error", children: bucket.error })
12357
12411
  ] });
12358
12412
  }
12359
12413
  function simpleAggregate(clause, fields) {
@@ -12375,7 +12429,7 @@ function simpleAggregate(clause, fields) {
12375
12429
  }
12376
12430
 
12377
12431
  // src/SortExtractionEditor.tsx
12378
- import { useEffect as useEffect18, useId as useId9, useMemo as useMemo10, useRef as useRef19, useState as useState26 } from "react";
12432
+ import { useEffect as useEffect18, useId as useId9, useMemo as useMemo10, useRef as useRef19, useState as useState27 } from "react";
12379
12433
 
12380
12434
  // src/sortExtractionPreview.ts
12381
12435
  function extractSortSamples(pattern, values) {
@@ -12434,17 +12488,17 @@ function previewSortExtraction(pattern, values, signal) {
12434
12488
  }
12435
12489
 
12436
12490
  // src/SortExtractionEditor.tsx
12437
- import { Fragment as Fragment20, jsx as jsx31, jsxs as jsxs27 } from "react/jsx-runtime";
12491
+ import { Fragment as Fragment20, jsx as jsx32, jsxs as jsxs28 } from "react/jsx-runtime";
12438
12492
  function SortExtractionEditor({ api, field, label, fieldOptions, onFieldChange, direction = "desc", onDirectionChange, title, applyLabel = "Apply extraction", initialPattern, disabled, onApply, onRemove, onClose }) {
12439
- const [pattern, setPattern] = useState26(initialPattern ?? "");
12440
- const [patternField, setPatternField] = useState26(field);
12493
+ const [pattern, setPattern] = useState27(initialPattern ?? "");
12494
+ const [patternField, setPatternField] = useState27(field);
12441
12495
  if (patternField !== field) {
12442
12496
  setPatternField(field);
12443
12497
  setPattern(initialPattern ?? "");
12444
12498
  }
12445
- const [sample, setSample] = useState26(null);
12446
- const [sampleError, setSampleError] = useState26(null);
12447
- const [preview, setPreview] = useState26(null);
12499
+ const [sample, setSample] = useState27(null);
12500
+ const [sampleError, setSampleError] = useState27(null);
12501
+ const [preview, setPreview] = useState27(null);
12448
12502
  const request = useRef19(api.computed.preview);
12449
12503
  request.current = api.computed.preview;
12450
12504
  const inputId = useId9();
@@ -12489,79 +12543,79 @@ function SortExtractionEditor({ api, field, label, fieldOptions, onFieldChange,
12489
12543
  const previewWarning = sampleError ?? currentPreview?.error;
12490
12544
  const heading = title ?? `Regex extraction for ${label}`;
12491
12545
  const textValue = (value) => value == null ? "NULL" : String(value) === "" ? '""' : String(value);
12492
- return /* @__PURE__ */ jsxs27(ModalSurface, { title: heading, onClose, className: "qt-sort-extract-editor", chrome: false, children: [
12493
- /* @__PURE__ */ jsxs27("header", { className: "qt-overlay-header", children: [
12494
- /* @__PURE__ */ jsx31("h2", { children: heading }),
12495
- /* @__PURE__ */ jsx31("button", { type: "button", className: "qt-btn", onClick: onClose, "aria-label": title ? `Close ${title.toLowerCase()}` : `Close regex extraction for ${label}`, children: /* @__PURE__ */ jsx31(Icon, { name: "close" }) })
12546
+ return /* @__PURE__ */ jsxs28(ModalSurface, { title: heading, onClose, className: "qt-sort-extract-editor", chrome: false, children: [
12547
+ /* @__PURE__ */ jsxs28("header", { className: "qt-overlay-header", children: [
12548
+ /* @__PURE__ */ jsx32("h2", { children: heading }),
12549
+ /* @__PURE__ */ jsx32("button", { type: "button", className: "qt-btn", onClick: onClose, "aria-label": title ? `Close ${title.toLowerCase()}` : `Close regex extraction for ${label}`, children: /* @__PURE__ */ jsx32(Icon, { name: "close" }) })
12496
12550
  ] }),
12497
- /* @__PURE__ */ jsxs27("div", { className: "qt-overlay-body", children: [
12498
- fieldOptions && /* @__PURE__ */ jsxs27(Fragment20, { children: [
12499
- /* @__PURE__ */ jsx31("label", { className: "qt-sort-extract-label", htmlFor: fieldId, children: "Field" }),
12500
- /* @__PURE__ */ jsx31("select", { id: fieldId, className: "qt-input qt-sort-extract-field", value: field, disabled, onChange: (event) => onFieldChange?.(event.target.value), children: fieldOptions.map((option) => /* @__PURE__ */ jsx31("option", { value: option.name, children: option.label }, option.name)) })
12551
+ /* @__PURE__ */ jsxs28("div", { className: "qt-overlay-body", children: [
12552
+ fieldOptions && /* @__PURE__ */ jsxs28(Fragment20, { children: [
12553
+ /* @__PURE__ */ jsx32("label", { className: "qt-sort-extract-label", htmlFor: fieldId, children: "Field" }),
12554
+ /* @__PURE__ */ jsx32("select", { id: fieldId, className: "qt-input qt-sort-extract-field", value: field, disabled, onChange: (event) => onFieldChange?.(event.target.value), children: fieldOptions.map((option) => /* @__PURE__ */ jsx32("option", { value: option.name, children: option.label }, option.name)) })
12501
12555
  ] }),
12502
- onDirectionChange && /* @__PURE__ */ jsxs27(Fragment20, { children: [
12503
- /* @__PURE__ */ jsx31("label", { className: "qt-sort-extract-label", htmlFor: directionId, children: "Direction" }),
12504
- /* @__PURE__ */ jsxs27("select", { id: directionId, className: "qt-input qt-sort-extract-direction", value: direction, disabled, onChange: (event) => onDirectionChange(event.target.value), children: [
12505
- /* @__PURE__ */ jsx31("option", { value: "asc", children: "Ascending" }),
12506
- /* @__PURE__ */ jsx31("option", { value: "desc", children: "Descending" })
12556
+ onDirectionChange && /* @__PURE__ */ jsxs28(Fragment20, { children: [
12557
+ /* @__PURE__ */ jsx32("label", { className: "qt-sort-extract-label", htmlFor: directionId, children: "Direction" }),
12558
+ /* @__PURE__ */ jsxs28("select", { id: directionId, className: "qt-input qt-sort-extract-direction", value: direction, disabled, onChange: (event) => onDirectionChange(event.target.value), children: [
12559
+ /* @__PURE__ */ jsx32("option", { value: "asc", children: "Ascending" }),
12560
+ /* @__PURE__ */ jsx32("option", { value: "desc", children: "Descending" })
12507
12561
  ] })
12508
12562
  ] }),
12509
- /* @__PURE__ */ jsx31("label", { className: "qt-sort-extract-label", htmlFor: inputId, children: "Regular expression" }),
12510
- /* @__PURE__ */ jsx31("input", { id: inputId, className: "qt-input qt-sort-extract-input", value: pattern, onChange: (event) => setPattern(event.target.value), "aria-label": `Regex extract for ${label}`, "aria-describedby": helpId, "aria-invalid": Boolean(patternError), disabled, autoComplete: "off", spellCheck: false, placeholder: "e.g. (\\d+)" }),
12511
- /* @__PURE__ */ jsx31("p", { id: helpId, className: "qt-sort-extract-help", children: "Sort by the first capture group, or the whole match if there are no groups. Unmatched values become NULL; the sort\u2019s null placement still applies." }),
12512
- patternError && /* @__PURE__ */ jsx31("p", { className: "qt-sort-extract-error", role: "alert", children: patternError }),
12513
- previewWarning && /* @__PURE__ */ jsxs27("p", { className: "qt-sort-extract-error", role: "alert", children: [
12563
+ /* @__PURE__ */ jsx32("label", { className: "qt-sort-extract-label", htmlFor: inputId, children: "Regular expression" }),
12564
+ /* @__PURE__ */ jsx32("input", { id: inputId, className: "qt-input qt-sort-extract-input", value: pattern, onChange: (event) => setPattern(event.target.value), "aria-label": `Regex extract for ${label}`, "aria-describedby": helpId, "aria-invalid": Boolean(patternError), disabled, autoComplete: "off", spellCheck: false, placeholder: "e.g. (\\d+)" }),
12565
+ /* @__PURE__ */ jsx32("p", { id: helpId, className: "qt-sort-extract-help", children: "Sort by the first capture group, or the whole match if there are no groups. Unmatched values become NULL; the sort\u2019s null placement still applies." }),
12566
+ patternError && /* @__PURE__ */ jsx32("p", { className: "qt-sort-extract-error", role: "alert", children: patternError }),
12567
+ previewWarning && /* @__PURE__ */ jsxs28("p", { className: "qt-sort-extract-error", role: "alert", children: [
12514
12568
  "Preview unavailable: ",
12515
12569
  previewWarning,
12516
12570
  ". You can still apply a valid pattern."
12517
12571
  ] }),
12518
- Boolean(sample?.errors) && /* @__PURE__ */ jsx31("p", { className: "qt-sort-extract-error", role: "alert", children: "Some sampled values could not be read. The preview may be incomplete; you can still apply a valid pattern." }),
12519
- /* @__PURE__ */ jsx31("p", { className: "qt-sort-extract-status", role: "status", children: !sample && !sampleError ? "Loading sample\u2026" : !currentPreview && !patternError && !previewWarning ? "Updating preview\u2026" : sample ? `Preview of ${sample.processed} matching rows (${sample.groups.length} distinct values).` : "Sample unavailable." }),
12520
- /* @__PURE__ */ jsx31("div", { className: "qt-sort-extract-table-wrap", children: /* @__PURE__ */ jsxs27("table", { className: "qt-sort-extract-table", children: [
12521
- /* @__PURE__ */ jsx31("caption", { children: "Extraction preview" }),
12522
- /* @__PURE__ */ jsx31("thead", { children: /* @__PURE__ */ jsxs27("tr", { children: [
12523
- /* @__PURE__ */ jsx31("th", { scope: "col", children: "Original value" }),
12524
- /* @__PURE__ */ jsx31("th", { scope: "col", children: "Extracted sort value" }),
12525
- /* @__PURE__ */ jsx31("th", { scope: "col", children: "Rows" })
12572
+ Boolean(sample?.errors) && /* @__PURE__ */ jsx32("p", { className: "qt-sort-extract-error", role: "alert", children: "Some sampled values could not be read. The preview may be incomplete; you can still apply a valid pattern." }),
12573
+ /* @__PURE__ */ jsx32("p", { className: "qt-sort-extract-status", role: "status", children: !sample && !sampleError ? "Loading sample\u2026" : !currentPreview && !patternError && !previewWarning ? "Updating preview\u2026" : sample ? `Preview of ${sample.processed} matching rows (${sample.groups.length} distinct values).` : "Sample unavailable." }),
12574
+ /* @__PURE__ */ jsx32("div", { className: "qt-sort-extract-table-wrap", children: /* @__PURE__ */ jsxs28("table", { className: "qt-sort-extract-table", children: [
12575
+ /* @__PURE__ */ jsx32("caption", { children: "Extraction preview" }),
12576
+ /* @__PURE__ */ jsx32("thead", { children: /* @__PURE__ */ jsxs28("tr", { children: [
12577
+ /* @__PURE__ */ jsx32("th", { scope: "col", children: "Original value" }),
12578
+ /* @__PURE__ */ jsx32("th", { scope: "col", children: "Extracted sort value" }),
12579
+ /* @__PURE__ */ jsx32("th", { scope: "col", children: "Rows" })
12526
12580
  ] }) }),
12527
- /* @__PURE__ */ jsx31("tbody", { children: sample?.groups.map((group, index) => {
12581
+ /* @__PURE__ */ jsx32("tbody", { children: sample?.groups.map((group, index) => {
12528
12582
  const result = currentPreview?.results[index];
12529
- return /* @__PURE__ */ jsxs27("tr", { children: [
12530
- /* @__PURE__ */ jsx31("td", { children: group.result.error ? "Value error" : textValue(group.result.value) }),
12531
- /* @__PURE__ */ jsx31("td", { children: result ? /* @__PURE__ */ jsxs27(Fragment20, { children: [
12532
- /* @__PURE__ */ jsx31("code", { children: textValue(result.extracted) }),
12533
- !result.matched && /* @__PURE__ */ jsx31("small", { children: group.result.value == null ? "Null input" : "No match" })
12583
+ return /* @__PURE__ */ jsxs28("tr", { children: [
12584
+ /* @__PURE__ */ jsx32("td", { children: group.result.error ? "Value error" : textValue(group.result.value) }),
12585
+ /* @__PURE__ */ jsx32("td", { children: result ? /* @__PURE__ */ jsxs28(Fragment20, { children: [
12586
+ /* @__PURE__ */ jsx32("code", { children: textValue(result.extracted) }),
12587
+ !result.matched && /* @__PURE__ */ jsx32("small", { children: group.result.value == null ? "Null input" : "No match" })
12534
12588
  ] }) : "\u2014" }),
12535
- /* @__PURE__ */ jsx31("td", { children: group.count })
12589
+ /* @__PURE__ */ jsx32("td", { children: group.count })
12536
12590
  ] }, index);
12537
12591
  }) })
12538
12592
  ] }) }),
12539
- sample?.processed === 0 && /* @__PURE__ */ jsx31("p", { className: "qt-muted", children: "No matching rows to preview. You can still apply a valid pattern." })
12593
+ sample?.processed === 0 && /* @__PURE__ */ jsx32("p", { className: "qt-muted", children: "No matching rows to preview. You can still apply a valid pattern." })
12540
12594
  ] }),
12541
- /* @__PURE__ */ jsxs27("footer", { className: "qt-sort-extract-footer", children: [
12542
- initialPattern !== void 0 && /* @__PURE__ */ jsx31("button", { type: "button", className: "qt-link-btn", disabled, onClick: onRemove, "aria-label": `Remove regex extract for ${label}`, children: "Remove extraction" }),
12543
- /* @__PURE__ */ jsx31("button", { type: "button", className: "qt-btn", onClick: onClose, children: "Cancel" }),
12544
- /* @__PURE__ */ jsx31("button", { type: "button", className: "qt-btn qt-btn--primary", disabled: disabled || Boolean(patternError), onClick: () => onApply(pattern), children: applyLabel })
12595
+ /* @__PURE__ */ jsxs28("footer", { className: "qt-sort-extract-footer", children: [
12596
+ initialPattern !== void 0 && /* @__PURE__ */ jsx32("button", { type: "button", className: "qt-link-btn", disabled, onClick: onRemove, "aria-label": `Remove regex extract for ${label}`, children: "Remove extraction" }),
12597
+ /* @__PURE__ */ jsx32("button", { type: "button", className: "qt-btn", onClick: onClose, children: "Cancel" }),
12598
+ /* @__PURE__ */ jsx32("button", { type: "button", className: "qt-btn qt-btn--primary", disabled: disabled || Boolean(patternError), onClick: () => onApply(pattern), children: applyLabel })
12545
12599
  ] })
12546
12600
  ] });
12547
12601
  }
12548
12602
 
12549
12603
  // src/SortPicker.tsx
12550
- import { useEffect as useEffect19, useRef as useRef20, useState as useState27 } from "react";
12551
- import { jsx as jsx32, jsxs as jsxs28 } from "react/jsx-runtime";
12604
+ import { useEffect as useEffect19, useRef as useRef20, useState as useState28 } from "react";
12605
+ import { jsx as jsx33, jsxs as jsxs29 } from "react/jsx-runtime";
12552
12606
  function SortPicker({
12553
12607
  fields,
12554
12608
  onPick,
12555
12609
  onRegex,
12556
12610
  onClose
12557
12611
  }) {
12558
- const [field, setField] = useState27(null);
12559
- const [search, setSearch] = useState27("");
12612
+ const [field, setField] = useState28(null);
12613
+ const [search, setSearch] = useState28("");
12560
12614
  const ascending = useRef20(null);
12561
12615
  useEffect19(() => {
12562
12616
  if (field) ascending.current?.focus();
12563
12617
  }, [field]);
12564
- return /* @__PURE__ */ jsx32(
12618
+ return /* @__PURE__ */ jsx33(
12565
12619
  FieldPicker,
12566
12620
  {
12567
12621
  title: field ? `Sort by ${field.label}` : "Add sort",
@@ -12571,20 +12625,20 @@ function SortPicker({
12571
12625
  onPick: setField,
12572
12626
  onClose,
12573
12627
  ...field ? { onBack: () => setField(null) } : {},
12574
- children: field && /* @__PURE__ */ jsxs28("div", { className: "qt-sort-picker-options", children: [
12575
- /* @__PURE__ */ jsxs28("div", { className: "qt-sort-direction-grid", role: "group", "aria-label": "Sort direction", children: [
12576
- /* @__PURE__ */ jsxs28("button", { ref: ascending, type: "button", className: "qt-btn", onClick: () => onPick(field, "asc"), children: [
12577
- /* @__PURE__ */ jsx32(Icon, { name: "arrowUp" }),
12628
+ children: field && /* @__PURE__ */ jsxs29("div", { className: "qt-sort-picker-options", children: [
12629
+ /* @__PURE__ */ jsxs29("div", { className: "qt-sort-direction-grid", role: "group", "aria-label": "Sort direction", children: [
12630
+ /* @__PURE__ */ jsxs29("button", { ref: ascending, type: "button", className: "qt-btn", onClick: () => onPick(field, "asc"), children: [
12631
+ /* @__PURE__ */ jsx33(Icon, { name: "arrowUp" }),
12578
12632
  " Ascending"
12579
12633
  ] }),
12580
- /* @__PURE__ */ jsxs28("button", { type: "button", className: "qt-btn", onClick: () => onPick(field, "desc"), children: [
12581
- /* @__PURE__ */ jsx32(Icon, { name: "arrowDown" }),
12634
+ /* @__PURE__ */ jsxs29("button", { type: "button", className: "qt-btn", onClick: () => onPick(field, "desc"), children: [
12635
+ /* @__PURE__ */ jsx33(Icon, { name: "arrowDown" }),
12582
12636
  " Descending"
12583
12637
  ] })
12584
12638
  ] }),
12585
- /* @__PURE__ */ jsxs28("button", { type: "button", className: "qt-link-btn qt-sort-picker-regex", "aria-haspopup": "dialog", onClick: () => onRegex(field), children: [
12639
+ /* @__PURE__ */ jsxs29("button", { type: "button", className: "qt-link-btn qt-sort-picker-regex", "aria-haspopup": "dialog", onClick: () => onRegex(field), children: [
12586
12640
  "Regex extraction ",
12587
- /* @__PURE__ */ jsx32(Icon, { name: "chevronRight", size: 14 })
12641
+ /* @__PURE__ */ jsx33(Icon, { name: "chevronRight", size: 14 })
12588
12642
  ] })
12589
12643
  ] })
12590
12644
  }
@@ -12592,16 +12646,16 @@ function SortPicker({
12592
12646
  }
12593
12647
 
12594
12648
  // src/SetFilterEditor.tsx
12595
- import { useEffect as useEffect20, useRef as useRef21, useState as useState28 } from "react";
12649
+ import { useEffect as useEffect20, useRef as useRef21, useState as useState29 } from "react";
12596
12650
  import { filterValues, opsForField as opsForField2 } from "@pythia-software/query-table-core";
12597
- import { Fragment as Fragment21, jsx as jsx33, jsxs as jsxs29 } from "react/jsx-runtime";
12651
+ import { Fragment as Fragment21, jsx as jsx34, jsxs as jsxs30 } from "react/jsx-runtime";
12598
12652
  function SetFilterEditor({ api, field, returnFocus, classNames, mode: initialMode, values: initialValues, disabled, maxPredicates, onApply, onClose }) {
12599
- const [mode, setMode] = useState28(initialMode);
12600
- const [values, setValues] = useState28([...initialValues]);
12601
- const [search, setSearch] = useState28("");
12602
- const [suggestions, setSuggestions] = useState28([]);
12603
- const [error, setError] = useState28("");
12604
- const [loading, setLoading] = useState28(false);
12653
+ const [mode, setMode] = useState29(initialMode);
12654
+ const [values, setValues] = useState29([...initialValues]);
12655
+ const [search, setSearch] = useState29("");
12656
+ const [suggestions, setSuggestions] = useState29([]);
12657
+ const [error, setError] = useState29("");
12658
+ const [loading, setLoading] = useState29(false);
12605
12659
  const searchInput = useRef21(null);
12606
12660
  const presentation = useFilterValuePresentation();
12607
12661
  const strategy = filterValues(field);
@@ -12641,7 +12695,7 @@ function SetFilterEditor({ api, field, returnFocus, classNames, mode: initialMod
12641
12695
  setSearch("");
12642
12696
  searchInput.current?.focus();
12643
12697
  }
12644
- return /* @__PURE__ */ jsxs29(
12698
+ return /* @__PURE__ */ jsxs30(
12645
12699
  ModalSurface,
12646
12700
  {
12647
12701
  title: `Filter ${field.label}`,
@@ -12652,29 +12706,29 @@ function SetFilterEditor({ api, field, returnFocus, classNames, mode: initialMod
12652
12706
  backdropClassName: ["qt-set-backdrop", classNames?.setBackdrop].filter(Boolean).join(" "),
12653
12707
  className: ["qt-set-editor", classNames?.setEditor].filter(Boolean).join(" "),
12654
12708
  children: [
12655
- /* @__PURE__ */ jsxs29("h3", { children: [
12709
+ /* @__PURE__ */ jsxs30("h3", { children: [
12656
12710
  "Filter ",
12657
12711
  field.label
12658
12712
  ] }),
12659
- /* @__PURE__ */ jsxs29("label", { children: [
12713
+ /* @__PURE__ */ jsxs30("label", { children: [
12660
12714
  "Match mode ",
12661
- /* @__PURE__ */ jsxs29("select", { className: classNames?.select, "aria-label": "Match mode", value: mode, disabled, onChange: (event) => setMode(event.target.value), children: [
12662
- /* @__PURE__ */ jsx33("option", { value: "any", disabled: !allowsMode("any"), children: "ANY \u2014 at least one selected tag" }),
12663
- /* @__PURE__ */ jsx33("option", { value: "all", disabled: !allowsMode("all"), children: "ALL \u2014 every selected tag" }),
12664
- /* @__PURE__ */ jsx33("option", { value: "none", disabled: !allowsMode("none"), children: "NONE \u2014 exclude selected tags, include empty rows" }),
12665
- /* @__PURE__ */ jsx33("option", { value: "empty", disabled: !allowsMode("empty"), children: "EMPTY \u2014 no tags" })
12715
+ /* @__PURE__ */ jsxs30("select", { className: classNames?.select, "aria-label": "Match mode", value: mode, disabled, onChange: (event) => setMode(event.target.value), children: [
12716
+ /* @__PURE__ */ jsx34("option", { value: "any", disabled: !allowsMode("any"), children: "ANY \u2014 at least one selected tag" }),
12717
+ /* @__PURE__ */ jsx34("option", { value: "all", disabled: !allowsMode("all"), children: "ALL \u2014 every selected tag" }),
12718
+ /* @__PURE__ */ jsx34("option", { value: "none", disabled: !allowsMode("none"), children: "NONE \u2014 exclude selected tags, include empty rows" }),
12719
+ /* @__PURE__ */ jsx34("option", { value: "empty", disabled: !allowsMode("empty"), children: "EMPTY \u2014 no tags" })
12666
12720
  ] })
12667
12721
  ] }),
12668
- mode !== "empty" && /* @__PURE__ */ jsxs29(Fragment21, { children: [
12669
- /* @__PURE__ */ jsx33("div", { className: "qt-set-selected", "aria-label": "Selected tags", children: values.map((value) => /* @__PURE__ */ jsxs29("span", { className: "qt-chip", children: [
12670
- /* @__PURE__ */ jsx33(PresentedFilterValue, { field: field.name, value, label: labelFor(value) }),
12671
- strategy.source === "static" && !options.some((option) => option.value === value) && /* @__PURE__ */ jsxs29("small", { children: [
12722
+ mode !== "empty" && /* @__PURE__ */ jsxs30(Fragment21, { children: [
12723
+ /* @__PURE__ */ jsx34("div", { className: "qt-set-selected", "aria-label": "Selected tags", children: values.map((value) => /* @__PURE__ */ jsxs30("span", { className: "qt-chip", children: [
12724
+ /* @__PURE__ */ jsx34(PresentedFilterValue, { field: field.name, value, label: labelFor(value) }),
12725
+ strategy.source === "static" && !options.some((option) => option.value === value) && /* @__PURE__ */ jsxs30("small", { children: [
12672
12726
  " unavailable: ",
12673
12727
  value
12674
12728
  ] }),
12675
- /* @__PURE__ */ jsx33("button", { type: "button", className: "qt-chip-x", disabled, "aria-label": `Remove ${labelFor(value)}`, onClick: () => toggle(value), children: "\u2715" })
12729
+ /* @__PURE__ */ jsx34("button", { type: "button", className: "qt-chip-x", disabled, "aria-label": `Remove ${labelFor(value)}`, onClick: () => toggle(value), children: "\u2715" })
12676
12730
  ] }, value)) }),
12677
- /* @__PURE__ */ jsx33("input", { ref: searchInput, className: classNames?.input, "aria-label": `Search ${field.label} tags`, placeholder: "Search names or keys", value: search, onChange: (event) => setSearch(event.target.value), disabled, onKeyDown: (event) => {
12731
+ /* @__PURE__ */ jsx34("input", { ref: searchInput, className: classNames?.input, "aria-label": `Search ${field.label} tags`, placeholder: "Search names or keys", value: search, onChange: (event) => setSearch(event.target.value), disabled, onKeyDown: (event) => {
12678
12732
  if (event.key !== "Enter" || event.nativeEvent.isComposing || disabled) return;
12679
12733
  event.preventDefault();
12680
12734
  if (!search.trim()) return;
@@ -12682,25 +12736,25 @@ function SetFilterEditor({ api, field, returnFocus, classNames, mode: initialMod
12682
12736
  if (value !== void 0) addValue(value);
12683
12737
  else if (canCreate) addValue(search);
12684
12738
  } }),
12685
- /* @__PURE__ */ jsxs29("div", { className: "qt-set-options", role: "group", "aria-label": "Available tags", children: [
12686
- visible.map((option) => /* @__PURE__ */ jsxs29("label", { className: "qt-set-option", children: [
12687
- /* @__PURE__ */ jsx33("input", { type: "checkbox", checked: values.includes(option.value), disabled, onChange: () => toggle(option.value) }),
12688
- /* @__PURE__ */ jsx33(PresentedFilterValue, { field: field.name, value: option.value, label: labelFor(option.value) }),
12689
- labelFor(option.value) !== option.value && /* @__PURE__ */ jsx33("small", { children: option.value })
12739
+ /* @__PURE__ */ jsxs30("div", { className: "qt-set-options", role: "group", "aria-label": "Available tags", children: [
12740
+ visible.map((option) => /* @__PURE__ */ jsxs30("label", { className: "qt-set-option", children: [
12741
+ /* @__PURE__ */ jsx34("input", { type: "checkbox", checked: values.includes(option.value), disabled, onChange: () => toggle(option.value) }),
12742
+ /* @__PURE__ */ jsx34(PresentedFilterValue, { field: field.name, value: option.value, label: labelFor(option.value) }),
12743
+ labelFor(option.value) !== option.value && /* @__PURE__ */ jsx34("small", { children: option.value })
12690
12744
  ] }, option.value)),
12691
- !visible.length && !loading && /* @__PURE__ */ jsx33("span", { className: "qt-muted", children: strategy.source === "freeform" ? "Type a tag and press Enter" : "No matching tags" })
12745
+ !visible.length && !loading && /* @__PURE__ */ jsx34("span", { className: "qt-muted", children: strategy.source === "freeform" ? "Type a tag and press Enter" : "No matching tags" })
12692
12746
  ] }),
12693
- showCreate && /* @__PURE__ */ jsxs29("button", { type: "button", className: ["qt-btn", classNames?.button].filter(Boolean).join(" "), disabled, onClick: () => addValue(search), children: [
12747
+ showCreate && /* @__PURE__ */ jsxs30("button", { type: "button", className: ["qt-btn", classNames?.button].filter(Boolean).join(" "), disabled, onClick: () => addValue(search), children: [
12694
12748
  "Add \u201C",
12695
12749
  search,
12696
12750
  "\u201D"
12697
12751
  ] }),
12698
- /* @__PURE__ */ jsx33("span", { role: "status", children: loading ? "Loading tags\u2026" : error })
12752
+ /* @__PURE__ */ jsx34("span", { role: "status", children: loading ? "Loading tags\u2026" : error })
12699
12753
  ] }),
12700
- exceedsBudget && /* @__PURE__ */ jsx33("span", { role: "alert", children: "Too many tags for this query. Remove tags or other filters before applying." }),
12701
- /* @__PURE__ */ jsxs29("div", { className: "qt-set-actions", children: [
12702
- /* @__PURE__ */ jsx33("button", { type: "button", className: ["qt-btn", classNames?.button].filter(Boolean).join(" "), onClick: onClose, children: "Cancel" }),
12703
- /* @__PURE__ */ jsx33("button", { type: "button", className: ["qt-btn", classNames?.button].filter(Boolean).join(" "), disabled: disabled || exceedsBudget || !allowsMode(mode) || mode !== "empty" && values.length === 0, onClick: () => onApply(mode, mode === "empty" ? [] : values), children: "Apply filter" })
12754
+ exceedsBudget && /* @__PURE__ */ jsx34("span", { role: "alert", children: "Too many tags for this query. Remove tags or other filters before applying." }),
12755
+ /* @__PURE__ */ jsxs30("div", { className: "qt-set-actions", children: [
12756
+ /* @__PURE__ */ jsx34("button", { type: "button", className: ["qt-btn", classNames?.button].filter(Boolean).join(" "), onClick: onClose, children: "Cancel" }),
12757
+ /* @__PURE__ */ jsx34("button", { type: "button", className: ["qt-btn", classNames?.button].filter(Boolean).join(" "), disabled: disabled || exceedsBudget || !allowsMode(mode) || mode !== "empty" && values.length === 0, onClick: () => onApply(mode, mode === "empty" ? [] : values), children: "Apply filter" })
12704
12758
  ] })
12705
12759
  ]
12706
12760
  }
@@ -12714,7 +12768,7 @@ import {
12714
12768
  useId as useId10,
12715
12769
  useMemo as useMemo11,
12716
12770
  useRef as useRef22,
12717
- useState as useState29
12771
+ useState as useState30
12718
12772
  } from "react";
12719
12773
  import {
12720
12774
  NULLARY_OPS as NULLARY_OPS2,
@@ -12735,13 +12789,13 @@ import {
12735
12789
  } from "@pythia-software/query-table-core";
12736
12790
 
12737
12791
  // src/SavedQueriesModal.tsx
12738
- import { jsx as jsx34, jsxs as jsxs30 } from "react/jsx-runtime";
12792
+ import { jsx as jsx35, jsxs as jsxs31 } from "react/jsx-runtime";
12739
12793
  function SavedQueriesModal({ saved, onClose, onLoad }) {
12740
- return /* @__PURE__ */ jsx34(ModalSurface, { title: "Saved queries", onClose, children: /* @__PURE__ */ jsx34("div", { className: "qt-overlay-body", children: saved.loading ? /* @__PURE__ */ jsx34("p", { className: "qt-muted", children: "Loading\u2026" }) : saved.items.length === 0 ? /* @__PURE__ */ jsx34("p", { className: "qt-muted", children: "None saved yet. Save the current query from the toolbar." }) : /* @__PURE__ */ jsx34("ul", { className: "qt-saved-list", children: saved.items.map((s) => {
12794
+ return /* @__PURE__ */ jsx35(ModalSurface, { title: "Saved queries", onClose, children: /* @__PURE__ */ jsx35("div", { className: "qt-overlay-body", children: saved.loading ? /* @__PURE__ */ jsx35("p", { className: "qt-muted", children: "Loading\u2026" }) : saved.items.length === 0 ? /* @__PURE__ */ jsx35("p", { className: "qt-muted", children: "None saved yet. Save the current query from the toolbar." }) : /* @__PURE__ */ jsx35("ul", { className: "qt-saved-list", children: saved.items.map((s) => {
12741
12795
  const filters = s.query.where.length;
12742
12796
  const isDefault = saved.defaultId === s.id;
12743
- return /* @__PURE__ */ jsxs30("li", { className: "qt-saved-item", children: [
12744
- /* @__PURE__ */ jsxs30(
12797
+ return /* @__PURE__ */ jsxs31("li", { className: "qt-saved-item", children: [
12798
+ /* @__PURE__ */ jsxs31(
12745
12799
  "button",
12746
12800
  {
12747
12801
  type: "button",
@@ -12752,8 +12806,8 @@ function SavedQueriesModal({ saved, onClose, onLoad }) {
12752
12806
  onClose();
12753
12807
  },
12754
12808
  children: [
12755
- /* @__PURE__ */ jsx34("span", { className: "qt-saved-name", children: s.name }),
12756
- /* @__PURE__ */ jsxs30("span", { className: "qt-saved-meta qt-muted", children: [
12809
+ /* @__PURE__ */ jsx35("span", { className: "qt-saved-name", children: s.name }),
12810
+ /* @__PURE__ */ jsxs31("span", { className: "qt-saved-meta qt-muted", children: [
12757
12811
  isDefault ? "Default view \xB7 " : "",
12758
12812
  new Date(s.savedAt).toLocaleString(),
12759
12813
  " \xB7 ",
@@ -12764,7 +12818,7 @@ function SavedQueriesModal({ saved, onClose, onLoad }) {
12764
12818
  ]
12765
12819
  }
12766
12820
  ),
12767
- isDefault ? /* @__PURE__ */ jsx34(
12821
+ isDefault ? /* @__PURE__ */ jsx35(
12768
12822
  "button",
12769
12823
  {
12770
12824
  type: "button",
@@ -12773,7 +12827,7 @@ function SavedQueriesModal({ saved, onClose, onLoad }) {
12773
12827
  onClick: () => void saved.clearDefault(),
12774
12828
  children: "default"
12775
12829
  }
12776
- ) : /* @__PURE__ */ jsx34(
12830
+ ) : /* @__PURE__ */ jsx35(
12777
12831
  "button",
12778
12832
  {
12779
12833
  type: "button",
@@ -12783,7 +12837,7 @@ function SavedQueriesModal({ saved, onClose, onLoad }) {
12783
12837
  children: "make default"
12784
12838
  }
12785
12839
  ),
12786
- /* @__PURE__ */ jsx34(
12840
+ /* @__PURE__ */ jsx35(
12787
12841
  "button",
12788
12842
  {
12789
12843
  type: "button",
@@ -12798,7 +12852,7 @@ function SavedQueriesModal({ saved, onClose, onLoad }) {
12798
12852
  }
12799
12853
 
12800
12854
  // src/QueryBuilder.tsx
12801
- import { Fragment as Fragment23, jsx as jsx35, jsxs as jsxs31 } from "react/jsx-runtime";
12855
+ import { Fragment as Fragment23, jsx as jsx36, jsxs as jsxs32 } from "react/jsx-runtime";
12802
12856
  var cx5 = (...parts) => parts.filter((p) => Boolean(p)).join(" ");
12803
12857
  var MAX_AUTO_REFRESH_POLLS = 1e3;
12804
12858
  var DEFAULT_AUTO_REFRESH_FREQUENCY_MS = 2e4;
@@ -12846,7 +12900,7 @@ function formatStatusTime(ms) {
12846
12900
  });
12847
12901
  }
12848
12902
  function useFieldHasNull(api, fieldName) {
12849
- const [hasNull, setHasNull] = useState29(void 0);
12903
+ const [hasNull, setHasNull] = useState30(void 0);
12850
12904
  useEffect21(() => {
12851
12905
  if (!fieldName) return;
12852
12906
  let cancelled = false;
@@ -12948,21 +13002,21 @@ function QueryBuilder({
12948
13002
  selectPresentation ?? (selectPresentation = groupingUI.selectPresentation);
12949
13003
  const mobile = useMobileLayout();
12950
13004
  const UNSAVED_QUERY_EDIT_ID = "__qt-unsaved-query__";
12951
- const [showSaved, setShowSaved] = useState29(false);
12952
- const [shareCopied, setShareCopied] = useState29(false);
12953
- const [showActivity, setShowActivity] = useState29(false);
13005
+ const [showSaved, setShowSaved] = useState30(false);
13006
+ const [shareCopied, setShareCopied] = useState30(false);
13007
+ const [showActivity, setShowActivity] = useState30(false);
12954
13008
  const activityId = useId10();
12955
- const [showAutoRefresh, setShowAutoRefresh] = useState29(false);
12956
- const [autoRefreshFrequencyMs, setAutoRefreshFrequencyMs] = useState29(
13009
+ const [showAutoRefresh, setShowAutoRefresh] = useState30(false);
13010
+ const [autoRefreshFrequencyMs, setAutoRefreshFrequencyMs] = useState30(
12957
13011
  DEFAULT_AUTO_REFRESH_FREQUENCY_MS
12958
13012
  );
12959
- const [autoRefreshTurnOffAfterMs, setAutoRefreshTurnOffAfterMs] = useState29(
13013
+ const [autoRefreshTurnOffAfterMs, setAutoRefreshTurnOffAfterMs] = useState30(
12960
13014
  DEFAULT_AUTO_REFRESH_TURN_OFF_AFTER_MS
12961
13015
  );
12962
- const [editingSavedId, setEditingSavedId] = useState29(null);
12963
- const [editingSavedName, setEditingSavedName] = useState29("");
12964
- const [lastSavedId, setLastSavedId] = useState29(null);
12965
- const [collapsedFallback, setCollapsedFallback] = useState29(defaultCollapsed);
13016
+ const [editingSavedId, setEditingSavedId] = useState30(null);
13017
+ const [editingSavedName, setEditingSavedName] = useState30("");
13018
+ const [lastSavedId, setLastSavedId] = useState30(null);
13019
+ const [collapsedFallback, setCollapsedFallback] = useState30(defaultCollapsed);
12966
13020
  const collapsedControlled = typeof collapsed !== "undefined";
12967
13021
  const isCollapsed = collapsedControlled ? collapsed : collapsedFallback;
12968
13022
  const setCollapsed = (next) => {
@@ -12972,8 +13026,8 @@ function QueryBuilder({
12972
13026
  }
12973
13027
  setCollapsedFallback(next);
12974
13028
  };
12975
- const [lastUpdatedAt, setLastUpdatedAt] = useState29(null);
12976
- const [lastFailureAt, setLastFailureAt] = useState29(null);
13029
+ const [lastUpdatedAt, setLastUpdatedAt] = useState30(null);
13030
+ const [lastFailureAt, setLastFailureAt] = useState30(null);
12977
13031
  const byName = useMemo11(
12978
13032
  () => new Map(fields.map((f) => [f.name, f])),
12979
13033
  [fields]
@@ -13198,15 +13252,15 @@ function QueryBuilder({
13198
13252
  window.prompt("Copy this query URL", url.toString());
13199
13253
  }
13200
13254
  }
13201
- return /* @__PURE__ */ jsxs31("div", { className: cx5(
13255
+ return /* @__PURE__ */ jsxs32("div", { className: cx5(
13202
13256
  "qt-qb",
13203
13257
  api.grouping && "qt-qb--groupable",
13204
13258
  compact && "qt-qb--compact",
13205
13259
  classNames?.root
13206
13260
  ), children: [
13207
- /* @__PURE__ */ jsxs31("div", { className: "qt-qb-bar qt-qb-state-bar qt-qb-row", children: [
13208
- /* @__PURE__ */ jsxs31("span", { className: "qt-qb-state-main", children: [
13209
- /* @__PURE__ */ jsxs31(
13261
+ /* @__PURE__ */ jsxs32("div", { className: "qt-qb-bar qt-qb-state-bar qt-qb-row", children: [
13262
+ /* @__PURE__ */ jsxs32("span", { className: "qt-qb-state-main", children: [
13263
+ /* @__PURE__ */ jsxs32(
13210
13264
  "button",
13211
13265
  {
13212
13266
  type: "button",
@@ -13217,7 +13271,7 @@ function QueryBuilder({
13217
13271
  "aria-label": isCollapsed ? "Expand query builder" : "Collapse query builder",
13218
13272
  title: isCollapsed ? "Expand query builder" : "Collapse query builder",
13219
13273
  children: [
13220
- /* @__PURE__ */ jsx35(
13274
+ /* @__PURE__ */ jsx36(
13221
13275
  Icon,
13222
13276
  {
13223
13277
  name: "chevronDown",
@@ -13228,12 +13282,12 @@ function QueryBuilder({
13228
13282
  )
13229
13283
  }
13230
13284
  ),
13231
- /* @__PURE__ */ jsx35("span", { children: "Query" })
13285
+ /* @__PURE__ */ jsx36("span", { children: "Query" })
13232
13286
  ]
13233
13287
  }
13234
13288
  ),
13235
- savedQueryControls !== void 0 ? savedQueryControls : /* @__PURE__ */ jsxs31("span", { className: "qt-qb-saved", children: [
13236
- /* @__PURE__ */ jsx35(
13289
+ savedQueryControls !== void 0 ? savedQueryControls : /* @__PURE__ */ jsxs32("span", { className: "qt-qb-saved", children: [
13290
+ /* @__PURE__ */ jsx36(
13237
13291
  "button",
13238
13292
  {
13239
13293
  type: "button",
@@ -13245,11 +13299,11 @@ function QueryBuilder({
13245
13299
  "aria-label": isSavedQuery ? "Rename saved query" : "Save query",
13246
13300
  disabled: isBusy,
13247
13301
  onClick: beginEditSavedName,
13248
- children: /* @__PURE__ */ jsx35(Icon, { name: "star", size: 16, filled: isSavedQuery })
13302
+ children: /* @__PURE__ */ jsx36(Icon, { name: "star", size: 16, filled: isSavedQuery })
13249
13303
  }
13250
13304
  ),
13251
- isEditingSaved || isEditingUnsaved ? /* @__PURE__ */ jsxs31("span", { className: "qt-qb-saved-input-wrap", children: [
13252
- /* @__PURE__ */ jsx35(
13305
+ isEditingSaved || isEditingUnsaved ? /* @__PURE__ */ jsxs32("span", { className: "qt-qb-saved-input-wrap", children: [
13306
+ /* @__PURE__ */ jsx36(
13253
13307
  "input",
13254
13308
  {
13255
13309
  type: "text",
@@ -13272,7 +13326,7 @@ function QueryBuilder({
13272
13326
  onClick: (e) => e.stopPropagation()
13273
13327
  }
13274
13328
  ),
13275
- /* @__PURE__ */ jsx35(
13329
+ /* @__PURE__ */ jsx36(
13276
13330
  "button",
13277
13331
  {
13278
13332
  type: "button",
@@ -13284,10 +13338,10 @@ function QueryBuilder({
13284
13338
  cancelNameEdit();
13285
13339
  },
13286
13340
  onClick: (e) => e.stopPropagation(),
13287
- children: /* @__PURE__ */ jsx35(Icon, { name: "close" })
13341
+ children: /* @__PURE__ */ jsx36(Icon, { name: "close" })
13288
13342
  }
13289
13343
  )
13290
- ] }) : /* @__PURE__ */ jsx35(
13344
+ ] }) : /* @__PURE__ */ jsx36(
13291
13345
  "button",
13292
13346
  {
13293
13347
  type: "button",
@@ -13300,24 +13354,24 @@ function QueryBuilder({
13300
13354
  }
13301
13355
  )
13302
13356
  ] }),
13303
- isCollapsed ? /* @__PURE__ */ jsx35(
13357
+ isCollapsed ? /* @__PURE__ */ jsx36(
13304
13358
  "span",
13305
13359
  {
13306
13360
  className: "qt-qb-summary qt-truncate",
13307
13361
  title: summary ? void 0 : collapsedSummary,
13308
- children: summary ?? /* @__PURE__ */ jsxs31(Fragment23, { children: [
13309
- /* @__PURE__ */ jsx35("span", { className: "qt-qb-summary-kw", children: "WHERE" }),
13362
+ children: summary ?? /* @__PURE__ */ jsxs32(Fragment23, { children: [
13363
+ /* @__PURE__ */ jsx36("span", { className: "qt-qb-summary-kw", children: "WHERE" }),
13310
13364
  " ",
13311
- /* @__PURE__ */ jsx35("strong", { children: collapsedWhereText }),
13365
+ /* @__PURE__ */ jsx36("strong", { children: collapsedWhereText }),
13312
13366
  " ",
13313
- /* @__PURE__ */ jsx35("span", { className: "qt-qb-summary-kw", children: "ORDER BY" }),
13367
+ /* @__PURE__ */ jsx36("span", { className: "qt-qb-summary-kw", children: "ORDER BY" }),
13314
13368
  " ",
13315
- /* @__PURE__ */ jsx35("strong", { children: collapsedOrderText })
13369
+ /* @__PURE__ */ jsx36("strong", { children: collapsedOrderText })
13316
13370
  ] })
13317
13371
  }
13318
13372
  ) : null
13319
13373
  ] }),
13320
- savedQueryControls === void 0 && showUpdateButton ? /* @__PURE__ */ jsx35(
13374
+ savedQueryControls === void 0 && showUpdateButton ? /* @__PURE__ */ jsx36(
13321
13375
  "button",
13322
13376
  {
13323
13377
  type: "button",
@@ -13327,7 +13381,7 @@ function QueryBuilder({
13327
13381
  children: `Update Query '${lastSavedQuery?.name ?? "query"}'`
13328
13382
  }
13329
13383
  ) : null,
13330
- /* @__PURE__ */ jsxs31(
13384
+ /* @__PURE__ */ jsxs32(
13331
13385
  "button",
13332
13386
  {
13333
13387
  type: "button",
@@ -13337,28 +13391,28 @@ function QueryBuilder({
13337
13391
  "aria-live": "polite",
13338
13392
  disabled: api.loading || api.links.busy,
13339
13393
  children: [
13340
- /* @__PURE__ */ jsx35(Icon, { name: shareCopied ? "check" : "share" }),
13394
+ /* @__PURE__ */ jsx36(Icon, { name: shareCopied ? "check" : "share" }),
13341
13395
  shareCopied ? "Copied!" : "Share"
13342
13396
  ]
13343
13397
  }
13344
13398
  ),
13345
- api.links.kind === "local" && /* @__PURE__ */ jsx35("small", { role: "status", children: "Temporary link \xB7 this browser only" }),
13346
- api.links.error && /* @__PURE__ */ jsx35("small", { role: "alert", children: api.links.error.message }),
13347
- savedQueryControls === void 0 && /* @__PURE__ */ jsxs31(
13399
+ api.links.kind === "local" && /* @__PURE__ */ jsx36("small", { role: "status", children: "Temporary link \xB7 this browser only" }),
13400
+ api.links.error && /* @__PURE__ */ jsx36("small", { role: "alert", children: api.links.error.message }),
13401
+ savedQueryControls === void 0 && /* @__PURE__ */ jsxs32(
13348
13402
  "button",
13349
13403
  {
13350
13404
  type: "button",
13351
13405
  className: cx5("qt-btn", classNames?.button),
13352
13406
  onClick: () => setShowSaved(true),
13353
13407
  children: [
13354
- /* @__PURE__ */ jsx35(Icon, { name: "bookmark" }),
13408
+ /* @__PURE__ */ jsx36(Icon, { name: "bookmark" }),
13355
13409
  "Saved",
13356
13410
  api.saved.items.length > 0 ? ` (${api.saved.items.length})` : ""
13357
13411
  ]
13358
13412
  }
13359
13413
  ),
13360
- /* @__PURE__ */ jsxs31("div", { className: "qt-property-history qt-query-history", role: "group", "aria-label": "Query history", children: [
13361
- /* @__PURE__ */ jsx35(
13414
+ /* @__PURE__ */ jsxs32("div", { className: "qt-property-history qt-query-history", role: "group", "aria-label": "Query history", children: [
13415
+ /* @__PURE__ */ jsx36(
13362
13416
  "button",
13363
13417
  {
13364
13418
  type: "button",
@@ -13367,10 +13421,10 @@ function QueryBuilder({
13367
13421
  title: "Undo query change",
13368
13422
  disabled: !api.canUndo || isBusy,
13369
13423
  onClick: api.undo,
13370
- children: /* @__PURE__ */ jsx35(Icon, { name: "undo", size: 14 })
13424
+ children: /* @__PURE__ */ jsx36(Icon, { name: "undo", size: 14 })
13371
13425
  }
13372
13426
  ),
13373
- /* @__PURE__ */ jsx35(
13427
+ /* @__PURE__ */ jsx36(
13374
13428
  "button",
13375
13429
  {
13376
13430
  type: "button",
@@ -13379,10 +13433,10 @@ function QueryBuilder({
13379
13433
  title: "Redo query change",
13380
13434
  disabled: !api.canRedo || isBusy,
13381
13435
  onClick: api.redo,
13382
- children: /* @__PURE__ */ jsx35(Icon, { name: "redo", size: 14 })
13436
+ children: /* @__PURE__ */ jsx36(Icon, { name: "redo", size: 14 })
13383
13437
  }
13384
13438
  ),
13385
- /* @__PURE__ */ jsx35(
13439
+ /* @__PURE__ */ jsx36(
13386
13440
  "button",
13387
13441
  {
13388
13442
  type: "button",
@@ -13391,13 +13445,13 @@ function QueryBuilder({
13391
13445
  title: "Reset query",
13392
13446
  disabled: isBusy,
13393
13447
  onClick: api.resetAll,
13394
- children: /* @__PURE__ */ jsx35(Icon, { name: "reset", size: 14 })
13448
+ children: /* @__PURE__ */ jsx36(Icon, { name: "reset", size: 14 })
13395
13449
  }
13396
13450
  )
13397
13451
  ] })
13398
13452
  ] }),
13399
- !isCollapsed ? /* @__PURE__ */ jsx35("div", { className: "qt-qb-bar qt-qb-editor-bar", children: /* @__PURE__ */ jsxs31("div", { id: bodyId, className: "qt-qb-body", children: [
13400
- /* @__PURE__ */ jsx35(
13453
+ !isCollapsed ? /* @__PURE__ */ jsx36("div", { className: "qt-qb-bar qt-qb-editor-bar", children: /* @__PURE__ */ jsxs32("div", { id: bodyId, className: "qt-qb-body", children: [
13454
+ /* @__PURE__ */ jsx36(
13401
13455
  SelectRow,
13402
13456
  {
13403
13457
  api,
@@ -13407,7 +13461,7 @@ function QueryBuilder({
13407
13461
  presentation: selectPresentation
13408
13462
  }
13409
13463
  ),
13410
- whereRow ?? /* @__PURE__ */ jsx35(
13464
+ whereRow ?? /* @__PURE__ */ jsx36(
13411
13465
  WhereRow,
13412
13466
  {
13413
13467
  api,
@@ -13418,7 +13472,7 @@ function QueryBuilder({
13418
13472
  }
13419
13473
  ),
13420
13474
  clauses,
13421
- /* @__PURE__ */ jsx35(
13475
+ /* @__PURE__ */ jsx36(
13422
13476
  OrderRow,
13423
13477
  {
13424
13478
  api,
@@ -13427,7 +13481,7 @@ function QueryBuilder({
13427
13481
  disabled: isBusy
13428
13482
  }
13429
13483
  ),
13430
- /* @__PURE__ */ jsx35(
13484
+ /* @__PURE__ */ jsx36(
13431
13485
  WindowRow,
13432
13486
  {
13433
13487
  api,
@@ -13437,7 +13491,7 @@ function QueryBuilder({
13437
13491
  disabled: isBusy
13438
13492
  }
13439
13493
  ),
13440
- /* @__PURE__ */ jsx35(
13494
+ /* @__PURE__ */ jsx36(
13441
13495
  MetricsRow,
13442
13496
  {
13443
13497
  api,
@@ -13447,8 +13501,8 @@ function QueryBuilder({
13447
13501
  }
13448
13502
  )
13449
13503
  ] }) }) : null,
13450
- /* @__PURE__ */ jsxs31("div", { className: "qt-qb-bar qt-qb-run-bar qt-qb-row", children: [
13451
- /* @__PURE__ */ jsx35(
13504
+ /* @__PURE__ */ jsxs32("div", { className: "qt-qb-bar qt-qb-run-bar qt-qb-row", children: [
13505
+ /* @__PURE__ */ jsx36(
13452
13506
  "span",
13453
13507
  {
13454
13508
  className: "qt-qb-run-metric qt-qb-run-metric--strong",
@@ -13456,16 +13510,16 @@ function QueryBuilder({
13456
13510
  children: api.loading ? "loading\u2026" : `${rowSummary} rows`
13457
13511
  }
13458
13512
  ),
13459
- /* @__PURE__ */ jsxs31("span", { className: "qt-qb-run-metric", children: [
13513
+ /* @__PURE__ */ jsxs32("span", { className: "qt-qb-run-metric", children: [
13460
13514
  "Last updated ",
13461
13515
  lastUpdatedText
13462
13516
  ] }),
13463
- failureText ? /* @__PURE__ */ jsx35("span", { className: "qt-qb-run-error", children: failureText }) : null,
13464
- /* @__PURE__ */ jsxs31("span", { className: "qt-qb-run-actions", children: [
13465
- autoRefreshStatus ? /* @__PURE__ */ jsx35("span", { className: "qt-qb-auto-status", children: `Every ${formatDuration2(autoRefreshStatus.frequencyMs)}; clear after ${formatDuration2(
13517
+ failureText ? /* @__PURE__ */ jsx36("span", { className: "qt-qb-run-error", children: failureText }) : null,
13518
+ /* @__PURE__ */ jsxs32("span", { className: "qt-qb-run-actions", children: [
13519
+ autoRefreshStatus ? /* @__PURE__ */ jsx36("span", { className: "qt-qb-auto-status", children: `Every ${formatDuration2(autoRefreshStatus.frequencyMs)}; clear after ${formatDuration2(
13466
13520
  autoRefreshStatus.turnOffAfterMs
13467
13521
  )} (${autoRefreshStatus.pollCount} polls run)` }) : null,
13468
- /* @__PURE__ */ jsx35(
13522
+ /* @__PURE__ */ jsx36(
13469
13523
  "button",
13470
13524
  {
13471
13525
  type: "button",
@@ -13479,11 +13533,11 @@ function QueryBuilder({
13479
13533
  "aria-expanded": showActivity,
13480
13534
  "aria-controls": activityId,
13481
13535
  onClick: () => setShowActivity((v) => !v),
13482
- children: /* @__PURE__ */ jsx35(Icon, { name: "stopwatch" })
13536
+ children: /* @__PURE__ */ jsx36(Icon, { name: "stopwatch" })
13483
13537
  }
13484
13538
  ),
13485
- /* @__PURE__ */ jsxs31("span", { className: "qt-auto-refresh", children: [
13486
- /* @__PURE__ */ jsxs31(
13539
+ /* @__PURE__ */ jsxs32("span", { className: "qt-auto-refresh", children: [
13540
+ /* @__PURE__ */ jsxs32(
13487
13541
  "button",
13488
13542
  {
13489
13543
  type: "button",
@@ -13498,12 +13552,12 @@ function QueryBuilder({
13498
13552
  "aria-expanded": showAutoRefresh,
13499
13553
  title: autoRefreshStatus ? "View or clear auto-update" : "Configure auto-update",
13500
13554
  children: [
13501
- /* @__PURE__ */ jsx35(Icon, { name: "clock" }),
13555
+ /* @__PURE__ */ jsx36(Icon, { name: "clock" }),
13502
13556
  autoRefreshButtonText
13503
13557
  ]
13504
13558
  }
13505
13559
  ),
13506
- showAutoRefresh && autoRefreshRef.current ? /* @__PURE__ */ jsxs31(
13560
+ showAutoRefresh && autoRefreshRef.current ? /* @__PURE__ */ jsxs32(
13507
13561
  Popover,
13508
13562
  {
13509
13563
  anchor: autoRefreshRef.current,
@@ -13512,27 +13566,27 @@ function QueryBuilder({
13512
13566
  label: "Auto-refresh settings",
13513
13567
  onClose: () => setShowAutoRefresh(false),
13514
13568
  children: [
13515
- /* @__PURE__ */ jsxs31("label", { className: "qt-auto-refresh-field", children: [
13516
- /* @__PURE__ */ jsx35("span", { children: "Frequency" }),
13517
- /* @__PURE__ */ jsx35(
13569
+ /* @__PURE__ */ jsxs32("label", { className: "qt-auto-refresh-field", children: [
13570
+ /* @__PURE__ */ jsx36("span", { children: "Frequency" }),
13571
+ /* @__PURE__ */ jsx36(
13518
13572
  "select",
13519
13573
  {
13520
13574
  className: "qt-auto-refresh-select",
13521
13575
  value: autoRefreshFrequencyMs,
13522
13576
  onChange: (e) => setAutoRefreshFrequencyMs(Number(e.target.value)),
13523
- children: AUTO_REFRESH_FREQUENCIES.map((option) => /* @__PURE__ */ jsx35("option", { value: option.value, children: option.label }, option.value))
13577
+ children: AUTO_REFRESH_FREQUENCIES.map((option) => /* @__PURE__ */ jsx36("option", { value: option.value, children: option.label }, option.value))
13524
13578
  }
13525
13579
  )
13526
13580
  ] }),
13527
- /* @__PURE__ */ jsxs31("label", { className: "qt-auto-refresh-field", children: [
13528
- /* @__PURE__ */ jsx35("span", { children: "Turn off after" }),
13529
- /* @__PURE__ */ jsx35(
13581
+ /* @__PURE__ */ jsxs32("label", { className: "qt-auto-refresh-field", children: [
13582
+ /* @__PURE__ */ jsx36("span", { children: "Turn off after" }),
13583
+ /* @__PURE__ */ jsx36(
13530
13584
  "select",
13531
13585
  {
13532
13586
  className: "qt-auto-refresh-select",
13533
13587
  value: autoRefreshTurnOffAfterMs,
13534
13588
  onChange: (e) => setAutoRefreshTurnOffAfterMs(Number(e.target.value)),
13535
- children: AUTO_REFRESH_TURN_OFF_AFTER.map((option) => /* @__PURE__ */ jsx35(
13589
+ children: AUTO_REFRESH_TURN_OFF_AFTER.map((option) => /* @__PURE__ */ jsx36(
13536
13590
  "option",
13537
13591
  {
13538
13592
  value: option.value,
@@ -13550,7 +13604,7 @@ function QueryBuilder({
13550
13604
  }
13551
13605
  )
13552
13606
  ] }),
13553
- /* @__PURE__ */ jsx35(
13607
+ /* @__PURE__ */ jsx36(
13554
13608
  "span",
13555
13609
  {
13556
13610
  className: cx5(
@@ -13560,7 +13614,7 @@ function QueryBuilder({
13560
13614
  children: canSubmitAutoRefresh ? `${selectedAutoRefreshPolls} polls maximum` : `Choose between 1 and 1000 polls`
13561
13615
  }
13562
13616
  ),
13563
- autoRefreshStatus ? /* @__PURE__ */ jsxs31("span", { className: "qt-auto-refresh-status", children: [
13617
+ autoRefreshStatus ? /* @__PURE__ */ jsxs32("span", { className: "qt-auto-refresh-status", children: [
13564
13618
  "Active: every",
13565
13619
  " ",
13566
13620
  formatDuration2(autoRefreshStatus.frequencyMs),
@@ -13571,8 +13625,8 @@ function QueryBuilder({
13571
13625
  autoRefreshStatus.pollCount,
13572
13626
  " polls run."
13573
13627
  ] }) : null,
13574
- /* @__PURE__ */ jsxs31("span", { className: "qt-auto-refresh-actions", children: [
13575
- /* @__PURE__ */ jsx35(
13628
+ /* @__PURE__ */ jsxs32("span", { className: "qt-auto-refresh-actions", children: [
13629
+ /* @__PURE__ */ jsx36(
13576
13630
  "button",
13577
13631
  {
13578
13632
  type: "button",
@@ -13582,7 +13636,7 @@ function QueryBuilder({
13582
13636
  children: autoRefreshStatus ? "Update" : "Start"
13583
13637
  }
13584
13638
  ),
13585
- autoRefreshStatus ? /* @__PURE__ */ jsx35(
13639
+ autoRefreshStatus ? /* @__PURE__ */ jsx36(
13586
13640
  "button",
13587
13641
  {
13588
13642
  type: "button",
@@ -13599,7 +13653,7 @@ function QueryBuilder({
13599
13653
  }
13600
13654
  ) : null
13601
13655
  ] }),
13602
- /* @__PURE__ */ jsxs31(
13656
+ /* @__PURE__ */ jsxs32(
13603
13657
  "button",
13604
13658
  {
13605
13659
  type: "button",
@@ -13607,7 +13661,7 @@ function QueryBuilder({
13607
13661
  onClick: api.refresh,
13608
13662
  disabled: isBusy,
13609
13663
  children: [
13610
- /* @__PURE__ */ jsx35(Icon, { name: "refresh" }),
13664
+ /* @__PURE__ */ jsx36(Icon, { name: "refresh" }),
13611
13665
  "Run Now"
13612
13666
  ]
13613
13667
  }
@@ -13615,8 +13669,8 @@ function QueryBuilder({
13615
13669
  ] })
13616
13670
  ] }),
13617
13671
  groupingUI.overlays,
13618
- showActivity && /* @__PURE__ */ jsx35(RequestActivity, { id: activityId, activity: api.requestActivity, children: requestActivityDetails }),
13619
- savedQueryControls === void 0 && showSaved ? /* @__PURE__ */ jsx35(
13672
+ showActivity && /* @__PURE__ */ jsx36(RequestActivity, { id: activityId, activity: api.requestActivity, children: requestActivityDetails }),
13673
+ savedQueryControls === void 0 && showSaved ? /* @__PURE__ */ jsx36(
13620
13674
  SavedQueriesModal,
13621
13675
  {
13622
13676
  saved: api.saved,
@@ -13643,13 +13697,13 @@ function SelectRow({
13643
13697
  }
13644
13698
  }
13645
13699
  const mobile = useMobileLayout();
13646
- const [editingColumns, setEditingColumns] = useState29(false);
13647
- const [editingField, setEditingField] = useState29();
13700
+ const [editingColumns, setEditingColumns] = useState30(false);
13701
+ const [editingField, setEditingField] = useState30();
13648
13702
  function openColumnEditor(field) {
13649
13703
  setEditingField(field);
13650
13704
  setEditingColumns(true);
13651
13705
  }
13652
- const detailSettingsButton = (field) => field === ITEM_DETAILS_COLUMN3 && api.itemDetails ? /* @__PURE__ */ jsx35(
13706
+ const detailSettingsButton = (field) => field === ITEM_DETAILS_COLUMN3 && api.itemDetails ? /* @__PURE__ */ jsx36(
13653
13707
  "button",
13654
13708
  {
13655
13709
  type: "button",
@@ -13660,10 +13714,10 @@ function SelectRow({
13660
13714
  "aria-expanded": editingColumns && editingField === field,
13661
13715
  disabled,
13662
13716
  onClick: () => openColumnEditor(field),
13663
- children: /* @__PURE__ */ jsx35(Icon, { name: "chevronRight", size: 18 })
13717
+ children: /* @__PURE__ */ jsx36(Icon, { name: "chevronRight", size: 18 })
13664
13718
  }
13665
13719
  ) : null;
13666
- const [adding, setAdding] = useState29(false);
13720
+ const [adding, setAdding] = useState30(false);
13667
13721
  const addColumnRef = useRef22(null);
13668
13722
  const fieldLabelByName = useMemo11(
13669
13723
  () => new Map(select.fields.map((f) => [f.name, f.label])),
@@ -13675,10 +13729,10 @@ function SelectRow({
13675
13729
  const fieldNames = select.visible.map((c) => c.field);
13676
13730
  const dragSource = columnDrag.source;
13677
13731
  const rendered = columnDrag.preview(fieldNames);
13678
- const actions = /* @__PURE__ */ jsxs31(Fragment23, { children: [
13679
- /* @__PURE__ */ jsxs31(PickerAnchor, { children: [
13680
- /* @__PURE__ */ jsxs31("span", { className: "qt-split-btn", role: "group", "aria-label": "Column actions", children: [
13681
- /* @__PURE__ */ jsxs31(
13732
+ const actions = /* @__PURE__ */ jsxs32(Fragment23, { children: [
13733
+ /* @__PURE__ */ jsxs32(PickerAnchor, { children: [
13734
+ /* @__PURE__ */ jsxs32("span", { className: "qt-split-btn", role: "group", "aria-label": "Column actions", children: [
13735
+ /* @__PURE__ */ jsxs32(
13682
13736
  "button",
13683
13737
  {
13684
13738
  type: "button",
@@ -13690,12 +13744,12 @@ function SelectRow({
13690
13744
  onClick: () => setAdding(!adding),
13691
13745
  disabled: disabled || !presentation?.renderPicker && select.hidden.length === 0,
13692
13746
  children: [
13693
- /* @__PURE__ */ jsx35(Icon, { name: "add" }),
13747
+ /* @__PURE__ */ jsx36(Icon, { name: "add" }),
13694
13748
  mobile ? "Add" : "add column"
13695
13749
  ]
13696
13750
  }
13697
13751
  ),
13698
- /* @__PURE__ */ jsx35(
13752
+ /* @__PURE__ */ jsx36(
13699
13753
  "button",
13700
13754
  {
13701
13755
  type: "button",
@@ -13706,11 +13760,11 @@ function SelectRow({
13706
13760
  "aria-expanded": editingColumns,
13707
13761
  disabled,
13708
13762
  onClick: () => openColumnEditor(),
13709
- children: /* @__PURE__ */ jsx35(Icon, { name: "chevronRight", size: 18 })
13763
+ children: /* @__PURE__ */ jsx36(Icon, { name: "chevronRight", size: 18 })
13710
13764
  }
13711
13765
  )
13712
13766
  ] }),
13713
- adding ? presentation?.renderPicker ? presentation.renderPicker(() => setAdding(false)) : /* @__PURE__ */ jsx35(
13767
+ adding ? presentation?.renderPicker ? presentation.renderPicker(() => setAdding(false)) : /* @__PURE__ */ jsx36(
13714
13768
  FieldPicker,
13715
13769
  {
13716
13770
  anchor: addColumnRef.current ?? void 0,
@@ -13723,7 +13777,7 @@ function SelectRow({
13723
13777
  }
13724
13778
  ) : null
13725
13779
  ] }),
13726
- /* @__PURE__ */ jsx35(
13780
+ /* @__PURE__ */ jsx36(
13727
13781
  "button",
13728
13782
  {
13729
13783
  type: "button",
@@ -13736,12 +13790,12 @@ function SelectRow({
13736
13790
  }
13737
13791
  )
13738
13792
  ] });
13739
- return /* @__PURE__ */ jsxs31("div", { className: "qt-qb-row qt-qb-row--select", children: [
13740
- /* @__PURE__ */ jsxs31("div", { className: "qt-qb-section-header", children: [
13741
- /* @__PURE__ */ jsx35("span", { className: "qt-qb-kw", "data-mobile-label": "Columns", children: "select" }),
13793
+ return /* @__PURE__ */ jsxs32("div", { className: "qt-qb-row qt-qb-row--select", children: [
13794
+ /* @__PURE__ */ jsxs32("div", { className: "qt-qb-section-header", children: [
13795
+ /* @__PURE__ */ jsx36("span", { className: "qt-qb-kw", "data-mobile-label": "Columns", children: "select" }),
13742
13796
  mobile && actions
13743
13797
  ] }),
13744
- editingColumns && (presentation?.renderEditor ? presentation.renderEditor(() => setEditingColumns(false)) : /* @__PURE__ */ jsx35(
13798
+ editingColumns && (presentation?.renderEditor ? presentation.renderEditor(() => setEditingColumns(false)) : /* @__PURE__ */ jsx36(
13745
13799
  SelectColumnEditor,
13746
13800
  {
13747
13801
  api,
@@ -13750,7 +13804,7 @@ function SelectRow({
13750
13804
  notice: presentation?.editorNotice
13751
13805
  }
13752
13806
  )),
13753
- mobile ? /* @__PURE__ */ jsx35(
13807
+ mobile ? /* @__PURE__ */ jsx36(
13754
13808
  ReorderList,
13755
13809
  {
13756
13810
  className: "qt-query-reorder-list qt-query-reorder-list--columns",
@@ -13762,10 +13816,10 @@ function SelectRow({
13762
13816
  })),
13763
13817
  onMove: select.move,
13764
13818
  disabled,
13765
- renderItem: (item) => /* @__PURE__ */ jsxs31(Fragment23, { children: [
13766
- presentation?.renderChip?.(item.id, item.label) ?? /* @__PURE__ */ jsx35("span", { className: "qt-chip-field", children: item.label }),
13819
+ renderItem: (item) => /* @__PURE__ */ jsxs32(Fragment23, { children: [
13820
+ presentation?.renderChip?.(item.id, item.label) ?? /* @__PURE__ */ jsx36("span", { className: "qt-chip-field", children: item.label }),
13767
13821
  detailSettingsButton(item.id),
13768
- /* @__PURE__ */ jsx35(
13822
+ /* @__PURE__ */ jsx36(
13769
13823
  "button",
13770
13824
  {
13771
13825
  type: "button",
@@ -13773,14 +13827,14 @@ function SelectRow({
13773
13827
  onClick: () => removeColumn(item.id),
13774
13828
  disabled,
13775
13829
  "aria-label": `Remove ${item.label} column`,
13776
- children: /* @__PURE__ */ jsx35(Icon, { name: "close" })
13830
+ children: /* @__PURE__ */ jsx36(Icon, { name: "close" })
13777
13831
  }
13778
13832
  )
13779
13833
  ] })
13780
13834
  }
13781
13835
  ) : rendered.map((name) => {
13782
13836
  const label = fieldLabelByName.get(name) ?? name;
13783
- return /* @__PURE__ */ jsxs31(
13837
+ return /* @__PURE__ */ jsxs32(
13784
13838
  "span",
13785
13839
  {
13786
13840
  className: cx5(
@@ -13823,10 +13877,10 @@ function SelectRow({
13823
13877
  onDragEnd: () => columnDrag.end(),
13824
13878
  title: "drag to reorder",
13825
13879
  children: [
13826
- /* @__PURE__ */ jsx35("span", { "aria-hidden": true, className: "qt-chip-grip", children: /* @__PURE__ */ jsx35(Icon, { name: "grip" }) }),
13827
- presentation?.renderChip?.(name, label) ?? /* @__PURE__ */ jsx35("span", { className: "qt-chip-field", children: label }),
13880
+ /* @__PURE__ */ jsx36("span", { "aria-hidden": true, className: "qt-chip-grip", children: /* @__PURE__ */ jsx36(Icon, { name: "grip" }) }),
13881
+ presentation?.renderChip?.(name, label) ?? /* @__PURE__ */ jsx36("span", { className: "qt-chip-field", children: label }),
13828
13882
  detailSettingsButton(name),
13829
- /* @__PURE__ */ jsx35(
13883
+ /* @__PURE__ */ jsx36(
13830
13884
  "button",
13831
13885
  {
13832
13886
  type: "button",
@@ -13834,7 +13888,7 @@ function SelectRow({
13834
13888
  onClick: () => removeColumn(name),
13835
13889
  disabled,
13836
13890
  "aria-label": `Remove ${label} column`,
13837
- children: /* @__PURE__ */ jsx35(Icon, { name: "close" })
13891
+ children: /* @__PURE__ */ jsx36(Icon, { name: "close" })
13838
13892
  }
13839
13893
  )
13840
13894
  ]
@@ -13855,7 +13909,7 @@ function QueryFilterRow({
13855
13909
  () => new Map(fields.map((field) => [field.name, field])),
13856
13910
  [fields]
13857
13911
  );
13858
- return /* @__PURE__ */ jsx35(
13912
+ return /* @__PURE__ */ jsx36(
13859
13913
  WhereRow,
13860
13914
  {
13861
13915
  api,
@@ -13882,14 +13936,14 @@ function WhereRow({
13882
13936
  disabled,
13883
13937
  label = "where"
13884
13938
  }) {
13885
- const [adding, setAdding] = useState29(false);
13939
+ const [adding, setAdding] = useState30(false);
13886
13940
  const mobile = useMobileLayout();
13887
13941
  const editorId = useId10();
13888
13942
  const nextSetId = useRef22(0);
13889
13943
  const addFilterButton = useRef22(null);
13890
- const [editingSet, setEditingSet] = useState29(null);
13891
- const [drag, setDrag] = useState29(null);
13892
- const [editingFilter, setEditingFilter] = useState29(null);
13944
+ const [editingSet, setEditingSet] = useState30(null);
13945
+ const [drag, setDrag] = useState30(null);
13946
+ const [editingFilter, setEditingFilter] = useState30(null);
13893
13947
  const where = api.query.where;
13894
13948
  const whereSignature = JSON.stringify(where);
13895
13949
  const setEditors = /* @__PURE__ */ new Map();
@@ -13974,9 +14028,9 @@ function WhereRow({
13974
14028
  }
13975
14029
  setDrag(null);
13976
14030
  }
13977
- const actions = /* @__PURE__ */ jsxs31(Fragment23, { children: [
13978
- /* @__PURE__ */ jsxs31(PickerAnchor, { children: [
13979
- /* @__PURE__ */ jsxs31(
14031
+ const actions = /* @__PURE__ */ jsxs32(Fragment23, { children: [
14032
+ /* @__PURE__ */ jsxs32(PickerAnchor, { children: [
14033
+ /* @__PURE__ */ jsxs32(
13980
14034
  "button",
13981
14035
  {
13982
14036
  ref: addFilterButton,
@@ -13988,12 +14042,12 @@ function WhereRow({
13988
14042
  onClick: () => setAdding(!adding),
13989
14043
  disabled,
13990
14044
  children: [
13991
- /* @__PURE__ */ jsx35(Icon, { name: "add" }),
14045
+ /* @__PURE__ */ jsx36(Icon, { name: "add" }),
13992
14046
  label === "having" ? "having" : "add filter"
13993
14047
  ]
13994
14048
  }
13995
14049
  ),
13996
- adding && /* @__PURE__ */ jsx35(
14050
+ adding && /* @__PURE__ */ jsx36(
13997
14051
  FieldPicker,
13998
14052
  {
13999
14053
  anchor: addFilterButton.current ?? void 0,
@@ -14004,7 +14058,7 @@ function WhereRow({
14004
14058
  }
14005
14059
  )
14006
14060
  ] }),
14007
- where.length > 0 && /* @__PURE__ */ jsx35(
14061
+ where.length > 0 && /* @__PURE__ */ jsx36(
14008
14062
  "button",
14009
14063
  {
14010
14064
  type: "button",
@@ -14016,18 +14070,18 @@ function WhereRow({
14016
14070
  }
14017
14071
  )
14018
14072
  ] });
14019
- return /* @__PURE__ */ jsxs31("div", { className: cx5("qt-qb-row qt-qb-row--filters", where.length === 0 && "qt-qb-row--unused"), "data-clause": label, children: [
14020
- /* @__PURE__ */ jsxs31("div", { className: "qt-qb-section-header", children: [
14021
- /* @__PURE__ */ jsx35("span", { className: "qt-qb-kw", "data-mobile-label": label === "having" ? "Having" : "Filters", children: label }),
14073
+ return /* @__PURE__ */ jsxs32("div", { className: cx5("qt-qb-row qt-qb-row--filters", where.length === 0 && "qt-qb-row--unused"), "data-clause": label, children: [
14074
+ /* @__PURE__ */ jsxs32("div", { className: "qt-qb-section-header", children: [
14075
+ /* @__PURE__ */ jsx36("span", { className: "qt-qb-kw", "data-mobile-label": label === "having" ? "Having" : "Filters", children: label }),
14022
14076
  mobile && actions
14023
14077
  ] }),
14024
14078
  where.map((term, index) => {
14025
14079
  if (hiddenSetTerms.has(index)) return null;
14026
14080
  const set = setEditors.get(index);
14027
- return /* @__PURE__ */ jsxs31("span", { className: "qt-where-term-wrap", children: [
14028
- index > 0 && hasOr && /* @__PURE__ */ jsx35("span", { className: "qt-where-and", children: "AND" }),
14029
- set ? /* @__PURE__ */ jsxs31("span", { className: cx5("qt-chip", classNames?.chip), children: [
14030
- /* @__PURE__ */ jsxs31(
14081
+ return /* @__PURE__ */ jsxs32("span", { className: "qt-where-term-wrap", children: [
14082
+ index > 0 && hasOr && /* @__PURE__ */ jsx36("span", { className: "qt-where-and", children: "AND" }),
14083
+ set ? /* @__PURE__ */ jsxs32("span", { className: cx5("qt-chip", classNames?.chip), children: [
14084
+ /* @__PURE__ */ jsxs32(
14031
14085
  "button",
14032
14086
  {
14033
14087
  type: "button",
@@ -14049,8 +14103,8 @@ function WhereRow({
14049
14103
  ]
14050
14104
  }
14051
14105
  ),
14052
- set.metadata.values.map((value) => /* @__PURE__ */ jsxs31("span", { className: "qt-set-tag", children: [
14053
- /* @__PURE__ */ jsx35(
14106
+ set.metadata.values.map((value) => /* @__PURE__ */ jsxs32("span", { className: "qt-set-tag", children: [
14107
+ /* @__PURE__ */ jsx36(
14054
14108
  PresentedFilterValue,
14055
14109
  {
14056
14110
  field: set.field.name,
@@ -14058,7 +14112,7 @@ function WhereRow({
14058
14112
  label: setFilterValueLabel(set.field, value)
14059
14113
  }
14060
14114
  ),
14061
- /* @__PURE__ */ jsx35(
14115
+ /* @__PURE__ */ jsx36(
14062
14116
  "button",
14063
14117
  {
14064
14118
  type: "button",
@@ -14078,7 +14132,7 @@ function WhereRow({
14078
14132
  }
14079
14133
  )
14080
14134
  ] }, value)),
14081
- /* @__PURE__ */ jsx35(
14135
+ /* @__PURE__ */ jsx36(
14082
14136
  "button",
14083
14137
  {
14084
14138
  type: "button",
@@ -14089,7 +14143,7 @@ function WhereRow({
14089
14143
  children: "\u2715"
14090
14144
  }
14091
14145
  )
14092
- ] }) : /* @__PURE__ */ jsx35(
14146
+ ] }) : /* @__PURE__ */ jsx36(
14093
14147
  TermChip,
14094
14148
  {
14095
14149
  api,
@@ -14110,7 +14164,7 @@ function WhereRow({
14110
14164
  )
14111
14165
  ] }, index);
14112
14166
  }),
14113
- editingSet && /* @__PURE__ */ jsx35(
14167
+ editingSet && /* @__PURE__ */ jsx36(
14114
14168
  SetFilterEditor,
14115
14169
  {
14116
14170
  api,
@@ -14174,7 +14228,7 @@ function TermChip({
14174
14228
  const group = isOrGroup(term);
14175
14229
  const predicates = predicatesOf2(term);
14176
14230
  if (mobile)
14177
- return /* @__PURE__ */ jsx35(
14231
+ return /* @__PURE__ */ jsx36(
14178
14232
  MobileFilter,
14179
14233
  {
14180
14234
  api,
@@ -14187,7 +14241,7 @@ function TermChip({
14187
14241
  onOpenChange: onEditorChange
14188
14242
  }
14189
14243
  );
14190
- const grip = /* @__PURE__ */ jsx35(
14244
+ const grip = /* @__PURE__ */ jsx36(
14191
14245
  "span",
14192
14246
  {
14193
14247
  className: "qt-chip-grip",
@@ -14200,10 +14254,10 @@ function TermChip({
14200
14254
  },
14201
14255
  onDragEnd,
14202
14256
  title: "drag to reorder, or drop onto another filter to make an OR",
14203
- children: /* @__PURE__ */ jsx35(Icon, { name: "grip" })
14257
+ children: /* @__PURE__ */ jsx36(Icon, { name: "grip" })
14204
14258
  }
14205
14259
  );
14206
- return /* @__PURE__ */ jsxs31(
14260
+ return /* @__PURE__ */ jsxs32(
14207
14261
  "span",
14208
14262
  {
14209
14263
  className: cx5(
@@ -14221,9 +14275,9 @@ function TermChip({
14221
14275
  },
14222
14276
  children: [
14223
14277
  grip,
14224
- group ? /* @__PURE__ */ jsx35("span", { className: "qt-or-group", children: predicates.map((clause, predIndex) => /* @__PURE__ */ jsxs31("span", { className: "qt-or-member", children: [
14225
- predIndex > 0 && /* @__PURE__ */ jsx35("span", { className: "qt-chip-and qt-chip-or", children: "OR" }),
14226
- /* @__PURE__ */ jsx35(
14278
+ group ? /* @__PURE__ */ jsx36("span", { className: "qt-or-group", children: predicates.map((clause, predIndex) => /* @__PURE__ */ jsxs32("span", { className: "qt-or-member", children: [
14279
+ predIndex > 0 && /* @__PURE__ */ jsx36("span", { className: "qt-chip-and qt-chip-or", children: "OR" }),
14280
+ /* @__PURE__ */ jsx36(
14227
14281
  PredicateEditor,
14228
14282
  {
14229
14283
  api,
@@ -14235,7 +14289,7 @@ function TermChip({
14235
14289
  onRemove: () => api.removePredicate(index, predIndex)
14236
14290
  }
14237
14291
  )
14238
- ] }, predIndex)) }) : /* @__PURE__ */ jsx35(
14292
+ ] }, predIndex)) }) : /* @__PURE__ */ jsx36(
14239
14293
  PredicateEditor,
14240
14294
  {
14241
14295
  api,
@@ -14262,8 +14316,8 @@ function MobileFilter({
14262
14316
  onOpenChange
14263
14317
  }) {
14264
14318
  const predicates = predicatesOf2(term);
14265
- return /* @__PURE__ */ jsxs31(Fragment23, { children: [
14266
- /* @__PURE__ */ jsx35(
14319
+ return /* @__PURE__ */ jsxs32(Fragment23, { children: [
14320
+ /* @__PURE__ */ jsx36(
14267
14321
  MobileClauseSummary,
14268
14322
  {
14269
14323
  editLabel: `Edit filter: ${whereTermAsText(term, byName)}`,
@@ -14271,24 +14325,24 @@ function MobileFilter({
14271
14325
  className: classNames?.chip,
14272
14326
  filter: true,
14273
14327
  onEdit: () => onOpenChange(true),
14274
- children: /* @__PURE__ */ jsx35("span", { children: predicates.map((clause, position) => {
14328
+ children: /* @__PURE__ */ jsx36("span", { children: predicates.map((clause, position) => {
14275
14329
  const strategy = byName.get(clause.field)?.filter?.values;
14276
14330
  const option = strategy?.source === "static" ? strategy.options.find(
14277
14331
  (choice) => typeof choice !== "string" && choice.value === clause.value
14278
14332
  ) : void 0;
14279
14333
  const label = typeof option === "object" ? option.label : clause.value === "" ? '""' : clause.value;
14280
14334
  const emptyStringCondition = clause.value === "0" && (clause.op === "length_eq" || clause.op === "length_gt");
14281
- return /* @__PURE__ */ jsxs31("span", { className: "qt-mobile-filter-summary", children: [
14282
- position > 0 && /* @__PURE__ */ jsx35("small", { children: "OR" }),
14283
- /* @__PURE__ */ jsx35("strong", { children: byName.get(clause.field)?.label ?? clause.field }),
14284
- /* @__PURE__ */ jsxs31("span", { children: [
14335
+ return /* @__PURE__ */ jsxs32("span", { className: "qt-mobile-filter-summary", children: [
14336
+ position > 0 && /* @__PURE__ */ jsx36("small", { children: "OR" }),
14337
+ /* @__PURE__ */ jsx36("strong", { children: byName.get(clause.field)?.label ?? clause.field }),
14338
+ /* @__PURE__ */ jsxs32("span", { children: [
14285
14339
  choiceLabel(
14286
14340
  clause.op,
14287
14341
  Boolean(clause.negated),
14288
14342
  clause.value
14289
14343
  ),
14290
14344
  " ",
14291
- !NULLARY_OPS2.has(clause.op) && !emptyStringCondition && /* @__PURE__ */ jsx35(
14345
+ !NULLARY_OPS2.has(clause.op) && !emptyStringCondition && /* @__PURE__ */ jsx36(
14292
14346
  PresentedFilterValue,
14293
14347
  {
14294
14348
  field: clause.field,
@@ -14301,15 +14355,15 @@ function MobileFilter({
14301
14355
  }) })
14302
14356
  }
14303
14357
  ),
14304
- open && /* @__PURE__ */ jsx35(
14358
+ open && /* @__PURE__ */ jsx36(
14305
14359
  ModalSurface,
14306
14360
  {
14307
14361
  title: predicates.length > 1 ? "Edit filter group" : `Filter by ${byName.get(predicates[0].field)?.label ?? predicates[0].field}`,
14308
14362
  onClose: () => onOpenChange(false),
14309
- children: /* @__PURE__ */ jsxs31("div", { className: "qt-overlay-body qt-filter-editor", children: [
14310
- predicates.map((clause, position) => /* @__PURE__ */ jsxs31(Fragment22, { children: [
14311
- position > 0 && /* @__PURE__ */ jsx35("p", { className: "qt-muted", children: "OR" }),
14312
- /* @__PURE__ */ jsx35(
14363
+ children: /* @__PURE__ */ jsxs32("div", { className: "qt-overlay-body qt-filter-editor", children: [
14364
+ predicates.map((clause, position) => /* @__PURE__ */ jsxs32(Fragment22, { children: [
14365
+ position > 0 && /* @__PURE__ */ jsx36("p", { className: "qt-muted", children: "OR" }),
14366
+ /* @__PURE__ */ jsx36(
14313
14367
  PredicateEditor,
14314
14368
  {
14315
14369
  api,
@@ -14326,7 +14380,7 @@ function MobileFilter({
14326
14380
  }
14327
14381
  )
14328
14382
  ] }, position)),
14329
- predicates.length > 1 && /* @__PURE__ */ jsx35(
14383
+ predicates.length > 1 && /* @__PURE__ */ jsx36(
14330
14384
  "button",
14331
14385
  {
14332
14386
  type: "button",
@@ -14340,9 +14394,9 @@ function MobileFilter({
14340
14394
  children: "Remove filter group"
14341
14395
  }
14342
14396
  ),
14343
- api.query.where.length > 1 && /* @__PURE__ */ jsxs31("label", { className: "qt-filter-combine", children: [
14397
+ api.query.where.length > 1 && /* @__PURE__ */ jsxs32("label", { className: "qt-filter-combine", children: [
14344
14398
  "Match either filter (OR)",
14345
- /* @__PURE__ */ jsxs31(
14399
+ /* @__PURE__ */ jsxs32(
14346
14400
  "select",
14347
14401
  {
14348
14402
  className: "qt-input",
@@ -14354,9 +14408,9 @@ function MobileFilter({
14354
14408
  api.mergeFilters(index, Number(event.target.value));
14355
14409
  },
14356
14410
  children: [
14357
- /* @__PURE__ */ jsx35("option", { value: "", children: "Combine with another filter\u2026" }),
14411
+ /* @__PURE__ */ jsx36("option", { value: "", children: "Combine with another filter\u2026" }),
14358
14412
  api.query.where.map(
14359
- (candidate, position) => position !== index && /* @__PURE__ */ jsx35("option", { value: position, children: whereTermAsText(candidate, byName) }, position)
14413
+ (candidate, position) => position !== index && /* @__PURE__ */ jsx36("option", { value: position, children: whereTermAsText(candidate, byName) }, position)
14360
14414
  )
14361
14415
  ]
14362
14416
  }
@@ -14409,7 +14463,7 @@ function OpPicker({
14409
14463
  ) : { op: choice.op, negated: false };
14410
14464
  return resolved.op === clause.op && Boolean(resolved.negated) === Boolean(clause.negated);
14411
14465
  };
14412
- return /* @__PURE__ */ jsx35("span", { className: "qt-op-picker", children: /* @__PURE__ */ jsx35(
14466
+ return /* @__PURE__ */ jsx36("span", { className: "qt-op-picker", children: /* @__PURE__ */ jsx36(
14413
14467
  MenuButton,
14414
14468
  {
14415
14469
  label: "Choose condition",
@@ -14419,15 +14473,15 @@ function OpPicker({
14419
14473
  disabled: disabled || visiblePairs.length === 0,
14420
14474
  "aria-label": choiceLabel(clause.op, Boolean(clause.negated), clause.value)
14421
14475
  },
14422
- trigger: /* @__PURE__ */ jsxs31(Fragment23, { children: [
14476
+ trigger: /* @__PURE__ */ jsxs32(Fragment23, { children: [
14423
14477
  choiceLabel(clause.op, Boolean(clause.negated), clause.value),
14424
- /* @__PURE__ */ jsx35(Icon, { name: "chevronDown", size: 12, className: "qt-op-caret" })
14478
+ /* @__PURE__ */ jsx36(Icon, { name: "chevronDown", size: 12, className: "qt-op-caret" })
14425
14479
  ] }),
14426
- children: /* @__PURE__ */ jsxs31(MenuGroup, { label: `Condition for ${field?.label ?? clause.field}`, columns: 2, className: "qt-op-pop", children: [
14427
- /* @__PURE__ */ jsx35("span", { className: "qt-cm-col-head", children: "keep" }),
14428
- /* @__PURE__ */ jsx35("span", { className: "qt-cm-col-head qt-cm-col-head--neg", children: "exclude" }),
14429
- visiblePairs.map((pair, i) => /* @__PURE__ */ jsxs31(Fragment22, { children: [
14430
- /* @__PURE__ */ jsx35(
14480
+ children: /* @__PURE__ */ jsxs32(MenuGroup, { label: `Condition for ${field?.label ?? clause.field}`, columns: 2, className: "qt-op-pop", children: [
14481
+ /* @__PURE__ */ jsx36("span", { className: "qt-cm-col-head", children: "keep" }),
14482
+ /* @__PURE__ */ jsx36("span", { className: "qt-cm-col-head qt-cm-col-head--neg", children: "exclude" }),
14483
+ visiblePairs.map((pair, i) => /* @__PURE__ */ jsxs32(Fragment22, { children: [
14484
+ /* @__PURE__ */ jsx36(
14431
14485
  MenuItem,
14432
14486
  {
14433
14487
  className: cx5("qt-op-cell", isActive(pair.keep) && "qt-op-cell--on"),
@@ -14437,7 +14491,7 @@ function OpPicker({
14437
14491
  children: choiceLabel(pair.keep.op, pair.keep.negated, clause.value)
14438
14492
  }
14439
14493
  ),
14440
- /* @__PURE__ */ jsx35(
14494
+ /* @__PURE__ */ jsx36(
14441
14495
  MenuItem,
14442
14496
  {
14443
14497
  className: cx5("qt-op-cell", "qt-op-cell--neg", isActive(pair.exclude) && "qt-op-cell--on"),
@@ -14475,7 +14529,7 @@ function PredicateEditor({
14475
14529
  choice.negated ? negateClause2(next, field ? opsForField3(field) : void 0) : next
14476
14530
  );
14477
14531
  }
14478
- const conditionControl = /* @__PURE__ */ jsx35(
14532
+ const conditionControl = /* @__PURE__ */ jsx36(
14479
14533
  OpPicker,
14480
14534
  {
14481
14535
  field,
@@ -14485,7 +14539,7 @@ function PredicateEditor({
14485
14539
  onPick: pickOp
14486
14540
  }
14487
14541
  );
14488
- const valueControl = needsValue ? /* @__PURE__ */ jsx35(
14542
+ const valueControl = needsValue ? /* @__PURE__ */ jsx36(
14489
14543
  ValueInput,
14490
14544
  {
14491
14545
  api,
@@ -14498,7 +14552,7 @@ function PredicateEditor({
14498
14552
  onChange: (value) => onChange({ ...clause, value })
14499
14553
  }
14500
14554
  ) : null;
14501
- const removeControl = /* @__PURE__ */ jsx35(
14555
+ const removeControl = /* @__PURE__ */ jsx36(
14502
14556
  "button",
14503
14557
  {
14504
14558
  type: "button",
@@ -14506,13 +14560,13 @@ function PredicateEditor({
14506
14560
  onClick: onRemove,
14507
14561
  disabled,
14508
14562
  "aria-label": `Remove ${field?.label ?? clause.field} filter`,
14509
- children: mobile ? "Remove filter" : /* @__PURE__ */ jsx35(Icon, { name: "close" })
14563
+ children: mobile ? "Remove filter" : /* @__PURE__ */ jsx36(Icon, { name: "close" })
14510
14564
  }
14511
14565
  );
14512
14566
  if (mobile)
14513
- return /* @__PURE__ */ jsxs31("div", { className: "qt-mobile-predicate qt-mobile-form", children: [
14514
- showField && /* @__PURE__ */ jsx35("strong", { className: "qt-mobile-form-field--wide", children: field?.label ?? clause.field }),
14515
- /* @__PURE__ */ jsxs31(
14567
+ return /* @__PURE__ */ jsxs32("div", { className: "qt-mobile-predicate qt-mobile-form", children: [
14568
+ showField && /* @__PURE__ */ jsx36("strong", { className: "qt-mobile-form-field--wide", children: field?.label ?? clause.field }),
14569
+ /* @__PURE__ */ jsxs32(
14516
14570
  "label",
14517
14571
  {
14518
14572
  className: cx5(
@@ -14520,19 +14574,19 @@ function PredicateEditor({
14520
14574
  !needsValue && "qt-mobile-form-field--wide"
14521
14575
  ),
14522
14576
  children: [
14523
- /* @__PURE__ */ jsx35("span", { children: "Condition" }),
14577
+ /* @__PURE__ */ jsx36("span", { children: "Condition" }),
14524
14578
  conditionControl
14525
14579
  ]
14526
14580
  }
14527
14581
  ),
14528
- valueControl && /* @__PURE__ */ jsxs31("label", { className: "qt-mobile-form-field", children: [
14529
- /* @__PURE__ */ jsx35("span", { children: "Value" }),
14582
+ valueControl && /* @__PURE__ */ jsxs32("label", { className: "qt-mobile-form-field", children: [
14583
+ /* @__PURE__ */ jsx36("span", { children: "Value" }),
14530
14584
  valueControl
14531
14585
  ] }),
14532
14586
  removeControl
14533
14587
  ] });
14534
- return /* @__PURE__ */ jsxs31("span", { className: "qt-pred", children: [
14535
- /* @__PURE__ */ jsx35("span", { className: "qt-chip-field", children: field?.label ?? clause.field }),
14588
+ return /* @__PURE__ */ jsxs32("span", { className: "qt-pred", children: [
14589
+ /* @__PURE__ */ jsx36("span", { className: "qt-chip-field", children: field?.label ?? clause.field }),
14536
14590
  conditionControl,
14537
14591
  valueControl,
14538
14592
  removeControl
@@ -14552,7 +14606,7 @@ function ValueInput({
14552
14606
  const strategy = field ? filterValuesFor(field) : { source: "freeform" };
14553
14607
  if (!forceFreeform && strategy.source === "static") {
14554
14608
  if (presentation.render || presentation.label || strategy.options.some((o) => typeof o !== "string")) {
14555
- return /* @__PURE__ */ jsx35(
14609
+ return /* @__PURE__ */ jsx36(
14556
14610
  PresentedValueInput,
14557
14611
  {
14558
14612
  field: field?.name ?? "",
@@ -14562,7 +14616,7 @@ function ValueInput({
14562
14616
  }
14563
14617
  );
14564
14618
  }
14565
- return /* @__PURE__ */ jsxs31(
14619
+ return /* @__PURE__ */ jsxs32(
14566
14620
  "select",
14567
14621
  {
14568
14622
  className: cx5("qt-chip-val", classNames?.select),
@@ -14570,10 +14624,10 @@ function ValueInput({
14570
14624
  value,
14571
14625
  onChange: (e) => onChange(e.target.value),
14572
14626
  children: [
14573
- /* @__PURE__ */ jsx35("option", { value: "", children: "\u2014" }),
14627
+ /* @__PURE__ */ jsx36("option", { value: "", children: "\u2014" }),
14574
14628
  strategy.options.map((o) => {
14575
14629
  const option = typeof o === "string" ? { value: o, label: o } : o;
14576
- return /* @__PURE__ */ jsx35("option", { value: option.value, children: option.label }, option.value);
14630
+ return /* @__PURE__ */ jsx36("option", { value: option.value, children: option.label }, option.value);
14577
14631
  })
14578
14632
  ]
14579
14633
  }
@@ -14586,7 +14640,7 @@ function ValueInput({
14586
14640
  5,
14587
14641
  4
14588
14642
  );
14589
- return /* @__PURE__ */ jsx35(
14643
+ return /* @__PURE__ */ jsx36(
14590
14644
  "input",
14591
14645
  {
14592
14646
  className: cx5("qt-chip-val", classNames?.input),
@@ -14601,7 +14655,7 @@ function ValueInput({
14601
14655
  }
14602
14656
  );
14603
14657
  }
14604
- return /* @__PURE__ */ jsx35(
14658
+ return /* @__PURE__ */ jsx36(
14605
14659
  AutocompleteInput,
14606
14660
  {
14607
14661
  api,
@@ -14619,7 +14673,7 @@ function AutocompleteInput({
14619
14673
  classNames,
14620
14674
  onChange
14621
14675
  }) {
14622
- const [result, setResult] = useState29({
14676
+ const [result, setResult] = useState30({
14623
14677
  values: [],
14624
14678
  hasMore: false
14625
14679
  });
@@ -14638,8 +14692,8 @@ function AutocompleteInput({
14638
14692
  clearTimeout(t);
14639
14693
  };
14640
14694
  }, [api, field.name, value]);
14641
- return /* @__PURE__ */ jsxs31("span", { className: "qt-autocomplete", children: [
14642
- /* @__PURE__ */ jsx35(
14695
+ return /* @__PURE__ */ jsxs32("span", { className: "qt-autocomplete", children: [
14696
+ /* @__PURE__ */ jsx36(
14643
14697
  "input",
14644
14698
  {
14645
14699
  className: cx5("qt-chip-val", classNames?.input),
@@ -14654,8 +14708,8 @@ function AutocompleteInput({
14654
14708
  onChange: (e) => onChange(e.target.value)
14655
14709
  }
14656
14710
  ),
14657
- /* @__PURE__ */ jsx35("datalist", { id: listId, children: result.values.map((v) => /* @__PURE__ */ jsx35("option", { value: v }, v)) }),
14658
- result.hasMore && /* @__PURE__ */ jsx35("span", { className: "qt-autocomplete-hint", children: "keep typing to refine\u2026" })
14711
+ /* @__PURE__ */ jsx36("datalist", { id: listId, children: result.values.map((v) => /* @__PURE__ */ jsx36("option", { value: v }, v)) }),
14712
+ result.hasMore && /* @__PURE__ */ jsx36("span", { className: "qt-autocomplete-hint", children: "keep typing to refine\u2026" })
14659
14713
  ] });
14660
14714
  }
14661
14715
  function MobileClauseSummary({
@@ -14666,7 +14720,7 @@ function MobileClauseSummary({
14666
14720
  onEdit,
14667
14721
  children
14668
14722
  }) {
14669
- return /* @__PURE__ */ jsx35("div", { className: cx5("qt-mobile-clause", className), children: /* @__PURE__ */ jsxs31(
14723
+ return /* @__PURE__ */ jsx36("div", { className: cx5("qt-mobile-clause", className), children: /* @__PURE__ */ jsxs32(
14670
14724
  "button",
14671
14725
  {
14672
14726
  type: "button",
@@ -14679,7 +14733,7 @@ function MobileClauseSummary({
14679
14733
  onClick: onEdit,
14680
14734
  children: [
14681
14735
  children,
14682
- /* @__PURE__ */ jsx35("span", { className: "qt-mobile-filter-edit", children: /* @__PURE__ */ jsx35(Icon, { name: "pencil" }) })
14736
+ /* @__PURE__ */ jsx36("span", { className: "qt-mobile-filter-edit", children: /* @__PURE__ */ jsx36(Icon, { name: "pencil" }) })
14683
14737
  ]
14684
14738
  }
14685
14739
  ) });
@@ -14695,20 +14749,20 @@ function MobileChipEditor({
14695
14749
  }) {
14696
14750
  const mobile = useMobileLayout();
14697
14751
  if (!mobile) return children;
14698
- return /* @__PURE__ */ jsxs31(Fragment23, { children: [
14699
- /* @__PURE__ */ jsx35(
14752
+ return /* @__PURE__ */ jsxs32(Fragment23, { children: [
14753
+ /* @__PURE__ */ jsx36(
14700
14754
  MobileClauseSummary,
14701
14755
  {
14702
14756
  editLabel: `Edit ${title}: ${summary}`,
14703
14757
  disabled,
14704
14758
  onEdit: () => onOpenChange(true),
14705
- children: /* @__PURE__ */ jsxs31("span", { className: "qt-mobile-filter-summary", children: [
14706
- /* @__PURE__ */ jsx35("strong", { children: summaryTitle }),
14707
- /* @__PURE__ */ jsx35("span", { children: summary })
14759
+ children: /* @__PURE__ */ jsxs32("span", { className: "qt-mobile-filter-summary", children: [
14760
+ /* @__PURE__ */ jsx36("strong", { children: summaryTitle }),
14761
+ /* @__PURE__ */ jsx36("span", { children: summary })
14708
14762
  ] })
14709
14763
  }
14710
14764
  ),
14711
- open && /* @__PURE__ */ jsx35(ModalSurface, { title, onClose: () => onOpenChange(false), children: /* @__PURE__ */ jsx35("div", { className: "qt-overlay-body qt-mobile-chip-editor", children }) })
14765
+ open && /* @__PURE__ */ jsx36(ModalSurface, { title, onClose: () => onOpenChange(false), children: /* @__PURE__ */ jsx36("div", { className: "qt-overlay-body qt-mobile-chip-editor", children }) })
14712
14766
  ] });
14713
14767
  }
14714
14768
  function OrderTermChip({
@@ -14734,10 +14788,10 @@ function OrderTermChip({
14734
14788
  }) {
14735
14789
  const fieldHasNull = useFieldHasNull(api, field?.name);
14736
14790
  const mobile = useMobileLayout();
14737
- const [extractOpen, setExtractOpen] = useState29(false);
14791
+ const [extractOpen, setExtractOpen] = useState30(false);
14738
14792
  const title = `Sort by ${label}`;
14739
14793
  const summary = `${term.dir === "asc" ? "Ascending" : "Descending"}${showPriority ? ` \xB7 Priority ${priority}` : ""}${term.extract ? " \xB7 Regex extraction" : ""}`;
14740
- const extractionEditor = extractOpen && /* @__PURE__ */ jsx35(
14794
+ const extractionEditor = extractOpen && /* @__PURE__ */ jsx36(
14741
14795
  SortExtractionEditor,
14742
14796
  {
14743
14797
  api,
@@ -14757,8 +14811,8 @@ function OrderTermChip({
14757
14811
  }
14758
14812
  );
14759
14813
  if (mobile)
14760
- return /* @__PURE__ */ jsxs31(Fragment23, { children: [
14761
- /* @__PURE__ */ jsx35(
14814
+ return /* @__PURE__ */ jsxs32(Fragment23, { children: [
14815
+ /* @__PURE__ */ jsx36(
14762
14816
  MobileChipEditor,
14763
14817
  {
14764
14818
  title,
@@ -14767,10 +14821,10 @@ function OrderTermChip({
14767
14821
  disabled,
14768
14822
  open: editorOpen,
14769
14823
  onOpenChange: onEditorChange,
14770
- children: /* @__PURE__ */ jsxs31("div", { className: "qt-mobile-form", children: [
14771
- /* @__PURE__ */ jsxs31("label", { className: "qt-mobile-form-field", children: [
14772
- /* @__PURE__ */ jsx35("span", { children: "Direction" }),
14773
- /* @__PURE__ */ jsxs31(
14824
+ children: /* @__PURE__ */ jsxs32("div", { className: "qt-mobile-form", children: [
14825
+ /* @__PURE__ */ jsxs32("label", { className: "qt-mobile-form-field", children: [
14826
+ /* @__PURE__ */ jsx36("span", { children: "Direction" }),
14827
+ /* @__PURE__ */ jsxs32(
14774
14828
  "select",
14775
14829
  {
14776
14830
  className: cx5("qt-input", classNames?.select),
@@ -14780,15 +14834,15 @@ function OrderTermChip({
14780
14834
  dir: event.target.value
14781
14835
  }),
14782
14836
  children: [
14783
- /* @__PURE__ */ jsx35("option", { value: "asc", children: "Ascending" }),
14784
- /* @__PURE__ */ jsx35("option", { value: "desc", children: "Descending" })
14837
+ /* @__PURE__ */ jsx36("option", { value: "asc", children: "Ascending" }),
14838
+ /* @__PURE__ */ jsx36("option", { value: "desc", children: "Descending" })
14785
14839
  ]
14786
14840
  }
14787
14841
  )
14788
14842
  ] }),
14789
- (term.extract != null || fieldHasNull !== false) && /* @__PURE__ */ jsxs31("label", { className: "qt-mobile-form-field", children: [
14790
- /* @__PURE__ */ jsx35("span", { children: "Null values" }),
14791
- /* @__PURE__ */ jsxs31(
14843
+ (term.extract != null || fieldHasNull !== false) && /* @__PURE__ */ jsxs32("label", { className: "qt-mobile-form-field", children: [
14844
+ /* @__PURE__ */ jsx36("span", { children: "Null values" }),
14845
+ /* @__PURE__ */ jsxs32(
14792
14846
  "select",
14793
14847
  {
14794
14848
  className: cx5("qt-input", classNames?.select),
@@ -14798,15 +14852,15 @@ function OrderTermChip({
14798
14852
  nulls: event.target.value
14799
14853
  }),
14800
14854
  children: [
14801
- /* @__PURE__ */ jsx35("option", { value: "last", children: "Last" }),
14802
- /* @__PURE__ */ jsx35("option", { value: "first", children: "First" })
14855
+ /* @__PURE__ */ jsx36("option", { value: "last", children: "Last" }),
14856
+ /* @__PURE__ */ jsx36("option", { value: "first", children: "First" })
14803
14857
  ]
14804
14858
  }
14805
14859
  )
14806
14860
  ] }),
14807
- /* @__PURE__ */ jsxs31("div", { className: "qt-mobile-form-field qt-mobile-form-field--wide", children: [
14808
- /* @__PURE__ */ jsx35("span", { children: "Extraction" }),
14809
- /* @__PURE__ */ jsxs31(
14861
+ /* @__PURE__ */ jsxs32("div", { className: "qt-mobile-form-field qt-mobile-form-field--wide", children: [
14862
+ /* @__PURE__ */ jsx36("span", { children: "Extraction" }),
14863
+ /* @__PURE__ */ jsxs32(
14810
14864
  "button",
14811
14865
  {
14812
14866
  type: "button",
@@ -14815,13 +14869,13 @@ function OrderTermChip({
14815
14869
  onClick: () => setExtractOpen(true),
14816
14870
  "aria-label": `Configure regex extract for ${label}`,
14817
14871
  children: [
14818
- /* @__PURE__ */ jsx35(Icon, { name: term.extract ? "pencil" : "add" }),
14872
+ /* @__PURE__ */ jsx36(Icon, { name: term.extract ? "pencil" : "add" }),
14819
14873
  term.extract ? "Edit regex extraction" : "regex extract"
14820
14874
  ]
14821
14875
  }
14822
14876
  )
14823
14877
  ] }),
14824
- /* @__PURE__ */ jsx35("div", { className: "qt-mobile-form-actions", children: /* @__PURE__ */ jsx35(
14878
+ /* @__PURE__ */ jsx36("div", { className: "qt-mobile-form-actions", children: /* @__PURE__ */ jsx36(
14825
14879
  "button",
14826
14880
  {
14827
14881
  type: "button",
@@ -14837,8 +14891,8 @@ function OrderTermChip({
14837
14891
  ),
14838
14892
  extractionEditor
14839
14893
  ] });
14840
- return /* @__PURE__ */ jsxs31(Fragment23, { children: [
14841
- /* @__PURE__ */ jsxs31(
14894
+ return /* @__PURE__ */ jsxs32(Fragment23, { children: [
14895
+ /* @__PURE__ */ jsxs32(
14842
14896
  "span",
14843
14897
  {
14844
14898
  className: cx5(
@@ -14862,10 +14916,10 @@ function OrderTermChip({
14862
14916
  onDragEnd,
14863
14917
  title: "drag to reorder sort priority",
14864
14918
  children: [
14865
- /* @__PURE__ */ jsx35("span", { "aria-hidden": true, className: "qt-chip-grip", children: /* @__PURE__ */ jsx35(Icon, { name: "grip" }) }),
14866
- showPriority && /* @__PURE__ */ jsx35("span", { className: "qt-chip-priority", children: priority }),
14867
- /* @__PURE__ */ jsx35("span", { className: "qt-chip-field", children: label }),
14868
- /* @__PURE__ */ jsxs31(
14919
+ /* @__PURE__ */ jsx36("span", { "aria-hidden": true, className: "qt-chip-grip", children: /* @__PURE__ */ jsx36(Icon, { name: "grip" }) }),
14920
+ showPriority && /* @__PURE__ */ jsx36("span", { className: "qt-chip-priority", children: priority }),
14921
+ /* @__PURE__ */ jsx36("span", { className: "qt-chip-field", children: label }),
14922
+ /* @__PURE__ */ jsxs32(
14869
14923
  "button",
14870
14924
  {
14871
14925
  type: "button",
@@ -14873,12 +14927,12 @@ function OrderTermChip({
14873
14927
  disabled,
14874
14928
  onClick: () => updateTerm(dataIndex, { dir: term.dir === "asc" ? "desc" : "asc" }),
14875
14929
  children: [
14876
- /* @__PURE__ */ jsx35(Icon, { name: term.dir === "asc" ? "arrowUp" : "arrowDown" }),
14930
+ /* @__PURE__ */ jsx36(Icon, { name: term.dir === "asc" ? "arrowUp" : "arrowDown" }),
14877
14931
  term.dir === "asc" ? "asc" : "desc"
14878
14932
  ]
14879
14933
  }
14880
14934
  ),
14881
- term.extract && /* @__PURE__ */ jsxs31(
14935
+ term.extract && /* @__PURE__ */ jsxs32(
14882
14936
  "button",
14883
14937
  {
14884
14938
  type: "button",
@@ -14888,12 +14942,12 @@ function OrderTermChip({
14888
14942
  disabled,
14889
14943
  onClick: () => setExtractOpen(true),
14890
14944
  children: [
14891
- /* @__PURE__ */ jsx35(Icon, { name: "pencil" }),
14945
+ /* @__PURE__ */ jsx36(Icon, { name: "pencil" }),
14892
14946
  "regex extraction"
14893
14947
  ]
14894
14948
  }
14895
14949
  ),
14896
- (term.extract != null || fieldHasNull !== false) && /* @__PURE__ */ jsxs31(
14950
+ (term.extract != null || fieldHasNull !== false) && /* @__PURE__ */ jsxs32(
14897
14951
  "button",
14898
14952
  {
14899
14953
  type: "button",
@@ -14909,7 +14963,7 @@ function OrderTermChip({
14909
14963
  ]
14910
14964
  }
14911
14965
  ),
14912
- /* @__PURE__ */ jsx35(
14966
+ /* @__PURE__ */ jsx36(
14913
14967
  "button",
14914
14968
  {
14915
14969
  type: "button",
@@ -14917,7 +14971,7 @@ function OrderTermChip({
14917
14971
  onClick: () => removeTerm(dataIndex),
14918
14972
  disabled,
14919
14973
  "aria-label": `Remove ${label} sort`,
14920
- children: /* @__PURE__ */ jsx35(Icon, { name: "close" })
14974
+ children: /* @__PURE__ */ jsx36(Icon, { name: "close" })
14921
14975
  }
14922
14976
  )
14923
14977
  ]
@@ -14938,11 +14992,11 @@ function OrderRow({
14938
14992
  () => new Map(fields.map((f) => [f.name, f])),
14939
14993
  [fields]
14940
14994
  );
14941
- const [drag, setDrag] = useState29(null);
14942
- const [adding, setAdding] = useState29(false);
14943
- const [regexField, setRegexField] = useState29(null);
14944
- const [regexDirection, setRegexDirection] = useState29("desc");
14945
- const [editingSort, setEditingSort] = useState29(null);
14995
+ const [drag, setDrag] = useState30(null);
14996
+ const [adding, setAdding] = useState30(false);
14997
+ const [regexField, setRegexField] = useState30(null);
14998
+ const [regexDirection, setRegexDirection] = useState30("desc");
14999
+ const [editingSort, setEditingSort] = useState30(null);
14946
15000
  function setOrderBy(next) {
14947
15001
  api.setSort(next);
14948
15002
  }
@@ -15035,7 +15089,7 @@ function OrderRow({
15035
15089
  }
15036
15090
  const renderTerm = (name, position) => {
15037
15091
  const term = termByField.get(name);
15038
- return /* @__PURE__ */ jsx35(
15092
+ return /* @__PURE__ */ jsx36(
15039
15093
  OrderTermChip,
15040
15094
  {
15041
15095
  api,
@@ -15065,10 +15119,10 @@ function OrderRow({
15065
15119
  const next = api.defaults.orderBy[i];
15066
15120
  return term.field === next?.field && term.dir === next?.dir && (term.nulls ?? "last") === (next?.nulls ?? "last") && (term.extract?.regex ?? null) === (next?.extract?.regex ?? null);
15067
15121
  });
15068
- const actions = /* @__PURE__ */ jsxs31(Fragment23, { children: [
15069
- /* @__PURE__ */ jsxs31(PickerAnchor, { children: [
15070
- /* @__PURE__ */ jsxs31("span", { className: "qt-split-btn", role: "group", "aria-label": "Sort actions", children: [
15071
- /* @__PURE__ */ jsxs31(
15122
+ const actions = /* @__PURE__ */ jsxs32(Fragment23, { children: [
15123
+ /* @__PURE__ */ jsxs32(PickerAnchor, { children: [
15124
+ /* @__PURE__ */ jsxs32("span", { className: "qt-split-btn", role: "group", "aria-label": "Sort actions", children: [
15125
+ /* @__PURE__ */ jsxs32(
15072
15126
  "button",
15073
15127
  {
15074
15128
  type: "button",
@@ -15079,12 +15133,12 @@ function OrderRow({
15079
15133
  onClick: () => setAdding((previous) => !previous),
15080
15134
  disabled: disabled || sortable.length === 0,
15081
15135
  children: [
15082
- /* @__PURE__ */ jsx35(Icon, { name: "add" }),
15136
+ /* @__PURE__ */ jsx36(Icon, { name: "add" }),
15083
15137
  mobile ? "Add" : "add sort"
15084
15138
  ]
15085
15139
  }
15086
15140
  ),
15087
- /* @__PURE__ */ jsx35(
15141
+ /* @__PURE__ */ jsx36(
15088
15142
  "button",
15089
15143
  {
15090
15144
  type: "button",
@@ -15095,11 +15149,11 @@ function OrderRow({
15095
15149
  "aria-expanded": regexField != null,
15096
15150
  disabled: disabled || sortable.length === 0,
15097
15151
  onClick: () => openRegexConfigurator(),
15098
- children: /* @__PURE__ */ jsx35(Icon, { name: "chevronRight", size: 18 })
15152
+ children: /* @__PURE__ */ jsx36(Icon, { name: "chevronRight", size: 18 })
15099
15153
  }
15100
15154
  )
15101
15155
  ] }),
15102
- adding && /* @__PURE__ */ jsx35(
15156
+ adding && /* @__PURE__ */ jsx36(
15103
15157
  SortPicker,
15104
15158
  {
15105
15159
  fields: sortable,
@@ -15109,7 +15163,7 @@ function OrderRow({
15109
15163
  }
15110
15164
  )
15111
15165
  ] }),
15112
- !isDefaultOrderBy && /* @__PURE__ */ jsx35(
15166
+ !isDefaultOrderBy && /* @__PURE__ */ jsx36(
15113
15167
  "button",
15114
15168
  {
15115
15169
  type: "button",
@@ -15120,13 +15174,13 @@ function OrderRow({
15120
15174
  }
15121
15175
  )
15122
15176
  ] });
15123
- return /* @__PURE__ */ jsxs31("div", { className: cx5("qt-qb-row qt-qb-row--sort", orderBy.length === 0 && "qt-qb-row--unused"), children: [
15124
- /* @__PURE__ */ jsxs31("div", { className: "qt-qb-section-header", children: [
15125
- /* @__PURE__ */ jsx35("span", { className: "qt-qb-kw", "data-mobile-label": "Sort", children: "order by" }),
15177
+ return /* @__PURE__ */ jsxs32("div", { className: cx5("qt-qb-row qt-qb-row--sort", orderBy.length === 0 && "qt-qb-row--unused"), children: [
15178
+ /* @__PURE__ */ jsxs32("div", { className: "qt-qb-section-header", children: [
15179
+ /* @__PURE__ */ jsx36("span", { className: "qt-qb-kw", "data-mobile-label": "Sort", children: "order by" }),
15126
15180
  mobile && actions
15127
15181
  ] }),
15128
- orderBy.length === 0 && !adding && /* @__PURE__ */ jsx35("span", { className: "qt-qb-hint", children: "(default)" }),
15129
- mobile && orderBy.length > 0 ? /* @__PURE__ */ jsx35(
15182
+ orderBy.length === 0 && !adding && /* @__PURE__ */ jsx36("span", { className: "qt-qb-hint", children: "(default)" }),
15183
+ mobile && orderBy.length > 0 ? /* @__PURE__ */ jsx36(
15130
15184
  ReorderList,
15131
15185
  {
15132
15186
  className: "qt-query-reorder-list",
@@ -15148,7 +15202,7 @@ function OrderRow({
15148
15202
  }
15149
15203
  ) : rendered.map(renderTerm),
15150
15204
  !mobile && actions,
15151
- regexField && /* @__PURE__ */ jsx35(
15205
+ regexField && /* @__PURE__ */ jsx36(
15152
15206
  SortExtractionEditor,
15153
15207
  {
15154
15208
  api,
@@ -15190,10 +15244,10 @@ function WindowRow({
15190
15244
  }) {
15191
15245
  const { query } = api;
15192
15246
  const offsetId = useId10();
15193
- const [addingOffset, setAddingOffset] = useState29(false);
15247
+ const [addingOffset, setAddingOffset] = useState30(false);
15194
15248
  const offsetInput = useRef22(null);
15195
- const [limitDraft, setLimitDraft] = useState29(String(query.limit));
15196
- const [offsetDraft, setOffsetDraft] = useState29(String(query.offset));
15249
+ const [limitDraft, setLimitDraft] = useState30(String(query.limit));
15250
+ const [offsetDraft, setOffsetDraft] = useState30(String(query.offset));
15197
15251
  useEffect21(() => setLimitDraft(String(query.limit)), [query.limit]);
15198
15252
  useEffect21(() => setOffsetDraft(String(query.offset)), [query.offset]);
15199
15253
  useEffect21(() => {
@@ -15211,10 +15265,10 @@ function WindowRow({
15211
15265
  function commitOffset() {
15212
15266
  api.setOffset(Math.max(0, Number(offsetDraft) || 0));
15213
15267
  }
15214
- return /* @__PURE__ */ jsxs31("div", { className: "qt-qb-row qt-qb-pagination", children: [
15215
- /* @__PURE__ */ jsxs31("label", { className: "qt-qb-window-field", children: [
15216
- /* @__PURE__ */ jsx35("span", { className: "qt-qb-kw", "data-mobile-label": "Limit", children: "limit" }),
15217
- /* @__PURE__ */ jsx35(
15268
+ return /* @__PURE__ */ jsxs32("div", { className: "qt-qb-row qt-qb-pagination", children: [
15269
+ /* @__PURE__ */ jsxs32("label", { className: "qt-qb-window-field", children: [
15270
+ /* @__PURE__ */ jsx36("span", { className: "qt-qb-kw", "data-mobile-label": "Limit", children: "limit" }),
15271
+ /* @__PURE__ */ jsx36(
15218
15272
  "input",
15219
15273
  {
15220
15274
  className: cx5("qt-qb-num", classNames?.input),
@@ -15228,8 +15282,8 @@ function WindowRow({
15228
15282
  }
15229
15283
  )
15230
15284
  ] }),
15231
- !compact || query.offset > 0 || addingOffset ? /* @__PURE__ */ jsxs31("div", { className: "qt-qb-window-field", children: [
15232
- /* @__PURE__ */ jsx35(
15285
+ !compact || query.offset > 0 || addingOffset ? /* @__PURE__ */ jsxs32("div", { className: "qt-qb-window-field", children: [
15286
+ /* @__PURE__ */ jsx36(
15233
15287
  "label",
15234
15288
  {
15235
15289
  className: "qt-qb-kw",
@@ -15238,8 +15292,8 @@ function WindowRow({
15238
15292
  children: "offset"
15239
15293
  }
15240
15294
  ),
15241
- /* @__PURE__ */ jsxs31("span", { className: "qt-qb-num-combo", children: [
15242
- /* @__PURE__ */ jsx35(
15295
+ /* @__PURE__ */ jsxs32("span", { className: "qt-qb-num-combo", children: [
15296
+ /* @__PURE__ */ jsx36(
15243
15297
  "input",
15244
15298
  {
15245
15299
  ref: offsetInput,
@@ -15254,7 +15308,7 @@ function WindowRow({
15254
15308
  onKeyDown: (e) => e.key === "Enter" && commitOffset()
15255
15309
  }
15256
15310
  ),
15257
- query.offset >= query.limit && /* @__PURE__ */ jsxs31(
15311
+ query.offset >= query.limit && /* @__PURE__ */ jsxs32(
15258
15312
  "button",
15259
15313
  {
15260
15314
  type: "button",
@@ -15269,7 +15323,7 @@ function WindowRow({
15269
15323
  ]
15270
15324
  }
15271
15325
  ),
15272
- /* @__PURE__ */ jsxs31(
15326
+ /* @__PURE__ */ jsxs32(
15273
15327
  "button",
15274
15328
  {
15275
15329
  type: "button",
@@ -15285,12 +15339,12 @@ function WindowRow({
15285
15339
  }
15286
15340
  )
15287
15341
  ] }),
15288
- compact && /* @__PURE__ */ jsx35("button", { type: "button", className: "qt-chip-x", "aria-label": "Clear offset", disabled, onClick: () => {
15342
+ compact && /* @__PURE__ */ jsx36("button", { type: "button", className: "qt-chip-x", "aria-label": "Clear offset", disabled, onClick: () => {
15289
15343
  setAddingOffset(false);
15290
15344
  api.setOffset(0);
15291
- }, children: /* @__PURE__ */ jsx35(Icon, { name: "close" }) })
15292
- ] }) : /* @__PURE__ */ jsxs31("button", { type: "button", className: "qt-add", "aria-label": "Add offset", disabled, onClick: () => setAddingOffset(true), children: [
15293
- /* @__PURE__ */ jsx35(Icon, { name: "add" }),
15345
+ }, children: /* @__PURE__ */ jsx36(Icon, { name: "close" }) })
15346
+ ] }) : /* @__PURE__ */ jsxs32("button", { type: "button", className: "qt-add", "aria-label": "Add offset", disabled, onClick: () => setAddingOffset(true), children: [
15347
+ /* @__PURE__ */ jsx36(Icon, { name: "add" }),
15294
15348
  "add offset"
15295
15349
  ] })
15296
15350
  ] });
@@ -15301,7 +15355,7 @@ function MetricsRow({
15301
15355
  theme,
15302
15356
  locale
15303
15357
  }) {
15304
- const [editing, setEditing] = useState29(false);
15358
+ const [editing, setEditing] = useState30(false);
15305
15359
  const allFields = useMemo11(
15306
15360
  () => [
15307
15361
  ...fields,
@@ -15311,10 +15365,10 @@ function MetricsRow({
15311
15365
  ],
15312
15366
  [fields, api.computed.catalogue]
15313
15367
  );
15314
- return /* @__PURE__ */ jsxs31(Fragment23, { children: [
15315
- api.aggregations.clauses.length === 0 && /* @__PURE__ */ jsx35("div", { className: "qt-qb-row qt-qb-row--metrics qt-qb-row--unused", children: /* @__PURE__ */ jsxs31("div", { className: "qt-qb-section-header", children: [
15316
- /* @__PURE__ */ jsx35("span", { className: "qt-qb-kw", "data-mobile-label": "Metrics", children: "metrics" }),
15317
- /* @__PURE__ */ jsxs31(
15368
+ return /* @__PURE__ */ jsxs32(Fragment23, { children: [
15369
+ api.aggregations.clauses.length === 0 && /* @__PURE__ */ jsx36("div", { className: "qt-qb-row qt-qb-row--metrics qt-qb-row--unused", children: /* @__PURE__ */ jsxs32("div", { className: "qt-qb-section-header", children: [
15370
+ /* @__PURE__ */ jsx36("span", { className: "qt-qb-kw", "data-mobile-label": "Metrics", children: "metrics" }),
15371
+ /* @__PURE__ */ jsxs32(
15318
15372
  "button",
15319
15373
  {
15320
15374
  type: "button",
@@ -15323,14 +15377,14 @@ function MetricsRow({
15323
15377
  "aria-haspopup": "dialog",
15324
15378
  onClick: () => setEditing(true),
15325
15379
  children: [
15326
- /* @__PURE__ */ jsx35(Icon, { name: "add" }),
15380
+ /* @__PURE__ */ jsx36(Icon, { name: "add" }),
15327
15381
  "add metric",
15328
- /* @__PURE__ */ jsx35(Icon, { name: "arrowRight", size: 14 })
15382
+ /* @__PURE__ */ jsx36(Icon, { name: "arrowRight", size: 14 })
15329
15383
  ]
15330
15384
  }
15331
15385
  )
15332
15386
  ] }) }),
15333
- editing && /* @__PURE__ */ jsx35(
15387
+ editing && /* @__PURE__ */ jsx36(
15334
15388
  MetricsEditor,
15335
15389
  {
15336
15390
  api,
@@ -15344,17 +15398,17 @@ function MetricsRow({
15344
15398
  }
15345
15399
 
15346
15400
  // src/SelectionToolbar.tsx
15347
- import { jsx as jsx36, jsxs as jsxs32 } from "react/jsx-runtime";
15401
+ import { jsx as jsx37, jsxs as jsxs33 } from "react/jsx-runtime";
15348
15402
  var cx6 = (...parts) => parts.filter(Boolean).join(" ");
15349
15403
  function SelectionToolbar({ selection, actions, alwaysShow, className }) {
15350
15404
  if (selection.count === 0 && !alwaysShow) return null;
15351
15405
  const selectedIds = [...selection.selected];
15352
- return /* @__PURE__ */ jsxs32("div", { className: cx6("qt-selection-toolbar", className), role: "toolbar", children: [
15353
- /* @__PURE__ */ jsxs32("span", { className: "qt-selection-count", children: [
15406
+ return /* @__PURE__ */ jsxs33("div", { className: cx6("qt-selection-toolbar", className), role: "toolbar", children: [
15407
+ /* @__PURE__ */ jsxs33("span", { className: "qt-selection-count", children: [
15354
15408
  selection.count,
15355
15409
  " selected"
15356
15410
  ] }),
15357
- /* @__PURE__ */ jsx36(
15411
+ /* @__PURE__ */ jsx37(
15358
15412
  "button",
15359
15413
  {
15360
15414
  type: "button",
@@ -15364,7 +15418,7 @@ function SelectionToolbar({ selection, actions, alwaysShow, className }) {
15364
15418
  children: "clear"
15365
15419
  }
15366
15420
  ),
15367
- /* @__PURE__ */ jsx36("span", { className: "qt-selection-actions", children: actions(selectedIds, selection) })
15421
+ /* @__PURE__ */ jsx37("span", { className: "qt-selection-actions", children: actions(selectedIds, selection) })
15368
15422
  ] });
15369
15423
  }
15370
15424
  export {