@xenosystem/blocks 0.13.6 → 0.13.8

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.
@@ -2,6 +2,7 @@ import {
2
2
  DiamondIcon,
3
3
  EntryIcon,
4
4
  EyedropperIcon,
5
+ ICONS,
5
6
  KindGlyph,
6
7
  LinkIcon,
7
8
  LockStateIcon,
@@ -17,14 +18,14 @@ import {
17
18
  VisibilityIcon,
18
19
  XIcon,
19
20
  XIcon2
20
- } from "../chunk-UGA6G7IN.js";
21
+ } from "../chunk-BNALWAAQ.js";
22
+ import "../chunk-GTN5EDY3.js";
21
23
  import {
22
- CaseGlyph,
23
24
  ChevronGlyph,
24
25
  CollapseGlyph,
25
26
  ExpandGlyph,
26
27
  RefreshGlyph
27
- } from "../chunk-YTSBYJVH.js";
28
+ } from "../chunk-K7YLLV2W.js";
28
29
  import "../chunk-2KG3PWR4.js";
29
30
 
30
31
  // src/edit/layers/panel.ts
@@ -1490,9 +1491,9 @@ function LayersPanelView({ controller }) {
1490
1491
  const getSnapshot = useCallback(() => controller.getRevision(), [controller]);
1491
1492
  useSyncExternalStore(subscribe, getSnapshot, getSnapshot);
1492
1493
  const view = layersViewState(controller);
1493
- const ui5 = (intent) => applyLayersUi(controller, intent);
1494
+ const ui6 = (intent) => applyLayersUi(controller, intent);
1494
1495
  return /* @__PURE__ */ jsxs(Column, { className: "xeno-layers-panel", children: [
1495
- view.searchShown ? /* @__PURE__ */ jsx2(Toolbar, { children: /* @__PURE__ */ jsx2(SearchField, { value: view.filter, onChange: (v) => ui5({ kind: "filter", value: v }), placeholder: "Search layers", label: "Search layers" }) }) : null,
1496
+ view.searchShown ? /* @__PURE__ */ jsx2(Toolbar, { children: /* @__PURE__ */ jsx2(SearchField, { value: view.filter, onChange: (v) => ui6({ kind: "filter", value: v }), placeholder: "Search layers", label: "Search layers" }) }) : null,
1496
1497
  /* @__PURE__ */ jsxs(LayersScroller, { controller, children: [
1497
1498
  /* @__PURE__ */ jsx2(RowList, { role: "tree", "aria-label": "Layers", children: /* @__PURE__ */ jsx2(VirtualWindow, { totalHeight: view.totalHeight, offsetTop: view.offsetTop, children: view.rows.map((row2) => /* @__PURE__ */ jsx2(LayerRow, { row: row2, thumbnailSize: view.thumbnailSize, controller }, row2.id)) }) }),
1498
1499
  view.empty ? /* @__PURE__ */ jsx2(EmptyState, { title: "No layers" }) : null
@@ -1605,7 +1606,7 @@ function LayersThumbnail({ thumbnailKey, size, controller }) {
1605
1606
  return /* @__PURE__ */ jsx2(Thumbnail, { size, data: controller.getThumbnail(thumbnailKey) });
1606
1607
  }
1607
1608
  function LayerRow({ row: row2, thumbnailSize, controller }) {
1608
- const ui5 = (intent) => applyLayersUi(controller, intent);
1609
+ const ui6 = (intent) => applyLayersUi(controller, intent);
1609
1610
  return /* @__PURE__ */ jsx2(
1610
1611
  Row,
1611
1612
  {
@@ -1620,11 +1621,11 @@ function LayerRow({ row: row2, thumbnailSize, controller }) {
1620
1621
  title: row2.title,
1621
1622
  icon: row2.hasThumbnail ? /* @__PURE__ */ jsx2(LayersThumbnail, { thumbnailKey: row2.thumbnailKey, size: thumbnailSize, controller }) : /* @__PURE__ */ jsx2(KindGlyph, {}),
1622
1623
  leading: /* @__PURE__ */ jsxs(Fragment, { children: [
1623
- row2.showVisibility ? /* @__PURE__ */ jsx2(IconButton, { size: "sm", icon: /* @__PURE__ */ jsx2(VisibilityIcon, { open: row2.visible }), label: row2.visibilityLabel, active: row2.visible, onClick: () => ui5({ kind: "toggleProp", id: row2.id, prop: "visible" }) }) : null,
1624
- row2.showLock ? /* @__PURE__ */ jsx2(IconButton, { size: "sm", icon: /* @__PURE__ */ jsx2(LockStateIcon, { locked: row2.locked }), label: row2.lockLabel, active: row2.locked, onClick: () => ui5({ kind: "toggleProp", id: row2.id, prop: "locked" }) }) : null,
1625
- row2.showSolo ? /* @__PURE__ */ jsx2(ChipToggle, { glyph: "S", label: "Solo", on: row2.solo, onChange: () => ui5({ kind: "toggleProp", id: row2.id, prop: "solo" }) }) : null,
1626
- row2.showMute ? /* @__PURE__ */ jsx2(ChipToggle, { glyph: "M", label: "Mute", on: row2.muted, onChange: () => ui5({ kind: "toggleProp", id: row2.id, prop: "muted" }) }) : null,
1627
- row2.showArm ? /* @__PURE__ */ jsx2(ChipToggle, { glyph: "R", label: "Arm", on: row2.armed, onChange: () => ui5({ kind: "toggleProp", id: row2.id, prop: "armed" }) }) : null,
1624
+ row2.showVisibility ? /* @__PURE__ */ jsx2(IconButton, { size: "sm", icon: /* @__PURE__ */ jsx2(VisibilityIcon, { open: row2.visible }), label: row2.visibilityLabel, active: row2.visible, onClick: () => ui6({ kind: "toggleProp", id: row2.id, prop: "visible" }) }) : null,
1625
+ row2.showLock ? /* @__PURE__ */ jsx2(IconButton, { size: "sm", icon: /* @__PURE__ */ jsx2(LockStateIcon, { locked: row2.locked }), label: row2.lockLabel, active: row2.locked, onClick: () => ui6({ kind: "toggleProp", id: row2.id, prop: "locked" }) }) : null,
1626
+ row2.showSolo ? /* @__PURE__ */ jsx2(ChipToggle, { glyph: "S", label: "Solo", on: row2.solo, onChange: () => ui6({ kind: "toggleProp", id: row2.id, prop: "solo" }) }) : null,
1627
+ row2.showMute ? /* @__PURE__ */ jsx2(ChipToggle, { glyph: "M", label: "Mute", on: row2.muted, onChange: () => ui6({ kind: "toggleProp", id: row2.id, prop: "muted" }) }) : null,
1628
+ row2.showArm ? /* @__PURE__ */ jsx2(ChipToggle, { glyph: "R", label: "Arm", on: row2.armed, onChange: () => ui6({ kind: "toggleProp", id: row2.id, prop: "armed" }) }) : null,
1628
1629
  row2.showColor ? /* @__PURE__ */ jsx2(ColorTag, { color: row2.colorLabel }) : null
1629
1630
  ] }),
1630
1631
  label: row2.renaming ? /* @__PURE__ */ jsx2(LayersRenameField, { id: row2.id, controller }) : row2.name,
@@ -1632,9 +1633,9 @@ function LayerRow({ row: row2, thumbnailSize, controller }) {
1632
1633
  row2.adornments.map((a) => /* @__PURE__ */ jsx2(Badge, { size: "sm", title: a.title, children: a.text }, a.key)),
1633
1634
  row2.showOpacity ? /* @__PURE__ */ jsx2(Text, { role: "number", children: row2.opacity }) : null
1634
1635
  ] }),
1635
- onExpandedChange: () => ui5({ kind: "toggleExpanded", id: row2.id }),
1636
- onDoubleClick: () => ui5({ kind: "beginRename", id: row2.id }),
1637
- onContextMenuAt: (x, y) => ui5({ kind: "contextMenu", id: row2.id, x, y })
1636
+ onExpandedChange: () => ui6({ kind: "toggleExpanded", id: row2.id }),
1637
+ onDoubleClick: () => ui6({ kind: "beginRename", id: row2.id }),
1638
+ onContextMenuAt: (x, y) => ui6({ kind: "contextMenu", id: row2.id, x, y })
1638
1639
  }
1639
1640
  );
1640
1641
  }
@@ -2026,8 +2027,8 @@ function constraintsOf(field) {
2026
2027
  scale: field.scale
2027
2028
  };
2028
2029
  }
2029
- function parseNumeric(text5) {
2030
- const trimmed = String(text5).trim();
2030
+ function parseNumeric(text6) {
2031
+ const trimmed = String(text6).trim();
2031
2032
  if (trimmed.length === 0) return { ok: false, reason: "empty" };
2032
2033
  const match = /^[+-]?(\d+\.?\d*|\.\d+)(?:[eE][+-]?\d+)?/.exec(trimmed);
2033
2034
  if (!match) return { ok: false, reason: "nan" };
@@ -2052,8 +2053,8 @@ function normalizeNumeric(value, c) {
2052
2053
  function formatNumeric(value, field) {
2053
2054
  if (!Number.isFinite(value)) return "";
2054
2055
  const precision = field.precision;
2055
- const text5 = typeof precision === "number" && Number.isFinite(precision) ? value.toFixed(Math.max(0, Math.floor(precision))) : String(value);
2056
- return field.unit ? `${text5}${field.unit}` : text5;
2056
+ const text6 = typeof precision === "number" && Number.isFinite(precision) ? value.toFixed(Math.max(0, Math.floor(precision))) : String(value);
2057
+ return field.unit ? `${text6}${field.unit}` : text6;
2057
2058
  }
2058
2059
  function usesLogScale(c) {
2059
2060
  return c.scale === "log" && typeof c.min === "number" && typeof c.max === "number" && c.min > 0 && c.max > c.min;
@@ -2387,44 +2388,44 @@ var InspectorPanelController = class {
2387
2388
  if (!field || !isFieldEditable(field)) return;
2388
2389
  const mixed = isFieldMixed(field);
2389
2390
  const value = this.getFieldValue(fieldId);
2390
- const text5 = mixed ? "" : field.type === "number" && typeof value === "number" ? formatNumeric(value, field) : value === void 0 || value === null ? "" : String(value);
2391
- this.drafts.set(fieldId, { text: text5, original: value });
2391
+ const text6 = mixed ? "" : field.type === "number" && typeof value === "number" ? formatNumeric(value, field) : value === void 0 || value === null ? "" : String(value);
2392
+ this.drafts.set(fieldId, { text: text6, original: value });
2392
2393
  this.focusedFieldId = fieldId;
2393
2394
  this.emitFieldFocus(fieldId);
2394
2395
  this.notify();
2395
2396
  }
2396
2397
  /** Update the draft text (typing). Emits nothing under the `blur` policy. */
2397
- setDraft(fieldId, text5) {
2398
+ setDraft(fieldId, text6) {
2398
2399
  const draft = this.drafts.get(fieldId);
2399
2400
  if (!draft) {
2400
- this.drafts.set(fieldId, { text: text5, original: this.getFieldValue(fieldId) });
2401
+ this.drafts.set(fieldId, { text: text6, original: this.getFieldValue(fieldId) });
2401
2402
  } else {
2402
- draft.text = text5;
2403
+ draft.text = text6;
2403
2404
  }
2404
2405
  const field = this.getField(fieldId);
2405
2406
  if (field && commitPolicyOf(field) === "live") {
2406
- const parsed = this.parseDraft(fieldId, text5);
2407
+ const parsed = this.parseDraft(fieldId, text6);
2407
2408
  if (parsed.ok) this.emitSet(fieldId, parsed.value);
2408
2409
  }
2409
2410
  this.notify();
2410
2411
  }
2411
2412
  /** Parse a draft string into a field-appropriate value. */
2412
- parseDraft(fieldId, text5) {
2413
+ parseDraft(fieldId, text6) {
2413
2414
  const field = this.getField(fieldId);
2414
2415
  if (!field) return { ok: false };
2415
2416
  if (field.type === "number") {
2416
- const parsed = parseNumeric(text5);
2417
+ const parsed = parseNumeric(text6);
2417
2418
  if (!parsed.ok) return { ok: false };
2418
2419
  return { ok: true, value: normalizeNumeric(parsed.value, constraintsOf(field)) };
2419
2420
  }
2420
2421
  if (field.type === "json") {
2421
2422
  try {
2422
- return { ok: true, value: JSON.parse(text5) };
2423
+ return { ok: true, value: JSON.parse(text6) };
2423
2424
  } catch {
2424
2425
  return { ok: false };
2425
2426
  }
2426
2427
  }
2427
- return { ok: true, value: text5 };
2428
+ return { ok: true, value: text6 };
2428
2429
  }
2429
2430
  /**
2430
2431
  * Commit the draft (Enter / blur). Invalid input reverts instead of committing garbage.
@@ -3350,7 +3351,7 @@ function NumberWidget({ field, controller, component }) {
3350
3351
  },
3351
3352
  [controller, editable, field.id, component]
3352
3353
  );
3353
- const text5 = component !== void 0 ? (() => {
3354
+ const text6 = component !== void 0 ? (() => {
3354
3355
  const raw = controller.getFieldValue(field.id);
3355
3356
  const v = Array.isArray(raw) ? raw[component] : void 0;
3356
3357
  return typeof v === "number" ? formatNumeric(v, field) : "";
@@ -3362,7 +3363,7 @@ function NumberWidget({ field, controller, component }) {
3362
3363
  Input2,
3363
3364
  {
3364
3365
  inputMode: "decimal",
3365
- value: text5,
3366
+ value: text6,
3366
3367
  placeholder: mixed ? controller.getMixedPlaceholder() : field.placeholder,
3367
3368
  mixed,
3368
3369
  readOnly: !editable,
@@ -3516,7 +3517,7 @@ function ListWidget({ field, controller }) {
3516
3517
  editable ? /* @__PURE__ */ jsxs2(Fragment2, { children: [
3517
3518
  /* @__PURE__ */ jsx3(IconButton2, { size: "sm", icon: /* @__PURE__ */ jsx3("span", { "aria-hidden": true, children: "\u2191" }), label: "Move up", disabled: i === 0, onClick: () => move(i, i - 1) }),
3518
3519
  /* @__PURE__ */ jsx3(IconButton2, { size: "sm", icon: /* @__PURE__ */ jsx3("span", { "aria-hidden": true, children: "\u2193" }), label: "Move down", disabled: i === items.length - 1, onClick: () => move(i, i + 1) }),
3519
- /* @__PURE__ */ jsx3(IconButton2, { size: "sm", icon: /* @__PURE__ */ jsx3(XIcon, {}), label: "Remove", onClick: () => write(items.filter((_, j) => j !== i)) })
3520
+ /* @__PURE__ */ jsx3(IconButton2, { size: "sm", icon: /* @__PURE__ */ jsx3(XIcon2, {}), label: "Remove", onClick: () => write(items.filter((_, j) => j !== i)) })
3520
3521
  ] }) : null
3521
3522
  ] }, i)),
3522
3523
  editable ? /* @__PURE__ */ jsx3(TextButton, { onClick: () => write([...items, ""]), children: "+ Add" }) : null
@@ -3580,7 +3581,7 @@ function ActionGlyph({ glyph }) {
3580
3581
  return /* @__PURE__ */ jsx4("span", { "aria-hidden": true, children: glyph });
3581
3582
  }
3582
3583
  function SectionView({ section, controller }) {
3583
- const ui5 = (intent) => applyInspectorUi(controller, intent);
3584
+ const ui6 = (intent) => applyInspectorUi(controller, intent);
3584
3585
  const hasActions = section.actions.length > 0 || section.hasAddMenu;
3585
3586
  return /* @__PURE__ */ jsxs3(
3586
3587
  Section,
@@ -3589,13 +3590,13 @@ function SectionView({ section, controller }) {
3589
3590
  flush: true,
3590
3591
  collapsible: section.collapsible,
3591
3592
  collapsed: section.collapsed,
3592
- onCollapsedChange: () => ui5({ kind: "toggleSectionCollapsed", sectionId: section.id }),
3593
+ onCollapsedChange: () => ui6({ kind: "toggleSectionCollapsed", sectionId: section.id }),
3593
3594
  enabled: section.enabled,
3594
- onEnabledChange: () => ui5({ kind: "toggleSectionEnabled", sectionId: section.id }),
3595
+ onEnabledChange: () => ui6({ kind: "toggleSectionEnabled", sectionId: section.id }),
3595
3596
  badge: section.badge ? /* @__PURE__ */ jsx4(Badge2, { children: section.badge }) : null,
3596
3597
  actions: hasActions ? /* @__PURE__ */ jsxs3(Fragment3, { children: [
3597
- section.actions.map((action) => /* @__PURE__ */ jsx4(IconButton3, { size: "sm", icon: /* @__PURE__ */ jsx4(ActionGlyph, { glyph: action.glyph }), label: action.label, disabled: action.disabled, onClick: () => ui5({ kind: "runAction", sectionId: section.id, actionId: action.id }) }, action.id)),
3598
- section.hasAddMenu ? /* @__PURE__ */ jsx4(Menu, { size: "sm", trigger: "\uFF0B", items: section.addItems, label: section.addLabel, align: "end", onSelect: (id) => ui5({ kind: "addItem", sectionId: section.id, itemId: id }) }) : null
3598
+ section.actions.map((action) => /* @__PURE__ */ jsx4(IconButton3, { size: "sm", icon: /* @__PURE__ */ jsx4(ActionGlyph, { glyph: action.glyph }), label: action.label, disabled: action.disabled, onClick: () => ui6({ kind: "runAction", sectionId: section.id, actionId: action.id }) }, action.id)),
3599
+ section.hasAddMenu ? /* @__PURE__ */ jsx4(Menu, { size: "sm", trigger: "\uFF0B", items: section.addItems, label: section.addLabel, align: "end", onSelect: (id) => ui6({ kind: "addItem", sectionId: section.id, itemId: id }) }) : null
3599
3600
  ] }) : null,
3600
3601
  children: [
3601
3602
  section.showEmptyHint ? /* @__PURE__ */ jsx4(Stack2, { pad: "inset", children: /* @__PURE__ */ jsx4(Text3, { role: "caption", children: section.emptyHint }) }) : null,
@@ -3605,7 +3606,7 @@ function SectionView({ section, controller }) {
3605
3606
  );
3606
3607
  }
3607
3608
  function FieldRow({ row: row2, controller }) {
3608
- const ui5 = (intent) => applyInspectorUi(controller, intent);
3609
+ const ui6 = (intent) => applyInspectorUi(controller, intent);
3609
3610
  return /* @__PURE__ */ jsxs3(Fragment3, { children: [
3610
3611
  /* @__PURE__ */ jsxs3(
3611
3612
  Field,
@@ -3613,19 +3614,19 @@ function FieldRow({ row: row2, controller }) {
3613
3614
  label: row2.label,
3614
3615
  title: row2.title,
3615
3616
  focused: row2.focused,
3616
- onLabelClick: () => ui5({ kind: "focusField", fieldId: row2.id }),
3617
- onContextMenu: (x, y) => ui5({ kind: "contextMenu", fieldId: row2.id, x, y }),
3617
+ onLabelClick: () => ui6({ kind: "focusField", fieldId: row2.id }),
3618
+ onContextMenu: (x, y) => ui6({ kind: "contextMenu", fieldId: row2.id, x, y }),
3618
3619
  leading: row2.showKeyframes ? /* @__PURE__ */ jsxs3(Fragment3, { children: [
3619
- /* @__PURE__ */ jsx4(IconButton3, { size: "sm", icon: /* @__PURE__ */ jsx4(StopwatchIcon, {}), label: "Toggle animation", active: row2.animated, onClick: () => ui5({ kind: "keyframe", fieldId: row2.id, op: "toggleAnim" }) }),
3620
- row2.animated ? /* @__PURE__ */ jsx4(IconButton3, { size: "sm", icon: /* @__PURE__ */ jsx4(PrevIcon, {}), label: "Previous keyframe", disabled: row2.prevDisabled, onClick: () => ui5({ kind: "keyframe", fieldId: row2.id, op: "prev" }) }) : null,
3621
- row2.animated ? /* @__PURE__ */ jsx4(IconButton3, { size: "sm", icon: /* @__PURE__ */ jsx4(DiamondIcon, { filled: row2.onKeyframe }), label: row2.keyframeLabel, onClick: () => ui5({ kind: "keyframe", fieldId: row2.id, op: row2.keyframeOp }) }) : null,
3622
- row2.animated ? /* @__PURE__ */ jsx4(IconButton3, { size: "sm", icon: /* @__PURE__ */ jsx4(NextIcon, {}), label: "Next keyframe", disabled: row2.nextDisabled, onClick: () => ui5({ kind: "keyframe", fieldId: row2.id, op: "next" }) }) : null
3620
+ /* @__PURE__ */ jsx4(IconButton3, { size: "sm", icon: /* @__PURE__ */ jsx4(StopwatchIcon, {}), label: "Toggle animation", active: row2.animated, onClick: () => ui6({ kind: "keyframe", fieldId: row2.id, op: "toggleAnim" }) }),
3621
+ row2.animated ? /* @__PURE__ */ jsx4(IconButton3, { size: "sm", icon: /* @__PURE__ */ jsx4(PrevIcon, {}), label: "Previous keyframe", disabled: row2.prevDisabled, onClick: () => ui6({ kind: "keyframe", fieldId: row2.id, op: "prev" }) }) : null,
3622
+ row2.animated ? /* @__PURE__ */ jsx4(IconButton3, { size: "sm", icon: /* @__PURE__ */ jsx4(DiamondIcon, { filled: row2.onKeyframe }), label: row2.keyframeLabel, onClick: () => ui6({ kind: "keyframe", fieldId: row2.id, op: row2.keyframeOp }) }) : null,
3623
+ row2.animated ? /* @__PURE__ */ jsx4(IconButton3, { size: "sm", icon: /* @__PURE__ */ jsx4(NextIcon, {}), label: "Next keyframe", disabled: row2.nextDisabled, onClick: () => ui6({ kind: "keyframe", fieldId: row2.id, op: "next" }) }) : null
3623
3624
  ] }) : null,
3624
3625
  trailing: /* @__PURE__ */ jsxs3(Fragment3, { children: [
3625
- row2.showEasing ? /* @__PURE__ */ jsx4(Select2, { size: "sm", options: row2.easingOptions, value: row2.easing, label: "Easing", onChange: (v) => ui5({ kind: "setEasing", fieldId: row2.id, easing: v }) }) : null,
3626
+ row2.showEasing ? /* @__PURE__ */ jsx4(Select2, { size: "sm", options: row2.easingOptions, value: row2.easing, label: "Easing", onChange: (v) => ui6({ kind: "setEasing", fieldId: row2.id, easing: v }) }) : null,
3626
3627
  row2.showKeyframes ? /* @__PURE__ */ jsx4(Badge2, { size: "sm", children: row2.keyframeChip }) : null,
3627
- row2.showToken ? /* @__PURE__ */ jsx4(IconButton3, { size: "sm", icon: /* @__PURE__ */ jsx4(LinkIcon, {}), label: row2.tokenActionLabel, active: row2.bound, onClick: () => ui5({ kind: "bindToken", fieldId: row2.id }) }) : null,
3628
- row2.showReset ? /* @__PURE__ */ jsx4(IconButton3, { size: "sm", icon: /* @__PURE__ */ jsx4(ResetIcon, {}), label: "Reset to default", onClick: () => ui5({ kind: "resetField", fieldId: row2.id }) }) : null
3628
+ row2.showToken ? /* @__PURE__ */ jsx4(IconButton3, { size: "sm", icon: /* @__PURE__ */ jsx4(LinkIcon, {}), label: row2.tokenActionLabel, active: row2.bound, onClick: () => ui6({ kind: "bindToken", fieldId: row2.id }) }) : null,
3629
+ row2.showReset ? /* @__PURE__ */ jsx4(IconButton3, { size: "sm", icon: /* @__PURE__ */ jsx4(ResetIcon, {}), label: "Reset to default", onClick: () => ui6({ kind: "resetField", fieldId: row2.id }) }) : null
3629
3630
  ] }),
3630
3631
  children: [
3631
3632
  row2.bound ? /* @__PURE__ */ jsx4(Badge2, { title: row2.tokenTitle, children: row2.tokenLabel }) : null,
@@ -4878,23 +4879,23 @@ function HistoryPanelView({ controller }) {
4878
4879
  const getSnapshot = useCallback4(() => controller.getRevision(), [controller]);
4879
4880
  useSyncExternalStore3(subscribe, getSnapshot, getSnapshot);
4880
4881
  const view = historyViewState(controller);
4881
- const ui5 = (intent) => applyHistoryUi(controller, intent);
4882
+ const ui6 = (intent) => applyHistoryUi(controller, intent);
4882
4883
  return /* @__PURE__ */ jsxs4(Column3, { className: "xeno-history-panel", children: [
4883
4884
  /* @__PURE__ */ jsx5(
4884
4885
  Toolbar2,
4885
4886
  {
4886
4887
  left: /* @__PURE__ */ jsxs4(Fragment4, { children: [
4887
- /* @__PURE__ */ jsx5(IconButton4, { size: "sm", icon: /* @__PURE__ */ jsx5(UndoIcon, {}), label: "Undo", disabled: !view.canUndo, onClick: () => ui5({ kind: "undo" }) }),
4888
- /* @__PURE__ */ jsx5(IconButton4, { size: "sm", icon: /* @__PURE__ */ jsx5(RedoIcon, {}), label: "Redo", disabled: !view.canRedo, onClick: () => ui5({ kind: "redo" }) })
4888
+ /* @__PURE__ */ jsx5(IconButton4, { size: "sm", icon: /* @__PURE__ */ jsx5(UndoIcon, {}), label: "Undo", disabled: !view.canUndo, onClick: () => ui6({ kind: "undo" }) }),
4889
+ /* @__PURE__ */ jsx5(IconButton4, { size: "sm", icon: /* @__PURE__ */ jsx5(RedoIcon, {}), label: "Redo", disabled: !view.canRedo, onClick: () => ui6({ kind: "redo" }) })
4889
4890
  ] }),
4890
4891
  right: /* @__PURE__ */ jsxs4(Fragment4, { children: [
4891
4892
  /* @__PURE__ */ jsx5(Text4, { role: "number", children: view.counter }),
4892
- view.clearAllowed ? /* @__PURE__ */ jsx5(IconButton4, { size: "sm", icon: /* @__PURE__ */ jsx5(TrashIcon, {}), label: "Clear history", onClick: () => ui5({ kind: "requestClear" }) }) : null
4893
+ view.clearAllowed ? /* @__PURE__ */ jsx5(IconButton4, { size: "sm", icon: /* @__PURE__ */ jsx5(TrashIcon, {}), label: "Clear history", onClick: () => ui6({ kind: "requestClear" }) }) : null
4893
4894
  ] }),
4894
- children: view.searchShown ? /* @__PURE__ */ jsx5(SearchField3, { value: view.filter, onChange: (v) => ui5({ kind: "filter", value: v }), placeholder: "Search history", label: "Search history" }) : null
4895
+ children: view.searchShown ? /* @__PURE__ */ jsx5(SearchField3, { value: view.filter, onChange: (v) => ui6({ kind: "filter", value: v }), placeholder: "Search history", label: "Search history" }) : null
4895
4896
  }
4896
4897
  ),
4897
- view.confirmingClear ? /* @__PURE__ */ jsx5(InlineConfirm, { message: "Clear all history?", label: "Confirm clear history", confirmLabel: "Clear", onConfirm: () => ui5({ kind: "confirmClear" }), onCancel: () => ui5({ kind: "cancelClear" }) }) : null,
4898
+ view.confirmingClear ? /* @__PURE__ */ jsx5(InlineConfirm, { message: "Clear all history?", label: "Confirm clear history", confirmLabel: "Clear", onConfirm: () => ui6({ kind: "confirmClear" }), onCancel: () => ui6({ kind: "cancelClear" }) }) : null,
4898
4899
  view.pruned ? /* @__PURE__ */ jsx5(Text4, { role: "caption", children: "Earlier history discarded (limit reached)" }) : null,
4899
4900
  /* @__PURE__ */ jsxs4(HistoryScroller, { controller, children: [
4900
4901
  /* @__PURE__ */ jsx5(RowList2, { role: "listbox", "aria-label": "History", children: /* @__PURE__ */ jsx5(VirtualWindow2, { totalHeight: view.totalHeight, offsetTop: view.offsetTop, children: view.rows.map((row2) => /* @__PURE__ */ jsx5(HistoryRowView, { row: row2, controller }, row2.key)) }) }),
@@ -4942,7 +4943,7 @@ function HistoryCancelButton({ entryId, controller }) {
4942
4943
  IconButton4,
4943
4944
  {
4944
4945
  size: "sm",
4945
- icon: /* @__PURE__ */ jsx5(XIcon2, {}),
4946
+ icon: /* @__PURE__ */ jsx5(XIcon, {}),
4946
4947
  label: "Cancel operation",
4947
4948
  pointerOnly: true,
4948
4949
  onClick: (e) => {
@@ -4953,7 +4954,7 @@ function HistoryCancelButton({ entryId, controller }) {
4953
4954
  );
4954
4955
  }
4955
4956
  function HistoryRowView({ row: row2, controller }) {
4956
- const ui5 = (intent) => applyHistoryUi(controller, intent);
4957
+ const ui6 = (intent) => applyHistoryUi(controller, intent);
4957
4958
  return /* @__PURE__ */ jsx5(
4958
4959
  Row2,
4959
4960
  {
@@ -4976,9 +4977,9 @@ function HistoryRowView({ row: row2, controller }) {
4976
4977
  row2.showTime ? /* @__PURE__ */ jsx5(Text4, { role: "meta", children: row2.time }) : null,
4977
4978
  row2.pending ? /* @__PURE__ */ jsx5(HistoryCancelButton, { entryId: row2.cancelId, controller }) : null
4978
4979
  ] }),
4979
- onClick: () => ui5({ kind: "jump", entryId: row2.entryId }),
4980
- onMouseEnter: () => ui5({ kind: "hover", entryId: row2.entryId }),
4981
- onContextMenuAt: (x, y) => ui5({ kind: "contextMenu", entryId: row2.entryId, x, y })
4980
+ onClick: () => ui6({ kind: "jump", entryId: row2.entryId }),
4981
+ onMouseEnter: () => ui6({ kind: "hover", entryId: row2.entryId }),
4982
+ onContextMenuAt: (x, y) => ui6({ kind: "contextMenu", entryId: row2.entryId, x, y })
4982
4983
  }
4983
4984
  );
4984
4985
  }
@@ -6264,27 +6265,27 @@ function ColorPanelView({ controller }) {
6264
6265
  const getSnapshot = useCallback5(() => controller.getRevision(), [controller]);
6265
6266
  useSyncExternalStore4(subscribe, getSnapshot, getSnapshot);
6266
6267
  const view = colorViewState(controller);
6267
- const ui5 = (intent) => applyColorUi(controller, intent);
6268
+ const ui6 = (intent) => applyColorUi(controller, intent);
6268
6269
  return /* @__PURE__ */ jsx6(Column4, { className: "xeno-color-panel", children: /* @__PURE__ */ jsxs5(Stack3, { gap: 8, children: [
6269
6270
  view.fgBg ? /* @__PURE__ */ jsxs5(Stack3, { direction: "row", pad: "none", children: [
6270
- /* @__PURE__ */ jsx6(ColorChip, { color: view.hex, label: "Foreground", pressed: view.fgActive, onClick: () => ui5({ kind: "setChannel", channel: "fg" }) }),
6271
- /* @__PURE__ */ jsx6(IconButton5, { size: "sm", icon: /* @__PURE__ */ jsx6(SwapIcon, {}), label: "Swap FG/BG (X)", onClick: () => ui5({ kind: "swapChannels" }) }),
6272
- /* @__PURE__ */ jsx6(ColorChip, { color: null, label: "Background", pressed: view.bgActive, onClick: () => ui5({ kind: "setChannel", channel: "bg" }) })
6271
+ /* @__PURE__ */ jsx6(ColorChip, { color: view.hex, label: "Foreground", pressed: view.fgActive, onClick: () => ui6({ kind: "setChannel", channel: "fg" }) }),
6272
+ /* @__PURE__ */ jsx6(IconButton5, { size: "sm", icon: /* @__PURE__ */ jsx6(SwapIcon, {}), label: "Swap FG/BG (X)", onClick: () => ui6({ kind: "swapChannels" }) }),
6273
+ /* @__PURE__ */ jsx6(ColorChip, { color: null, label: "Background", pressed: view.bgActive, onClick: () => ui6({ kind: "setChannel", channel: "bg" }) })
6273
6274
  ] }) : null,
6274
6275
  /* @__PURE__ */ jsx6(ColorPicker, { controller }),
6275
6276
  /* @__PURE__ */ jsxs5(Stack3, { direction: "row", pad: "none", gap: 4, children: [
6276
- /* @__PURE__ */ jsx6(Select3, { size: "sm", label: "Color model", value: view.space, options: view.spaceOptions, onChange: (v) => ui5({ kind: "setSpace", space: v }) }),
6277
- view.isHex ? /* @__PURE__ */ jsx6(Input3, { variant: "mono", label: "Hex", value: view.hex, onChange: (v) => ui5({ kind: "setHex", value: v }), disabled: view.bound }) : null,
6278
- view.components.map((comp) => /* @__PURE__ */ jsx6(NumberInput, { caption: comp.label, value: comp.value, onChange: (n) => ui5({ kind: "setComponent", index: comp.index, value: n }), disabled: view.bound }, comp.key)),
6279
- view.alphaShown ? /* @__PURE__ */ jsx6(NumberInput, { caption: "A", label: "Alpha", min: 0, max: 100, value: view.alphaPercent, onChange: (n) => ui5({ kind: "setAlpha", percent: n }), disabled: view.bound }) : null,
6280
- /* @__PURE__ */ jsx6(IconButton5, { size: "sm", icon: /* @__PURE__ */ jsx6(EyedropperIcon, {}), label: "Pick from screen", onClick: () => ui5({ kind: "eyedropper" }) })
6277
+ /* @__PURE__ */ jsx6(Select3, { size: "sm", label: "Color model", value: view.space, options: view.spaceOptions, onChange: (v) => ui6({ kind: "setSpace", space: v }) }),
6278
+ view.isHex ? /* @__PURE__ */ jsx6(Input3, { variant: "mono", label: "Hex", value: view.hex, onChange: (v) => ui6({ kind: "setHex", value: v }), disabled: view.bound }) : null,
6279
+ view.components.map((comp) => /* @__PURE__ */ jsx6(NumberInput, { caption: comp.label, value: comp.value, onChange: (n) => ui6({ kind: "setComponent", index: comp.index, value: n }), disabled: view.bound }, comp.key)),
6280
+ view.alphaShown ? /* @__PURE__ */ jsx6(NumberInput, { caption: "A", label: "Alpha", min: 0, max: 100, value: view.alphaPercent, onChange: (n) => ui6({ kind: "setAlpha", percent: n }), disabled: view.bound }) : null,
6281
+ /* @__PURE__ */ jsx6(IconButton5, { size: "sm", icon: /* @__PURE__ */ jsx6(EyedropperIcon, {}), label: "Pick from screen", onClick: () => ui6({ kind: "eyedropper" }) })
6281
6282
  ] }),
6282
6283
  view.hasTokens ? /* @__PURE__ */ jsx6(Field2, { label: "Token", htmlFor: "xeno-color-token", children: /* @__PURE__ */ jsxs5(Stack3, { direction: "row", pad: "none", gap: 4, children: [
6283
- /* @__PURE__ */ jsx6(Select3, { size: "sm", label: "Bind token", value: view.boundTokenId, placeholder: "\u2014 raw \u2014", options: view.tokenOptions, onChange: (id) => ui5({ kind: "bindToken", tokenId: id }) }),
6284
- view.bound ? /* @__PURE__ */ jsx6(TextButton2, { onClick: () => ui5({ kind: "unbindToken" }), children: "Unbind" }) : null
6284
+ /* @__PURE__ */ jsx6(Select3, { size: "sm", label: "Bind token", value: view.boundTokenId, placeholder: "\u2014 raw \u2014", options: view.tokenOptions, onChange: (id) => ui6({ kind: "bindToken", tokenId: id }) }),
6285
+ view.bound ? /* @__PURE__ */ jsx6(TextButton2, { onClick: () => ui6({ kind: "unbindToken" }), children: "Unbind" }) : null
6285
6286
  ] }) }) : null,
6286
- /* @__PURE__ */ jsx6(Section2, { title: "Swatches", flush: true, actions: /* @__PURE__ */ jsx6(TextButton2, { onClick: () => ui5({ kind: "addSwatch" }), children: "+ Save" }), children: /* @__PURE__ */ jsx6(SwatchGrid, { label: "Swatches", children: view.swatches.map((sw) => /* @__PURE__ */ jsx6(ColorChip, { size: "grid", color: sw.hex, label: sw.hex, onClick: () => ui5({ kind: "selectColor", hex: sw.hex }), onContextMenu: () => ui5({ kind: "removeSwatch", hex: sw.hex }) }, sw.key)) }) }),
6287
- view.hasRecent ? /* @__PURE__ */ jsx6(Section2, { title: "Recent", flush: true, children: /* @__PURE__ */ jsx6(SwatchGrid, { label: "Recent", children: view.recent.map((r) => /* @__PURE__ */ jsx6(ColorChip, { size: "grid", color: r.hex, label: r.hex, onClick: () => ui5({ kind: "selectColor", hex: r.hex }) }, r.key)) }) }) : null
6287
+ /* @__PURE__ */ jsx6(Section2, { title: "Swatches", flush: true, actions: /* @__PURE__ */ jsx6(TextButton2, { onClick: () => ui6({ kind: "addSwatch" }), children: "+ Save" }), children: /* @__PURE__ */ jsx6(SwatchGrid, { label: "Swatches", children: view.swatches.map((sw) => /* @__PURE__ */ jsx6(ColorChip, { size: "grid", color: sw.hex, label: sw.hex, onClick: () => ui6({ kind: "selectColor", hex: sw.hex }), onContextMenu: () => ui6({ kind: "removeSwatch", hex: sw.hex }) }, sw.key)) }) }),
6288
+ view.hasRecent ? /* @__PURE__ */ jsx6(Section2, { title: "Recent", flush: true, children: /* @__PURE__ */ jsx6(SwatchGrid, { label: "Recent", children: view.recent.map((r) => /* @__PURE__ */ jsx6(ColorChip, { size: "grid", color: r.hex, label: r.hex, onClick: () => ui6({ kind: "selectColor", hex: r.hex }) }, r.key)) }) }) : null
6288
6289
  ] }) });
6289
6290
  }
6290
6291
  function ColorPicker({ controller }) {
@@ -8946,11 +8947,11 @@ var FindController = class {
8946
8947
  * @param text - The new query text.
8947
8948
  * @param immediate - Skip the debounce (a paste, or pressing Enter).
8948
8949
  */
8949
- setText(text5, immediate = false) {
8950
- if (text5 === this.text) return;
8951
- this.text = text5;
8950
+ setText(text6, immediate = false) {
8951
+ if (text6 === this.text) return;
8952
+ this.text = text6;
8952
8953
  this.index = -1;
8953
- if (text5 === "") {
8954
+ if (text6 === "") {
8954
8955
  this.clearResults("idle");
8955
8956
  this.emitQuery(true);
8956
8957
  return;
@@ -8978,8 +8979,8 @@ var FindController = class {
8978
8979
  this.notify();
8979
8980
  }
8980
8981
  /** The replacement text. Never emitted on its own — a replacement is not a search. */
8981
- setReplaceText(text5) {
8982
- this.replaceText = text5;
8982
+ setReplaceText(text6) {
8983
+ this.replaceText = text6;
8983
8984
  this.notify();
8984
8985
  }
8985
8986
  /** Show or hide the replace row. */
@@ -9344,7 +9345,9 @@ var findManifest = {
9344
9345
  import { useSyncExternalStore as useSyncExternalStore7 } from "react";
9345
9346
  import {
9346
9347
  Badge as Badge5,
9348
+ Column as Column5,
9347
9349
  EmptyState as EmptyState5,
9350
+ Highlight,
9348
9351
  IconButton as IconButton6,
9349
9352
  Row as Row3,
9350
9353
  RowList as RowList3,
@@ -9352,64 +9355,260 @@ import {
9352
9355
  SearchField as SearchField4,
9353
9356
  Section as Section3,
9354
9357
  StatusBar as StatusBar5,
9358
+ Text as Text5,
9355
9359
  TextButton as TextButton3,
9356
9360
  Toolbar as Toolbar4,
9357
9361
  ToolbarGroup as ToolbarGroup2
9358
9362
  } from "@xenosystem/components/chrome";
9359
- import { jsx as jsx9, jsxs as jsxs8 } from "react/jsx-runtime";
9360
- function CaseIcon() {
9361
- return /* @__PURE__ */ jsx9(CaseGlyph, { size: 12 });
9362
- }
9363
- function WordIcon() {
9364
- return /* @__PURE__ */ jsxs8("svg", { width: "12", height: "12", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "1.5", children: [
9365
- /* @__PURE__ */ jsx9("path", { d: "M7 12h10" }),
9366
- /* @__PURE__ */ jsx9("path", { d: "M3 7v10" }),
9367
- /* @__PURE__ */ jsx9("path", { d: "M21 7v10" })
9368
- ] });
9369
- }
9370
- function RegexIcon() {
9371
- return /* @__PURE__ */ jsxs8("svg", { width: "12", height: "12", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "1.5", children: [
9372
- /* @__PURE__ */ jsx9("path", { d: "M12 4v8" }),
9373
- /* @__PURE__ */ jsx9("path", { d: "m8.5 6 7 4" }),
9374
- /* @__PURE__ */ jsx9("path", { d: "m8.5 10 7-4" }),
9375
- /* @__PURE__ */ jsx9("path", { d: "M5 18h2" })
9376
- ] });
9377
- }
9378
- function UpIcon() {
9379
- return /* @__PURE__ */ jsx9("svg", { width: "12", height: "12", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "1.5", children: /* @__PURE__ */ jsx9("path", { d: "m18 15-6-6-6 6" }) });
9380
- }
9381
- function DownIcon() {
9382
- return /* @__PURE__ */ jsx9("svg", { width: "12", height: "12", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "1.5", children: /* @__PURE__ */ jsx9("path", { d: "m6 9 6 6 6-6" }) });
9363
+
9364
+ // src/edit/find/declaration.ts
9365
+ function findViewState(c, options = {}) {
9366
+ const s = c.getState();
9367
+ const hasText = s.text !== "";
9368
+ const statusKind = s.status === "invalidPattern" ? "invalid" : s.status === "failed" ? "failed" : s.status === "searching" ? "searching" : !hasText || s.status === "idle" ? "none" : "count";
9369
+ let flat = -1;
9370
+ const row2 = (m) => {
9371
+ flat += 1;
9372
+ return { id: m.id, index: flat, current: flat === s.index, segments: highlightSegments(m.snippet ?? "", m.ranges), location: m.locationLabel };
9373
+ };
9374
+ const isFlat = s.groups.length === 1 && s.groups[0].id === "";
9375
+ const rows = isFlat ? s.matches.map(row2) : [];
9376
+ const groups = isFlat ? [] : s.groups.map((g) => ({ id: g.id, label: g.label || "Results", count: g.matches.length, rows: g.matches.map(row2) }));
9377
+ const showResults = options.showResults ?? true;
9378
+ return {
9379
+ text: s.text,
9380
+ hasText,
9381
+ placeholder: options.placeholder ?? "Find",
9382
+ caseSensitive: s.options.caseSensitive,
9383
+ wholeWord: s.options.wholeWord,
9384
+ regex: s.options.regex,
9385
+ status: s.status,
9386
+ message: s.message,
9387
+ statusKind,
9388
+ searchingBadge: statusKind === "searching",
9389
+ countShown: statusKind === "count",
9390
+ counter: `${s.displayIndex}/${s.count}${s.truncated ? "+" : ""}`,
9391
+ hasMatches: s.matches.length > 0,
9392
+ replaceVisible: s.replaceVisible,
9393
+ replaceText: s.replaceText,
9394
+ canReplace: s.canReplace,
9395
+ allLabel: `All (${s.matches.length})`,
9396
+ replaceLabel: s.replaceVisible ? "Hide replace" : "Replace",
9397
+ showResults,
9398
+ idle: s.status === "idle",
9399
+ invalid: s.status === "invalidPattern",
9400
+ failed: s.status === "failed",
9401
+ noResults: s.noResults,
9402
+ noResultsHint: `Nothing in scope matches \u201C${s.text}\u201D.`,
9403
+ invalidHint: s.message ?? "The expression could not be read. Fix it to search.",
9404
+ failedHint: s.message ?? "The host could not complete the search.",
9405
+ flat: showResults && !s.noResults && s.status !== "idle" && s.status !== "invalidPattern" && s.status !== "failed" && isFlat,
9406
+ grouped: showResults && !s.noResults && s.status !== "idle" && s.status !== "invalidPattern" && s.status !== "failed" && !isFlat,
9407
+ rows,
9408
+ groups,
9409
+ truncatedLabel: s.truncated ? `showing first ${s.matches.length}` : void 0,
9410
+ scope: s.options.scope
9411
+ };
9383
9412
  }
9384
- function StatusLine({
9385
- status,
9386
- message,
9387
- count,
9388
- displayIndex,
9389
- truncated,
9390
- hasText
9391
- }) {
9392
- if (status === "invalidPattern") {
9393
- return /* @__PURE__ */ jsx9(Badge5, { tone: "error", title: message ?? void 0, children: "invalid pattern" });
9394
- }
9395
- if (status === "failed") {
9396
- return /* @__PURE__ */ jsx9(Badge5, { tone: "error", title: message ?? void 0, children: "search failed" });
9397
- }
9398
- if (status === "searching") return /* @__PURE__ */ jsx9(Badge5, { children: "searching\u2026" });
9399
- if (!hasText || status === "idle") return null;
9400
- return /* @__PURE__ */ jsxs8("span", { style: { fontVariantNumeric: "tabular-nums", fontSize: 10, opacity: 0.55 }, children: [
9401
- displayIndex,
9402
- "/",
9403
- count,
9404
- truncated ? "+" : ""
9405
- ] });
9413
+ function applyFindUi(c, intent) {
9414
+ switch (intent.kind) {
9415
+ case "text":
9416
+ c.setText(intent.value);
9417
+ break;
9418
+ case "option":
9419
+ c.setOptions({ [intent.option]: !c.getState().options[intent.option] });
9420
+ break;
9421
+ case "previous":
9422
+ c.previous();
9423
+ break;
9424
+ case "next":
9425
+ c.next();
9426
+ break;
9427
+ case "toggleReplace":
9428
+ c.setReplaceVisible(!c.getState().replaceVisible);
9429
+ break;
9430
+ case "replaceText":
9431
+ c.setReplaceText(intent.value);
9432
+ break;
9433
+ case "replaceCurrent":
9434
+ c.replaceCurrent();
9435
+ break;
9436
+ case "replaceAll":
9437
+ c.replaceAll();
9438
+ break;
9439
+ case "select":
9440
+ c.select(intent.matchId);
9441
+ break;
9442
+ case "contextMenu":
9443
+ c.requestContextMenu(intent.matchId, intent.x, intent.y);
9444
+ break;
9445
+ }
9406
9446
  }
9407
- function FindPanelView({
9408
- controller,
9409
- showResults = true,
9410
- placeholder = "Find"
9411
- }) {
9412
- const state = useSyncExternalStore7(controller.subscribe, controller.getState, controller.getState);
9447
+ var findViewManifest = {
9448
+ id: findManifest.id,
9449
+ version: "1.0.0",
9450
+ title: "Find",
9451
+ category: "edit",
9452
+ layout: { slot: "side" },
9453
+ inputs: [{ id: "view", type: "object", label: "View state", description: "The FindViewModel the runtime derives from the controller on every draw." }],
9454
+ outputs: [{ id: "ui", type: "object", label: "UI intent", description: "{ kind, value?, option?, matchId?, x?, y? } \u2014 applied by the runtime to the controller." }],
9455
+ commands: []
9456
+ };
9457
+ var EMPTY5 = {
9458
+ text: "",
9459
+ hasText: false,
9460
+ placeholder: "Find",
9461
+ caseSensitive: false,
9462
+ wholeWord: false,
9463
+ regex: false,
9464
+ status: "idle",
9465
+ message: null,
9466
+ statusKind: "none",
9467
+ searchingBadge: false,
9468
+ countShown: false,
9469
+ counter: "0/0",
9470
+ hasMatches: false,
9471
+ replaceVisible: false,
9472
+ replaceText: "",
9473
+ canReplace: false,
9474
+ allLabel: "All (0)",
9475
+ replaceLabel: "Replace",
9476
+ showResults: true,
9477
+ idle: true,
9478
+ invalid: false,
9479
+ failed: false,
9480
+ noResults: false,
9481
+ noResultsHint: "",
9482
+ invalidHint: "",
9483
+ failedHint: "",
9484
+ flat: false,
9485
+ grouped: false,
9486
+ rows: [],
9487
+ groups: []
9488
+ };
9489
+ var BEHAVIOURS5 = {
9490
+ "edit/findPanelView": (inputs) => inputs.view ?? EMPTY5
9491
+ };
9492
+ var FIND_RUNTIME_UNITS = ["find/Keys"];
9493
+ var text5 = (b) => ({ component: "text", props: { text: b } });
9494
+ var ui5 = (kind, fields = {}) => ({ emit: "ui", value: { object: { kind: { value: kind }, ...fields } } });
9495
+ var option = (option2, icon, label) => ({
9496
+ component: "chrome/IconButton",
9497
+ props: { label: { value: label }, active: { input: `view.${option2}` }, icon: { node: { component: icon, props: { size: { value: 12 } } } } },
9498
+ on: { onClick: ui5("option", { option: { value: option2 } }) }
9499
+ });
9500
+ var resultRow = {
9501
+ component: "chrome/Row",
9502
+ each: { item: "rows", key: "id" },
9503
+ props: { noIcon: { value: true }, selected: { item: "current" }, meta: { item: "location" }, label: { node: { component: "chrome/Highlight", props: { segments: { item: "segments" } } } } },
9504
+ on: {
9505
+ onClick: ui5("select", { matchId: { item: "id" } }),
9506
+ onContextMenuAt: ui5("contextMenu", { matchId: { item: "id" }, x: { arg: "", index: 0 }, y: { arg: "", index: 1 } })
9507
+ }
9508
+ };
9509
+ var flatRow = { ...resultRow, each: { input: "view.rows", key: "id" } };
9510
+ var emptyState = (when, title, hint) => ({ component: "chrome/EmptyState", when: { input: when }, props: { title: { value: title }, hint } });
9511
+ var FIND_DECLARATION = {
9512
+ format: "xeno.block@1",
9513
+ manifest: findViewManifest,
9514
+ behaviour: "edit/findPanelView",
9515
+ composition: {
9516
+ component: "find/Keys",
9517
+ children: [
9518
+ {
9519
+ component: "chrome/Toolbar",
9520
+ props: {
9521
+ left: { node: { component: "chrome/SearchField", props: { value: { input: "view.text" }, placeholder: { input: "view.placeholder" } }, on: { onChange: ui5("text", { value: { arg: "" } }) } } },
9522
+ right: {
9523
+ node: {
9524
+ component: "chrome/ToolbarGroup",
9525
+ props: { end: { value: true } },
9526
+ children: [option("caseSensitive", "icons/Case", "Match case"), option("wholeWord", "icons/WholeWord", "Whole word"), option("regex", "icons/Regex", "Regular expression")]
9527
+ }
9528
+ }
9529
+ }
9530
+ },
9531
+ {
9532
+ component: "chrome/Toolbar",
9533
+ props: {
9534
+ divided: { value: false },
9535
+ left: {
9536
+ node: {
9537
+ component: "fragment",
9538
+ children: [
9539
+ { component: "chrome/Badge", when: { input: "view.invalid" }, props: { tone: { value: "error" }, title: { input: "view.message" } }, children: [text5({ value: "invalid pattern" })] },
9540
+ { component: "chrome/Badge", when: { input: "view.failed" }, props: { tone: { value: "error" }, title: { input: "view.message" } }, children: [text5({ value: "search failed" })] },
9541
+ { component: "chrome/Badge", when: { input: "view.searchingBadge" }, children: [text5({ value: "searching\u2026" })] },
9542
+ { component: "chrome/Text", when: { input: "view.countShown" }, props: { role: { value: "number" } }, children: [text5({ input: "view.counter" })] }
9543
+ ]
9544
+ }
9545
+ },
9546
+ right: {
9547
+ node: {
9548
+ component: "chrome/ToolbarGroup",
9549
+ props: { end: { value: true } },
9550
+ children: [
9551
+ { component: "chrome/IconButton", props: { label: { value: "Previous match" }, disabled: { not: { input: "view.hasMatches" } }, icon: { node: { component: "icons/Chevron", props: { direction: { value: "up" }, size: { value: 12 } } } } }, on: { onClick: ui5("previous") } },
9552
+ { component: "chrome/IconButton", props: { label: { value: "Next match" }, disabled: { not: { input: "view.hasMatches" } }, icon: { node: { component: "icons/Chevron", props: { direction: { value: "down" }, size: { value: 12 } } } } }, on: { onClick: ui5("next") } },
9553
+ { component: "chrome/TextButton", on: { onClick: ui5("toggleReplace") }, children: [text5({ input: "view.replaceLabel" })] }
9554
+ ]
9555
+ }
9556
+ }
9557
+ }
9558
+ },
9559
+ { component: "chrome/Text", when: { input: "view.invalid" }, props: { role: { value: "caption" }, className: { value: "xeno-find-message" } }, children: [text5({ input: "view.message" })] },
9560
+ {
9561
+ component: "chrome/Toolbar",
9562
+ when: { input: "view.replaceVisible" },
9563
+ props: {
9564
+ left: { node: { component: "chrome/SearchField", props: { value: { input: "view.replaceText" }, placeholder: { value: "Replace with" } }, on: { onChange: ui5("replaceText", { value: { arg: "" } }) } } },
9565
+ right: {
9566
+ node: {
9567
+ component: "chrome/ToolbarGroup",
9568
+ props: { end: { value: true } },
9569
+ children: [
9570
+ { component: "chrome/TextButton", props: { disabled: { not: { input: "view.canReplace" } } }, on: { onClick: ui5("replaceCurrent") }, children: [text5({ value: "Replace" })] },
9571
+ { component: "chrome/TextButton", props: { disabled: { not: { input: "view.canReplace" } } }, on: { onClick: ui5("replaceAll") }, children: [text5({ input: "view.allLabel" })] }
9572
+ ]
9573
+ }
9574
+ }
9575
+ }
9576
+ },
9577
+ {
9578
+ component: "chrome/ScrollArea",
9579
+ when: { input: "view.showResults" },
9580
+ children: [
9581
+ emptyState("view.idle", "Find", { value: "Type to search. Enter goes to the next match." }),
9582
+ emptyState("view.invalid", "Invalid pattern", { input: "view.invalidHint" }),
9583
+ emptyState("view.failed", "Search failed", { input: "view.failedHint" }),
9584
+ emptyState("view.noResults", "No matches", { input: "view.noResultsHint" }),
9585
+ { component: "chrome/RowList", when: { input: "view.flat" }, children: [flatRow] },
9586
+ {
9587
+ component: "fragment",
9588
+ when: { input: "view.grouped" },
9589
+ children: [
9590
+ {
9591
+ component: "chrome/Section",
9592
+ each: { input: "view.groups", key: "id" },
9593
+ props: { title: { item: "label" }, flush: { value: true }, badge: { node: { component: "chrome/Badge", children: [text5({ item: "count" })] } } },
9594
+ children: [{ component: "chrome/RowList", children: [resultRow] }]
9595
+ }
9596
+ ]
9597
+ }
9598
+ ]
9599
+ },
9600
+ { component: "chrome/StatusBar", props: { left: { input: "view.truncatedLabel" }, right: { input: "view.scope" } } }
9601
+ ]
9602
+ }
9603
+ };
9604
+
9605
+ // src/edit/find/react/FindPanelView.tsx
9606
+ import { Fragment as Fragment6, jsx as jsx9, jsxs as jsxs8 } from "react/jsx-runtime";
9607
+ var CaseIcon = ICONS["icons/Case"];
9608
+ var WordIcon = ICONS["icons/WholeWord"];
9609
+ var RegexIcon = ICONS["icons/Regex"];
9610
+ var Chevron = ICONS["icons/Chevron"];
9611
+ function FindKeys({ controller, children }) {
9413
9612
  const onKeyDown = (event) => {
9414
9613
  if (event.key === "Enter") {
9415
9614
  event.preventDefault();
@@ -9420,69 +9619,38 @@ function FindPanelView({
9420
9619
  controller.clear();
9421
9620
  }
9422
9621
  };
9423
- const renderMatch = (match, index) => /* @__PURE__ */ jsx9(
9622
+ return /* @__PURE__ */ jsx9(Column5, { onKeyDown, children });
9623
+ }
9624
+ function findRuntimeComponents(controller) {
9625
+ return {
9626
+ "find/Keys": ({ children }) => /* @__PURE__ */ jsx9(FindKeys, { controller, children })
9627
+ };
9628
+ }
9629
+ function FindPanelView({ controller, showResults, placeholder }) {
9630
+ useSyncExternalStore7(controller.subscribe, controller.getState, controller.getState);
9631
+ const view = findViewState(controller, { showResults, placeholder });
9632
+ const ui6 = (intent) => applyFindUi(controller, intent);
9633
+ const renderRow = (row2) => /* @__PURE__ */ jsx9(
9424
9634
  Row3,
9425
9635
  {
9426
9636
  noIcon: true,
9427
- selected: index === state.index,
9428
- onClick: () => controller.select(match.id),
9429
- onContextMenu: (event) => {
9430
- event.preventDefault();
9431
- controller.requestContextMenu?.(match.id, event.clientX, event.clientY);
9432
- },
9433
- label: /* @__PURE__ */ jsx9("span", { children: highlightSegments(match.snippet ?? "", match.ranges).map((segment, i) => /* @__PURE__ */ jsx9(
9434
- "span",
9435
- {
9436
- style: segment.hit ? { background: "var(--xeno-control)", borderRadius: 2 } : void 0,
9437
- children: segment.text
9438
- },
9439
- i
9440
- )) }),
9441
- meta: match.locationLabel
9637
+ selected: row2.current,
9638
+ meta: row2.location,
9639
+ label: /* @__PURE__ */ jsx9(Highlight, { segments: row2.segments }),
9640
+ onClick: () => ui6({ kind: "select", matchId: row2.id }),
9641
+ onContextMenuAt: (x, y) => ui6({ kind: "contextMenu", matchId: row2.id, x, y })
9442
9642
  },
9443
- match.id
9643
+ row2.id
9444
9644
  );
9445
- let flatIndex = -1;
9446
- return /* @__PURE__ */ jsxs8("div", { style: { display: "flex", flexDirection: "column", height: "100%", minHeight: 0 }, onKeyDown, children: [
9645
+ return /* @__PURE__ */ jsxs8(FindKeys, { controller, children: [
9447
9646
  /* @__PURE__ */ jsx9(
9448
9647
  Toolbar4,
9449
9648
  {
9450
- left: /* @__PURE__ */ jsx9(
9451
- SearchField4,
9452
- {
9453
- value: state.text,
9454
- onChange: (value) => controller.setText(value),
9455
- placeholder
9456
- }
9457
- ),
9649
+ left: /* @__PURE__ */ jsx9(SearchField4, { value: view.text, placeholder: view.placeholder, onChange: (value) => ui6({ kind: "text", value }) }),
9458
9650
  right: /* @__PURE__ */ jsxs8(ToolbarGroup2, { end: true, children: [
9459
- /* @__PURE__ */ jsx9(
9460
- IconButton6,
9461
- {
9462
- label: "Match case",
9463
- active: state.options.caseSensitive,
9464
- onClick: () => controller.setOptions({ caseSensitive: !state.options.caseSensitive }),
9465
- icon: /* @__PURE__ */ jsx9(CaseIcon, {})
9466
- }
9467
- ),
9468
- /* @__PURE__ */ jsx9(
9469
- IconButton6,
9470
- {
9471
- label: "Whole word",
9472
- active: state.options.wholeWord,
9473
- onClick: () => controller.setOptions({ wholeWord: !state.options.wholeWord }),
9474
- icon: /* @__PURE__ */ jsx9(WordIcon, {})
9475
- }
9476
- ),
9477
- /* @__PURE__ */ jsx9(
9478
- IconButton6,
9479
- {
9480
- label: "Regular expression",
9481
- active: state.options.regex,
9482
- onClick: () => controller.setOptions({ regex: !state.options.regex }),
9483
- icon: /* @__PURE__ */ jsx9(RegexIcon, {})
9484
- }
9485
- )
9651
+ /* @__PURE__ */ jsx9(IconButton6, { label: "Match case", active: view.caseSensitive, icon: /* @__PURE__ */ jsx9(CaseIcon, { size: 12 }), onClick: () => ui6({ kind: "option", option: "caseSensitive" }) }),
9652
+ /* @__PURE__ */ jsx9(IconButton6, { label: "Whole word", active: view.wholeWord, icon: /* @__PURE__ */ jsx9(WordIcon, { size: 12 }), onClick: () => ui6({ kind: "option", option: "wholeWord" }) }),
9653
+ /* @__PURE__ */ jsx9(IconButton6, { label: "Regular expression", active: view.regex, icon: /* @__PURE__ */ jsx9(RegexIcon, { size: 12 }), onClick: () => ui6({ kind: "option", option: "regex" }) })
9486
9654
  ] })
9487
9655
  }
9488
9656
  ),
@@ -9490,85 +9658,39 @@ function FindPanelView({
9490
9658
  Toolbar4,
9491
9659
  {
9492
9660
  divided: false,
9493
- left: /* @__PURE__ */ jsx9(
9494
- StatusLine,
9495
- {
9496
- status: state.status,
9497
- message: state.message,
9498
- count: state.count,
9499
- displayIndex: state.displayIndex,
9500
- truncated: state.truncated,
9501
- hasText: state.text !== ""
9502
- }
9503
- ),
9661
+ left: /* @__PURE__ */ jsxs8(Fragment6, { children: [
9662
+ view.invalid ? /* @__PURE__ */ jsx9(Badge5, { tone: "error", title: view.message ?? void 0, children: "invalid pattern" }) : null,
9663
+ view.failed ? /* @__PURE__ */ jsx9(Badge5, { tone: "error", title: view.message ?? void 0, children: "search failed" }) : null,
9664
+ view.searchingBadge ? /* @__PURE__ */ jsx9(Badge5, { children: "searching\u2026" }) : null,
9665
+ view.countShown ? /* @__PURE__ */ jsx9(Text5, { role: "number", children: view.counter }) : null
9666
+ ] }),
9504
9667
  right: /* @__PURE__ */ jsxs8(ToolbarGroup2, { end: true, children: [
9505
- /* @__PURE__ */ jsx9(
9506
- IconButton6,
9507
- {
9508
- label: "Previous match",
9509
- disabled: state.matches.length === 0,
9510
- onClick: () => controller.previous(),
9511
- icon: /* @__PURE__ */ jsx9(UpIcon, {})
9512
- }
9513
- ),
9514
- /* @__PURE__ */ jsx9(
9515
- IconButton6,
9516
- {
9517
- label: "Next match",
9518
- disabled: state.matches.length === 0,
9519
- onClick: () => controller.next(),
9520
- icon: /* @__PURE__ */ jsx9(DownIcon, {})
9521
- }
9522
- ),
9523
- /* @__PURE__ */ jsx9(TextButton3, { onClick: () => controller.setReplaceVisible(!state.replaceVisible), children: state.replaceVisible ? "Hide replace" : "Replace" })
9668
+ /* @__PURE__ */ jsx9(IconButton6, { label: "Previous match", disabled: !view.hasMatches, icon: /* @__PURE__ */ jsx9(Chevron, { direction: "up", size: 12 }), onClick: () => ui6({ kind: "previous" }) }),
9669
+ /* @__PURE__ */ jsx9(IconButton6, { label: "Next match", disabled: !view.hasMatches, icon: /* @__PURE__ */ jsx9(Chevron, { direction: "down", size: 12 }), onClick: () => ui6({ kind: "next" }) }),
9670
+ /* @__PURE__ */ jsx9(TextButton3, { onClick: () => ui6({ kind: "toggleReplace" }), children: view.replaceLabel })
9524
9671
  ] })
9525
9672
  }
9526
9673
  ),
9527
- state.message && state.status === "invalidPattern" ? /* @__PURE__ */ jsx9("div", { style: { padding: "2px 8px 4px", fontSize: 9, opacity: 0.6 }, children: state.message }) : null,
9528
- state.replaceVisible ? /* @__PURE__ */ jsx9(
9674
+ view.invalid ? /* @__PURE__ */ jsx9(Text5, { role: "caption", className: "xeno-find-message", children: view.message }) : null,
9675
+ view.replaceVisible ? /* @__PURE__ */ jsx9(
9529
9676
  Toolbar4,
9530
9677
  {
9531
- left: /* @__PURE__ */ jsx9(
9532
- SearchField4,
9533
- {
9534
- value: state.replaceText,
9535
- onChange: (value) => controller.setReplaceText(value),
9536
- placeholder: "Replace with"
9537
- }
9538
- ),
9678
+ left: /* @__PURE__ */ jsx9(SearchField4, { value: view.replaceText, placeholder: "Replace with", onChange: (value) => ui6({ kind: "replaceText", value }) }),
9539
9679
  right: /* @__PURE__ */ jsxs8(ToolbarGroup2, { end: true, children: [
9540
- /* @__PURE__ */ jsx9(TextButton3, { disabled: !state.canReplace, onClick: () => controller.replaceCurrent(), children: "Replace" }),
9541
- /* @__PURE__ */ jsxs8(TextButton3, { disabled: !state.canReplace, onClick: () => controller.replaceAll(), children: [
9542
- "All (",
9543
- state.matches.length,
9544
- ")"
9545
- ] })
9680
+ /* @__PURE__ */ jsx9(TextButton3, { disabled: !view.canReplace, onClick: () => ui6({ kind: "replaceCurrent" }), children: "Replace" }),
9681
+ /* @__PURE__ */ jsx9(TextButton3, { disabled: !view.canReplace, onClick: () => ui6({ kind: "replaceAll" }), children: view.allLabel })
9546
9682
  ] })
9547
9683
  }
9548
9684
  ) : null,
9549
- showResults ? /* @__PURE__ */ jsx9(ScrollArea4, { children: state.status === "idle" ? /* @__PURE__ */ jsx9(EmptyState5, { title: "Find", hint: "Type to search. Enter goes to the next match." }) : state.status === "invalidPattern" ? /* @__PURE__ */ jsx9(
9550
- EmptyState5,
9551
- {
9552
- title: "Invalid pattern",
9553
- hint: state.message ?? "The expression could not be read. Fix it to search."
9554
- }
9555
- ) : state.status === "failed" ? /* @__PURE__ */ jsx9(EmptyState5, { title: "Search failed", hint: state.message ?? "The host could not complete the search." }) : state.noResults ? /* @__PURE__ */ jsx9(EmptyState5, { title: "No matches", hint: `Nothing in scope matches \u201C${state.text}\u201D.` }) : state.groups.length === 1 && state.groups[0].id === "" ? /* @__PURE__ */ jsx9(RowList3, { children: state.matches.map((m) => renderMatch(m, ++flatIndex)) }) : state.groups.map((group) => /* @__PURE__ */ jsx9(
9556
- Section3,
9557
- {
9558
- title: group.label || "Results",
9559
- flush: true,
9560
- badge: /* @__PURE__ */ jsx9(Badge5, { children: group.matches.length }),
9561
- children: /* @__PURE__ */ jsx9(RowList3, { children: group.matches.map((m) => renderMatch(m, ++flatIndex)) })
9562
- },
9563
- group.id
9564
- )) }) : null,
9565
- /* @__PURE__ */ jsx9(
9566
- StatusBar5,
9567
- {
9568
- left: state.truncated ? `showing first ${state.matches.length}` : void 0,
9569
- right: state.options.scope
9570
- }
9571
- )
9685
+ view.showResults ? /* @__PURE__ */ jsxs8(ScrollArea4, { children: [
9686
+ view.idle ? /* @__PURE__ */ jsx9(EmptyState5, { title: "Find", hint: "Type to search. Enter goes to the next match." }) : null,
9687
+ view.invalid ? /* @__PURE__ */ jsx9(EmptyState5, { title: "Invalid pattern", hint: view.invalidHint }) : null,
9688
+ view.failed ? /* @__PURE__ */ jsx9(EmptyState5, { title: "Search failed", hint: view.failedHint }) : null,
9689
+ view.noResults ? /* @__PURE__ */ jsx9(EmptyState5, { title: "No matches", hint: view.noResultsHint }) : null,
9690
+ view.flat ? /* @__PURE__ */ jsx9(RowList3, { children: view.rows.map(renderRow) }) : null,
9691
+ view.grouped ? view.groups.map((group) => /* @__PURE__ */ jsx9(Section3, { title: group.label, flush: true, badge: /* @__PURE__ */ jsx9(Badge5, { children: group.count }), children: /* @__PURE__ */ jsx9(RowList3, { children: group.rows.map(renderRow) }) }, group.id)) : null
9692
+ ] }) : null,
9693
+ /* @__PURE__ */ jsx9(StatusBar5, { left: view.truncatedLabel, right: view.scope })
9572
9694
  ] });
9573
9695
  }
9574
9696
 
@@ -10223,7 +10345,7 @@ import {
10223
10345
  Toolbar as Toolbar5,
10224
10346
  ToolbarGroup as ToolbarGroup3
10225
10347
  } from "@xenosystem/components/chrome";
10226
- import { Fragment as Fragment6, jsx as jsx10, jsxs as jsxs9 } from "react/jsx-runtime";
10348
+ import { Fragment as Fragment7, jsx as jsx10, jsxs as jsxs9 } from "react/jsx-runtime";
10227
10349
  var ANCHOR_BADGE = {
10228
10350
  live: null,
10229
10351
  stale: {
@@ -10419,7 +10541,7 @@ function CommentsPanelView({
10419
10541
  title: "No comments",
10420
10542
  hint: emptyHint ?? "Select something and add a comment."
10421
10543
  }
10422
- ) : /* @__PURE__ */ jsxs9(Fragment6, { children: [
10544
+ ) : /* @__PURE__ */ jsxs9(Fragment7, { children: [
10423
10545
  open.map((view) => /* @__PURE__ */ jsx10(
10424
10546
  ThreadCard,
10425
10547
  {
@@ -11654,7 +11776,7 @@ var nodegraphManifest = {
11654
11776
  // src/edit/nodegraph/react/NodeGraphPanelView.tsx
11655
11777
  import { useCallback as useCallback7, useEffect as useEffect7, useRef as useRef8, useSyncExternalStore as useSyncExternalStore9 } from "react";
11656
11778
  import { EmptyState as EmptyState7, StatusBar as StatusBar7, Toolbar as Toolbar6, ToolbarGroup as ToolbarGroup4 } from "@xenosystem/components/chrome";
11657
- import { Fragment as Fragment7, jsx as jsx11, jsxs as jsxs10 } from "react/jsx-runtime";
11779
+ import { Fragment as Fragment8, jsx as jsx11, jsxs as jsxs10 } from "react/jsx-runtime";
11658
11780
  var HEADER_H2 = 24;
11659
11781
  var PORT_ROW_H2 = 18;
11660
11782
  function NodeGraphPanelView({ controller }) {
@@ -11877,7 +11999,7 @@ function NodeRect({ node, selected, zoom }) {
11877
11999
  children: node.title
11878
12000
  }
11879
12001
  ),
11880
- node.collapsed ? null : /* @__PURE__ */ jsxs10(Fragment7, { children: [
12002
+ node.collapsed ? null : /* @__PURE__ */ jsxs10(Fragment8, { children: [
11881
12003
  node.inputs.map((port, i) => /* @__PURE__ */ jsx11(
11882
12004
  Port,
11883
12005
  {
@@ -12610,12 +12732,12 @@ var TreeController = class {
12610
12732
  }
12611
12733
  if (event.key.length === 1 && !event.ctrlKey && !event.metaKey && !event.altKey) {
12612
12734
  const fresh = now - this.typeAhead.at > this.typeAheadMs;
12613
- const text5 = (fresh ? "" : this.typeAhead.text) + event.key.toLowerCase();
12614
- this.typeAhead = { text: text5, at: now };
12735
+ const text6 = (fresh ? "" : this.typeAhead.text) + event.key.toLowerCase();
12736
+ this.typeAhead = { text: text6, at: now };
12615
12737
  const from = fresh ? current : current + 1;
12616
12738
  for (let i = 0; i < rows.length; i += 1) {
12617
12739
  const candidate = rows[(from + i) % rows.length];
12618
- if (candidate.node.label.toLowerCase().startsWith(text5)) {
12740
+ if (candidate.node.label.toLowerCase().startsWith(text6)) {
12619
12741
  this.focusedId = candidate.id;
12620
12742
  this.select([candidate.id]);
12621
12743
  return true;
@@ -12641,9 +12763,9 @@ var TreeController = class {
12641
12763
  return true;
12642
12764
  }
12643
12765
  /** Update the rename draft. */
12644
- updateRenameDraft(text5) {
12766
+ updateRenameDraft(text6) {
12645
12767
  if (!this.renaming) return;
12646
- this.renaming = { ...this.renaming, draft: text5 };
12768
+ this.renaming = { ...this.renaming, draft: text6 };
12647
12769
  this.notify();
12648
12770
  }
12649
12771
  /**
@@ -13195,7 +13317,7 @@ import {
13195
13317
  ToolbarGroup as ToolbarGroup5
13196
13318
  } from "@xenosystem/components/chrome";
13197
13319
  import { computeWindow as computeWindow3 } from "@xenosystem/tree-core";
13198
- import { Fragment as Fragment8, jsx as jsx12, jsxs as jsxs11 } from "react/jsx-runtime";
13320
+ import { Fragment as Fragment9, jsx as jsx12, jsxs as jsxs11 } from "react/jsx-runtime";
13199
13321
  function TreePanelView({
13200
13322
  controller,
13201
13323
  rowHeight = 24,
@@ -13412,7 +13534,7 @@ function TreeRowView({
13412
13534
  onPointerUp: () => {
13413
13535
  if (state.drag) controller.endDrag();
13414
13536
  },
13415
- icon: /* @__PURE__ */ jsxs11(Fragment8, { children: [
13537
+ icon: /* @__PURE__ */ jsxs11(Fragment9, { children: [
13416
13538
  twisty,
13417
13539
  /* @__PURE__ */ jsx12(NodeIcon, { icon: node.icon ?? defaultIconFor(node.kind) })
13418
13540
  ] }),
@@ -13442,7 +13564,7 @@ function TreeRowView({
13442
13564
  }
13443
13565
  ) : node.label,
13444
13566
  meta: /* @__PURE__ */ jsx12(ChildStateChip, { row: row2, controller }),
13445
- trailing: /* @__PURE__ */ jsxs11(Fragment8, { children: [
13567
+ trailing: /* @__PURE__ */ jsxs11(Fragment9, { children: [
13446
13568
  columns?.map((columnId) => /* @__PURE__ */ jsx12("span", { style: { opacity: 0.7, fontVariantNumeric: "tabular-nums" }, children: node.columns?.[columnId] ?? "" }, columnId)),
13447
13569
  node.glyphs?.map((glyph) => /* @__PURE__ */ jsx12("span", { title: glyph.title, style: { display: "flex", opacity: 0.7 }, children: /* @__PURE__ */ jsx12(NodeIcon, { icon: glyph.icon }) }, glyph.id)),
13448
13570
  node.badges?.map((badge) => (
@@ -13732,8 +13854,12 @@ export {
13732
13854
  EMPTY_SCHEMA,
13733
13855
  EMPTY_TREE,
13734
13856
  EMPTY_TREE_SOURCE,
13857
+ BEHAVIOURS5 as FIND_BEHAVIOURS,
13858
+ FIND_DECLARATION,
13735
13859
  FIND_PANEL_ID,
13860
+ FIND_RUNTIME_UNITS,
13736
13861
  FindController,
13862
+ FindKeys,
13737
13863
  FindPanelView,
13738
13864
  GENERIC_ICON,
13739
13865
  GraphController,
@@ -13776,6 +13902,7 @@ export {
13776
13902
  anchorStateOf,
13777
13903
  appliedCount,
13778
13904
  applyColorUi,
13905
+ applyFindUi,
13779
13906
  applyHistoryUi,
13780
13907
  applyInspectorUi,
13781
13908
  applyLayersUi,
@@ -13833,7 +13960,10 @@ export {
13833
13960
  findManifest,
13834
13961
  findPanel,
13835
13962
  findPort,
13963
+ findRuntimeComponents,
13836
13964
  findSectionOf,
13965
+ findViewManifest,
13966
+ findViewState,
13837
13967
  fitToBounds,
13838
13968
  fitValueRange,
13839
13969
  flattenVisible,