@pixerate/editor-react 0.72.0 → 0.73.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -35,6 +35,7 @@ __export(src_exports, {
35
35
  BrushOptionsBar: () => BrushOptionsBar,
36
36
  BubbleMenu: () => BubbleMenu,
37
37
  ChartNodeView: () => ChartNodeView,
38
+ ColorProfilePanel: () => ColorProfilePanel,
38
39
  CommandPalette: () => CommandPalette,
39
40
  CommentButton: () => CommentButton,
40
41
  CommentsPanel: () => CommentsPanel,
@@ -3787,8 +3788,8 @@ function useImageEditor(options = {}) {
3787
3788
  }
3788
3789
 
3789
3790
  // src/image-editor/ImageEditor.tsx
3790
- var import_react46 = __toESM(require("react"), 1);
3791
- var import_image_editor14 = require("@pixerate/editor/image-editor");
3791
+ var import_react47 = __toESM(require("react"), 1);
3792
+ var import_image_editor15 = require("@pixerate/editor/image-editor");
3792
3793
 
3793
3794
  // src/image-editor/ControlSlider.tsx
3794
3795
  var import_image_editor2 = require("@pixerate/editor/image-editor");
@@ -4523,6 +4524,17 @@ var LayersPanel = ({ controller, thumbnailSize = 32, psd = true, psdFileName = "
4523
4524
  children: "\u22EF"
4524
4525
  }
4525
4526
  ),
4527
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
4528
+ "select",
4529
+ {
4530
+ "aria-label": "Bits per channel",
4531
+ title: "Image \u203A Mode: bits per channel",
4532
+ className: "rounded bg-slate-800 px-1 py-0.5 text-[11px] text-slate-200",
4533
+ value: controller.bitDepth,
4534
+ onChange: (e) => attempt(() => controller.setBitDepth(Number(e.target.value))),
4535
+ children: import_image_editor7.BIT_DEPTH_OPTIONS.map((o) => /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("option", { value: o.depth, title: o.title, children: o.label }, o.depth))
4536
+ }
4537
+ ),
4526
4538
  psd && /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(import_jsx_runtime22.Fragment, { children: [
4527
4539
  /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("button", { type: "button", className: iconButton, onClick: () => fileInput.current?.click(), children: "Open PSD\u2026" }),
4528
4540
  /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("button", { type: "button", className: iconButton, onClick: () => psdTask(async () => (await (0, import_image_editor7.downloadPsd)(controller, psdFileName)).warnings), children: "Export PSD" }),
@@ -5025,10 +5037,90 @@ var BrushOptionsBar = ({ controller, className }) => {
5025
5037
  ] });
5026
5038
  };
5027
5039
 
5028
- // src/image-editor/SelectionOptionsBar.tsx
5040
+ // src/image-editor/ColorProfilePanel.tsx
5029
5041
  var import_react41 = require("react");
5030
5042
  var import_image_editor9 = require("@pixerate/editor/image-editor");
5031
5043
  var import_jsx_runtime24 = require("react/jsx-runtime");
5044
+ var chip2 = "px-2 py-1 rounded text-[11px] bg-slate-800 text-slate-300 hover:text-white";
5045
+ var select = "rounded bg-slate-800 px-1 py-0.5 text-[11px] text-slate-200";
5046
+ var ColorProfilePanel = ({ controller, className }) => {
5047
+ const [, setTick] = (0, import_react41.useState)(0);
5048
+ (0, import_react41.useEffect)(() => controller.subscribe(() => setTick((n) => n + 1)), [controller]);
5049
+ const [target, setTarget] = (0, import_react41.useState)("display-p3");
5050
+ const [intent, setIntent] = (0, import_react41.useState)("relative");
5051
+ const [bpc, setBpc] = (0, import_react41.useState)(true);
5052
+ const [error, setError] = (0, import_react41.useState)(null);
5053
+ const view = (0, import_image_editor9.colorPanelView)(controller);
5054
+ const attempt = (fn) => {
5055
+ try {
5056
+ setError(null);
5057
+ fn();
5058
+ } catch (err) {
5059
+ setError(err instanceof Error ? err.message : String(err));
5060
+ }
5061
+ };
5062
+ const proofWith = (patch) => {
5063
+ const cur = view.proof;
5064
+ const id = patch.id ?? cur?.id ?? "coated-cmyk";
5065
+ attempt(
5066
+ () => controller.setProofSetup({
5067
+ profile: id,
5068
+ intent: patch.intent ?? cur?.intent ?? "relative",
5069
+ simulatePaper: patch.simulatePaper ?? cur?.simulatePaper ?? false,
5070
+ gamutWarning: patch.gamutWarning ?? cur?.gamutWarning ?? false
5071
+ })
5072
+ );
5073
+ };
5074
+ return /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { className: `flex flex-col gap-2 text-xs text-slate-200 ${className ?? ""}`, "data-testid": "color-profile-panel", children: [
5075
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { className: "flex items-center gap-2", children: [
5076
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("span", { className: "text-slate-400", children: "Profile" }),
5077
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("span", { "data-testid": "color-profile-name", children: view.profileName })
5078
+ ] }),
5079
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { className: "flex flex-wrap items-center gap-1", role: "group", "aria-label": "Assign or convert", children: [
5080
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("select", { "aria-label": "Target profile", className: select, value: target, onChange: (e) => setTarget(e.target.value), children: import_image_editor9.WORKING_SPACE_OPTIONS.map((o) => /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("option", { value: o.id, children: o.label }, o.id)) }),
5081
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("select", { "aria-label": "Rendering intent", className: select, value: intent, onChange: (e) => setIntent(e.target.value), children: import_image_editor9.INTENT_OPTIONS.map((o) => /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("option", { value: o.id, title: o.title, children: o.label }, o.id)) }),
5082
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("label", { className: "flex items-center gap-1", children: [
5083
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("input", { type: "checkbox", "aria-label": "Black point compensation", checked: bpc, onChange: (e) => setBpc(e.target.checked), className: "accent-indigo-500" }),
5084
+ "BPC"
5085
+ ] }),
5086
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("button", { type: "button", className: chip2, title: "Edit \u203A Assign Profile: keep the numbers", onClick: () => attempt(() => controller.assignProfile(target)), children: "Assign" }),
5087
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("button", { type: "button", className: chip2, title: "Edit \u203A Convert to Profile: keep the look", onClick: () => attempt(() => controller.convertToProfile(target, { intent, bpc })), children: "Convert" })
5088
+ ] }),
5089
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { className: "flex flex-wrap items-center gap-1", role: "group", "aria-label": "Proof setup", children: [
5090
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("span", { className: "text-slate-400", children: "Proof" }),
5091
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(
5092
+ "select",
5093
+ {
5094
+ "aria-label": "Proof profile",
5095
+ className: select,
5096
+ value: view.proof?.id ?? "",
5097
+ onChange: (e) => e.target.value ? proofWith({ id: e.target.value }) : attempt(() => controller.setProofSetup(null)),
5098
+ children: [
5099
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("option", { value: "", children: "Off" }),
5100
+ import_image_editor9.PROOF_PROFILE_OPTIONS.map((o) => /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("option", { value: o.id, children: o.label }, o.id))
5101
+ ]
5102
+ }
5103
+ ),
5104
+ view.proof && /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(import_jsx_runtime24.Fragment, { children: [
5105
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("select", { "aria-label": "Proof intent", className: select, value: view.proof.intent, onChange: (e) => proofWith({ intent: e.target.value }), children: import_image_editor9.INTENT_OPTIONS.map((o) => /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("option", { value: o.id, children: o.label }, o.id)) }),
5106
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("label", { className: "flex items-center gap-1", children: [
5107
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("input", { type: "checkbox", "aria-label": "Simulate paper colour", checked: view.proof.simulatePaper, onChange: (e) => proofWith({ simulatePaper: e.target.checked }), className: "accent-indigo-500" }),
5108
+ "Paper"
5109
+ ] }),
5110
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("label", { className: "flex items-center gap-1", children: [
5111
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("input", { type: "checkbox", "aria-label": "Gamut warning", checked: view.proof.gamutWarning, onChange: (e) => proofWith({ gamutWarning: e.target.checked }), className: "accent-indigo-500" }),
5112
+ "Gamut warning"
5113
+ ] })
5114
+ ] })
5115
+ ] }),
5116
+ error && /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("p", { role: "alert", className: "text-rose-400", children: error })
5117
+ ] });
5118
+ };
5119
+
5120
+ // src/image-editor/SelectionOptionsBar.tsx
5121
+ var import_react42 = require("react");
5122
+ var import_image_editor10 = require("@pixerate/editor/image-editor");
5123
+ var import_jsx_runtime25 = require("react/jsx-runtime");
5032
5124
  var MODIFY_OPS = [
5033
5125
  { op: "grow", label: "Grow" },
5034
5126
  { op: "shrink", label: "Shrink" },
@@ -5045,20 +5137,20 @@ var SelectionOptionsBar = ({
5045
5137
  quickMask,
5046
5138
  className = ""
5047
5139
  }) => {
5048
- const [radius, setRadius] = (0, import_react41.useState)(2);
5140
+ const [radius, setRadius] = (0, import_react42.useState)(2);
5049
5141
  const set = (patch) => onOptionsChange({ ...options, ...patch });
5050
5142
  const sel = selection === void 0 ? controller.getSelection() : selection;
5051
5143
  const qm = quickMask ?? Boolean(controller.getState().quickMask);
5052
- return /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { "data-testid": "selection-options-bar", className: `flex flex-col gap-3 text-xs ${className}`, children: [
5053
- /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { role: "group", "aria-label": "Selection tool", className: "flex flex-wrap gap-1", children: import_image_editor9.SELECTION_TOOLS.map((t) => /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("button", { type: "button", "aria-pressed": options.tool === t.id, className: btn(options.tool === t.id), onClick: () => set({ tool: t.id }), children: t.label }, t.id)) }),
5054
- /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { role: "group", "aria-label": "Selection mode", className: "flex flex-wrap gap-1", children: import_image_editor9.SELECTION_MODES.map((m) => /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("button", { type: "button", "aria-pressed": options.mode === m, className: btn(options.mode === m), onClick: () => set({ mode: m }), children: import_image_editor9.SELECTION_MODE_LABELS[m] }, m)) }),
5055
- options.tool === "wand" && /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { className: "flex flex-col gap-2", children: [
5056
- /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("label", { className: "flex flex-col gap-1", children: [
5057
- /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("span", { className: "flex justify-between text-slate-400", children: [
5058
- /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("span", { children: "Tolerance" }),
5059
- /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("span", { className: "font-mono", children: options.tolerance })
5144
+ return /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { "data-testid": "selection-options-bar", className: `flex flex-col gap-3 text-xs ${className}`, children: [
5145
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("div", { role: "group", "aria-label": "Selection tool", className: "flex flex-wrap gap-1", children: import_image_editor10.SELECTION_TOOLS.map((t) => /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("button", { type: "button", "aria-pressed": options.tool === t.id, className: btn(options.tool === t.id), onClick: () => set({ tool: t.id }), children: t.label }, t.id)) }),
5146
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("div", { role: "group", "aria-label": "Selection mode", className: "flex flex-wrap gap-1", children: import_image_editor10.SELECTION_MODES.map((m) => /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("button", { type: "button", "aria-pressed": options.mode === m, className: btn(options.mode === m), onClick: () => set({ mode: m }), children: import_image_editor10.SELECTION_MODE_LABELS[m] }, m)) }),
5147
+ options.tool === "wand" && /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { className: "flex flex-col gap-2", children: [
5148
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("label", { className: "flex flex-col gap-1", children: [
5149
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("span", { className: "flex justify-between text-slate-400", children: [
5150
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("span", { children: "Tolerance" }),
5151
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("span", { className: "font-mono", children: options.tolerance })
5060
5152
  ] }),
5061
- /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
5153
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
5062
5154
  "input",
5063
5155
  {
5064
5156
  type: "range",
@@ -5072,17 +5164,17 @@ var SelectionOptionsBar = ({
5072
5164
  }
5073
5165
  )
5074
5166
  ] }),
5075
- /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("label", { className: "flex items-center gap-2 text-slate-300", children: [
5076
- /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("input", { type: "checkbox", checked: options.contiguous, onChange: (e) => set({ contiguous: e.target.checked }) }),
5167
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("label", { className: "flex items-center gap-2 text-slate-300", children: [
5168
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("input", { type: "checkbox", checked: options.contiguous, onChange: (e) => set({ contiguous: e.target.checked }) }),
5077
5169
  "Contiguous"
5078
5170
  ] }),
5079
- /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("label", { className: "flex items-center gap-2 text-slate-300", children: [
5080
- /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("input", { type: "checkbox", checked: options.sampleMerged, onChange: (e) => set({ sampleMerged: e.target.checked }) }),
5171
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("label", { className: "flex items-center gap-2 text-slate-300", children: [
5172
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("input", { type: "checkbox", checked: options.sampleMerged, onChange: (e) => set({ sampleMerged: e.target.checked }) }),
5081
5173
  "Sample adjusted image"
5082
5174
  ] }),
5083
- /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("label", { className: "flex items-center gap-2 text-slate-300", children: [
5175
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("label", { className: "flex items-center gap-2 text-slate-300", children: [
5084
5176
  "Sample",
5085
- /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(
5177
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(
5086
5178
  "select",
5087
5179
  {
5088
5180
  "aria-label": "Sample from",
@@ -5090,27 +5182,27 @@ var SelectionOptionsBar = ({
5090
5182
  onChange: (e) => set({ sample: e.target.value }),
5091
5183
  className: "bg-slate-800 border border-slate-700 rounded px-1 py-0.5",
5092
5184
  children: [
5093
- /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("option", { value: "composite", children: "All layers" }),
5094
- /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("option", { value: "active-layer", children: "Active layer" })
5185
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("option", { value: "composite", children: "All layers" }),
5186
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("option", { value: "active-layer", children: "Active layer" })
5095
5187
  ]
5096
5188
  }
5097
5189
  )
5098
5190
  ] })
5099
5191
  ] }),
5100
- /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("label", { className: "flex items-center gap-2 text-slate-300", children: [
5101
- /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("input", { type: "checkbox", checked: options.antiAlias, onChange: (e) => set({ antiAlias: e.target.checked }) }),
5192
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("label", { className: "flex items-center gap-2 text-slate-300", children: [
5193
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("input", { type: "checkbox", checked: options.antiAlias, onChange: (e) => set({ antiAlias: e.target.checked }) }),
5102
5194
  "Anti-alias"
5103
5195
  ] }),
5104
- /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { className: "flex flex-wrap gap-1", children: [
5105
- /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("button", { type: "button", className: btn(false), onClick: () => controller.selectAll(), children: "Select All" }),
5106
- /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("button", { type: "button", className: btn(false), disabled: !sel, onClick: () => controller.deselect(), children: "Deselect" }),
5107
- /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("button", { type: "button", className: btn(false), onClick: () => controller.invertSelection(), children: "Inverse" }),
5108
- /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("button", { type: "button", "aria-pressed": qm, className: btn(qm), onClick: () => controller.setQuickMask(!qm), children: "Quick Mask" })
5196
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { className: "flex flex-wrap gap-1", children: [
5197
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("button", { type: "button", className: btn(false), onClick: () => controller.selectAll(), children: "Select All" }),
5198
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("button", { type: "button", className: btn(false), disabled: !sel, onClick: () => controller.deselect(), children: "Deselect" }),
5199
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("button", { type: "button", className: btn(false), onClick: () => controller.invertSelection(), children: "Inverse" }),
5200
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("button", { type: "button", "aria-pressed": qm, className: btn(qm), onClick: () => controller.setQuickMask(!qm), children: "Quick Mask" })
5109
5201
  ] }),
5110
- /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { className: "flex flex-wrap items-center gap-1", children: [
5111
- /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("label", { className: "flex items-center gap-1 text-slate-400", children: [
5202
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { className: "flex flex-wrap items-center gap-1", children: [
5203
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("label", { className: "flex items-center gap-1 text-slate-400", children: [
5112
5204
  "Radius",
5113
- /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
5205
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
5114
5206
  "input",
5115
5207
  {
5116
5208
  type: "number",
@@ -5124,24 +5216,24 @@ var SelectionOptionsBar = ({
5124
5216
  }
5125
5217
  )
5126
5218
  ] }),
5127
- MODIFY_OPS.map(({ op, label }) => /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("button", { type: "button", className: btn(false), disabled: !sel, onClick: () => controller.modifySelection(op, radius), children: label }, op))
5219
+ MODIFY_OPS.map(({ op, label }) => /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("button", { type: "button", className: btn(false), disabled: !sel, onClick: () => controller.modifySelection(op, radius), children: label }, op))
5128
5220
  ] }),
5129
- /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("p", { "data-testid": "selection-status", className: "text-slate-400", children: (0, import_image_editor9.describeSelection)(sel) })
5221
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("p", { "data-testid": "selection-status", className: "text-slate-400", children: (0, import_image_editor10.describeSelection)(sel) })
5130
5222
  ] });
5131
5223
  };
5132
5224
 
5133
5225
  // src/image-editor/RefineEdgePanel.tsx
5134
- var import_react42 = require("react");
5135
- var import_image_editor10 = require("@pixerate/editor/image-editor");
5136
- var import_jsx_runtime25 = require("react/jsx-runtime");
5226
+ var import_react43 = require("react");
5227
+ var import_image_editor11 = require("@pixerate/editor/image-editor");
5228
+ var import_jsx_runtime26 = require("react/jsx-runtime");
5137
5229
  var DEFAULT_PARAMS = { radius: 8, smartRadius: false, smooth: 0, feather: 0, contrast: 0, shiftEdge: 0 };
5138
5230
  var button2 = "px-2 py-1 rounded-md border border-slate-800 bg-slate-950 text-[11px] text-slate-200 hover:text-white disabled:opacity-40";
5139
5231
  var RefineEdgePanel = ({ controller, selection, layers, className = "" }) => {
5140
- const [params, setParams] = (0, import_react42.useState)(DEFAULT_PARAMS);
5141
- const [busy, setBusy] = (0, import_react42.useState)(false);
5142
- const [error, setError] = (0, import_react42.useState)(null);
5143
- const [layerId, setLayerId] = (0, import_react42.useState)("");
5144
- const [newKind, setNewKind] = (0, import_react42.useState)("hueSaturation");
5232
+ const [params, setParams] = (0, import_react43.useState)(DEFAULT_PARAMS);
5233
+ const [busy, setBusy] = (0, import_react43.useState)(false);
5234
+ const [error, setError] = (0, import_react43.useState)(null);
5235
+ const [layerId, setLayerId] = (0, import_react43.useState)("");
5236
+ const [newKind, setNewKind] = (0, import_react43.useState)("hueSaturation");
5145
5237
  const sel = selection === void 0 ? controller.getSelection() : selection;
5146
5238
  const list = layers ?? controller.getAdjustmentLayers();
5147
5239
  const target = list.find((l) => l.id === layerId) ?? list[list.length - 1];
@@ -5156,17 +5248,17 @@ var RefineEdgePanel = ({ controller, selection, layers, className = "" }) => {
5156
5248
  setBusy(false);
5157
5249
  }
5158
5250
  };
5159
- return /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { "data-testid": "refine-edge-panel", className: `flex flex-col gap-3 text-xs ${className}`, children: [
5160
- /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("span", { className: "font-semibold text-slate-200 uppercase tracking-wider text-[11px]", children: "Refine Edge" }),
5161
- import_image_editor10.REFINE_EDGE_CONTROLS.map((c) => /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("label", { className: "flex flex-col gap-1", children: [
5162
- /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("span", { className: "flex justify-between text-slate-400", children: [
5163
- /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("span", { children: c.label }),
5164
- /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("span", { className: "font-mono", children: [
5251
+ return /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("div", { "data-testid": "refine-edge-panel", className: `flex flex-col gap-3 text-xs ${className}`, children: [
5252
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("span", { className: "font-semibold text-slate-200 uppercase tracking-wider text-[11px]", children: "Refine Edge" }),
5253
+ import_image_editor11.REFINE_EDGE_CONTROLS.map((c) => /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("label", { className: "flex flex-col gap-1", children: [
5254
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("span", { className: "flex justify-between text-slate-400", children: [
5255
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("span", { children: c.label }),
5256
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("span", { className: "font-mono", children: [
5165
5257
  params[c.id],
5166
5258
  c.unit
5167
5259
  ] })
5168
5260
  ] }),
5169
- /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
5261
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
5170
5262
  "input",
5171
5263
  {
5172
5264
  type: "range",
@@ -5180,67 +5272,67 @@ var RefineEdgePanel = ({ controller, selection, layers, className = "" }) => {
5180
5272
  }
5181
5273
  )
5182
5274
  ] }, c.id)),
5183
- /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("label", { className: "flex items-center gap-2 text-slate-300", children: [
5184
- /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("input", { type: "checkbox", checked: params.smartRadius, onChange: (e) => setParams({ ...params, smartRadius: e.target.checked }) }),
5275
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("label", { className: "flex items-center gap-2 text-slate-300", children: [
5276
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("input", { type: "checkbox", checked: params.smartRadius, onChange: (e) => setParams({ ...params, smartRadius: e.target.checked }) }),
5185
5277
  "Smart Radius"
5186
5278
  ] }),
5187
- /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { className: "flex gap-1", children: [
5188
- /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("button", { type: "button", className: button2, disabled: !sel || busy, onClick: refine, children: "Refine Edge" }),
5189
- /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("button", { type: "button", className: button2, onClick: () => setParams(DEFAULT_PARAMS), children: "Reset" })
5279
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("div", { className: "flex gap-1", children: [
5280
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("button", { type: "button", className: button2, disabled: !sel || busy, onClick: refine, children: "Refine Edge" }),
5281
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("button", { type: "button", className: button2, onClick: () => setParams(DEFAULT_PARAMS), children: "Reset" })
5190
5282
  ] }),
5191
- error && /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("p", { role: "alert", className: "text-rose-400", children: error }),
5192
- /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("span", { className: "font-semibold text-slate-200 uppercase tracking-wider text-[11px] mt-2", children: "Layer Mask" }),
5193
- /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { className: "flex gap-1 items-center", children: [
5194
- /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
5283
+ error && /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("p", { role: "alert", className: "text-rose-400", children: error }),
5284
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("span", { className: "font-semibold text-slate-200 uppercase tracking-wider text-[11px] mt-2", children: "Layer Mask" }),
5285
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("div", { className: "flex gap-1 items-center", children: [
5286
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
5195
5287
  "select",
5196
5288
  {
5197
5289
  "aria-label": "New masked layer kind",
5198
5290
  value: newKind,
5199
5291
  onChange: (e) => setNewKind(e.target.value),
5200
5292
  className: "flex-1 bg-slate-950 border border-slate-800 rounded px-1 py-1 text-slate-200",
5201
- children: import_image_editor10.ADJUSTMENT_KINDS.map((k) => /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("option", { value: k.kind, children: k.label }, k.kind))
5293
+ children: import_image_editor11.ADJUSTMENT_KINDS.map((k) => /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("option", { value: k.kind, children: k.label }, k.kind))
5202
5294
  }
5203
5295
  ),
5204
- /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
5296
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
5205
5297
  "button",
5206
5298
  {
5207
5299
  type: "button",
5208
5300
  className: button2,
5209
5301
  disabled: !sel,
5210
- onClick: () => sel && setLayerId(controller.addAdjustmentLayer({ kind: newKind, mask: (0, import_image_editor10.layerMaskFromSelection)(sel) })),
5302
+ onClick: () => sel && setLayerId(controller.addAdjustmentLayer({ kind: newKind, mask: (0, import_image_editor11.layerMaskFromSelection)(sel) })),
5211
5303
  children: "New Masked Layer"
5212
5304
  }
5213
5305
  )
5214
5306
  ] }),
5215
- list.length > 0 && target && /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { className: "flex flex-col gap-2", children: [
5216
- /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
5307
+ list.length > 0 && target && /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("div", { className: "flex flex-col gap-2", children: [
5308
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
5217
5309
  "select",
5218
5310
  {
5219
5311
  "aria-label": "Mask layer",
5220
5312
  value: target.id,
5221
5313
  onChange: (e) => setLayerId(e.target.value),
5222
5314
  className: "bg-slate-950 border border-slate-800 rounded px-1 py-1 text-slate-200",
5223
- children: list.map((l) => /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("option", { value: l.id, children: [
5224
- l.name || (0, import_image_editor10.adjustmentKindLabel)(l.kind),
5315
+ children: list.map((l) => /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("option", { value: l.id, children: [
5316
+ l.name || (0, import_image_editor11.adjustmentKindLabel)(l.kind),
5225
5317
  l.mask ? " (masked)" : ""
5226
5318
  ] }, l.id))
5227
5319
  }
5228
5320
  ),
5229
- /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { className: "flex flex-wrap gap-1", children: [
5230
- /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("button", { type: "button", className: button2, disabled: !sel, onClick: () => controller.applySelectionAsLayerMask(target.id), children: "Mask with Selection" }),
5231
- /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("button", { type: "button", className: button2, disabled: !target.mask, onClick: () => controller.selectionFromLayerMask(target.id), children: "Load as Selection" }),
5232
- /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("button", { type: "button", className: button2, disabled: !target.mask, onClick: () => controller.setAdjustmentLayerMask(target.id, null), children: "Remove Mask" })
5321
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("div", { className: "flex flex-wrap gap-1", children: [
5322
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("button", { type: "button", className: button2, disabled: !sel, onClick: () => controller.applySelectionAsLayerMask(target.id), children: "Mask with Selection" }),
5323
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("button", { type: "button", className: button2, disabled: !target.mask, onClick: () => controller.selectionFromLayerMask(target.id), children: "Load as Selection" }),
5324
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("button", { type: "button", className: button2, disabled: !target.mask, onClick: () => controller.setAdjustmentLayerMask(target.id, null), children: "Remove Mask" })
5233
5325
  ] }),
5234
- target.mask && /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(import_jsx_runtime25.Fragment, { children: [
5235
- /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("label", { className: "flex flex-col gap-1", children: [
5236
- /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("span", { className: "flex justify-between text-slate-400", children: [
5237
- /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("span", { children: "Density" }),
5238
- /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("span", { className: "font-mono", children: [
5326
+ target.mask && /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(import_jsx_runtime26.Fragment, { children: [
5327
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("label", { className: "flex flex-col gap-1", children: [
5328
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("span", { className: "flex justify-between text-slate-400", children: [
5329
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("span", { children: "Density" }),
5330
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("span", { className: "font-mono", children: [
5239
5331
  Math.round((target.mask.density ?? 1) * 100),
5240
5332
  "%"
5241
5333
  ] })
5242
5334
  ] }),
5243
- /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
5335
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
5244
5336
  "input",
5245
5337
  {
5246
5338
  type: "range",
@@ -5254,15 +5346,15 @@ var RefineEdgePanel = ({ controller, selection, layers, className = "" }) => {
5254
5346
  }
5255
5347
  )
5256
5348
  ] }),
5257
- /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("label", { className: "flex flex-col gap-1", children: [
5258
- /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("span", { className: "flex justify-between text-slate-400", children: [
5259
- /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("span", { children: "Mask Feather" }),
5260
- /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("span", { className: "font-mono", children: [
5349
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("label", { className: "flex flex-col gap-1", children: [
5350
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("span", { className: "flex justify-between text-slate-400", children: [
5351
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("span", { children: "Mask Feather" }),
5352
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("span", { className: "font-mono", children: [
5261
5353
  target.mask.feather ?? 0,
5262
5354
  "px"
5263
5355
  ] })
5264
5356
  ] }),
5265
- /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
5357
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
5266
5358
  "input",
5267
5359
  {
5268
5360
  type: "range",
@@ -5282,14 +5374,14 @@ var RefineEdgePanel = ({ controller, selection, layers, className = "" }) => {
5282
5374
  };
5283
5375
 
5284
5376
  // src/image-editor/FreeTransformOptionsBar.tsx
5285
- var import_react43 = require("react");
5286
- var import_image_editor11 = require("@pixerate/editor/image-editor");
5287
- var import_jsx_runtime26 = require("react/jsx-runtime");
5288
- var chip2 = (on) => `px-2 py-1 rounded text-[11px] ${on ? "bg-indigo-600 text-white" : "bg-slate-800 text-slate-300 hover:text-white"}`;
5377
+ var import_react44 = require("react");
5378
+ var import_image_editor12 = require("@pixerate/editor/image-editor");
5379
+ var import_jsx_runtime27 = require("react/jsx-runtime");
5380
+ var chip3 = (on) => `px-2 py-1 rounded text-[11px] ${on ? "bg-indigo-600 text-white" : "bg-slate-800 text-slate-300 hover:text-white"}`;
5289
5381
  var round = (v, unit) => unit === "px" ? Math.round(v * 10) / 10 : Math.round(v * 100) / 100;
5290
5382
  var FreeTransformOptionsBar = ({ tool, className }) => {
5291
- const [, setTick] = (0, import_react43.useState)(0);
5292
- (0, import_react43.useEffect)(() => tool.subscribe(() => setTick((n) => n + 1)), [tool]);
5383
+ const [, setTick] = (0, import_react44.useState)(0);
5384
+ (0, import_react44.useEffect)(() => tool.subscribe(() => setTick((n) => n + 1)), [tool]);
5293
5385
  const bar = tool.bar();
5294
5386
  if (!tool.active || !bar) return null;
5295
5387
  const warp = tool.warpBar();
@@ -5301,17 +5393,17 @@ var FreeTransformOptionsBar = ({ tool, className }) => {
5301
5393
  const v = Number(raw);
5302
5394
  if (raw.trim() !== "" && Number.isFinite(v) && Math.abs(v - bar[field]) > 1e-9) tool.setField(field, v);
5303
5395
  };
5304
- return /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("div", { className: `flex flex-wrap items-center gap-2 text-xs text-slate-200 ${className ?? ""}`, "data-testid": "free-transform-options", role: "toolbar", "aria-label": "Free Transform options", children: [
5305
- /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("div", { className: "flex gap-1", role: "group", "aria-label": "Transform mode", children: import_image_editor11.FREE_TRANSFORM_MODE_OPTIONS.map((m) => /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("button", { type: "button", title: m.title, "aria-pressed": tool.mode === m.id, className: chip2(tool.mode === m.id), onClick: () => tool.setMode(m.id), children: m.label }, m.id)) }),
5306
- /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("div", { className: "grid grid-cols-3 gap-px", role: "group", "aria-label": "Reference point", children: import_image_editor11.TRANSFORM_ANCHORS.map((a) => /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("button", { type: "button", "aria-label": `Reference point ${a}`, title: `Reference point: ${a}`, className: "h-2.5 w-2.5 rounded-sm bg-slate-700 hover:bg-indigo-500", onClick: () => tool.setReference(a) }, a)) }),
5307
- tool.mode === "warp" && /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("div", { className: "flex flex-wrap items-center gap-2", role: "group", "aria-label": "Warp options", children: [
5308
- /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("label", { className: "flex items-center gap-1", children: [
5309
- /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("span", { className: "text-slate-400", children: "Warp" }),
5310
- /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("select", { "aria-label": "Warp style", value: warp.style, onChange: (e) => tool.setWarp({ style: e.target.value }), className: "rounded border border-slate-700 bg-slate-900 px-1 py-0.5", children: import_image_editor11.WARP_STYLE_OPTIONS.map((o) => /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("option", { value: o.id, children: o.label }, o.id)) })
5396
+ return /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("div", { className: `flex flex-wrap items-center gap-2 text-xs text-slate-200 ${className ?? ""}`, "data-testid": "free-transform-options", role: "toolbar", "aria-label": "Free Transform options", children: [
5397
+ /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("div", { className: "flex gap-1", role: "group", "aria-label": "Transform mode", children: import_image_editor12.FREE_TRANSFORM_MODE_OPTIONS.map((m) => /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("button", { type: "button", title: m.title, "aria-pressed": tool.mode === m.id, className: chip3(tool.mode === m.id), onClick: () => tool.setMode(m.id), children: m.label }, m.id)) }),
5398
+ /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("div", { className: "grid grid-cols-3 gap-px", role: "group", "aria-label": "Reference point", children: import_image_editor12.TRANSFORM_ANCHORS.map((a) => /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("button", { type: "button", "aria-label": `Reference point ${a}`, title: `Reference point: ${a}`, className: "h-2.5 w-2.5 rounded-sm bg-slate-700 hover:bg-indigo-500", onClick: () => tool.setReference(a) }, a)) }),
5399
+ tool.mode === "warp" && /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("div", { className: "flex flex-wrap items-center gap-2", role: "group", "aria-label": "Warp options", children: [
5400
+ /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("label", { className: "flex items-center gap-1", children: [
5401
+ /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("span", { className: "text-slate-400", children: "Warp" }),
5402
+ /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("select", { "aria-label": "Warp style", value: warp.style, onChange: (e) => tool.setWarp({ style: e.target.value }), className: "rounded border border-slate-700 bg-slate-900 px-1 py-0.5", children: import_image_editor12.WARP_STYLE_OPTIONS.map((o) => /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("option", { value: o.id, children: o.label }, o.id)) })
5311
5403
  ] }),
5312
- ["bend", "horizontal", "vertical"].map((k) => /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("label", { className: "flex items-center gap-1", children: [
5313
- /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("span", { className: "text-slate-400", children: k === "bend" ? "Bend" : k === "horizontal" ? "H" : "V" }),
5314
- /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
5404
+ ["bend", "horizontal", "vertical"].map((k) => /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("label", { className: "flex items-center gap-1", children: [
5405
+ /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("span", { className: "text-slate-400", children: k === "bend" ? "Bend" : k === "horizontal" ? "H" : "V" }),
5406
+ /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
5315
5407
  "input",
5316
5408
  {
5317
5409
  type: "number",
@@ -5332,40 +5424,40 @@ var FreeTransformOptionsBar = ({ tool, className }) => {
5332
5424
  },
5333
5425
  `${k}:${warp[k]}`
5334
5426
  ),
5335
- /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("span", { className: "text-slate-500", children: "%" })
5427
+ /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("span", { className: "text-slate-500", children: "%" })
5336
5428
  ] }, k)),
5337
- /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
5429
+ /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
5338
5430
  "button",
5339
5431
  {
5340
5432
  type: "button",
5341
5433
  title: "Bend along the vertical axis",
5342
5434
  "aria-pressed": warp.orientation === "vertical",
5343
5435
  disabled: warp.style === "custom",
5344
- className: chip2(warp.orientation === "vertical"),
5436
+ className: chip3(warp.orientation === "vertical"),
5345
5437
  onClick: () => tool.setWarp({ orientation: warp.orientation === "vertical" ? "horizontal" : "vertical" }),
5346
5438
  children: "Vertical"
5347
5439
  }
5348
5440
  ),
5349
- /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("label", { className: "flex items-center gap-1", children: [
5350
- /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("span", { className: "text-slate-400", children: "Grid" }),
5351
- /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
5441
+ /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("label", { className: "flex items-center gap-1", children: [
5442
+ /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("span", { className: "text-slate-400", children: "Grid" }),
5443
+ /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
5352
5444
  "select",
5353
5445
  {
5354
5446
  "aria-label": "Warp grid",
5355
- value: import_image_editor11.WARP_GRID_OPTIONS.find((g) => g.columns === warp.columns && g.rows === warp.rows)?.id ?? "1x1",
5447
+ value: import_image_editor12.WARP_GRID_OPTIONS.find((g) => g.columns === warp.columns && g.rows === warp.rows)?.id ?? "1x1",
5356
5448
  onChange: (e) => {
5357
- const g = import_image_editor11.WARP_GRID_OPTIONS.find((o) => o.id === e.target.value);
5449
+ const g = import_image_editor12.WARP_GRID_OPTIONS.find((o) => o.id === e.target.value);
5358
5450
  tool.setWarp({ columns: g.columns, rows: g.rows });
5359
5451
  },
5360
5452
  className: "rounded border border-slate-700 bg-slate-900 px-1 py-0.5",
5361
- children: import_image_editor11.WARP_GRID_OPTIONS.map((g) => /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("option", { value: g.id, children: g.label }, g.id))
5453
+ children: import_image_editor12.WARP_GRID_OPTIONS.map((g) => /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("option", { value: g.id, children: g.label }, g.id))
5362
5454
  }
5363
5455
  )
5364
5456
  ] })
5365
5457
  ] }),
5366
- tool.mode !== "warp" && import_image_editor11.FREE_TRANSFORM_FIELDS.map((f) => /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("label", { className: "flex items-center gap-1", title: f.title, children: [
5367
- /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("span", { className: "text-slate-400", children: f.label }),
5368
- /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
5458
+ tool.mode !== "warp" && import_image_editor12.FREE_TRANSFORM_FIELDS.map((f) => /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("label", { className: "flex items-center gap-1", title: f.title, children: [
5459
+ /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("span", { className: "text-slate-400", children: f.label }),
5460
+ /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
5369
5461
  "input",
5370
5462
  {
5371
5463
  type: "number",
@@ -5385,14 +5477,14 @@ var FreeTransformOptionsBar = ({ tool, className }) => {
5385
5477
  },
5386
5478
  `${f.id}:${round(bar[f.id], f.unit)}`
5387
5479
  ),
5388
- /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("span", { className: "text-slate-500", children: f.unit }),
5389
- f.id === "scaleX" && /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
5480
+ /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("span", { className: "text-slate-500", children: f.unit }),
5481
+ f.id === "scaleX" && /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
5390
5482
  "button",
5391
5483
  {
5392
5484
  type: "button",
5393
5485
  "aria-label": "Keep width and height proportional",
5394
5486
  "aria-pressed": tool.proportional,
5395
- className: chip2(tool.proportional),
5487
+ className: chip3(tool.proportional),
5396
5488
  onClick: () => {
5397
5489
  tool.proportional = !tool.proportional;
5398
5490
  setTick((n) => n + 1);
@@ -5401,34 +5493,34 @@ var FreeTransformOptionsBar = ({ tool, className }) => {
5401
5493
  }
5402
5494
  )
5403
5495
  ] }, f.id)),
5404
- /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("label", { className: "flex items-center gap-1", children: [
5405
- /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("span", { className: "text-slate-400", children: "Interpolation" }),
5406
- /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
5496
+ /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("label", { className: "flex items-center gap-1", children: [
5497
+ /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("span", { className: "text-slate-400", children: "Interpolation" }),
5498
+ /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
5407
5499
  "select",
5408
5500
  {
5409
5501
  "aria-label": "Interpolation",
5410
5502
  value: tool.interpolation,
5411
5503
  onChange: (e) => tool.setInterpolation(e.target.value),
5412
5504
  className: "rounded border border-slate-700 bg-slate-900 px-1 py-0.5",
5413
- children: import_image_editor11.INTERPOLATIONS.map((i) => /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("option", { value: i, children: i[0].toUpperCase() + i.slice(1) }, i))
5505
+ children: import_image_editor12.INTERPOLATIONS.map((i) => /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("option", { value: i, children: i[0].toUpperCase() + i.slice(1) }, i))
5414
5506
  }
5415
5507
  )
5416
5508
  ] }),
5417
- /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("button", { type: "button", title: "Commit (Enter)", className: "px-2 py-1 rounded bg-emerald-600 text-white hover:bg-emerald-500", onClick: () => tool.commit(), children: "Commit" }),
5418
- /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("button", { type: "button", title: "Cancel (Esc)", className: chip2(false), onClick: () => tool.cancel(), children: "Cancel" }),
5419
- tool.error && /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("span", { role: "alert", className: "text-rose-400", children: tool.error })
5509
+ /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("button", { type: "button", title: "Commit (Enter)", className: "px-2 py-1 rounded bg-emerald-600 text-white hover:bg-emerald-500", onClick: () => tool.commit(), children: "Commit" }),
5510
+ /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("button", { type: "button", title: "Cancel (Esc)", className: chip3(false), onClick: () => tool.cancel(), children: "Cancel" }),
5511
+ tool.error && /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("span", { role: "alert", className: "text-rose-400", children: tool.error })
5420
5512
  ] });
5421
5513
  };
5422
5514
 
5423
5515
  // src/image-editor/ShapeOptionsBar.tsx
5424
- var import_react44 = require("react");
5425
- var import_image_editor12 = require("@pixerate/editor/image-editor");
5426
- var import_jsx_runtime27 = require("react/jsx-runtime");
5427
- var chip3 = (on) => `px-2 py-1 rounded text-[11px] ${on ? "bg-indigo-600 text-white" : "bg-slate-800 text-slate-300 hover:text-white"}`;
5516
+ var import_react45 = require("react");
5517
+ var import_image_editor13 = require("@pixerate/editor/image-editor");
5518
+ var import_jsx_runtime28 = require("react/jsx-runtime");
5519
+ var chip4 = (on) => `px-2 py-1 rounded text-[11px] ${on ? "bg-indigo-600 text-white" : "bg-slate-800 text-slate-300 hover:text-white"}`;
5428
5520
  var ShapeOptionsBar = ({ controller, options, onChange, className }) => {
5429
- const [, setTick] = (0, import_react44.useState)(0);
5430
- (0, import_react44.useEffect)(() => controller.subscribe(() => setTick((n) => n + 1)), [controller]);
5431
- const [error, setError] = (0, import_react44.useState)(null);
5521
+ const [, setTick] = (0, import_react45.useState)(0);
5522
+ (0, import_react45.useEffect)(() => controller.subscribe(() => setTick((n) => n + 1)), [controller]);
5523
+ const [error, setError] = (0, import_react45.useState)(null);
5432
5524
  const active = controller.getActiveLayer();
5433
5525
  const shapeId = active?.type === "shape" ? active.id : null;
5434
5526
  const set = (change) => {
@@ -5436,19 +5528,19 @@ var ShapeOptionsBar = ({ controller, options, onChange, className }) => {
5436
5528
  if (!shapeId) return;
5437
5529
  try {
5438
5530
  setError(null);
5439
- (0, import_image_editor12.applyShapeOptions)(controller, shapeId, change);
5531
+ (0, import_image_editor13.applyShapeOptions)(controller, shapeId, change);
5440
5532
  } catch (e) {
5441
5533
  setError(e instanceof Error ? e.message : String(e));
5442
5534
  }
5443
5535
  };
5444
5536
  const num = (v, min, max) => Math.max(min, Math.min(max, Number(v) || min));
5445
- return /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("div", { className: `flex flex-col gap-2 text-xs text-slate-200 ${className ?? ""}`, "data-testid": "shape-options", children: [
5446
- /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("div", { className: "flex flex-wrap gap-1", role: "toolbar", "aria-label": "Shape kind", children: import_image_editor12.LIVE_SHAPE_KINDS.map((k) => /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("button", { type: "button", "aria-pressed": options.kind === k, className: chip3(options.kind === k), onClick: () => onChange({ ...options, kind: k }), children: import_image_editor12.SHAPE_KIND_LABELS[k] }, k)) }),
5447
- /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("div", { className: "flex flex-wrap items-center gap-3", children: [
5448
- /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("label", { className: "flex items-center gap-1", children: [
5449
- /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("input", { type: "checkbox", "aria-label": "Fill", checked: options.fill !== null, onChange: (e) => set({ fill: e.target.checked ? "#4f46e5" : null }) }),
5537
+ return /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("div", { className: `flex flex-col gap-2 text-xs text-slate-200 ${className ?? ""}`, "data-testid": "shape-options", children: [
5538
+ /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("div", { className: "flex flex-wrap gap-1", role: "toolbar", "aria-label": "Shape kind", children: import_image_editor13.LIVE_SHAPE_KINDS.map((k) => /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("button", { type: "button", "aria-pressed": options.kind === k, className: chip4(options.kind === k), onClick: () => onChange({ ...options, kind: k }), children: import_image_editor13.SHAPE_KIND_LABELS[k] }, k)) }),
5539
+ /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("div", { className: "flex flex-wrap items-center gap-3", children: [
5540
+ /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("label", { className: "flex items-center gap-1", children: [
5541
+ /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("input", { type: "checkbox", "aria-label": "Fill", checked: options.fill !== null, onChange: (e) => set({ fill: e.target.checked ? "#4f46e5" : null }) }),
5450
5542
  "Fill",
5451
- /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
5543
+ /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
5452
5544
  "input",
5453
5545
  {
5454
5546
  type: "color",
@@ -5460,10 +5552,10 @@ var ShapeOptionsBar = ({ controller, options, onChange, className }) => {
5460
5552
  }
5461
5553
  )
5462
5554
  ] }),
5463
- /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("label", { className: "flex items-center gap-1", children: [
5464
- /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("input", { type: "checkbox", "aria-label": "Stroke", checked: options.stroke !== null, onChange: (e) => set({ stroke: e.target.checked ? "#000000" : null }) }),
5555
+ /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("label", { className: "flex items-center gap-1", children: [
5556
+ /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("input", { type: "checkbox", "aria-label": "Stroke", checked: options.stroke !== null, onChange: (e) => set({ stroke: e.target.checked ? "#000000" : null }) }),
5465
5557
  "Stroke",
5466
- /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
5558
+ /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
5467
5559
  "input",
5468
5560
  {
5469
5561
  type: "color",
@@ -5475,9 +5567,9 @@ var ShapeOptionsBar = ({ controller, options, onChange, className }) => {
5475
5567
  }
5476
5568
  )
5477
5569
  ] }),
5478
- /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("label", { className: "flex items-center gap-1", children: [
5570
+ /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("label", { className: "flex items-center gap-1", children: [
5479
5571
  "Width",
5480
- /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
5572
+ /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
5481
5573
  "input",
5482
5574
  {
5483
5575
  type: "number",
@@ -5491,23 +5583,23 @@ var ShapeOptionsBar = ({ controller, options, onChange, className }) => {
5491
5583
  )
5492
5584
  ] })
5493
5585
  ] }),
5494
- /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("div", { className: "flex flex-wrap items-center gap-3", children: [
5495
- options.kind === "rect" && /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("label", { className: "flex items-center gap-1", children: [
5586
+ /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("div", { className: "flex flex-wrap items-center gap-3", children: [
5587
+ options.kind === "rect" && /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("label", { className: "flex items-center gap-1", children: [
5496
5588
  "Radius",
5497
- /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("input", { type: "number", "aria-label": "Corner radius", min: 0, max: 1e3, value: options.radius, onChange: (e) => set({ radius: num(e.target.value, 0, 1e3) }), className: "w-14 rounded border border-slate-700 bg-slate-950 px-1 py-0.5" })
5589
+ /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("input", { type: "number", "aria-label": "Corner radius", min: 0, max: 1e3, value: options.radius, onChange: (e) => set({ radius: num(e.target.value, 0, 1e3) }), className: "w-14 rounded border border-slate-700 bg-slate-950 px-1 py-0.5" })
5498
5590
  ] }),
5499
- options.kind === "polygon" && /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("label", { className: "flex items-center gap-1", children: [
5591
+ options.kind === "polygon" && /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("label", { className: "flex items-center gap-1", children: [
5500
5592
  "Sides",
5501
- /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("input", { type: "number", "aria-label": "Sides", min: 3, max: 100, value: options.sides, onChange: (e) => set({ sides: num(e.target.value, 3, 100) }), className: "w-14 rounded border border-slate-700 bg-slate-950 px-1 py-0.5" })
5593
+ /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("input", { type: "number", "aria-label": "Sides", min: 3, max: 100, value: options.sides, onChange: (e) => set({ sides: num(e.target.value, 3, 100) }), className: "w-14 rounded border border-slate-700 bg-slate-950 px-1 py-0.5" })
5502
5594
  ] }),
5503
- options.kind === "star" && /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)(import_jsx_runtime27.Fragment, { children: [
5504
- /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("label", { className: "flex items-center gap-1", children: [
5595
+ options.kind === "star" && /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)(import_jsx_runtime28.Fragment, { children: [
5596
+ /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("label", { className: "flex items-center gap-1", children: [
5505
5597
  "Points",
5506
- /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("input", { type: "number", "aria-label": "Points", min: 3, max: 100, value: options.points, onChange: (e) => set({ points: num(e.target.value, 3, 100) }), className: "w-14 rounded border border-slate-700 bg-slate-950 px-1 py-0.5" })
5598
+ /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("input", { type: "number", "aria-label": "Points", min: 3, max: 100, value: options.points, onChange: (e) => set({ points: num(e.target.value, 3, 100) }), className: "w-14 rounded border border-slate-700 bg-slate-950 px-1 py-0.5" })
5507
5599
  ] }),
5508
- /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("label", { className: "flex items-center gap-1", children: [
5600
+ /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("label", { className: "flex items-center gap-1", children: [
5509
5601
  "Inner",
5510
- /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
5602
+ /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
5511
5603
  "input",
5512
5604
  {
5513
5605
  type: "range",
@@ -5522,33 +5614,33 @@ var ShapeOptionsBar = ({ controller, options, onChange, className }) => {
5522
5614
  )
5523
5615
  ] })
5524
5616
  ] }),
5525
- options.kind === "line" && /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)(import_jsx_runtime27.Fragment, { children: [
5526
- /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("label", { className: "flex items-center gap-1", children: [
5617
+ options.kind === "line" && /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)(import_jsx_runtime28.Fragment, { children: [
5618
+ /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("label", { className: "flex items-center gap-1", children: [
5527
5619
  "Weight",
5528
- /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("input", { type: "number", "aria-label": "Line weight", min: 1, max: 200, value: options.weight, onChange: (e) => set({ weight: num(e.target.value, 1, 200) }), className: "w-14 rounded border border-slate-700 bg-slate-950 px-1 py-0.5" })
5620
+ /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("input", { type: "number", "aria-label": "Line weight", min: 1, max: 200, value: options.weight, onChange: (e) => set({ weight: num(e.target.value, 1, 200) }), className: "w-14 rounded border border-slate-700 bg-slate-950 px-1 py-0.5" })
5529
5621
  ] }),
5530
- /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("label", { className: "flex items-center gap-1", children: [
5531
- /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("input", { type: "checkbox", "aria-label": "Arrowhead", checked: options.arrow, onChange: (e) => set({ arrow: e.target.checked }) }),
5622
+ /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("label", { className: "flex items-center gap-1", children: [
5623
+ /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("input", { type: "checkbox", "aria-label": "Arrowhead", checked: options.arrow, onChange: (e) => set({ arrow: e.target.checked }) }),
5532
5624
  "Arrowhead"
5533
5625
  ] })
5534
5626
  ] })
5535
5627
  ] }),
5536
- /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("p", { className: "text-[10px] text-slate-500", children: "Drag on the image to draw. Shift: square, circle or 45\xB0 line. Alt: from the centre." }),
5537
- error && /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("p", { role: "alert", className: "text-rose-400", children: error })
5628
+ /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("p", { className: "text-[10px] text-slate-500", children: "Drag on the image to draw. Shift: square, circle or 45\xB0 line. Alt: from the centre." }),
5629
+ error && /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("p", { role: "alert", className: "text-rose-400", children: error })
5538
5630
  ] });
5539
5631
  };
5540
5632
 
5541
5633
  // src/image-editor/TypeOptionsBar.tsx
5542
- var import_react45 = require("react");
5543
- var import_image_editor13 = require("@pixerate/editor/image-editor");
5544
- var import_jsx_runtime28 = require("react/jsx-runtime");
5545
- var chip4 = (on) => `px-2 py-1 rounded text-[11px] ${on ? "bg-indigo-600 text-white" : "bg-slate-800 text-slate-300 hover:text-white"}`;
5634
+ var import_react46 = require("react");
5635
+ var import_image_editor14 = require("@pixerate/editor/image-editor");
5636
+ var import_jsx_runtime29 = require("react/jsx-runtime");
5637
+ var chip5 = (on) => `px-2 py-1 rounded text-[11px] ${on ? "bg-indigo-600 text-white" : "bg-slate-800 text-slate-300 hover:text-white"}`;
5546
5638
  var ALIGN_LABELS = { left: "Left", center: "Centre", right: "Right", justify: "Justify" };
5547
5639
  var TypeOptionsBar = ({ controller, options, onChange, session, className }) => {
5548
- const [, setTick] = (0, import_react45.useState)(0);
5549
- (0, import_react45.useEffect)(() => controller.subscribe(() => setTick((n) => n + 1)), [controller]);
5550
- (0, import_react45.useEffect)(() => session?.subscribe(() => setTick((n) => n + 1)), [session]);
5551
- const [error, setError] = (0, import_react45.useState)(null);
5640
+ const [, setTick] = (0, import_react46.useState)(0);
5641
+ (0, import_react46.useEffect)(() => controller.subscribe(() => setTick((n) => n + 1)), [controller]);
5642
+ (0, import_react46.useEffect)(() => session?.subscribe(() => setTick((n) => n + 1)), [session]);
5643
+ const [error, setError] = (0, import_react46.useState)(null);
5552
5644
  const active = controller.getActiveLayer();
5553
5645
  const typeId = !session && active?.type === "type" ? active.id : null;
5554
5646
  const here = session?.alive ? session.styleHere() : {};
@@ -5580,11 +5672,11 @@ var TypeOptionsBar = ({ controller, options, onChange, session, className }) =>
5580
5672
  setError(e instanceof Error ? e.message : String(e));
5581
5673
  }
5582
5674
  };
5583
- return /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("div", { className: `flex flex-col gap-2 text-xs text-slate-200 ${className ?? ""}`, "data-testid": "type-options", children: [
5584
- /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("div", { className: "flex flex-wrap items-center gap-2", children: [
5585
- /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("label", { className: "flex items-center gap-1", children: [
5675
+ return /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("div", { className: `flex flex-col gap-2 text-xs text-slate-200 ${className ?? ""}`, "data-testid": "type-options", children: [
5676
+ /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("div", { className: "flex flex-wrap items-center gap-2", children: [
5677
+ /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("label", { className: "flex items-center gap-1", children: [
5586
5678
  "Font",
5587
- /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
5679
+ /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
5588
5680
  "input",
5589
5681
  {
5590
5682
  list: "pixerate-type-fonts",
@@ -5594,11 +5686,11 @@ var TypeOptionsBar = ({ controller, options, onChange, session, className }) =>
5594
5686
  className: "w-32 rounded border border-slate-700 bg-slate-950 px-1 py-0.5"
5595
5687
  }
5596
5688
  ),
5597
- /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("datalist", { id: "pixerate-type-fonts", children: fonts.map((f) => /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("option", { value: f }, f)) })
5689
+ /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("datalist", { id: "pixerate-type-fonts", children: fonts.map((f) => /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("option", { value: f }, f)) })
5598
5690
  ] }),
5599
- /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("label", { className: "flex items-center gap-1", children: [
5691
+ /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("label", { className: "flex items-center gap-1", children: [
5600
5692
  "Size",
5601
- /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
5693
+ /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
5602
5694
  "input",
5603
5695
  {
5604
5696
  type: "number",
@@ -5611,24 +5703,24 @@ var TypeOptionsBar = ({ controller, options, onChange, session, className }) =>
5611
5703
  }
5612
5704
  )
5613
5705
  ] }),
5614
- /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("button", { type: "button", "aria-pressed": shown.fontWeight >= 600, className: `${chip4(shown.fontWeight >= 600)} font-bold`, onClick: () => style({ fontWeight: shown.fontWeight >= 600 ? 400 : 700 }), children: "B" }),
5615
- /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("button", { type: "button", "aria-pressed": shown.italic, className: `${chip4(shown.italic)} italic`, onClick: () => style({ italic: !shown.italic }), children: "I" }),
5616
- /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("input", { type: "color", "aria-label": "Text colour", value: shown.color, onChange: (e) => style({ color: e.target.value }), className: "h-6 w-8 rounded border border-slate-700 bg-transparent" })
5706
+ /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("button", { type: "button", "aria-pressed": shown.fontWeight >= 600, className: `${chip5(shown.fontWeight >= 600)} font-bold`, onClick: () => style({ fontWeight: shown.fontWeight >= 600 ? 400 : 700 }), children: "B" }),
5707
+ /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("button", { type: "button", "aria-pressed": shown.italic, className: `${chip5(shown.italic)} italic`, onClick: () => style({ italic: !shown.italic }), children: "I" }),
5708
+ /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("input", { type: "color", "aria-label": "Text colour", value: shown.color, onChange: (e) => style({ color: e.target.value }), className: "h-6 w-8 rounded border border-slate-700 bg-transparent" })
5617
5709
  ] }),
5618
- /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("div", { className: "flex gap-1", role: "toolbar", "aria-label": "Alignment", children: import_image_editor13.TEXT_ALIGNS.map((a) => /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("button", { type: "button", "aria-pressed": options.align === a, className: chip4(options.align === a), onClick: () => style({ align: a }), children: ALIGN_LABELS[a] }, a)) }),
5619
- /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("p", { className: "text-[10px] text-slate-500", children: "Click to type point text, drag for a paragraph box, click text to edit it. Esc finishes." }),
5620
- missing.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("p", { role: "status", className: "text-amber-400", "data-testid": "type-missing-fonts", children: [
5710
+ /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("div", { className: "flex gap-1", role: "toolbar", "aria-label": "Alignment", children: import_image_editor14.TEXT_ALIGNS.map((a) => /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("button", { type: "button", "aria-pressed": options.align === a, className: chip5(options.align === a), onClick: () => style({ align: a }), children: ALIGN_LABELS[a] }, a)) }),
5711
+ /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("p", { className: "text-[10px] text-slate-500", children: "Click to type point text, drag for a paragraph box, click text to edit it. Esc finishes." }),
5712
+ missing.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("p", { role: "status", className: "text-amber-400", "data-testid": "type-missing-fonts", children: [
5621
5713
  "Missing ",
5622
5714
  missing.length === 1 ? "font" : "fonts",
5623
5715
  ": ",
5624
5716
  missing.join(", ")
5625
5717
  ] }),
5626
- error && /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("p", { role: "alert", className: "text-rose-400", children: error })
5718
+ error && /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("p", { role: "alert", className: "text-rose-400", children: error })
5627
5719
  ] });
5628
5720
  };
5629
5721
 
5630
5722
  // src/image-editor/ImageEditor.tsx
5631
- var import_jsx_runtime29 = require("react/jsx-runtime");
5723
+ var import_jsx_runtime30 = require("react/jsx-runtime");
5632
5724
  var ImageEditor = ({
5633
5725
  editor: externalEditor,
5634
5726
  src,
@@ -5643,65 +5735,65 @@ var ImageEditor = ({
5643
5735
  const internalEditor = useImageEditor({ image: src });
5644
5736
  const editor = externalEditor || internalEditor;
5645
5737
  const { state, controller } = editor;
5646
- const legacyProcess = (0, import_image_editor14.normalizeProcessVersion)(state.adjustments.process) < import_image_editor14.LATEST_PROCESS_VERSION;
5647
- const canvasRef = (0, import_react46.useRef)(null);
5648
- const containerRef = (0, import_react46.useRef)(null);
5649
- const [activeTab, setActiveTab] = (0, import_react46.useState)("crop");
5650
- const [activeCropRatio, setActiveCropRatio] = (0, import_react46.useState)(null);
5651
- const [selectionOptions, setSelectionOptions] = (0, import_react46.useState)(import_image_editor14.DEFAULT_SELECTION_TOOL_OPTIONS);
5652
- const selectionOptionsRef = (0, import_react46.useRef)(selectionOptions);
5738
+ const legacyProcess = (0, import_image_editor15.normalizeProcessVersion)(state.adjustments.process) < import_image_editor15.LATEST_PROCESS_VERSION;
5739
+ const canvasRef = (0, import_react47.useRef)(null);
5740
+ const containerRef = (0, import_react47.useRef)(null);
5741
+ const [activeTab, setActiveTab] = (0, import_react47.useState)("crop");
5742
+ const [activeCropRatio, setActiveCropRatio] = (0, import_react47.useState)(null);
5743
+ const [selectionOptions, setSelectionOptions] = (0, import_react47.useState)(import_image_editor15.DEFAULT_SELECTION_TOOL_OPTIONS);
5744
+ const selectionOptionsRef = (0, import_react47.useRef)(selectionOptions);
5653
5745
  selectionOptionsRef.current = selectionOptions;
5654
- const selectionGestureRef = (0, import_react46.useRef)(null);
5746
+ const selectionGestureRef = (0, import_react47.useRef)(null);
5655
5747
  if (!selectionGestureRef.current || selectionGestureRef.current.controller !== controller) {
5656
- selectionGestureRef.current = new import_image_editor14.SelectionGesture(controller, () => selectionOptionsRef.current);
5748
+ selectionGestureRef.current = new import_image_editor15.SelectionGesture(controller, () => selectionOptionsRef.current);
5657
5749
  }
5658
- const selectionDraftRef = (0, import_react46.useRef)(null);
5659
- const [selectionError, setSelectionError] = (0, import_react46.useState)(null);
5660
- const paintGestureRef = (0, import_react46.useRef)(null);
5661
- const paintControllerRef = (0, import_react46.useRef)(controller);
5750
+ const selectionDraftRef = (0, import_react47.useRef)(null);
5751
+ const [selectionError, setSelectionError] = (0, import_react47.useState)(null);
5752
+ const paintGestureRef = (0, import_react47.useRef)(null);
5753
+ const paintControllerRef = (0, import_react47.useRef)(controller);
5662
5754
  if (!paintGestureRef.current || paintControllerRef.current !== controller) {
5663
- paintGestureRef.current = new import_image_editor14.PaintGesture(controller);
5755
+ paintGestureRef.current = new import_image_editor15.PaintGesture(controller);
5664
5756
  paintControllerRef.current = controller;
5665
5757
  }
5666
- const brushCursorRef = (0, import_react46.useRef)(null);
5667
- const [paintError, setPaintError] = (0, import_react46.useState)(null);
5668
- const transformToolRef = (0, import_react46.useRef)(null);
5669
- const transformControllerRef = (0, import_react46.useRef)(controller);
5758
+ const brushCursorRef = (0, import_react47.useRef)(null);
5759
+ const [paintError, setPaintError] = (0, import_react47.useState)(null);
5760
+ const transformToolRef = (0, import_react47.useRef)(null);
5761
+ const transformControllerRef = (0, import_react47.useRef)(controller);
5670
5762
  if (!transformToolRef.current || transformControllerRef.current !== controller) {
5671
5763
  transformToolRef.current?.cancel();
5672
- transformToolRef.current = new import_image_editor14.FreeTransformTool(controller, {
5764
+ transformToolRef.current = new import_image_editor15.FreeTransformTool(controller, {
5673
5765
  schedule: (run) => typeof requestAnimationFrame !== "undefined" ? requestAnimationFrame(run) : run()
5674
5766
  });
5675
5767
  transformControllerRef.current = controller;
5676
5768
  }
5677
5769
  const transformTool = transformToolRef.current;
5678
- const [, setTransformTick] = (0, import_react46.useState)(0);
5679
- const [transformCursor, setTransformCursor] = (0, import_react46.useState)("default");
5680
- const [shapeOptions, setShapeOptions] = (0, import_react46.useState)(import_image_editor14.DEFAULT_SHAPE_TOOL_OPTIONS);
5681
- const shapeOptionsRef = (0, import_react46.useRef)(shapeOptions);
5770
+ const [, setTransformTick] = (0, import_react47.useState)(0);
5771
+ const [transformCursor, setTransformCursor] = (0, import_react47.useState)("default");
5772
+ const [shapeOptions, setShapeOptions] = (0, import_react47.useState)(import_image_editor15.DEFAULT_SHAPE_TOOL_OPTIONS);
5773
+ const shapeOptionsRef = (0, import_react47.useRef)(shapeOptions);
5682
5774
  shapeOptionsRef.current = shapeOptions;
5683
- const [typeOptions, setTypeOptions] = (0, import_react46.useState)(import_image_editor14.DEFAULT_TYPE_TOOL_OPTIONS);
5684
- const typeOptionsRef = (0, import_react46.useRef)(typeOptions);
5775
+ const [typeOptions, setTypeOptions] = (0, import_react47.useState)(import_image_editor15.DEFAULT_TYPE_TOOL_OPTIONS);
5776
+ const typeOptionsRef = (0, import_react47.useRef)(typeOptions);
5685
5777
  typeOptionsRef.current = typeOptions;
5686
- const shapeGestureRef = (0, import_react46.useRef)(null);
5687
- const typeToolRef = (0, import_react46.useRef)(null);
5688
- const shapeTypeControllerRef = (0, import_react46.useRef)(controller);
5778
+ const shapeGestureRef = (0, import_react47.useRef)(null);
5779
+ const typeToolRef = (0, import_react47.useRef)(null);
5780
+ const shapeTypeControllerRef = (0, import_react47.useRef)(controller);
5689
5781
  if (!shapeGestureRef.current || !typeToolRef.current || shapeTypeControllerRef.current !== controller) {
5690
5782
  typeToolRef.current?.finish();
5691
- shapeGestureRef.current = new import_image_editor14.ShapeDrawGesture(controller, () => shapeOptionsRef.current);
5692
- typeToolRef.current = new import_image_editor14.TypeToolGesture(controller, () => typeOptionsRef.current);
5783
+ shapeGestureRef.current = new import_image_editor15.ShapeDrawGesture(controller, () => shapeOptionsRef.current);
5784
+ typeToolRef.current = new import_image_editor15.TypeToolGesture(controller, () => typeOptionsRef.current);
5693
5785
  shapeTypeControllerRef.current = controller;
5694
5786
  }
5695
- const typeInputRef = (0, import_react46.useRef)(null);
5696
- const [typeSession, setTypeSession] = (0, import_react46.useState)(typeToolRef.current.session);
5697
- const [shapeTypeError, setShapeTypeError] = (0, import_react46.useState)(null);
5698
- const [inpaintPrompt, setInpaintPrompt] = (0, import_react46.useState)("");
5699
- const [inpaintMaskMode, setInpaintMaskMode] = (0, import_react46.useState)("annotations");
5700
- const [isRemovingBg, setIsRemovingBg] = (0, import_react46.useState)(false);
5701
- const [isInpainting, setIsInpainting] = (0, import_react46.useState)(false);
5702
- const [aiError, setAiError] = (0, import_react46.useState)(null);
5703
- const [aiSuccess, setAiSuccess] = (0, import_react46.useState)(null);
5704
- const [aiTarget, setAiTarget] = (0, import_react46.useState)("auto");
5787
+ const typeInputRef = (0, import_react47.useRef)(null);
5788
+ const [typeSession, setTypeSession] = (0, import_react47.useState)(typeToolRef.current.session);
5789
+ const [shapeTypeError, setShapeTypeError] = (0, import_react47.useState)(null);
5790
+ const [inpaintPrompt, setInpaintPrompt] = (0, import_react47.useState)("");
5791
+ const [inpaintMaskMode, setInpaintMaskMode] = (0, import_react47.useState)("annotations");
5792
+ const [isRemovingBg, setIsRemovingBg] = (0, import_react47.useState)(false);
5793
+ const [isInpainting, setIsInpainting] = (0, import_react47.useState)(false);
5794
+ const [aiError, setAiError] = (0, import_react47.useState)(null);
5795
+ const [aiSuccess, setAiSuccess] = (0, import_react47.useState)(null);
5796
+ const [aiTarget, setAiTarget] = (0, import_react47.useState)("auto");
5705
5797
  const aiOptions = aiTarget === "auto" ? {} : { target: aiTarget };
5706
5798
  const effectiveOnInpaint = onInpaint || aiHooks?.onInpaint;
5707
5799
  const effectiveOnRemoveBg = onRemoveBackground || aiHooks?.onRemoveBackground;
@@ -5764,18 +5856,18 @@ var ImageEditor = ({
5764
5856
  setIsInpainting(false);
5765
5857
  }
5766
5858
  };
5767
- const [activeColor, setActiveColor] = (0, import_react46.useState)("#ef4444");
5768
- const [strokeWidth, setStrokeWidth] = (0, import_react46.useState)(3);
5769
- const [fontSize, setFontSize] = (0, import_react46.useState)(24);
5770
- const [textInput, setTextInput] = (0, import_react46.useState)("");
5771
- const draftAnnotationRef = (0, import_react46.useRef)(null);
5772
- const draftCropRef = (0, import_react46.useRef)(null);
5773
- const cropDragInfoRef = (0, import_react46.useRef)(null);
5774
- const annotationDragInfoRef = (0, import_react46.useRef)(null);
5775
- const isDrawingRef = (0, import_react46.useRef)(false);
5776
- const currentPathRef = (0, import_react46.useRef)([]);
5777
- const dragStartPointRef = (0, import_react46.useRef)(null);
5778
- const renderCanvas = (0, import_react46.useCallback)(
5859
+ const [activeColor, setActiveColor] = (0, import_react47.useState)("#ef4444");
5860
+ const [strokeWidth, setStrokeWidth] = (0, import_react47.useState)(3);
5861
+ const [fontSize, setFontSize] = (0, import_react47.useState)(24);
5862
+ const [textInput, setTextInput] = (0, import_react47.useState)("");
5863
+ const draftAnnotationRef = (0, import_react47.useRef)(null);
5864
+ const draftCropRef = (0, import_react47.useRef)(null);
5865
+ const cropDragInfoRef = (0, import_react47.useRef)(null);
5866
+ const annotationDragInfoRef = (0, import_react47.useRef)(null);
5867
+ const isDrawingRef = (0, import_react47.useRef)(false);
5868
+ const currentPathRef = (0, import_react47.useRef)([]);
5869
+ const dragStartPointRef = (0, import_react47.useRef)(null);
5870
+ const renderCanvas = (0, import_react47.useCallback)(
5779
5871
  async (draftAnnotation, draftCrop) => {
5780
5872
  const canvas = canvasRef.current;
5781
5873
  const container = containerRef.current;
@@ -5798,8 +5890,8 @@ var ImageEditor = ({
5798
5890
  },
5799
5891
  [controller, activeTab, transformTool]
5800
5892
  );
5801
- (0, import_react46.useEffect)(() => typeSession?.subscribe(() => void renderCanvas()), [typeSession, renderCanvas]);
5802
- (0, import_react46.useEffect)(() => {
5893
+ (0, import_react47.useEffect)(() => typeSession?.subscribe(() => void renderCanvas()), [typeSession, renderCanvas]);
5894
+ (0, import_react47.useEffect)(() => {
5803
5895
  if (activeTab === "annotate" && state.activeTool === "type") return;
5804
5896
  if (typeToolRef.current?.session) {
5805
5897
  typeToolRef.current.finish();
@@ -5834,7 +5926,7 @@ var ImageEditor = ({
5834
5926
  el.value = "";
5835
5927
  }
5836
5928
  };
5837
- (0, import_react46.useEffect)(() => transformTool.subscribe(() => {
5929
+ (0, import_react47.useEffect)(() => transformTool.subscribe(() => {
5838
5930
  setTransformTick((n) => n + 1);
5839
5931
  void renderCanvas();
5840
5932
  }), [transformTool, renderCanvas]);
@@ -5845,8 +5937,8 @@ var ImageEditor = ({
5845
5937
  const sy = rect.height > 0 ? canvas.height / rect.height : 1;
5846
5938
  const s = controller.getState();
5847
5939
  const cropping = activeTab === "crop";
5848
- const projection = (0, import_image_editor14.getViewportProjection)(s, canvas.width, canvas.height, cropping);
5849
- const pt = (0, import_image_editor14.canvasToImagePoint)({ x: (e.clientX - rect.left) * sx, y: (e.clientY - rect.top) * sy }, s, canvas.width, canvas.height, cropping);
5940
+ const projection = (0, import_image_editor15.getViewportProjection)(s, canvas.width, canvas.height, cropping);
5941
+ const pt = (0, import_image_editor15.canvasToImagePoint)({ x: (e.clientX - rect.left) * sx, y: (e.clientY - rect.top) * sy }, s, canvas.width, canvas.height, cropping);
5850
5942
  transformTool.setView(projection.scale);
5851
5943
  return { pt, tolerance: 6 / (projection.scale || 1) };
5852
5944
  };
@@ -5877,7 +5969,7 @@ var ImageEditor = ({
5877
5969
  transformTool.up();
5878
5970
  return true;
5879
5971
  };
5880
- (0, import_react46.useEffect)(() => {
5972
+ (0, import_react47.useEffect)(() => {
5881
5973
  if (typeof window === "undefined") return;
5882
5974
  const onKey = (e) => {
5883
5975
  if (transformTool.key(e)) e.preventDefault();
@@ -5885,7 +5977,7 @@ var ImageEditor = ({
5885
5977
  window.addEventListener("keydown", onKey);
5886
5978
  return () => window.removeEventListener("keydown", onKey);
5887
5979
  }, [transformTool]);
5888
- (0, import_react46.useEffect)(() => {
5980
+ (0, import_react47.useEffect)(() => {
5889
5981
  const raf = typeof requestAnimationFrame !== "undefined" ? requestAnimationFrame : (cb) => setTimeout(cb, 0);
5890
5982
  const caf = typeof cancelAnimationFrame !== "undefined" ? cancelAnimationFrame : (id) => clearTimeout(id);
5891
5983
  const animId = raf(() => {
@@ -5893,12 +5985,12 @@ var ImageEditor = ({
5893
5985
  });
5894
5986
  return () => caf(animId);
5895
5987
  }, [renderCanvas, state]);
5896
- (0, import_react46.useEffect)(() => {
5988
+ (0, import_react47.useEffect)(() => {
5897
5989
  if (activeTab === "crop" && editor.state.activeTool !== "crop") {
5898
5990
  editor.setTool("crop");
5899
5991
  }
5900
5992
  }, [activeTab, editor]);
5901
- (0, import_react46.useEffect)(() => {
5993
+ (0, import_react47.useEffect)(() => {
5902
5994
  const container = containerRef.current;
5903
5995
  if (!container) return;
5904
5996
  if (typeof ResizeObserver !== "undefined") {
@@ -5934,8 +6026,8 @@ var ImageEditor = ({
5934
6026
  const sy = rect.height > 0 ? canvas.height / rect.height : 1;
5935
6027
  const s = controller.getState();
5936
6028
  return list.map((ev) => ({
5937
- ...(0, import_image_editor14.canvasToImagePoint)({ x: (ev.clientX - rect.left) * sx, y: (ev.clientY - rect.top) * sy }, s, canvas.width, canvas.height, false),
5938
- pressure: (0, import_image_editor14.pointerPressure)(ev)
6029
+ ...(0, import_image_editor15.canvasToImagePoint)({ x: (ev.clientX - rect.left) * sx, y: (ev.clientY - rect.top) * sy }, s, canvas.width, canvas.height, false),
6030
+ pressure: (0, import_image_editor15.pointerPressure)(ev)
5939
6031
  }));
5940
6032
  };
5941
6033
  const handlePaintPointerDown = (e) => {
@@ -5966,10 +6058,10 @@ var ImageEditor = ({
5966
6058
  if (g.error) setPaintError(g.error);
5967
6059
  }
5968
6060
  };
5969
- (0, import_react46.useEffect)(() => {
6061
+ (0, import_react47.useEffect)(() => {
5970
6062
  if (activeTab !== "paint" || typeof window === "undefined") return;
5971
6063
  const onKey = (e) => {
5972
- if ((0, import_image_editor14.handlePaintShortcut)(controller, e)) e.preventDefault();
6064
+ if ((0, import_image_editor15.handlePaintShortcut)(controller, e)) e.preventDefault();
5973
6065
  };
5974
6066
  window.addEventListener("keydown", onKey);
5975
6067
  return () => window.removeEventListener("keydown", onKey);
@@ -5980,7 +6072,7 @@ var ImageEditor = ({
5980
6072
  const canvasPt = getCanvasEventPoint(e);
5981
6073
  if (activeTab === "select") {
5982
6074
  const gesture = selectionGestureRef.current;
5983
- const imgPt = (0, import_image_editor14.canvasToImagePoint)(canvasPt, state, canvas.width, canvas.height, false);
6075
+ const imgPt = (0, import_image_editor15.canvasToImagePoint)(canvasPt, state, canvas.width, canvas.height, false);
5984
6076
  void gesture.begin(imgPt, e).then(() => setSelectionError(gesture.error));
5985
6077
  return;
5986
6078
  }
@@ -5991,8 +6083,8 @@ var ImageEditor = ({
5991
6083
  width: state.imageDimensions.width,
5992
6084
  height: state.imageDimensions.height
5993
6085
  };
5994
- const handle = (0, import_image_editor14.hitTestCrop)(canvasPt, state, canvas.width, canvas.height, 14, activeCrop);
5995
- const startImgPt = (0, import_image_editor14.canvasToImagePoint)(canvasPt, state, canvas.width, canvas.height, true);
6086
+ const handle = (0, import_image_editor15.hitTestCrop)(canvasPt, state, canvas.width, canvas.height, 14, activeCrop);
6087
+ const startImgPt = (0, import_image_editor15.canvasToImagePoint)(canvasPt, state, canvas.width, canvas.height, true);
5996
6088
  if (handle) {
5997
6089
  cropDragInfoRef.current = {
5998
6090
  handle,
@@ -6011,7 +6103,7 @@ var ImageEditor = ({
6011
6103
  return;
6012
6104
  }
6013
6105
  if (activeTab === "annotate" && (state.activeTool === "shape" || state.activeTool === "type")) {
6014
- const imgPt = (0, import_image_editor14.canvasToImagePoint)(canvasPt, state, canvas.width, canvas.height, false);
6106
+ const imgPt = (0, import_image_editor15.canvasToImagePoint)(canvasPt, state, canvas.width, canvas.height, false);
6015
6107
  setShapeTypeError(null);
6016
6108
  if (state.activeTool === "shape") shapeGestureRef.current.down(imgPt);
6017
6109
  else {
@@ -6022,12 +6114,12 @@ var ImageEditor = ({
6022
6114
  return;
6023
6115
  }
6024
6116
  if (activeTab === "annotate") {
6025
- const imgPt = (0, import_image_editor14.canvasToImagePoint)(canvasPt, state, canvas.width, canvas.height, false);
6117
+ const imgPt = (0, import_image_editor15.canvasToImagePoint)(canvasPt, state, canvas.width, canvas.height, false);
6026
6118
  dragStartPointRef.current = imgPt;
6027
6119
  if (state.activeTool === "select") {
6028
6120
  for (let i = state.annotations.length - 1; i >= 0; i--) {
6029
6121
  const ann = state.annotations[i];
6030
- if ((0, import_image_editor14.hitTestAnnotation)(imgPt, ann)) {
6122
+ if ((0, import_image_editor15.hitTestAnnotation)(imgPt, ann)) {
6031
6123
  editor.selectAnnotation(ann.id);
6032
6124
  annotationDragInfoRef.current = {
6033
6125
  annId: ann.id,
@@ -6063,7 +6155,7 @@ var ImageEditor = ({
6063
6155
  const canvasPt = getCanvasEventPoint(e);
6064
6156
  if (activeTab === "select") {
6065
6157
  const gesture = selectionGestureRef.current;
6066
- if (gesture.active && gesture.move((0, import_image_editor14.canvasToImagePoint)(canvasPt, state, canvas.width, canvas.height, false))) {
6158
+ if (gesture.active && gesture.move((0, import_image_editor15.canvasToImagePoint)(canvasPt, state, canvas.width, canvas.height, false))) {
6067
6159
  selectionDraftRef.current = gesture.draftPath;
6068
6160
  renderCanvas();
6069
6161
  }
@@ -6072,7 +6164,7 @@ var ImageEditor = ({
6072
6164
  if (activeTab === "crop") {
6073
6165
  const drag = cropDragInfoRef.current;
6074
6166
  if (drag) {
6075
- const currentImgPt = (0, import_image_editor14.canvasToImagePoint)(canvasPt, state, canvas.width, canvas.height, true);
6167
+ const currentImgPt = (0, import_image_editor15.canvasToImagePoint)(canvasPt, state, canvas.width, canvas.height, true);
6076
6168
  let newCrop;
6077
6169
  if (drag.handle === "new") {
6078
6170
  const minX = Math.max(0, Math.min(drag.startImgPt.x, currentImgPt.x));
@@ -6086,7 +6178,7 @@ var ImageEditor = ({
6086
6178
  height: Math.round(Math.max(20, maxY - minY))
6087
6179
  };
6088
6180
  } else {
6089
- newCrop = (0, import_image_editor14.calculateCropDrag)(
6181
+ newCrop = (0, import_image_editor15.calculateCropDrag)(
6090
6182
  drag.startCrop,
6091
6183
  drag.handle,
6092
6184
  drag.startImgPt,
@@ -6106,15 +6198,15 @@ var ImageEditor = ({
6106
6198
  width: state.imageDimensions.width,
6107
6199
  height: state.imageDimensions.height
6108
6200
  };
6109
- const handle = (0, import_image_editor14.hitTestCrop)(canvasPt, state, canvas.width, canvas.height, 14, activeCrop);
6110
- canvas.style.cursor = (0, import_image_editor14.getCropCursor)(handle, state.transform);
6201
+ const handle = (0, import_image_editor15.hitTestCrop)(canvasPt, state, canvas.width, canvas.height, 14, activeCrop);
6202
+ canvas.style.cursor = (0, import_image_editor15.getCropCursor)(handle, state.transform);
6111
6203
  }
6112
6204
  return;
6113
6205
  }
6114
6206
  if (activeTab === "annotate" && state.activeTool === "shape") {
6115
6207
  const g = shapeGestureRef.current;
6116
6208
  if (g.active) {
6117
- g.move((0, import_image_editor14.canvasToImagePoint)(canvasPt, state, canvas.width, canvas.height, false), { shift: e.shiftKey, alt: e.altKey });
6209
+ g.move((0, import_image_editor15.canvasToImagePoint)(canvasPt, state, canvas.width, canvas.height, false), { shift: e.shiftKey, alt: e.altKey });
6118
6210
  if (g.error) setShapeTypeError(g.error);
6119
6211
  }
6120
6212
  return;
@@ -6122,7 +6214,7 @@ var ImageEditor = ({
6122
6214
  if (activeTab === "annotate") {
6123
6215
  if (annotationDragInfoRef.current) {
6124
6216
  const drag = annotationDragInfoRef.current;
6125
- const currentImgPt2 = (0, import_image_editor14.canvasToImagePoint)(canvasPt, state, canvas.width, canvas.height, false);
6217
+ const currentImgPt2 = (0, import_image_editor15.canvasToImagePoint)(canvasPt, state, canvas.width, canvas.height, false);
6126
6218
  const dx = currentImgPt2.x - drag.startImgPt.x;
6127
6219
  const dy = currentImgPt2.y - drag.startImgPt.y;
6128
6220
  editor.updateAnnotation(drag.annId, {
@@ -6134,10 +6226,10 @@ var ImageEditor = ({
6134
6226
  const startPt = dragStartPointRef.current;
6135
6227
  if (!startPt) {
6136
6228
  if (state.activeTool === "select") {
6137
- const imgPt = (0, import_image_editor14.canvasToImagePoint)(canvasPt, state, canvas.width, canvas.height, false);
6229
+ const imgPt = (0, import_image_editor15.canvasToImagePoint)(canvasPt, state, canvas.width, canvas.height, false);
6138
6230
  let hovered = false;
6139
6231
  for (let i = state.annotations.length - 1; i >= 0; i--) {
6140
- if ((0, import_image_editor14.hitTestAnnotation)(imgPt, state.annotations[i])) {
6232
+ if ((0, import_image_editor15.hitTestAnnotation)(imgPt, state.annotations[i])) {
6141
6233
  hovered = true;
6142
6234
  break;
6143
6235
  }
@@ -6148,7 +6240,7 @@ var ImageEditor = ({
6148
6240
  }
6149
6241
  return;
6150
6242
  }
6151
- const currentImgPt = (0, import_image_editor14.canvasToImagePoint)(canvasPt, state, canvas.width, canvas.height, false);
6243
+ const currentImgPt = (0, import_image_editor15.canvasToImagePoint)(canvasPt, state, canvas.width, canvas.height, false);
6152
6244
  if (state.activeTool === "pen" && isDrawingRef.current) {
6153
6245
  currentPathRef.current.push(currentImgPt);
6154
6246
  const draft = {
@@ -6228,7 +6320,7 @@ var ImageEditor = ({
6228
6320
  if (activeTab === "select") {
6229
6321
  const gesture = selectionGestureRef.current;
6230
6322
  if (gesture.active) {
6231
- gesture.end((0, import_image_editor14.canvasToImagePoint)(canvasPt, state, canvas.width, canvas.height, false), e);
6323
+ gesture.end((0, import_image_editor15.canvasToImagePoint)(canvasPt, state, canvas.width, canvas.height, false), e);
6232
6324
  selectionDraftRef.current = null;
6233
6325
  renderCanvas();
6234
6326
  }
@@ -6251,7 +6343,7 @@ var ImageEditor = ({
6251
6343
  }
6252
6344
  if (activeTab === "annotate" && state.activeTool === "type") {
6253
6345
  const tool = typeToolRef.current;
6254
- tool.up((0, import_image_editor14.canvasToImagePoint)(canvasPt, state, canvas.width, canvas.height, false));
6346
+ tool.up((0, import_image_editor15.canvasToImagePoint)(canvasPt, state, canvas.width, canvas.height, false));
6255
6347
  setTypeSession(tool.session);
6256
6348
  if (tool.error) setShapeTypeError(tool.error);
6257
6349
  void renderCanvas();
@@ -6265,7 +6357,7 @@ var ImageEditor = ({
6265
6357
  }
6266
6358
  const startPt = dragStartPointRef.current;
6267
6359
  if (startPt) {
6268
- const currentImgPt = (0, import_image_editor14.canvasToImagePoint)(canvasPt, state, canvas.width, canvas.height, false);
6360
+ const currentImgPt = (0, import_image_editor15.canvasToImagePoint)(canvasPt, state, canvas.width, canvas.height, false);
6269
6361
  if (state.activeTool === "pen" && isDrawingRef.current) {
6270
6362
  if (currentPathRef.current.length > 1) {
6271
6363
  editor.addAnnotation({
@@ -6361,15 +6453,15 @@ var ImageEditor = ({
6361
6453
  link.click();
6362
6454
  }
6363
6455
  };
6364
- return /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)(
6456
+ return /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)(
6365
6457
  "div",
6366
6458
  {
6367
6459
  className: `flex flex-col bg-slate-900 border border-slate-800 rounded-xl overflow-hidden shadow-2xl text-slate-100 ${className}`,
6368
6460
  style,
6369
6461
  children: [
6370
- /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("div", { className: "flex flex-wrap items-center justify-between px-4 py-3 bg-slate-950/80 border-b border-slate-800 gap-3", children: [
6371
- /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("div", { className: "flex items-center gap-1 bg-slate-900 p-1 rounded-lg border border-slate-800 text-xs", children: [
6372
- /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
6462
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("div", { className: "flex flex-wrap items-center justify-between px-4 py-3 bg-slate-950/80 border-b border-slate-800 gap-3", children: [
6463
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("div", { className: "flex items-center gap-1 bg-slate-900 p-1 rounded-lg border border-slate-800 text-xs", children: [
6464
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
6373
6465
  "button",
6374
6466
  {
6375
6467
  type: "button",
@@ -6381,7 +6473,7 @@ var ImageEditor = ({
6381
6473
  children: "Transform & Crop"
6382
6474
  }
6383
6475
  ),
6384
- /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
6476
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
6385
6477
  "button",
6386
6478
  {
6387
6479
  type: "button",
@@ -6393,7 +6485,7 @@ var ImageEditor = ({
6393
6485
  children: "Adjustments"
6394
6486
  }
6395
6487
  ),
6396
- /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
6488
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
6397
6489
  "button",
6398
6490
  {
6399
6491
  type: "button",
@@ -6405,7 +6497,7 @@ var ImageEditor = ({
6405
6497
  children: "Layers"
6406
6498
  }
6407
6499
  ),
6408
- /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
6500
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
6409
6501
  "button",
6410
6502
  {
6411
6503
  type: "button",
@@ -6417,7 +6509,7 @@ var ImageEditor = ({
6417
6509
  children: "Paint"
6418
6510
  }
6419
6511
  ),
6420
- /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
6512
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
6421
6513
  "button",
6422
6514
  {
6423
6515
  type: "button",
@@ -6429,7 +6521,7 @@ var ImageEditor = ({
6429
6521
  children: "Select & Mask"
6430
6522
  }
6431
6523
  ),
6432
- /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
6524
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
6433
6525
  "button",
6434
6526
  {
6435
6527
  type: "button",
@@ -6441,7 +6533,7 @@ var ImageEditor = ({
6441
6533
  children: "Annotations"
6442
6534
  }
6443
6535
  ),
6444
- /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
6536
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
6445
6537
  "button",
6446
6538
  {
6447
6539
  type: "button",
@@ -6453,7 +6545,7 @@ var ImageEditor = ({
6453
6545
  children: "Depth Mask"
6454
6546
  }
6455
6547
  ),
6456
- /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)(
6548
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)(
6457
6549
  "button",
6458
6550
  {
6459
6551
  type: "button",
@@ -6463,14 +6555,14 @@ var ImageEditor = ({
6463
6555
  },
6464
6556
  className: `px-3 py-1.5 rounded-md font-medium transition-colors flex items-center gap-1.5 ${activeTab === "ai" ? "bg-indigo-600 text-white shadow" : "text-slate-400 hover:text-slate-200"}`,
6465
6557
  children: [
6466
- /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("svg", { className: "w-3.5 h-3.5", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("path", { d: "M12 2v4M12 18v4M4.93 4.93l2.83 2.83M16.24 16.24l2.83 2.83M2 12h4M18 12h4M4.93 19.07l2.83-2.83M16.24 7.76l2.83-2.83" }) }),
6558
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("svg", { className: "w-3.5 h-3.5", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("path", { d: "M12 2v4M12 18v4M4.93 4.93l2.83 2.83M16.24 16.24l2.83 2.83M2 12h4M18 12h4M4.93 19.07l2.83-2.83M16.24 7.76l2.83-2.83" }) }),
6467
6559
  "AI Tools"
6468
6560
  ]
6469
6561
  }
6470
6562
  )
6471
6563
  ] }),
6472
- /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("div", { className: "flex items-center gap-2 text-xs", children: [
6473
- /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
6564
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("div", { className: "flex items-center gap-2 text-xs", children: [
6565
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
6474
6566
  "button",
6475
6567
  {
6476
6568
  type: "button",
@@ -6481,7 +6573,7 @@ var ImageEditor = ({
6481
6573
  children: "\u21A9"
6482
6574
  }
6483
6575
  ),
6484
- /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
6576
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
6485
6577
  "button",
6486
6578
  {
6487
6579
  type: "button",
@@ -6492,7 +6584,7 @@ var ImageEditor = ({
6492
6584
  children: "\u21AA"
6493
6585
  }
6494
6586
  ),
6495
- /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
6587
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
6496
6588
  "button",
6497
6589
  {
6498
6590
  type: "button",
@@ -6501,8 +6593,8 @@ var ImageEditor = ({
6501
6593
  children: "Reset"
6502
6594
  }
6503
6595
  ),
6504
- /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("div", { className: "h-4 w-px bg-slate-800 mx-1" }),
6505
- /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
6596
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("div", { className: "h-4 w-px bg-slate-800 mx-1" }),
6597
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
6506
6598
  "button",
6507
6599
  {
6508
6600
  type: "button",
@@ -6512,11 +6604,11 @@ var ImageEditor = ({
6512
6604
  children: "-"
6513
6605
  }
6514
6606
  ),
6515
- /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("span", { className: "font-mono text-slate-400 w-10 text-center", children: [
6607
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("span", { className: "font-mono text-slate-400 w-10 text-center", children: [
6516
6608
  Math.round(state.zoom * 100),
6517
6609
  "%"
6518
6610
  ] }),
6519
- /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
6611
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
6520
6612
  "button",
6521
6613
  {
6522
6614
  type: "button",
@@ -6526,8 +6618,8 @@ var ImageEditor = ({
6526
6618
  children: "+"
6527
6619
  }
6528
6620
  ),
6529
- /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("div", { className: "h-4 w-px bg-slate-800 mx-1" }),
6530
- /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
6621
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("div", { className: "h-4 w-px bg-slate-800 mx-1" }),
6622
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
6531
6623
  "button",
6532
6624
  {
6533
6625
  type: "button",
@@ -6538,7 +6630,7 @@ var ImageEditor = ({
6538
6630
  children: "Hold Compare"
6539
6631
  }
6540
6632
  ),
6541
- /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
6633
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
6542
6634
  "button",
6543
6635
  {
6544
6636
  type: "button",
@@ -6549,16 +6641,16 @@ var ImageEditor = ({
6549
6641
  )
6550
6642
  ] })
6551
6643
  ] }),
6552
- transformTool.active && /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(FreeTransformOptionsBar, { tool: transformTool, className: "border-b border-slate-800 bg-slate-900/95 px-4 py-2" }),
6553
- !transformTool.active && transformTool.error && /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("div", { role: "alert", className: "border-b border-rose-900 bg-rose-950/80 px-4 py-1.5 text-xs text-rose-200", children: transformTool.error }),
6554
- /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("div", { className: "flex flex-col md:flex-row flex-1 min-h-[520px] md:h-[560px]", children: [
6555
- /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)(
6644
+ transformTool.active && /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(FreeTransformOptionsBar, { tool: transformTool, className: "border-b border-slate-800 bg-slate-900/95 px-4 py-2" }),
6645
+ !transformTool.active && transformTool.error && /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("div", { role: "alert", className: "border-b border-rose-900 bg-rose-950/80 px-4 py-1.5 text-xs text-rose-200", children: transformTool.error }),
6646
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("div", { className: "flex flex-col md:flex-row flex-1 min-h-[520px] md:h-[560px]", children: [
6647
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)(
6556
6648
  "div",
6557
6649
  {
6558
6650
  ref: containerRef,
6559
6651
  className: "relative flex-1 h-[360px] md:h-full min-h-[320px] bg-slate-950 overflow-hidden select-none",
6560
6652
  children: [
6561
- /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
6653
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
6562
6654
  "canvas",
6563
6655
  {
6564
6656
  ref: canvasRef,
@@ -6575,7 +6667,7 @@ var ImageEditor = ({
6575
6667
  className: `absolute inset-0 w-full h-full block ${transformTool.active ? "touch-none" : activeTab === "paint" ? "touch-none cursor-crosshair" : activeTab === "annotate" && state.activeTool === "type" ? "cursor-text" : activeTab === "annotate" && state.activeTool === "shape" ? "cursor-crosshair" : ""}`
6576
6668
  }
6577
6669
  ),
6578
- typeSession && /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
6670
+ typeSession && /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
6579
6671
  "textarea",
6580
6672
  {
6581
6673
  ref: typeInputRef,
@@ -6597,11 +6689,11 @@ var ImageEditor = ({
6597
6689
  ]
6598
6690
  }
6599
6691
  ),
6600
- /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("div", { className: "w-full md:w-80 bg-slate-900/90 border-t md:border-t-0 md:border-l border-slate-800 p-4 overflow-y-auto h-auto md:h-full md:max-h-[560px]", children: [
6601
- activeTab === "crop" && /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("div", { className: "flex flex-col gap-4 text-xs", children: [
6602
- /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("span", { className: "font-semibold text-slate-200 uppercase tracking-wider text-[11px]", children: "Aspect Ratio Presets" }),
6603
- /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("div", { className: "grid grid-cols-3 gap-2", children: [
6604
- /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
6692
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("div", { className: "w-full md:w-80 bg-slate-900/90 border-t md:border-t-0 md:border-l border-slate-800 p-4 overflow-y-auto h-auto md:h-full md:max-h-[560px]", children: [
6693
+ activeTab === "crop" && /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("div", { className: "flex flex-col gap-4 text-xs", children: [
6694
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("span", { className: "font-semibold text-slate-200 uppercase tracking-wider text-[11px]", children: "Aspect Ratio Presets" }),
6695
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("div", { className: "grid grid-cols-3 gap-2", children: [
6696
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
6605
6697
  "button",
6606
6698
  {
6607
6699
  type: "button",
@@ -6613,7 +6705,7 @@ var ImageEditor = ({
6613
6705
  children: "Freeform"
6614
6706
  }
6615
6707
  ),
6616
- /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
6708
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
6617
6709
  "button",
6618
6710
  {
6619
6711
  type: "button",
@@ -6625,7 +6717,7 @@ var ImageEditor = ({
6625
6717
  children: "1:1 Square"
6626
6718
  }
6627
6719
  ),
6628
- /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
6720
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
6629
6721
  "button",
6630
6722
  {
6631
6723
  type: "button",
@@ -6637,7 +6729,7 @@ var ImageEditor = ({
6637
6729
  children: "4:3 Standard"
6638
6730
  }
6639
6731
  ),
6640
- /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
6732
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
6641
6733
  "button",
6642
6734
  {
6643
6735
  type: "button",
@@ -6649,7 +6741,7 @@ var ImageEditor = ({
6649
6741
  children: "16:9 Wide"
6650
6742
  }
6651
6743
  ),
6652
- /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
6744
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
6653
6745
  "button",
6654
6746
  {
6655
6747
  type: "button",
@@ -6661,7 +6753,7 @@ var ImageEditor = ({
6661
6753
  children: "3:2 Photo"
6662
6754
  }
6663
6755
  ),
6664
- /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
6756
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
6665
6757
  "button",
6666
6758
  {
6667
6759
  type: "button",
@@ -6674,10 +6766,10 @@ var ImageEditor = ({
6674
6766
  }
6675
6767
  )
6676
6768
  ] }),
6677
- /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("div", { className: "h-px bg-slate-800 my-1" }),
6678
- /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("span", { className: "font-semibold text-slate-200 uppercase tracking-wider text-[11px]", children: "Orientation & Flips" }),
6679
- /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("div", { className: "grid grid-cols-2 gap-2", children: [
6680
- /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
6769
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("div", { className: "h-px bg-slate-800 my-1" }),
6770
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("span", { className: "font-semibold text-slate-200 uppercase tracking-wider text-[11px]", children: "Orientation & Flips" }),
6771
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("div", { className: "grid grid-cols-2 gap-2", children: [
6772
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
6681
6773
  "button",
6682
6774
  {
6683
6775
  type: "button",
@@ -6686,7 +6778,7 @@ var ImageEditor = ({
6686
6778
  children: "Rotate -90\xB0"
6687
6779
  }
6688
6780
  ),
6689
- /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
6781
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
6690
6782
  "button",
6691
6783
  {
6692
6784
  type: "button",
@@ -6695,7 +6787,7 @@ var ImageEditor = ({
6695
6787
  children: "Rotate +90\xB0"
6696
6788
  }
6697
6789
  ),
6698
- /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
6790
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
6699
6791
  "button",
6700
6792
  {
6701
6793
  type: "button",
@@ -6704,7 +6796,7 @@ var ImageEditor = ({
6704
6796
  children: "Flip Horizontal"
6705
6797
  }
6706
6798
  ),
6707
- /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
6799
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
6708
6800
  "button",
6709
6801
  {
6710
6802
  type: "button",
@@ -6715,10 +6807,10 @@ var ImageEditor = ({
6715
6807
  )
6716
6808
  ] })
6717
6809
  ] }),
6718
- activeTab === "adjust" && /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("div", { className: "flex flex-col gap-3 text-xs", children: [
6719
- /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("div", { className: "flex items-center justify-between", children: [
6720
- /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("span", { className: "font-semibold text-slate-200 uppercase tracking-wider text-[11px]", children: "Color Adjustments" }),
6721
- /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
6810
+ activeTab === "adjust" && /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("div", { className: "flex flex-col gap-3 text-xs", children: [
6811
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("div", { className: "flex items-center justify-between", children: [
6812
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("span", { className: "font-semibold text-slate-200 uppercase tracking-wider text-[11px]", children: "Color Adjustments" }),
6813
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
6722
6814
  "button",
6723
6815
  {
6724
6816
  type: "button",
@@ -6728,25 +6820,25 @@ var ImageEditor = ({
6728
6820
  }
6729
6821
  )
6730
6822
  ] }),
6731
- /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(Histogram, { histogram: editor.histogram }),
6732
- import_image_editor14.IMAGE_ADJUSTMENT_CONTROLS.map((spec) => /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)(import_react46.default.Fragment, { children: [
6733
- /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
6823
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(Histogram, { histogram: editor.histogram }),
6824
+ import_image_editor15.IMAGE_ADJUSTMENT_CONTROLS.map((spec) => /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)(import_react47.default.Fragment, { children: [
6825
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
6734
6826
  ControlSlider,
6735
6827
  {
6736
6828
  spec,
6737
- value: (0, import_image_editor14.readAdjustmentControls)(state.adjustments)[spec.id],
6829
+ value: (0, import_image_editor15.readAdjustmentControls)(state.adjustments)[spec.id],
6738
6830
  disabled: spec.requiresProcess !== void 0 && legacyProcess,
6739
6831
  onChange: (v) => editor.setAdjustments({ [spec.id]: v })
6740
6832
  }
6741
6833
  ),
6742
- spec.id === "tint" && legacyProcess && /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)(
6834
+ spec.id === "tint" && legacyProcess && /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)(
6743
6835
  "div",
6744
6836
  {
6745
6837
  className: "flex items-center justify-between gap-2 rounded border border-amber-500/30 bg-amber-500/10 px-2 py-1.5 text-[10px] text-amber-200",
6746
6838
  "data-testid": "image-editor-process-notice",
6747
6839
  children: [
6748
- /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("span", { children: "Legacy rendering (process 1). Tint needs the current process." }),
6749
- /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
6840
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("span", { children: "Legacy rendering (process 1). Tint needs the current process." }),
6841
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
6750
6842
  "button",
6751
6843
  {
6752
6844
  type: "button",
@@ -6759,7 +6851,7 @@ var ImageEditor = ({
6759
6851
  }
6760
6852
  )
6761
6853
  ] }, spec.id)),
6762
- /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("div", { className: "border-t border-slate-700/60 pt-3", children: /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
6854
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("div", { className: "border-t border-slate-700/60 pt-3", children: /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
6763
6855
  AdjustmentLayersPanel,
6764
6856
  {
6765
6857
  controller,
@@ -6768,9 +6860,9 @@ var ImageEditor = ({
6768
6860
  }
6769
6861
  ) })
6770
6862
  ] }),
6771
- activeTab === "layers" && /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("div", { className: "flex flex-col gap-3 text-xs", children: [
6772
- /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("span", { className: "font-semibold text-slate-200 uppercase tracking-wider text-[11px]", children: "Layers" }),
6773
- /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
6863
+ activeTab === "layers" && /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("div", { className: "flex flex-col gap-3 text-xs", children: [
6864
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("span", { className: "font-semibold text-slate-200 uppercase tracking-wider text-[11px]", children: "Layers" }),
6865
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
6774
6866
  "button",
6775
6867
  {
6776
6868
  type: "button",
@@ -6781,12 +6873,14 @@ var ImageEditor = ({
6781
6873
  children: "Free Transform"
6782
6874
  }
6783
6875
  ),
6784
- /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(LayersPanel, { controller })
6876
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(LayersPanel, { controller }),
6877
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("span", { className: "font-semibold text-slate-200 uppercase tracking-wider text-[11px]", children: "Colour" }),
6878
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(ColorProfilePanel, { controller })
6785
6879
  ] }),
6786
- activeTab === "paint" && /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("div", { className: "flex flex-col gap-3 text-xs", children: [
6787
- /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("span", { className: "font-semibold text-slate-200 uppercase tracking-wider text-[11px]", children: "Paint" }),
6788
- /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(BrushOptionsBar, { controller }),
6789
- /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
6880
+ activeTab === "paint" && /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("div", { className: "flex flex-col gap-3 text-xs", children: [
6881
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("span", { className: "font-semibold text-slate-200 uppercase tracking-wider text-[11px]", children: "Paint" }),
6882
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(BrushOptionsBar, { controller }),
6883
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
6790
6884
  "button",
6791
6885
  {
6792
6886
  type: "button",
@@ -6797,12 +6891,12 @@ var ImageEditor = ({
6797
6891
  children: "Free Transform"
6798
6892
  }
6799
6893
  ),
6800
- paintError && /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("p", { role: "alert", className: "text-rose-400", "data-testid": "paint-error", children: paintError }),
6801
- /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("div", { className: "border-t border-slate-700/60 pt-3", children: /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(LayersPanel, { controller }) })
6894
+ paintError && /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("p", { role: "alert", className: "text-rose-400", "data-testid": "paint-error", children: paintError }),
6895
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("div", { className: "border-t border-slate-700/60 pt-3", children: /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(LayersPanel, { controller }) })
6802
6896
  ] }),
6803
- activeTab === "annotate" && /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("div", { className: "flex flex-col gap-3 text-xs", children: [
6804
- /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("span", { className: "font-semibold text-slate-200 uppercase tracking-wider text-[11px]", children: "Shape & Type Layers" }),
6805
- /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("div", { className: "grid grid-cols-2 gap-1.5", children: ["shape", "type"].map((t) => /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
6897
+ activeTab === "annotate" && /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("div", { className: "flex flex-col gap-3 text-xs", children: [
6898
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("span", { className: "font-semibold text-slate-200 uppercase tracking-wider text-[11px]", children: "Shape & Type Layers" }),
6899
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("div", { className: "grid grid-cols-2 gap-1.5", children: ["shape", "type"].map((t) => /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
6806
6900
  "button",
6807
6901
  {
6808
6902
  type: "button",
@@ -6813,13 +6907,13 @@ var ImageEditor = ({
6813
6907
  },
6814
6908
  t
6815
6909
  )) }),
6816
- state.activeTool === "shape" && /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(ShapeOptionsBar, { controller, options: shapeOptions, onChange: setShapeOptions }),
6817
- state.activeTool === "type" && /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(TypeOptionsBar, { controller, options: typeOptions, onChange: setTypeOptions, session: typeSession }),
6818
- state.activeTool === "type" && typeSession && /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("button", { type: "button", onClick: finishTyping, className: "self-start rounded bg-slate-800 px-2 py-1 text-[11px] text-slate-200 hover:bg-slate-700", children: "Done editing text" }),
6819
- shapeTypeError && /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("p", { role: "alert", className: "text-rose-400", "data-testid": "shape-type-error", children: shapeTypeError }),
6820
- /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("div", { className: "h-px bg-slate-800 my-1" }),
6821
- /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("span", { className: "font-semibold text-slate-200 uppercase tracking-wider text-[11px]", children: "Draw & Annotate" }),
6822
- /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("div", { className: "grid grid-cols-3 gap-1.5", children: ["pen", "rect", "circle", "arrow", "line"].map((t) => /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
6910
+ state.activeTool === "shape" && /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(ShapeOptionsBar, { controller, options: shapeOptions, onChange: setShapeOptions }),
6911
+ state.activeTool === "type" && /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(TypeOptionsBar, { controller, options: typeOptions, onChange: setTypeOptions, session: typeSession }),
6912
+ state.activeTool === "type" && typeSession && /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("button", { type: "button", onClick: finishTyping, className: "self-start rounded bg-slate-800 px-2 py-1 text-[11px] text-slate-200 hover:bg-slate-700", children: "Done editing text" }),
6913
+ shapeTypeError && /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("p", { role: "alert", className: "text-rose-400", "data-testid": "shape-type-error", children: shapeTypeError }),
6914
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("div", { className: "h-px bg-slate-800 my-1" }),
6915
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("span", { className: "font-semibold text-slate-200 uppercase tracking-wider text-[11px]", children: "Draw & Annotate" }),
6916
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("div", { className: "grid grid-cols-3 gap-1.5", children: ["pen", "rect", "circle", "arrow", "line"].map((t) => /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
6823
6917
  "button",
6824
6918
  {
6825
6919
  type: "button",
@@ -6829,9 +6923,9 @@ var ImageEditor = ({
6829
6923
  },
6830
6924
  t
6831
6925
  )) }),
6832
- /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("div", { className: "flex items-center gap-2 mt-2", children: [
6833
- /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("label", { className: "text-slate-400", children: "Color:" }),
6834
- /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
6926
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("div", { className: "flex items-center gap-2 mt-2", children: [
6927
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("label", { className: "text-slate-400", children: "Color:" }),
6928
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
6835
6929
  "input",
6836
6930
  {
6837
6931
  type: "color",
@@ -6840,15 +6934,15 @@ var ImageEditor = ({
6840
6934
  className: "w-8 h-8 rounded border border-slate-700 cursor-pointer bg-transparent"
6841
6935
  }
6842
6936
  ),
6843
- /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("div", { className: "flex-1 ml-2", children: [
6844
- /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("div", { className: "flex justify-between text-slate-400 mb-0.5", children: [
6845
- /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("span", { children: "Width:" }),
6846
- /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("span", { className: "font-mono", children: [
6937
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("div", { className: "flex-1 ml-2", children: [
6938
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("div", { className: "flex justify-between text-slate-400 mb-0.5", children: [
6939
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("span", { children: "Width:" }),
6940
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("span", { className: "font-mono", children: [
6847
6941
  strokeWidth,
6848
6942
  "px"
6849
6943
  ] })
6850
6944
  ] }),
6851
- /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
6945
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
6852
6946
  "input",
6853
6947
  {
6854
6948
  type: "range",
@@ -6861,10 +6955,10 @@ var ImageEditor = ({
6861
6955
  )
6862
6956
  ] })
6863
6957
  ] }),
6864
- /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("div", { className: "h-px bg-slate-800 my-1" }),
6865
- /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("span", { className: "font-semibold text-slate-200 uppercase tracking-wider text-[11px]", children: "Add Text" }),
6866
- /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("div", { className: "flex gap-2", children: [
6867
- /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
6958
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("div", { className: "h-px bg-slate-800 my-1" }),
6959
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("span", { className: "font-semibold text-slate-200 uppercase tracking-wider text-[11px]", children: "Add Text" }),
6960
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("div", { className: "flex gap-2", children: [
6961
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
6868
6962
  "input",
6869
6963
  {
6870
6964
  type: "text",
@@ -6875,7 +6969,7 @@ var ImageEditor = ({
6875
6969
  className: "flex-1 bg-slate-950 border border-slate-700 rounded-lg px-2.5 py-1.5 text-xs text-slate-100 placeholder-slate-500 focus:outline-none focus:border-indigo-500"
6876
6970
  }
6877
6971
  ),
6878
- /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
6972
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
6879
6973
  "button",
6880
6974
  {
6881
6975
  type: "button",
@@ -6885,14 +6979,14 @@ var ImageEditor = ({
6885
6979
  }
6886
6980
  )
6887
6981
  ] }),
6888
- /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("div", { className: "flex items-center justify-between text-slate-400", children: [
6889
- /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("span", { children: "Font Size:" }),
6890
- /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("span", { className: "font-mono", children: [
6982
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("div", { className: "flex items-center justify-between text-slate-400", children: [
6983
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("span", { children: "Font Size:" }),
6984
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("span", { className: "font-mono", children: [
6891
6985
  fontSize,
6892
6986
  "px"
6893
6987
  ] })
6894
6988
  ] }),
6895
- /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
6989
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
6896
6990
  "input",
6897
6991
  {
6898
6992
  type: "range",
@@ -6903,14 +6997,14 @@ var ImageEditor = ({
6903
6997
  className: "w-full accent-indigo-500"
6904
6998
  }
6905
6999
  ),
6906
- /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("div", { className: "h-px bg-slate-800 my-1" }),
6907
- /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("div", { className: "flex items-center justify-between", children: [
6908
- /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("span", { className: "text-slate-400", children: [
7000
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("div", { className: "h-px bg-slate-800 my-1" }),
7001
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("div", { className: "flex items-center justify-between", children: [
7002
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("span", { className: "text-slate-400", children: [
6909
7003
  "Layers (",
6910
7004
  state.annotations.length,
6911
7005
  ")"
6912
7006
  ] }),
6913
- state.selectedAnnotationId && /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
7007
+ state.selectedAnnotationId && /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
6914
7008
  "button",
6915
7009
  {
6916
7010
  type: "button",
@@ -6919,7 +7013,7 @@ var ImageEditor = ({
6919
7013
  children: "Delete Selected"
6920
7014
  }
6921
7015
  ),
6922
- state.annotations.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
7016
+ state.annotations.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
6923
7017
  "button",
6924
7018
  {
6925
7019
  type: "button",
@@ -6930,10 +7024,10 @@ var ImageEditor = ({
6930
7024
  )
6931
7025
  ] })
6932
7026
  ] }),
6933
- activeTab === "depth" && /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("div", { className: "flex flex-col gap-3 text-xs", children: [
6934
- /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("div", { className: "flex items-center justify-between", children: [
6935
- /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("span", { className: "font-semibold text-slate-200 uppercase tracking-wider text-[11px]", children: "Depth Masking" }),
6936
- /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
7027
+ activeTab === "depth" && /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("div", { className: "flex flex-col gap-3 text-xs", children: [
7028
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("div", { className: "flex items-center justify-between", children: [
7029
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("span", { className: "font-semibold text-slate-200 uppercase tracking-wider text-[11px]", children: "Depth Masking" }),
7030
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
6937
7031
  "button",
6938
7032
  {
6939
7033
  type: "button",
@@ -6943,8 +7037,8 @@ var ImageEditor = ({
6943
7037
  }
6944
7038
  )
6945
7039
  ] }),
6946
- /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("label", { className: "flex items-center gap-2 cursor-pointer text-slate-300", children: [
6947
- /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
7040
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("label", { className: "flex items-center gap-2 cursor-pointer text-slate-300", children: [
7041
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
6948
7042
  "input",
6949
7043
  {
6950
7044
  type: "checkbox",
@@ -6953,12 +7047,12 @@ var ImageEditor = ({
6953
7047
  className: "rounded accent-indigo-500"
6954
7048
  }
6955
7049
  ),
6956
- /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("span", { children: "Enable Depth / Alpha Mask" })
7050
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("span", { children: "Enable Depth / Alpha Mask" })
6957
7051
  ] }),
6958
- state.depthMask.enabled && /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)(import_jsx_runtime29.Fragment, { children: [
6959
- /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("div", { children: [
6960
- /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("label", { className: "text-slate-400 block mb-1", children: "Mask Image URL:" }),
6961
- /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
7052
+ state.depthMask.enabled && /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)(import_jsx_runtime30.Fragment, { children: [
7053
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("div", { children: [
7054
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("label", { className: "text-slate-400 block mb-1", children: "Mask Image URL:" }),
7055
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
6962
7056
  "input",
6963
7057
  {
6964
7058
  type: "text",
@@ -6969,8 +7063,8 @@ var ImageEditor = ({
6969
7063
  }
6970
7064
  )
6971
7065
  ] }),
6972
- /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("div", { className: "flex gap-2", children: [
6973
- /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
7066
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("div", { className: "flex gap-2", children: [
7067
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
6974
7068
  "button",
6975
7069
  {
6976
7070
  type: "button",
@@ -6979,7 +7073,7 @@ var ImageEditor = ({
6979
7073
  children: "Threshold Mode"
6980
7074
  }
6981
7075
  ),
6982
- /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
7076
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
6983
7077
  "button",
6984
7078
  {
6985
7079
  type: "button",
@@ -6989,12 +7083,12 @@ var ImageEditor = ({
6989
7083
  }
6990
7084
  )
6991
7085
  ] }),
6992
- /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("div", { children: [
6993
- /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("div", { className: "flex justify-between text-slate-400 mb-1", children: [
6994
- /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("span", { children: "Depth Start (Lower):" }),
6995
- /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("span", { className: "font-mono", children: state.depthMask.depthRange[0] })
7086
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("div", { children: [
7087
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("div", { className: "flex justify-between text-slate-400 mb-1", children: [
7088
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("span", { children: "Depth Start (Lower):" }),
7089
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("span", { className: "font-mono", children: state.depthMask.depthRange[0] })
6996
7090
  ] }),
6997
- /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
7091
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
6998
7092
  "input",
6999
7093
  {
7000
7094
  type: "range",
@@ -7008,12 +7102,12 @@ var ImageEditor = ({
7008
7102
  }
7009
7103
  )
7010
7104
  ] }),
7011
- /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("div", { children: [
7012
- /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("div", { className: "flex justify-between text-slate-400 mb-1", children: [
7013
- /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("span", { children: "Depth Stop (Upper):" }),
7014
- /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("span", { className: "font-mono", children: state.depthMask.depthRange[1] })
7105
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("div", { children: [
7106
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("div", { className: "flex justify-between text-slate-400 mb-1", children: [
7107
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("span", { children: "Depth Stop (Upper):" }),
7108
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("span", { className: "font-mono", children: state.depthMask.depthRange[1] })
7015
7109
  ] }),
7016
- /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
7110
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
7017
7111
  "input",
7018
7112
  {
7019
7113
  type: "range",
@@ -7027,12 +7121,12 @@ var ImageEditor = ({
7027
7121
  }
7028
7122
  )
7029
7123
  ] }),
7030
- /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("div", { children: [
7031
- /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("div", { className: "flex justify-between text-slate-400 mb-1", children: [
7032
- /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("span", { children: "Softness:" }),
7033
- /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("span", { className: "font-mono", children: state.depthMask.softness })
7124
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("div", { children: [
7125
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("div", { className: "flex justify-between text-slate-400 mb-1", children: [
7126
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("span", { children: "Softness:" }),
7127
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("span", { className: "font-mono", children: state.depthMask.softness })
7034
7128
  ] }),
7035
- /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
7129
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
7036
7130
  "input",
7037
7131
  {
7038
7132
  type: "range",
@@ -7044,8 +7138,8 @@ var ImageEditor = ({
7044
7138
  }
7045
7139
  )
7046
7140
  ] }),
7047
- /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("label", { className: "flex items-center gap-2 cursor-pointer text-slate-300 mt-1", children: [
7048
- /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
7141
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("label", { className: "flex items-center gap-2 cursor-pointer text-slate-300 mt-1", children: [
7142
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
7049
7143
  "input",
7050
7144
  {
7051
7145
  type: "checkbox",
@@ -7054,12 +7148,12 @@ var ImageEditor = ({
7054
7148
  className: "rounded accent-indigo-500"
7055
7149
  }
7056
7150
  ),
7057
- /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("span", { children: "Invert Mask" })
7151
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("span", { children: "Invert Mask" })
7058
7152
  ] })
7059
7153
  ] })
7060
7154
  ] }),
7061
- activeTab === "select" && /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("div", { className: "flex flex-col gap-4 text-xs", children: [
7062
- /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
7155
+ activeTab === "select" && /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("div", { className: "flex flex-col gap-4 text-xs", children: [
7156
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
7063
7157
  SelectionOptionsBar,
7064
7158
  {
7065
7159
  controller,
@@ -7069,9 +7163,9 @@ var ImageEditor = ({
7069
7163
  quickMask: Boolean(state.quickMask)
7070
7164
  }
7071
7165
  ),
7072
- selectionError && /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("p", { role: "alert", className: "text-rose-400", children: selectionError }),
7073
- /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("div", { className: "flex gap-1", children: [
7074
- /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
7166
+ selectionError && /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("p", { role: "alert", className: "text-rose-400", children: selectionError }),
7167
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("div", { className: "flex gap-1", children: [
7168
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
7075
7169
  "button",
7076
7170
  {
7077
7171
  type: "button",
@@ -7082,7 +7176,7 @@ var ImageEditor = ({
7082
7176
  children: "Transform Selection"
7083
7177
  }
7084
7178
  ),
7085
- /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
7179
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
7086
7180
  "button",
7087
7181
  {
7088
7182
  type: "button",
@@ -7094,12 +7188,12 @@ var ImageEditor = ({
7094
7188
  }
7095
7189
  )
7096
7190
  ] }),
7097
- /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(RefineEdgePanel, { controller, selection: state.selection ?? null, layers: state.adjustments.layers })
7191
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(RefineEdgePanel, { controller, selection: state.selection ?? null, layers: state.adjustments.layers })
7098
7192
  ] }),
7099
- activeTab === "ai" && /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("div", { className: "flex flex-col gap-4 text-xs", children: [
7100
- /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("label", { className: "flex items-center justify-between gap-2 text-slate-300", children: [
7101
- /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("span", { children: "Results go to" }),
7102
- /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)(
7193
+ activeTab === "ai" && /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("div", { className: "flex flex-col gap-4 text-xs", children: [
7194
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("label", { className: "flex items-center justify-between gap-2 text-slate-300", children: [
7195
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("span", { children: "Results go to" }),
7196
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)(
7103
7197
  "select",
7104
7198
  {
7105
7199
  "aria-label": "AI result target",
@@ -7107,54 +7201,54 @@ var ImageEditor = ({
7107
7201
  onChange: (e) => setAiTarget(e.target.value),
7108
7202
  className: "bg-slate-800 border border-slate-700 rounded px-1.5 py-1",
7109
7203
  children: [
7110
- /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("option", { value: "auto", children: controller.isMultiLayer ? "Auto (new layer)" : "Auto (replace image)" }),
7111
- /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("option", { value: "new-layer", children: "New layer / mask" }),
7112
- /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("option", { value: "replace", children: "Replace image" })
7204
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("option", { value: "auto", children: controller.isMultiLayer ? "Auto (new layer)" : "Auto (replace image)" }),
7205
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("option", { value: "new-layer", children: "New layer / mask" }),
7206
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("option", { value: "replace", children: "Replace image" })
7113
7207
  ]
7114
7208
  }
7115
7209
  )
7116
7210
  ] }),
7117
- /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("div", { className: "p-3 rounded-lg bg-slate-950/60 border border-slate-800 flex flex-col gap-2.5", children: [
7118
- /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("div", { className: "flex items-center justify-between", children: [
7119
- /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("span", { className: "font-semibold text-slate-200 uppercase tracking-wider text-[11px] flex items-center gap-1.5", children: [
7120
- /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("svg", { className: "w-3.5 h-3.5 text-indigo-400", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("path", { d: "M6 3v12M18 9a3 3 0 1 0 0-6 3 3 0 0 0 0 6zM6 21a3 3 0 1 0 0-6 3 3 0 0 0 0 6z" }) }),
7211
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("div", { className: "p-3 rounded-lg bg-slate-950/60 border border-slate-800 flex flex-col gap-2.5", children: [
7212
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("div", { className: "flex items-center justify-between", children: [
7213
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("span", { className: "font-semibold text-slate-200 uppercase tracking-wider text-[11px] flex items-center gap-1.5", children: [
7214
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("svg", { className: "w-3.5 h-3.5 text-indigo-400", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("path", { d: "M6 3v12M18 9a3 3 0 1 0 0-6 3 3 0 0 0 0 6zM6 21a3 3 0 1 0 0-6 3 3 0 0 0 0 6z" }) }),
7121
7215
  "Background Removal"
7122
7216
  ] }),
7123
- isRemovingBg && /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("span", { className: "inline-flex items-center px-1.5 py-0.5 rounded text-[10px] font-medium bg-indigo-900/60 text-indigo-300 animate-pulse", children: "Removing..." })
7217
+ isRemovingBg && /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("span", { className: "inline-flex items-center px-1.5 py-0.5 rounded text-[10px] font-medium bg-indigo-900/60 text-indigo-300 animate-pulse", children: "Removing..." })
7124
7218
  ] }),
7125
- /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("p", { className: "text-slate-400 text-[11px] leading-relaxed", children: "Isolate foreground subject with AI alpha transparency segmentation." }),
7126
- /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
7219
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("p", { className: "text-slate-400 text-[11px] leading-relaxed", children: "Isolate foreground subject with AI alpha transparency segmentation." }),
7220
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
7127
7221
  "button",
7128
7222
  {
7129
7223
  type: "button",
7130
7224
  onClick: handleRemoveBackground,
7131
7225
  disabled: isRemovingBg || isInpainting,
7132
7226
  className: "mt-1 px-3 py-2 rounded-lg bg-indigo-600 hover:bg-indigo-500 disabled:opacity-50 text-white font-medium shadow transition-colors flex items-center justify-center gap-2",
7133
- children: isRemovingBg ? /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)(import_jsx_runtime29.Fragment, { children: [
7134
- /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("div", { className: "w-3.5 h-3.5 border-2 border-white/30 border-t-white rounded-full animate-spin" }),
7227
+ children: isRemovingBg ? /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)(import_jsx_runtime30.Fragment, { children: [
7228
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("div", { className: "w-3.5 h-3.5 border-2 border-white/30 border-t-white rounded-full animate-spin" }),
7135
7229
  "Removing Background..."
7136
- ] }) : /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)(import_jsx_runtime29.Fragment, { children: [
7137
- /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("svg", { className: "w-3.5 h-3.5", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("path", { d: "M12 2v4M12 18v4M4.93 4.93l2.83 2.83M16.24 16.24l2.83 2.83M2 12h4M18 12h4M4.93 19.07l2.83-2.83M16.24 7.76l2.83-2.83" }) }),
7230
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)(import_jsx_runtime30.Fragment, { children: [
7231
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("svg", { className: "w-3.5 h-3.5", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("path", { d: "M12 2v4M12 18v4M4.93 4.93l2.83 2.83M16.24 16.24l2.83 2.83M2 12h4M18 12h4M4.93 19.07l2.83-2.83M16.24 7.76l2.83-2.83" }) }),
7138
7232
  "Remove Background"
7139
7233
  ] })
7140
7234
  }
7141
7235
  )
7142
7236
  ] }),
7143
- /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("div", { className: "p-3 rounded-lg bg-slate-950/60 border border-slate-800 flex flex-col gap-2.5", children: [
7144
- /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("div", { className: "flex items-center justify-between", children: [
7145
- /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("span", { className: "font-semibold text-slate-200 uppercase tracking-wider text-[11px] flex items-center gap-1.5", children: [
7146
- /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("svg", { className: "w-3.5 h-3.5 text-purple-400", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: [
7147
- /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("path", { d: "m21.64 3.64-1.28-1.28a1.2 1.2 0 0 0-1.7 0l-9.72 9.72-1.94 4.86 4.86-1.94 9.72-9.72a1.2 1.2 0 0 0 .06-1.64z" }),
7148
- /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("path", { d: "m14 7 3 3" })
7237
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("div", { className: "p-3 rounded-lg bg-slate-950/60 border border-slate-800 flex flex-col gap-2.5", children: [
7238
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("div", { className: "flex items-center justify-between", children: [
7239
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("span", { className: "font-semibold text-slate-200 uppercase tracking-wider text-[11px] flex items-center gap-1.5", children: [
7240
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("svg", { className: "w-3.5 h-3.5 text-purple-400", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: [
7241
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("path", { d: "m21.64 3.64-1.28-1.28a1.2 1.2 0 0 0-1.7 0l-9.72 9.72-1.94 4.86 4.86-1.94 9.72-9.72a1.2 1.2 0 0 0 .06-1.64z" }),
7242
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("path", { d: "m14 7 3 3" })
7149
7243
  ] }),
7150
7244
  "Generative Inpainting"
7151
7245
  ] }),
7152
- isInpainting && /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("span", { className: "inline-flex items-center px-1.5 py-0.5 rounded text-[10px] font-medium bg-purple-900/60 text-purple-300 animate-pulse", children: "Inpainting..." })
7246
+ isInpainting && /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("span", { className: "inline-flex items-center px-1.5 py-0.5 rounded text-[10px] font-medium bg-purple-900/60 text-purple-300 animate-pulse", children: "Inpainting..." })
7153
7247
  ] }),
7154
- /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("p", { className: "text-slate-400 text-[11px] leading-relaxed", children: "Replace, modify, or fill selected regions using prompt-guided generative inpainting." }),
7155
- /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("div", { className: "flex flex-col gap-1", children: [
7156
- /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("label", { htmlFor: "ai-inpaint-prompt-react", className: "text-slate-300 text-[11px] font-medium", children: "Prompt" }),
7157
- /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
7248
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("p", { className: "text-slate-400 text-[11px] leading-relaxed", children: "Replace, modify, or fill selected regions using prompt-guided generative inpainting." }),
7249
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("div", { className: "flex flex-col gap-1", children: [
7250
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("label", { htmlFor: "ai-inpaint-prompt-react", className: "text-slate-300 text-[11px] font-medium", children: "Prompt" }),
7251
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
7158
7252
  "textarea",
7159
7253
  {
7160
7254
  id: "ai-inpaint-prompt-react",
@@ -7166,10 +7260,10 @@ var ImageEditor = ({
7166
7260
  }
7167
7261
  )
7168
7262
  ] }),
7169
- /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("div", { className: "flex flex-col gap-1", children: [
7170
- /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("span", { className: "text-slate-300 text-[11px] font-medium", children: "Target Mask Region" }),
7171
- /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("div", { className: "grid grid-cols-2 gap-1.5", children: [
7172
- /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)(
7263
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("div", { className: "flex flex-col gap-1", children: [
7264
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("span", { className: "text-slate-300 text-[11px] font-medium", children: "Target Mask Region" }),
7265
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("div", { className: "grid grid-cols-2 gap-1.5", children: [
7266
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)(
7173
7267
  "button",
7174
7268
  {
7175
7269
  type: "button",
@@ -7182,7 +7276,7 @@ var ImageEditor = ({
7182
7276
  ]
7183
7277
  }
7184
7278
  ),
7185
- /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)(
7279
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)(
7186
7280
  "button",
7187
7281
  {
7188
7282
  type: "button",
@@ -7197,25 +7291,25 @@ var ImageEditor = ({
7197
7291
  )
7198
7292
  ] })
7199
7293
  ] }),
7200
- /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
7294
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
7201
7295
  "button",
7202
7296
  {
7203
7297
  type: "button",
7204
7298
  onClick: handleInpaint,
7205
7299
  disabled: isInpainting || isRemovingBg || !inpaintPrompt.trim(),
7206
7300
  className: "mt-1 px-3 py-2 rounded-lg bg-purple-600 hover:bg-purple-500 disabled:opacity-50 text-white font-medium shadow transition-colors flex items-center justify-center gap-2",
7207
- children: isInpainting ? /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)(import_jsx_runtime29.Fragment, { children: [
7208
- /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("div", { className: "w-3.5 h-3.5 border-2 border-white/30 border-t-white rounded-full animate-spin" }),
7301
+ children: isInpainting ? /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)(import_jsx_runtime30.Fragment, { children: [
7302
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("div", { className: "w-3.5 h-3.5 border-2 border-white/30 border-t-white rounded-full animate-spin" }),
7209
7303
  "Generating Inpaint..."
7210
- ] }) : /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)(import_jsx_runtime29.Fragment, { children: [
7211
- /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("svg", { className: "w-3.5 h-3.5", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("path", { d: "M12 2v4M12 18v4M4.93 4.93l2.83 2.83M16.24 16.24l2.83 2.83M2 12h4M18 12h4M4.93 19.07l2.83-2.83M16.24 7.76l2.83-2.83" }) }),
7304
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)(import_jsx_runtime30.Fragment, { children: [
7305
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("svg", { className: "w-3.5 h-3.5", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("path", { d: "M12 2v4M12 18v4M4.93 4.93l2.83 2.83M16.24 16.24l2.83 2.83M2 12h4M18 12h4M4.93 19.07l2.83-2.83M16.24 7.76l2.83-2.83" }) }),
7212
7306
  "Apply Inpainting"
7213
7307
  ] })
7214
7308
  }
7215
7309
  )
7216
7310
  ] }),
7217
- aiError && /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("div", { className: "p-2.5 rounded-lg bg-rose-950/60 border border-rose-800 text-rose-300 text-[11px]", children: aiError }),
7218
- aiSuccess && /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("div", { className: "p-2.5 rounded-lg bg-emerald-950/60 border border-emerald-800 text-emerald-300 text-[11px]", children: aiSuccess })
7311
+ aiError && /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("div", { className: "p-2.5 rounded-lg bg-rose-950/60 border border-rose-800 text-rose-300 text-[11px]", children: aiError }),
7312
+ aiSuccess && /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("div", { className: "p-2.5 rounded-lg bg-emerald-950/60 border border-emerald-800 text-emerald-300 text-[11px]", children: aiSuccess })
7219
7313
  ] })
7220
7314
  ] })
7221
7315
  ] })
@@ -7225,7 +7319,7 @@ var ImageEditor = ({
7225
7319
  };
7226
7320
 
7227
7321
  // src/review/useReview.ts
7228
- var import_react47 = require("react");
7322
+ var import_react48 = require("react");
7229
7323
  var import_editor12 = require("@pixerate/editor");
7230
7324
  var EMPTY_COMMENTS = Object.freeze({
7231
7325
  threads: [],
@@ -7244,23 +7338,23 @@ function isCommentStore(value) {
7244
7338
  }
7245
7339
  function useComments(source) {
7246
7340
  const store = isCommentStore(source) ? source : (0, import_editor12.getCommentStore)(source);
7247
- const subscribe = (0, import_react47.useCallback)(
7341
+ const subscribe = (0, import_react48.useCallback)(
7248
7342
  (onChange) => store ? store.subscribe(() => onChange()) : noopUnsubscribe,
7249
7343
  [store]
7250
7344
  );
7251
7345
  const getSnapshot = () => store?.getSnapshot() ?? EMPTY_COMMENTS;
7252
- const snapshot = (0, import_react47.useSyncExternalStore)(subscribe, getSnapshot, getSnapshot);
7253
- return (0, import_react47.useMemo)(() => ({ ...snapshot, store }), [snapshot, store]);
7346
+ const snapshot = (0, import_react48.useSyncExternalStore)(subscribe, getSnapshot, getSnapshot);
7347
+ return (0, import_react48.useMemo)(() => ({ ...snapshot, store }), [snapshot, store]);
7254
7348
  }
7255
7349
  function useTrackChanges(editor) {
7256
7350
  const store = (0, import_editor12.getTrackChangesStore)(editor ?? null);
7257
- const subscribe = (0, import_react47.useCallback)(
7351
+ const subscribe = (0, import_react48.useCallback)(
7258
7352
  (onChange) => store ? store.subscribe(() => onChange()) : noopUnsubscribe,
7259
7353
  [store]
7260
7354
  );
7261
7355
  const getSnapshot = () => store?.getSnapshot() ?? EMPTY_TRACK_CHANGES;
7262
- const snapshot = (0, import_react47.useSyncExternalStore)(subscribe, getSnapshot, getSnapshot);
7263
- return (0, import_react47.useMemo)(() => {
7356
+ const snapshot = (0, import_react48.useSyncExternalStore)(subscribe, getSnapshot, getSnapshot);
7357
+ return (0, import_react48.useMemo)(() => {
7264
7358
  const run = (fn) => () => {
7265
7359
  if (editor && !editor.isDestroyed) fn(editor);
7266
7360
  };
@@ -7283,9 +7377,9 @@ function useTrackChanges(editor) {
7283
7377
  }
7284
7378
 
7285
7379
  // src/review/CommentsPanel.tsx
7286
- var import_react48 = require("react");
7380
+ var import_react49 = require("react");
7287
7381
  var import_editor13 = require("@pixerate/editor");
7288
- var import_jsx_runtime30 = require("react/jsx-runtime");
7382
+ var import_jsx_runtime31 = require("react/jsx-runtime");
7289
7383
  var buttonClass2 = "rounded px-2 py-1 text-xs text-muted-foreground hover:bg-muted hover:text-foreground disabled:opacity-50";
7290
7384
  var primaryButtonClass = "rounded px-2 py-1 text-xs bg-primary/10 text-primary hover:bg-primary/20 disabled:opacity-50";
7291
7385
  var textareaClass = "w-full resize-y rounded-md border border-input bg-background p-2 text-sm text-foreground focus:outline-none focus:ring-2 focus:ring-primary";
@@ -7299,18 +7393,18 @@ var CommentsPanel = ({
7299
7393
  emptyMessage = "No comments yet. Select text and add a comment."
7300
7394
  }) => {
7301
7395
  const { threads, activeThreadId, store } = useComments(storeProp ?? editor);
7302
- const [showResolved, setShowResolved] = (0, import_react48.useState)(showResolvedInitial);
7396
+ const [showResolved, setShowResolved] = (0, import_react49.useState)(showResolvedInitial);
7303
7397
  const author = authorProp ?? (0, import_editor13.getCommentAuthor)(editor) ?? { id: "anonymous", name: "Anonymous" };
7304
7398
  const visible = threads.filter((t) => showResolved || !t.resolved);
7305
7399
  const resolvedCount = threads.filter((t) => t.resolved).length;
7306
- return /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("aside", { className, "aria-label": "Comments", children: [
7307
- /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("div", { className: "flex items-center justify-between gap-2", children: [
7308
- /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("span", { className: "text-xs font-medium text-muted-foreground", children: [
7400
+ return /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)("aside", { className, "aria-label": "Comments", children: [
7401
+ /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)("div", { className: "flex items-center justify-between gap-2", children: [
7402
+ /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)("span", { className: "text-xs font-medium text-muted-foreground", children: [
7309
7403
  threads.length - resolvedCount,
7310
7404
  " open",
7311
7405
  resolvedCount > 0 ? ` \xB7 ${resolvedCount} resolved` : ""
7312
7406
  ] }),
7313
- resolvedCount > 0 && /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
7407
+ resolvedCount > 0 && /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
7314
7408
  "button",
7315
7409
  {
7316
7410
  type: "button",
@@ -7321,7 +7415,7 @@ var CommentsPanel = ({
7321
7415
  }
7322
7416
  )
7323
7417
  ] }),
7324
- visible.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("p", { className: "text-xs text-muted-foreground", children: emptyMessage }) : /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("ul", { className: "flex flex-col gap-2", role: "list", children: visible.map((thread) => /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
7418
+ visible.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("p", { className: "text-xs text-muted-foreground", children: emptyMessage }) : /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("ul", { className: "flex flex-col gap-2", role: "list", children: visible.map((thread) => /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
7325
7419
  CommentThreadCard,
7326
7420
  {
7327
7421
  thread,
@@ -7343,7 +7437,7 @@ var CommentThreadCard = ({
7343
7437
  author,
7344
7438
  formatTime
7345
7439
  }) => {
7346
- const [draft, setDraft] = (0, import_react48.useState)("");
7440
+ const [draft, setDraft] = (0, import_react49.useState)("");
7347
7441
  const isDraft = thread.body === "";
7348
7442
  const quote = thread.anchor?.quote ?? thread.lastQuote ?? "";
7349
7443
  const live = editor && !editor.isDestroyed ? editor : null;
@@ -7369,7 +7463,7 @@ var CommentThreadCard = ({
7369
7463
  setDraft("");
7370
7464
  };
7371
7465
  const stop = (e) => e.stopPropagation();
7372
- return /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)(
7466
+ return /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)(
7373
7467
  "li",
7374
7468
  {
7375
7469
  className: `flex flex-col gap-2 rounded-md border bg-background p-3 cursor-pointer ${active ? "border-primary ring-1 ring-primary" : "border-border"} ${thread.resolved ? "opacity-70" : ""}`,
@@ -7385,24 +7479,24 @@ var CommentThreadCard = ({
7385
7479
  }
7386
7480
  },
7387
7481
  children: [
7388
- /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("div", { className: "flex items-baseline justify-between gap-2", children: [
7389
- /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("span", { className: "font-medium", children: thread.author.name }),
7390
- /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("span", { className: "text-xs text-muted-foreground", children: formatTime(thread.createdAt) })
7482
+ /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)("div", { className: "flex items-baseline justify-between gap-2", children: [
7483
+ /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("span", { className: "font-medium", children: thread.author.name }),
7484
+ /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("span", { className: "text-xs text-muted-foreground", children: formatTime(thread.createdAt) })
7391
7485
  ] }),
7392
- quote && /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("blockquote", { className: "border-l-2 border-border pl-2 text-xs text-muted-foreground line-clamp-2", children: quote }),
7393
- thread.orphaned && /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("span", { className: "text-xs text-destructive", children: "The commented text was deleted." }),
7394
- thread.resolved && /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("span", { className: "text-xs text-muted-foreground", children: "Resolved" }),
7395
- !isDraft && /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("p", { className: "whitespace-pre-wrap break-words", children: thread.body }),
7396
- thread.replies.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("ul", { className: "flex flex-col gap-2 border-l border-border pl-3", role: "list", children: thread.replies.map((reply) => /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("li", { className: "flex flex-col gap-0.5", "data-reply-id": reply.id, children: [
7397
- /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("span", { className: "text-xs", children: [
7398
- /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("span", { className: "font-medium", children: reply.author.name }),
7486
+ quote && /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("blockquote", { className: "border-l-2 border-border pl-2 text-xs text-muted-foreground line-clamp-2", children: quote }),
7487
+ thread.orphaned && /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("span", { className: "text-xs text-destructive", children: "The commented text was deleted." }),
7488
+ thread.resolved && /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("span", { className: "text-xs text-muted-foreground", children: "Resolved" }),
7489
+ !isDraft && /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("p", { className: "whitespace-pre-wrap break-words", children: thread.body }),
7490
+ thread.replies.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("ul", { className: "flex flex-col gap-2 border-l border-border pl-3", role: "list", children: thread.replies.map((reply) => /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)("li", { className: "flex flex-col gap-0.5", "data-reply-id": reply.id, children: [
7491
+ /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)("span", { className: "text-xs", children: [
7492
+ /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("span", { className: "font-medium", children: reply.author.name }),
7399
7493
  " ",
7400
- /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("span", { className: "text-muted-foreground", children: formatTime(reply.createdAt) })
7494
+ /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("span", { className: "text-muted-foreground", children: formatTime(reply.createdAt) })
7401
7495
  ] }),
7402
- /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("p", { className: "whitespace-pre-wrap break-words", children: reply.body })
7496
+ /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("p", { className: "whitespace-pre-wrap break-words", children: reply.body })
7403
7497
  ] }, reply.id)) }),
7404
- (active || isDraft) && !thread.resolved && /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("div", { className: "flex flex-col gap-1", onClick: stop, children: [
7405
- /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
7498
+ (active || isDraft) && !thread.resolved && /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)("div", { className: "flex flex-col gap-1", onClick: stop, children: [
7499
+ /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
7406
7500
  "textarea",
7407
7501
  {
7408
7502
  className: textareaClass,
@@ -7420,9 +7514,9 @@ var CommentThreadCard = ({
7420
7514
  }
7421
7515
  }
7422
7516
  ),
7423
- /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("div", { className: "flex justify-end gap-1", children: [
7424
- isDraft && /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("button", { type: "button", className: buttonClass2, onClick: remove, children: "Cancel" }),
7425
- /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
7517
+ /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)("div", { className: "flex justify-end gap-1", children: [
7518
+ isDraft && /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("button", { type: "button", className: buttonClass2, onClick: remove, children: "Cancel" }),
7519
+ /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
7426
7520
  "button",
7427
7521
  {
7428
7522
  type: "button",
@@ -7434,9 +7528,9 @@ var CommentThreadCard = ({
7434
7528
  )
7435
7529
  ] })
7436
7530
  ] }),
7437
- !isDraft && /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("div", { className: "flex justify-end gap-1", onClick: stop, children: [
7438
- /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("button", { type: "button", className: buttonClass2, onClick: () => setResolved(!thread.resolved), children: thread.resolved ? "Reopen" : "Resolve" }),
7439
- /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
7531
+ !isDraft && /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)("div", { className: "flex justify-end gap-1", onClick: stop, children: [
7532
+ /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("button", { type: "button", className: buttonClass2, onClick: () => setResolved(!thread.resolved), children: thread.resolved ? "Reopen" : "Resolve" }),
7533
+ /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
7440
7534
  "button",
7441
7535
  {
7442
7536
  type: "button",
@@ -7452,7 +7546,7 @@ var CommentThreadCard = ({
7452
7546
  };
7453
7547
 
7454
7548
  // src/review/ReviewToolbar.tsx
7455
- var import_jsx_runtime31 = require("react/jsx-runtime");
7549
+ var import_jsx_runtime32 = require("react/jsx-runtime");
7456
7550
  var defaultDescriptionClass = "max-w-[16rem] truncate px-1 text-xs text-muted-foreground";
7457
7551
  var buttonClass3 = "rounded px-2 py-1 text-xs text-foreground hover:bg-muted disabled:opacity-40 disabled:hover:bg-transparent";
7458
7552
  var ReviewToolbar = ({
@@ -7465,8 +7559,8 @@ var ReviewToolbar = ({
7465
7559
  const count = review.changes.length;
7466
7560
  const current = review.currentChange;
7467
7561
  const index = current ? review.changes.findIndex((c) => c.id === current.id) + 1 : 0;
7468
- return /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)("div", { className, role: "toolbar", "aria-label": "Review", children: [
7469
- /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
7562
+ return /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("div", { className, role: "toolbar", "aria-label": "Review", children: [
7563
+ /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
7470
7564
  "button",
7471
7565
  {
7472
7566
  type: "button",
@@ -7477,8 +7571,8 @@ var ReviewToolbar = ({
7477
7571
  children: review.enabled ? "Tracking on" : "Track changes"
7478
7572
  }
7479
7573
  ),
7480
- /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("span", { className: "mx-1 h-4 w-px bg-border", "aria-hidden": "true" }),
7481
- /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
7574
+ /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("span", { className: "mx-1 h-4 w-px bg-border", "aria-hidden": "true" }),
7575
+ /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
7482
7576
  "button",
7483
7577
  {
7484
7578
  type: "button",
@@ -7489,8 +7583,8 @@ var ReviewToolbar = ({
7489
7583
  children: "\u2039"
7490
7584
  }
7491
7585
  ),
7492
- /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("span", { className: "min-w-[4rem] text-center text-xs text-muted-foreground", "aria-live": "polite", children: count === 0 ? "No changes" : current ? `${index} of ${count}` : `${count} changes` }),
7493
- /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
7586
+ /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("span", { className: "min-w-[4rem] text-center text-xs text-muted-foreground", "aria-live": "polite", children: count === 0 ? "No changes" : current ? `${index} of ${count}` : `${count} changes` }),
7587
+ /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
7494
7588
  "button",
7495
7589
  {
7496
7590
  type: "button",
@@ -7501,7 +7595,7 @@ var ReviewToolbar = ({
7501
7595
  children: "\u203A"
7502
7596
  }
7503
7597
  ),
7504
- showDescription && current && /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)(
7598
+ showDescription && current && /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)(
7505
7599
  "span",
7506
7600
  {
7507
7601
  className: descriptionClassName,
@@ -7513,8 +7607,8 @@ var ReviewToolbar = ({
7513
7607
  ]
7514
7608
  }
7515
7609
  ),
7516
- /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("span", { className: "mx-1 h-4 w-px bg-border", "aria-hidden": "true" }),
7517
- /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
7610
+ /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("span", { className: "mx-1 h-4 w-px bg-border", "aria-hidden": "true" }),
7611
+ /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
7518
7612
  "button",
7519
7613
  {
7520
7614
  type: "button",
@@ -7524,7 +7618,7 @@ var ReviewToolbar = ({
7524
7618
  children: "Accept"
7525
7619
  }
7526
7620
  ),
7527
- /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
7621
+ /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
7528
7622
  "button",
7529
7623
  {
7530
7624
  type: "button",
@@ -7534,18 +7628,18 @@ var ReviewToolbar = ({
7534
7628
  children: "Reject"
7535
7629
  }
7536
7630
  ),
7537
- /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("button", { type: "button", className: buttonClass3, disabled: count === 0, onClick: review.acceptAll, children: "Accept all" }),
7538
- /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("button", { type: "button", className: buttonClass3, disabled: count === 0, onClick: review.rejectAll, children: "Reject all" })
7631
+ /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("button", { type: "button", className: buttonClass3, disabled: count === 0, onClick: review.acceptAll, children: "Accept all" }),
7632
+ /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("button", { type: "button", className: buttonClass3, disabled: count === 0, onClick: review.rejectAll, children: "Reject all" })
7539
7633
  ] });
7540
7634
  };
7541
7635
 
7542
7636
  // src/review/CommentButton.tsx
7543
- var import_jsx_runtime32 = require("react/jsx-runtime");
7637
+ var import_jsx_runtime33 = require("react/jsx-runtime");
7544
7638
  var CommentButton = ({
7545
7639
  editor,
7546
7640
  className = "rounded px-2 py-1 text-xs text-popover-foreground hover:bg-muted",
7547
7641
  children = "Comment"
7548
- }) => /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
7642
+ }) => /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
7549
7643
  "button",
7550
7644
  {
7551
7645
  type: "button",
@@ -7557,13 +7651,13 @@ var CommentButton = ({
7557
7651
  );
7558
7652
 
7559
7653
  // src/review/useDocumentCompare.ts
7560
- var import_react49 = require("react");
7654
+ var import_react50 = require("react");
7561
7655
  var import_editor14 = require("@pixerate/editor");
7562
7656
  function useDocumentCompare(editor, options) {
7563
- const [summary, setSummary] = (0, import_react49.useState)(null);
7564
- const defaults = (0, import_react49.useRef)(options);
7657
+ const [summary, setSummary] = (0, import_react50.useState)(null);
7658
+ const defaults = (0, import_react50.useRef)(options);
7565
7659
  defaults.current = options;
7566
- const compare = (0, import_react49.useCallback)(
7660
+ const compare = (0, import_react50.useCallback)(
7567
7661
  (original, revised, overrides) => {
7568
7662
  if (!editor || editor.isDestroyed) return null;
7569
7663
  const result = (0, import_editor14.applyDocumentComparison)(editor, original, revised, {
@@ -7575,13 +7669,13 @@ function useDocumentCompare(editor, options) {
7575
7669
  },
7576
7670
  [editor]
7577
7671
  );
7578
- const clear = (0, import_react49.useCallback)(() => setSummary(null), []);
7579
- return (0, import_react49.useMemo)(() => ({ summary, compare, clear }), [summary, compare, clear]);
7672
+ const clear = (0, import_react50.useCallback)(() => setSummary(null), []);
7673
+ return (0, import_react50.useMemo)(() => ({ summary, compare, clear }), [summary, compare, clear]);
7580
7674
  }
7581
7675
 
7582
7676
  // src/review/TrackedChangesList.tsx
7583
7677
  var import_editor15 = require("@pixerate/editor");
7584
- var import_jsx_runtime33 = require("react/jsx-runtime");
7678
+ var import_jsx_runtime34 = require("react/jsx-runtime");
7585
7679
  var buttonClass4 = "rounded px-1.5 py-0.5 text-xs text-foreground hover:bg-muted disabled:opacity-40";
7586
7680
  var TrackedChangesList = ({
7587
7681
  editor,
@@ -7592,18 +7686,18 @@ var TrackedChangesList = ({
7592
7686
  }) => {
7593
7687
  const review = useTrackChanges(editor);
7594
7688
  if (review.changes.length === 0) {
7595
- return /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("div", { className, "data-tracked-changes-list": "", children: /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("div", { className: "pixerate-changes-empty text-xs text-muted-foreground", children: emptyState }) });
7689
+ return /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("div", { className, "data-tracked-changes-list": "", children: /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("div", { className: "pixerate-changes-empty text-xs text-muted-foreground", children: emptyState }) });
7596
7690
  }
7597
- return /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("ul", { className, role: "list", "aria-label": "Tracked changes", "data-tracked-changes-list": "", children: review.changes.map((change) => {
7691
+ return /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("ul", { className, role: "list", "aria-label": "Tracked changes", "data-tracked-changes-list": "", children: review.changes.map((change) => {
7598
7692
  const active = change.id === review.currentChangeId;
7599
- return /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)(
7693
+ return /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)(
7600
7694
  "li",
7601
7695
  {
7602
7696
  className: active ? `${itemClassName} ${activeItemClassName}` : itemClassName,
7603
7697
  "data-change-type": change.type,
7604
7698
  "data-change-id": change.id,
7605
7699
  children: [
7606
- /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)(
7700
+ /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)(
7607
7701
  "button",
7608
7702
  {
7609
7703
  type: "button",
@@ -7611,14 +7705,14 @@ var TrackedChangesList = ({
7611
7705
  title: `${change.author.name}: ${change.description}`,
7612
7706
  onClick: () => review.select(change.id),
7613
7707
  children: [
7614
- /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("span", { className: "font-medium", children: (0, import_editor15.trackedChangeLabel)(change) }),
7708
+ /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("span", { className: "font-medium", children: (0, import_editor15.trackedChangeLabel)(change) }),
7615
7709
  change.author.name ? ` \xB7 ${change.author.name}` : "",
7616
- /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("span", { className: "block truncate text-muted-foreground", children: change.description })
7710
+ /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("span", { className: "block truncate text-muted-foreground", children: change.description })
7617
7711
  ]
7618
7712
  }
7619
7713
  ),
7620
- /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("button", { type: "button", className: buttonClass4, onClick: () => review.accept(change.id), children: "Accept" }),
7621
- /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("button", { type: "button", className: buttonClass4, onClick: () => review.reject(change.id), children: "Reject" })
7714
+ /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("button", { type: "button", className: buttonClass4, onClick: () => review.accept(change.id), children: "Accept" }),
7715
+ /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("button", { type: "button", className: buttonClass4, onClick: () => review.reject(change.id), children: "Reject" })
7622
7716
  ]
7623
7717
  },
7624
7718
  `${change.type}:${change.id}`
@@ -7627,12 +7721,12 @@ var TrackedChangesList = ({
7627
7721
  };
7628
7722
 
7629
7723
  // src/commands/useCommandPalette.ts
7630
- var import_react50 = require("react");
7724
+ var import_react51 = require("react");
7631
7725
  var import_commands2 = require("@pixerate/editor/commands");
7632
7726
  function useCommandPalette(registry, options = {}) {
7633
- const optionsRef = (0, import_react50.useRef)(options);
7727
+ const optionsRef = (0, import_react51.useRef)(options);
7634
7728
  optionsRef.current = options;
7635
- const controller = (0, import_react50.useMemo)(
7729
+ const controller = (0, import_react51.useMemo)(
7636
7730
  () => (0, import_commands2.createCommandPaletteController)(registry, {
7637
7731
  context: () => {
7638
7732
  const c = optionsRef.current.context;
@@ -7653,9 +7747,9 @@ function useCommandPalette(registry, options = {}) {
7653
7747
  // eslint-disable-next-line react-hooks/exhaustive-deps
7654
7748
  [registry]
7655
7749
  );
7656
- const state = (0, import_react50.useSyncExternalStore)(controller.subscribe, controller.getState, controller.getState);
7750
+ const state = (0, import_react51.useSyncExternalStore)(controller.subscribe, controller.getState, controller.getState);
7657
7751
  const { hotkey, hotkeyTarget } = options;
7658
- (0, import_react50.useEffect)(() => {
7752
+ (0, import_react51.useEffect)(() => {
7659
7753
  if (!hotkey) return;
7660
7754
  const target = hotkeyTarget ?? (typeof window !== "undefined" ? window : null);
7661
7755
  if (!target) return;
@@ -7683,13 +7777,13 @@ function useCommandPalette(registry, options = {}) {
7683
7777
  }
7684
7778
 
7685
7779
  // src/commands/CommandPalette.tsx
7686
- var import_react51 = __toESM(require("react"), 1);
7687
- var import_jsx_runtime34 = require("react/jsx-runtime");
7780
+ var import_react52 = __toESM(require("react"), 1);
7781
+ var import_jsx_runtime35 = require("react/jsx-runtime");
7688
7782
  function HighlightedLabel({ item }) {
7689
- if (item.labelIndices.length === 0) return /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(import_jsx_runtime34.Fragment, { children: item.label });
7783
+ if (item.labelIndices.length === 0) return /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(import_jsx_runtime35.Fragment, { children: item.label });
7690
7784
  const marked = new Set(item.labelIndices);
7691
- return /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(import_jsx_runtime34.Fragment, { children: Array.from(item.label).map(
7692
- (ch, i) => marked.has(i) ? /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("span", { className: "font-semibold text-foreground", "data-match": "", children: ch }, i) : /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(import_react51.default.Fragment, { children: ch }, i)
7785
+ return /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(import_jsx_runtime35.Fragment, { children: Array.from(item.label).map(
7786
+ (ch, i) => marked.has(i) ? /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("span", { className: "font-semibold text-foreground", "data-match": "", children: ch }, i) : /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(import_react52.default.Fragment, { children: ch }, i)
7693
7787
  ) });
7694
7788
  }
7695
7789
  var CommandPalette = ({
@@ -7698,22 +7792,22 @@ var CommandPalette = ({
7698
7792
  emptyMessage = "No matching commands",
7699
7793
  className = ""
7700
7794
  }) => {
7701
- const inputRef = (0, import_react51.useRef)(null);
7702
- const listRef = (0, import_react51.useRef)(null);
7703
- const baseId = (0, import_react51.useId)();
7795
+ const inputRef = (0, import_react52.useRef)(null);
7796
+ const listRef = (0, import_react52.useRef)(null);
7797
+ const baseId = (0, import_react52.useId)();
7704
7798
  const listId = `${baseId}-list`;
7705
7799
  const optionId = (index) => `${baseId}-option-${index}`;
7706
7800
  const { open, query, items, activeIndex } = palette;
7707
- (0, import_react51.useEffect)(() => {
7801
+ (0, import_react52.useEffect)(() => {
7708
7802
  if (open) inputRef.current?.focus();
7709
7803
  }, [open]);
7710
- (0, import_react51.useEffect)(() => {
7804
+ (0, import_react52.useEffect)(() => {
7711
7805
  if (!open) return;
7712
7806
  const active = listRef.current?.querySelector('[aria-selected="true"]');
7713
7807
  active?.scrollIntoView?.({ block: "nearest" });
7714
7808
  }, [open, activeIndex]);
7715
7809
  if (!open) return null;
7716
- return /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
7810
+ return /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(
7717
7811
  "div",
7718
7812
  {
7719
7813
  className: "fixed inset-0 z-50 flex items-start justify-center bg-black/30 px-4 pt-[15vh]",
@@ -7721,7 +7815,7 @@ var CommandPalette = ({
7721
7815
  onMouseDown: (e) => {
7722
7816
  if (e.target === e.currentTarget) palette.setOpen(false);
7723
7817
  },
7724
- children: /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)(
7818
+ children: /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)(
7725
7819
  "div",
7726
7820
  {
7727
7821
  role: "dialog",
@@ -7730,7 +7824,7 @@ var CommandPalette = ({
7730
7824
  className: `w-full max-w-lg overflow-hidden rounded-lg border border-border bg-popover text-popover-foreground shadow-xl ${className}`,
7731
7825
  style: { background: "var(--popover, var(--background, #fff))" },
7732
7826
  children: [
7733
- /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
7827
+ /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(
7734
7828
  "input",
7735
7829
  {
7736
7830
  ref: inputRef,
@@ -7750,7 +7844,7 @@ var CommandPalette = ({
7750
7844
  className: "w-full border-b border-border bg-transparent px-3 py-2 text-sm outline-none placeholder:text-muted-foreground"
7751
7845
  }
7752
7846
  ),
7753
- items.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("div", { className: "px-3 py-6 text-center text-sm text-muted-foreground", children: emptyMessage }) : /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("ul", { ref: listRef, id: listId, role: "listbox", "aria-label": "Commands", className: "max-h-80 overflow-y-auto py-1", children: items.map((item, index) => /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)(
7847
+ items.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("div", { className: "px-3 py-6 text-center text-sm text-muted-foreground", children: emptyMessage }) : /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("ul", { ref: listRef, id: listId, role: "listbox", "aria-label": "Commands", className: "max-h-80 overflow-y-auto py-1", children: items.map((item, index) => /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)(
7754
7848
  "li",
7755
7849
  {
7756
7850
  id: optionId(index),
@@ -7765,12 +7859,12 @@ var CommandPalette = ({
7765
7859
  onClick: () => palette.run(item.id),
7766
7860
  className: `flex cursor-pointer items-center gap-2 px-3 py-1.5 text-sm ${index === activeIndex ? "bg-muted" : ""} ${item.enabled ? "" : "cursor-default opacity-50"}`,
7767
7861
  children: [
7768
- /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)("span", { className: "min-w-0 flex-1 truncate", children: [
7769
- /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(HighlightedLabel, { item }),
7770
- item.disabledReason && /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("span", { className: "ml-2 text-xs text-muted-foreground", "data-disabled-reason": "", children: item.disabledReason })
7862
+ /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)("span", { className: "min-w-0 flex-1 truncate", children: [
7863
+ /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(HighlightedLabel, { item }),
7864
+ item.disabledReason && /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("span", { className: "ml-2 text-xs text-muted-foreground", "data-disabled-reason": "", children: item.disabledReason })
7771
7865
  ] }),
7772
- item.group && /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("span", { className: "shrink-0 text-xs text-muted-foreground", children: item.group }),
7773
- item.shortcut && /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("kbd", { className: "shrink-0 rounded border border-border px-1.5 font-mono text-[10px] text-muted-foreground", children: item.shortcut })
7866
+ item.group && /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("span", { className: "shrink-0 text-xs text-muted-foreground", children: item.group }),
7867
+ item.shortcut && /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("kbd", { className: "shrink-0 rounded border border-border px-1.5 font-mono text-[10px] text-muted-foreground", children: item.shortcut })
7774
7868
  ]
7775
7869
  },
7776
7870
  item.id
@@ -7783,12 +7877,12 @@ var CommandPalette = ({
7783
7877
  };
7784
7878
 
7785
7879
  // src/commands/useCommandShortcuts.ts
7786
- var import_react52 = require("react");
7880
+ var import_react53 = require("react");
7787
7881
  function useCommandShortcuts(registry, options = {}) {
7788
- const optionsRef = (0, import_react52.useRef)(options);
7882
+ const optionsRef = (0, import_react53.useRef)(options);
7789
7883
  optionsRef.current = options;
7790
7884
  const { enabled = true, target } = options;
7791
- (0, import_react52.useEffect)(() => {
7885
+ (0, import_react53.useEffect)(() => {
7792
7886
  if (!registry || !enabled) return;
7793
7887
  const eventTarget = target ?? (typeof window !== "undefined" ? window : null);
7794
7888
  if (!eventTarget) return;
@@ -7806,14 +7900,14 @@ function useCommandShortcuts(registry, options = {}) {
7806
7900
  }, [registry, enabled, target]);
7807
7901
  }
7808
7902
  function useRegisterCommands(registry, specs) {
7809
- (0, import_react52.useEffect)(() => {
7903
+ (0, import_react53.useEffect)(() => {
7810
7904
  if (!registry || !specs || specs.length === 0) return;
7811
7905
  return registry.register(specs);
7812
7906
  }, [registry, specs]);
7813
7907
  }
7814
7908
 
7815
7909
  // src/persistence/useAutosave.ts
7816
- var import_react53 = require("react");
7910
+ var import_react54 = require("react");
7817
7911
  var import_persistence = require("@pixerate/editor/persistence");
7818
7912
  var IDLE = {
7819
7913
  status: "idle",
@@ -7824,18 +7918,18 @@ var IDLE = {
7824
7918
  ready: false
7825
7919
  };
7826
7920
  function useAutosave(options) {
7827
- const optionsRef = (0, import_react53.useRef)(options);
7921
+ const optionsRef = (0, import_react54.useRef)(options);
7828
7922
  optionsRef.current = options;
7829
7923
  const { storage, key, history, dirty } = options;
7830
7924
  const recover = options.recover !== false;
7831
7925
  const flushOnHide = options.flushOnHide !== false;
7832
7926
  const ready = options.ready !== false;
7833
- const [controller, setController] = (0, import_react53.useState)(null);
7834
- const [status, setStatus] = (0, import_react53.useState)(IDLE);
7835
- const [recovery, setRecovery] = (0, import_react53.useState)(null);
7836
- const [pendingRecovery, setPendingRecovery] = (0, import_react53.useState)(recover);
7837
- const revisionsRef = (0, import_react53.useRef)(null);
7838
- (0, import_react53.useEffect)(() => {
7927
+ const [controller, setController] = (0, import_react54.useState)(null);
7928
+ const [status, setStatus] = (0, import_react54.useState)(IDLE);
7929
+ const [recovery, setRecovery] = (0, import_react54.useState)(null);
7930
+ const [pendingRecovery, setPendingRecovery] = (0, import_react54.useState)(recover);
7931
+ const revisionsRef = (0, import_react54.useRef)(null);
7932
+ (0, import_react54.useEffect)(() => {
7839
7933
  const revisions = (0, import_persistence.createRevisionTracker)({ history, dirty });
7840
7934
  const o = optionsRef.current;
7841
7935
  const instance = (0, import_persistence.createAutosaveController)({
@@ -7878,10 +7972,10 @@ function useAutosave(options) {
7878
7972
  if (revisionsRef.current === revisions) revisionsRef.current = null;
7879
7973
  };
7880
7974
  }, [storage, key, history, dirty, recover]);
7881
- (0, import_react53.useEffect)(() => {
7975
+ (0, import_react54.useEffect)(() => {
7882
7976
  if (controller && ready && !pendingRecovery) controller.ready();
7883
7977
  }, [controller, ready, pendingRecovery]);
7884
- (0, import_react53.useEffect)(() => {
7978
+ (0, import_react54.useEffect)(() => {
7885
7979
  if (!controller || !flushOnHide || typeof window === "undefined") return;
7886
7980
  const flush = () => void controller.flushNow();
7887
7981
  const onVisibility = () => {
@@ -7894,31 +7988,31 @@ function useAutosave(options) {
7894
7988
  document.removeEventListener("visibilitychange", onVisibility);
7895
7989
  };
7896
7990
  }, [controller, flushOnHide]);
7897
- const restore = (0, import_react53.useCallback)(() => {
7991
+ const restore = (0, import_react54.useCallback)(() => {
7898
7992
  const snapshot = recovery?.snapshot;
7899
7993
  setRecovery(null);
7900
7994
  setPendingRecovery(false);
7901
7995
  return snapshot;
7902
7996
  }, [recovery]);
7903
- const discard = (0, import_react53.useCallback)(async () => {
7997
+ const discard = (0, import_react54.useCallback)(async () => {
7904
7998
  if (controller) await controller.discardRecovery();
7905
7999
  setRecovery(null);
7906
8000
  setPendingRecovery(false);
7907
8001
  }, [controller]);
7908
- const flushNow = (0, import_react53.useCallback)(async () => {
8002
+ const flushNow = (0, import_react54.useCallback)(async () => {
7909
8003
  await controller?.flushNow();
7910
8004
  }, [controller]);
7911
- const markClean = (0, import_react53.useCallback)(async () => {
8005
+ const markClean = (0, import_react54.useCallback)(async () => {
7912
8006
  revisionsRef.current?.markSaved();
7913
8007
  await controller?.markClean();
7914
8008
  }, [controller]);
7915
- const notifyChange = (0, import_react53.useCallback)(() => revisionsRef.current?.bump(), []);
8009
+ const notifyChange = (0, import_react54.useCallback)(() => revisionsRef.current?.bump(), []);
7916
8010
  return { status, recovery, pendingRecovery, restore, discard, flushNow, markClean, notifyChange, controller };
7917
8011
  }
7918
8012
 
7919
8013
  // src/persistence/RecoveryPrompt.tsx
7920
8014
  var import_persistence2 = require("@pixerate/editor/persistence");
7921
- var import_jsx_runtime35 = require("react/jsx-runtime");
8015
+ var import_jsx_runtime36 = require("react/jsx-runtime");
7922
8016
  var RecoveryPrompt = ({
7923
8017
  recovery,
7924
8018
  onRestore,
@@ -7930,7 +8024,7 @@ var RecoveryPrompt = ({
7930
8024
  }) => {
7931
8025
  if (!recovery) return null;
7932
8026
  const { name } = recovery.meta;
7933
- return /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)(
8027
+ return /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)(
7934
8028
  "div",
7935
8029
  {
7936
8030
  role: "alertdialog",
@@ -7938,15 +8032,15 @@ var RecoveryPrompt = ({
7938
8032
  "data-recovery-prompt": "",
7939
8033
  className: `flex flex-wrap items-center gap-3 rounded-md border border-border bg-background px-3 py-2 text-sm text-foreground shadow-sm ${className}`,
7940
8034
  children: [
7941
- /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)("span", { className: "min-w-0 flex-1", children: [
8035
+ /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)("span", { className: "min-w-0 flex-1", children: [
7942
8036
  (0, import_persistence2.formatRecoveryMessage)(recovery.meta, formatTime),
7943
- name ? /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)("span", { className: "ml-1 text-xs text-muted-foreground", children: [
8037
+ name ? /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)("span", { className: "ml-1 text-xs text-muted-foreground", children: [
7944
8038
  "(",
7945
8039
  name,
7946
8040
  ")"
7947
8041
  ] }) : null
7948
8042
  ] }),
7949
- /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(
8043
+ /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
7950
8044
  "button",
7951
8045
  {
7952
8046
  type: "button",
@@ -7956,7 +8050,7 @@ var RecoveryPrompt = ({
7956
8050
  children: restoreLabel
7957
8051
  }
7958
8052
  ),
7959
- /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(
8053
+ /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
7960
8054
  "button",
7961
8055
  {
7962
8056
  type: "button",
@@ -7972,17 +8066,17 @@ var RecoveryPrompt = ({
7972
8066
  };
7973
8067
 
7974
8068
  // src/generation/useGenerationPlan.ts
7975
- var import_react54 = require("react");
8069
+ var import_react55 = require("react");
7976
8070
  var import_generation = require("@pixerate/editor/generation");
7977
8071
  function useGenerationPlan(request, capabilities, options = {}) {
7978
8072
  const key = JSON.stringify([request, capabilities, options]);
7979
- return (0, import_react54.useMemo)(() => (0, import_generation.planGenerationRequest)(request, capabilities, options), [key]);
8073
+ return (0, import_react55.useMemo)(() => (0, import_generation.planGenerationRequest)(request, capabilities, options), [key]);
7980
8074
  }
7981
8075
  function useJobProgress(options) {
7982
8076
  const { startedAt, expectedMs, done, now, intervalMs = 1e3 } = options;
7983
- const [tick, setTick] = (0, import_react54.useState)(() => Date.now());
8077
+ const [tick, setTick] = (0, import_react55.useState)(() => Date.now());
7984
8078
  const ticking = !done && now === void 0;
7985
- (0, import_react54.useEffect)(() => {
8079
+ (0, import_react55.useEffect)(() => {
7986
8080
  if (!ticking) return;
7987
8081
  setTick(Date.now());
7988
8082
  const id = setInterval(() => setTick(Date.now()), Math.max(16, intervalMs));
@@ -7992,9 +8086,9 @@ function useJobProgress(options) {
7992
8086
  }
7993
8087
 
7994
8088
  // src/generation/GenerationSettings.tsx
7995
- var import_react55 = require("react");
8089
+ var import_react56 = require("react");
7996
8090
  var import_generation2 = require("@pixerate/editor/generation");
7997
- var import_jsx_runtime36 = require("react/jsx-runtime");
8091
+ var import_jsx_runtime37 = require("react/jsx-runtime");
7998
8092
  var inputClass2 = "w-full rounded-md border border-border bg-background px-2 py-1 text-sm outline-none focus:ring-1 focus:ring-ring";
7999
8093
  function Control({
8000
8094
  control,
@@ -8004,7 +8098,7 @@ function Control({
8004
8098
  }) {
8005
8099
  const shown = value ?? control.defaultValue;
8006
8100
  if (control.kind === "checkbox") {
8007
- return /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
8101
+ return /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
8008
8102
  "input",
8009
8103
  {
8010
8104
  id,
@@ -8016,7 +8110,7 @@ function Control({
8016
8110
  );
8017
8111
  }
8018
8112
  if (control.kind === "select") {
8019
- return /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)(
8113
+ return /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)(
8020
8114
  "select",
8021
8115
  {
8022
8116
  id,
@@ -8025,14 +8119,14 @@ function Control({
8025
8119
  value: shown === void 0 ? "" : String(shown),
8026
8120
  onChange: (e) => onValue((0, import_generation2.parseControlValue)(control, e.target.value)),
8027
8121
  children: [
8028
- shown === void 0 && /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("option", { value: "", children: "Default" }),
8029
- control.options.map((option) => /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("option", { value: String(option.value), children: option.label }, String(option.value)))
8122
+ shown === void 0 && /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("option", { value: "", children: "Default" }),
8123
+ control.options.map((option) => /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("option", { value: String(option.value), children: option.label }, String(option.value)))
8030
8124
  ]
8031
8125
  }
8032
8126
  );
8033
8127
  }
8034
8128
  if (control.kind === "textarea") {
8035
- return /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
8129
+ return /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
8036
8130
  "textarea",
8037
8131
  {
8038
8132
  id,
@@ -8046,8 +8140,8 @@ function Control({
8046
8140
  );
8047
8141
  }
8048
8142
  const numeric = typeof shown === "number" ? shown : void 0;
8049
- return /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)("div", { className: "flex items-center gap-2", children: [
8050
- /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
8143
+ return /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)("div", { className: "flex items-center gap-2", children: [
8144
+ /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
8051
8145
  "input",
8052
8146
  {
8053
8147
  id,
@@ -8061,7 +8155,7 @@ function Control({
8061
8155
  onChange: (e) => onValue((0, import_generation2.parseControlValue)(control, e.target.value))
8062
8156
  }
8063
8157
  ),
8064
- control.kind === "range" && /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("span", { className: "w-10 text-right tabular-nums text-muted-foreground", "data-field-value": "", children: numeric ?? "\u2013" })
8158
+ control.kind === "range" && /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("span", { className: "w-10 text-right tabular-nums text-muted-foreground", "data-field-value": "", children: numeric ?? "\u2013" })
8065
8159
  ] });
8066
8160
  }
8067
8161
  var GenerationSettings = ({
@@ -8075,17 +8169,17 @@ var GenerationSettings = ({
8075
8169
  renderReference,
8076
8170
  className = ""
8077
8171
  }) => {
8078
- const baseId = (0, import_react55.useId)();
8079
- const controls = (0, import_react55.useMemo)(() => (0, import_generation2.getGenerationControls)(capabilities), [capabilities]);
8172
+ const baseId = (0, import_react56.useId)();
8173
+ const controls = (0, import_react56.useMemo)(() => (0, import_generation2.getGenerationControls)(capabilities), [capabilities]);
8080
8174
  const computed = useGenerationPlan(value, capabilities, { strategy });
8081
8175
  const plan = planProp ?? computed;
8082
8176
  const slots = (0, import_generation2.getReferenceSlots)(capabilities, value);
8083
- return /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)("div", { className: `flex flex-col gap-3 text-sm ${className}`, "data-generation-settings": "", "data-model": capabilities.id, children: [
8177
+ return /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)("div", { className: `flex flex-col gap-3 text-sm ${className}`, "data-generation-settings": "", "data-model": capabilities.id, children: [
8084
8178
  controls.map((control) => {
8085
8179
  const id = `${baseId}-${control.key}`;
8086
- return /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)("div", { className: "flex flex-col gap-1", "data-control": control.key, children: [
8087
- /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("label", { htmlFor: id, className: "text-xs font-medium text-muted-foreground", title: control.description, children: control.label }),
8088
- /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
8180
+ return /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)("div", { className: "flex flex-col gap-1", "data-control": control.key, children: [
8181
+ /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("label", { htmlFor: id, className: "text-xs font-medium text-muted-foreground", title: control.description, children: control.label }),
8182
+ /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
8089
8183
  Control,
8090
8184
  {
8091
8185
  control,
@@ -8096,23 +8190,23 @@ var GenerationSettings = ({
8096
8190
  )
8097
8191
  ] }, control.key);
8098
8192
  }),
8099
- slots.map((slot) => /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)("fieldset", { className: "flex flex-col gap-1", "data-reference-role": slot.role, children: [
8100
- /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)("legend", { className: "text-xs font-medium text-muted-foreground", title: slot.description, children: [
8193
+ slots.map((slot) => /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)("fieldset", { className: "flex flex-col gap-1", "data-reference-role": slot.role, children: [
8194
+ /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)("legend", { className: "text-xs font-medium text-muted-foreground", title: slot.description, children: [
8101
8195
  slot.label,
8102
8196
  " ",
8103
- /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)("span", { className: "tabular-nums", "data-reference-count": "", children: [
8197
+ /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)("span", { className: "tabular-nums", "data-reference-count": "", children: [
8104
8198
  "(",
8105
8199
  slot.references.length,
8106
8200
  "/",
8107
8201
  slot.max,
8108
8202
  ")"
8109
8203
  ] }),
8110
- slot.min > 0 && /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("span", { className: "text-destructive", children: " *" })
8204
+ slot.min > 0 && /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("span", { className: "text-destructive", children: " *" })
8111
8205
  ] }),
8112
- /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)("ul", { className: "flex flex-wrap gap-1", children: [
8113
- slot.references.map((ref) => /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)("li", { className: "flex items-center gap-1 rounded border border-border px-1.5 py-0.5", "data-reference-id": ref.id, children: [
8114
- renderReference ? renderReference(ref) : /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("span", { className: "max-w-[10rem] truncate", children: ref.id }),
8115
- /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
8206
+ /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)("ul", { className: "flex flex-wrap gap-1", children: [
8207
+ slot.references.map((ref) => /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)("li", { className: "flex items-center gap-1 rounded border border-border px-1.5 py-0.5", "data-reference-id": ref.id, children: [
8208
+ renderReference ? renderReference(ref) : /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("span", { className: "max-w-[10rem] truncate", children: ref.id }),
8209
+ /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
8116
8210
  "button",
8117
8211
  {
8118
8212
  type: "button",
@@ -8123,7 +8217,7 @@ var GenerationSettings = ({
8123
8217
  }
8124
8218
  )
8125
8219
  ] }, ref.id)),
8126
- onAddReference && slot.canAdd && /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("li", { children: /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
8220
+ onAddReference && slot.canAdd && /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("li", { children: /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
8127
8221
  "button",
8128
8222
  {
8129
8223
  type: "button",
@@ -8134,21 +8228,21 @@ var GenerationSettings = ({
8134
8228
  ) })
8135
8229
  ] })
8136
8230
  ] }, slot.role)),
8137
- showAdjustments && plan.adjustments.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("ul", { role: "status", className: "flex flex-col gap-0.5 text-xs text-muted-foreground", "data-generation-adjustments": "", children: plan.adjustments.map((adjustment, index) => /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("li", { "data-adjustment-field": adjustment.field, "data-adjustment-kind": adjustment.kind, children: adjustment.reason }, index)) }),
8138
- showAdjustments && plan.errors.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("ul", { role: "alert", className: "flex flex-col gap-0.5 text-xs text-destructive", "data-generation-errors": "", children: plan.errors.map((error, index) => /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("li", { "data-error-field": error.field, children: error.message }, index)) })
8231
+ showAdjustments && plan.adjustments.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("ul", { role: "status", className: "flex flex-col gap-0.5 text-xs text-muted-foreground", "data-generation-adjustments": "", children: plan.adjustments.map((adjustment, index) => /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("li", { "data-adjustment-field": adjustment.field, "data-adjustment-kind": adjustment.kind, children: adjustment.reason }, index)) }),
8232
+ showAdjustments && plan.errors.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("ul", { role: "alert", className: "flex flex-col gap-0.5 text-xs text-destructive", "data-generation-errors": "", children: plan.errors.map((error, index) => /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("li", { "data-error-field": error.field, children: error.message }, index)) })
8139
8233
  ] });
8140
8234
  };
8141
8235
 
8142
8236
  // src/generation/JobProgress.tsx
8143
- var import_jsx_runtime37 = require("react/jsx-runtime");
8237
+ var import_jsx_runtime38 = require("react/jsx-runtime");
8144
8238
  var JobProgress = ({ title, className = "", ...options }) => {
8145
8239
  const progress = useJobProgress(options);
8146
- return /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)("div", { className: `flex flex-col gap-1 text-sm ${className}`, "data-job-progress": "", "data-done": options.done ? "" : void 0, children: [
8147
- /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)("div", { className: "flex items-center justify-between gap-2 text-muted-foreground", children: [
8148
- title && /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("span", { className: "truncate text-foreground", children: title }),
8149
- /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("span", { "data-job-progress-label": "", "aria-live": "polite", children: progress.label })
8240
+ return /* @__PURE__ */ (0, import_jsx_runtime38.jsxs)("div", { className: `flex flex-col gap-1 text-sm ${className}`, "data-job-progress": "", "data-done": options.done ? "" : void 0, children: [
8241
+ /* @__PURE__ */ (0, import_jsx_runtime38.jsxs)("div", { className: "flex items-center justify-between gap-2 text-muted-foreground", children: [
8242
+ title && /* @__PURE__ */ (0, import_jsx_runtime38.jsx)("span", { className: "truncate text-foreground", children: title }),
8243
+ /* @__PURE__ */ (0, import_jsx_runtime38.jsx)("span", { "data-job-progress-label": "", "aria-live": "polite", children: progress.label })
8150
8244
  ] }),
8151
- /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
8245
+ /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(
8152
8246
  "div",
8153
8247
  {
8154
8248
  role: "progressbar",
@@ -8158,7 +8252,7 @@ var JobProgress = ({ title, className = "", ...options }) => {
8158
8252
  "aria-valuenow": progress.percent,
8159
8253
  "aria-valuetext": `${progress.percent}%, ${progress.label}`,
8160
8254
  className: "h-1.5 w-full overflow-hidden rounded-full bg-muted",
8161
- children: /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
8255
+ children: /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(
8162
8256
  "div",
8163
8257
  {
8164
8258
  className: "h-full rounded-full bg-primary transition-[width] duration-500",
@@ -8171,9 +8265,9 @@ var JobProgress = ({ title, className = "", ...options }) => {
8171
8265
  };
8172
8266
 
8173
8267
  // src/generation/AssetMentionChips.tsx
8174
- var import_react56 = require("react");
8268
+ var import_react57 = require("react");
8175
8269
  var import_generation3 = require("@pixerate/editor/generation");
8176
- var import_jsx_runtime38 = require("react/jsx-runtime");
8270
+ var import_jsx_runtime39 = require("react/jsx-runtime");
8177
8271
  var AssetMentionChips = ({
8178
8272
  content,
8179
8273
  onChange,
@@ -8183,14 +8277,14 @@ var AssetMentionChips = ({
8183
8277
  renderAsset,
8184
8278
  className = ""
8185
8279
  }) => {
8186
- const [open, setOpen] = (0, import_react56.useState)(null);
8187
- const rootRef = (0, import_react56.useRef)(null);
8188
- const chips = (0, import_react56.useMemo)(
8280
+ const [open, setOpen] = (0, import_react57.useState)(null);
8281
+ const rootRef = (0, import_react57.useRef)(null);
8282
+ const chips = (0, import_react57.useMemo)(
8189
8283
  () => (0, import_generation3.describeAssetMentions)((0, import_generation3.findTextMentions)(content), assets, capabilities),
8190
8284
  [content, assets, capabilities]
8191
8285
  );
8192
8286
  const options = roles ?? (capabilities ? (0, import_generation3.getAssetRoleOptions)(capabilities) : (0, import_generation3.defaultAssetRoleOptions)());
8193
- (0, import_react56.useEffect)(() => {
8287
+ (0, import_react57.useEffect)(() => {
8194
8288
  if (open === null) return;
8195
8289
  const onPointer = (event) => {
8196
8290
  if (!rootRef.current?.contains(event.target)) setOpen(null);
@@ -8198,19 +8292,19 @@ var AssetMentionChips = ({
8198
8292
  document.addEventListener("mousedown", onPointer);
8199
8293
  return () => document.removeEventListener("mousedown", onPointer);
8200
8294
  }, [open]);
8201
- const pick = (chip5, role) => {
8295
+ const pick = (chip6, role) => {
8202
8296
  setOpen(null);
8203
- if (chip5.start === void 0) return;
8204
- onChange((0, import_generation3.setMentionRoleInText)(content, chip5.start, role));
8297
+ if (chip6.start === void 0) return;
8298
+ onChange((0, import_generation3.setMentionRoleInText)(content, chip6.start, role));
8205
8299
  };
8206
8300
  if (chips.length === 0) return null;
8207
- return /* @__PURE__ */ (0, import_jsx_runtime38.jsx)("div", { ref: rootRef, className: `flex flex-wrap gap-1.5 ${className}`, "data-asset-mention-chips": "", children: chips.map((chip5) => {
8208
- const error = chip5.issues.find((issue) => issue.severity === "error");
8209
- const warning = chip5.issues.find((issue) => issue.severity === "warning");
8301
+ return /* @__PURE__ */ (0, import_jsx_runtime39.jsx)("div", { ref: rootRef, className: `flex flex-wrap gap-1.5 ${className}`, "data-asset-mention-chips": "", children: chips.map((chip6) => {
8302
+ const error = chip6.issues.find((issue) => issue.severity === "error");
8303
+ const warning = chip6.issues.find((issue) => issue.severity === "warning");
8210
8304
  const problem = error ?? warning;
8211
- const isOpen = open === chip5.index;
8212
- return /* @__PURE__ */ (0, import_jsx_runtime38.jsxs)("span", { className: "relative inline-flex", "data-asset-chip": chip5.asset.id, children: [
8213
- /* @__PURE__ */ (0, import_jsx_runtime38.jsxs)(
8305
+ const isOpen = open === chip6.index;
8306
+ return /* @__PURE__ */ (0, import_jsx_runtime39.jsxs)("span", { className: "relative inline-flex", "data-asset-chip": chip6.asset.id, children: [
8307
+ /* @__PURE__ */ (0, import_jsx_runtime39.jsxs)(
8214
8308
  "button",
8215
8309
  {
8216
8310
  type: "button",
@@ -8218,82 +8312,82 @@ var AssetMentionChips = ({
8218
8312
  "aria-expanded": isOpen,
8219
8313
  title: problem?.message,
8220
8314
  "data-issue": problem?.code,
8221
- onClick: () => setOpen(isOpen ? null : chip5.index),
8315
+ onClick: () => setOpen(isOpen ? null : chip6.index),
8222
8316
  onKeyDown: (e) => {
8223
8317
  if (e.key === "Escape") setOpen(null);
8224
8318
  },
8225
8319
  className: `inline-flex items-center gap-1 rounded-full border px-2 py-0.5 text-xs ${error ? "border-red-500/60" : warning ? "border-amber-500/60" : "border-border"} bg-muted/40 hover:bg-muted`,
8226
8320
  children: [
8227
- /* @__PURE__ */ (0, import_jsx_runtime38.jsx)("span", { children: renderAsset ? renderAsset(chip5) : `@${chip5.asset.label ?? chip5.handle}` }),
8228
- /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(
8321
+ /* @__PURE__ */ (0, import_jsx_runtime39.jsx)("span", { children: renderAsset ? renderAsset(chip6) : `@${chip6.asset.label ?? chip6.handle}` }),
8322
+ /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(
8229
8323
  "span",
8230
8324
  {
8231
- className: `rounded px-1 text-[10px] uppercase tracking-wide ${chip5.role ? "bg-primary/15" : "opacity-60"}`,
8232
- "data-role-badge": chip5.role ?? "",
8233
- children: chip5.roleLabel ?? "No role"
8325
+ className: `rounded px-1 text-[10px] uppercase tracking-wide ${chip6.role ? "bg-primary/15" : "opacity-60"}`,
8326
+ "data-role-badge": chip6.role ?? "",
8327
+ children: chip6.roleLabel ?? "No role"
8234
8328
  }
8235
8329
  )
8236
8330
  ]
8237
8331
  }
8238
8332
  ),
8239
- isOpen && /* @__PURE__ */ (0, import_jsx_runtime38.jsxs)(
8333
+ isOpen && /* @__PURE__ */ (0, import_jsx_runtime39.jsxs)(
8240
8334
  "div",
8241
8335
  {
8242
8336
  role: "listbox",
8243
- "aria-label": `Role for ${chip5.asset.label ?? chip5.handle}`,
8337
+ "aria-label": `Role for ${chip6.asset.label ?? chip6.handle}`,
8244
8338
  className: "absolute left-0 top-full z-50 mt-1 flex min-w-[12rem] flex-col rounded-md border border-border bg-background p-1 text-xs shadow-lg",
8245
8339
  "data-role-picker": "",
8246
8340
  onKeyDown: (e) => {
8247
8341
  if (e.key === "Escape") setOpen(null);
8248
8342
  },
8249
8343
  children: [
8250
- options.map((option) => /* @__PURE__ */ (0, import_jsx_runtime38.jsxs)(
8344
+ options.map((option) => /* @__PURE__ */ (0, import_jsx_runtime39.jsxs)(
8251
8345
  "button",
8252
8346
  {
8253
8347
  type: "button",
8254
8348
  role: "option",
8255
- "aria-selected": chip5.role === option.role,
8349
+ "aria-selected": chip6.role === option.role,
8256
8350
  "data-role-option": option.role,
8257
8351
  title: option.description,
8258
- onClick: () => pick(chip5, option.role),
8352
+ onClick: () => pick(chip6, option.role),
8259
8353
  className: "flex items-center justify-between gap-2 rounded px-2 py-1 text-left hover:bg-muted",
8260
8354
  children: [
8261
- /* @__PURE__ */ (0, import_jsx_runtime38.jsx)("span", { children: option.label }),
8262
- option.accepts?.length ? /* @__PURE__ */ (0, import_jsx_runtime38.jsx)("span", { className: "text-[10px] opacity-60", children: option.accepts.join(", ") }) : null
8355
+ /* @__PURE__ */ (0, import_jsx_runtime39.jsx)("span", { children: option.label }),
8356
+ option.accepts?.length ? /* @__PURE__ */ (0, import_jsx_runtime39.jsx)("span", { className: "text-[10px] opacity-60", children: option.accepts.join(", ") }) : null
8263
8357
  ]
8264
8358
  },
8265
8359
  option.role
8266
8360
  )),
8267
- /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(
8361
+ /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(
8268
8362
  "button",
8269
8363
  {
8270
8364
  type: "button",
8271
8365
  role: "option",
8272
- "aria-selected": !chip5.role,
8366
+ "aria-selected": !chip6.role,
8273
8367
  "data-role-option": "",
8274
- onClick: () => pick(chip5, null),
8368
+ onClick: () => pick(chip6, null),
8275
8369
  className: "rounded px-2 py-1 text-left opacity-70 hover:bg-muted",
8276
8370
  children: "No role"
8277
8371
  }
8278
8372
  ),
8279
- chip5.issues.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime38.jsx)("ul", { className: "mt-1 border-t border-border px-2 pt-1 text-[10px]", "data-chip-issues": "", children: chip5.issues.map((issue, i) => /* @__PURE__ */ (0, import_jsx_runtime38.jsx)("li", { className: issue.severity === "error" ? "text-red-500" : "text-amber-500", children: issue.message }, i)) })
8373
+ chip6.issues.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime39.jsx)("ul", { className: "mt-1 border-t border-border px-2 pt-1 text-[10px]", "data-chip-issues": "", children: chip6.issues.map((issue, i) => /* @__PURE__ */ (0, import_jsx_runtime39.jsx)("li", { className: issue.severity === "error" ? "text-red-500" : "text-amber-500", children: issue.message }, i)) })
8280
8374
  ]
8281
8375
  }
8282
8376
  )
8283
- ] }, `${chip5.start}-${chip5.index}`);
8377
+ ] }, `${chip6.start}-${chip6.index}`);
8284
8378
  }) });
8285
8379
  };
8286
8380
 
8287
8381
  // src/generation/GenerationHistory.tsx
8288
- var import_react57 = require("react");
8382
+ var import_react58 = require("react");
8289
8383
  var import_generation4 = require("@pixerate/editor/generation");
8290
- var import_jsx_runtime39 = require("react/jsx-runtime");
8384
+ var import_jsx_runtime40 = require("react/jsx-runtime");
8291
8385
  function useGenerationRecords(store, filter) {
8292
- const [records, setRecords] = (0, import_react57.useState)([]);
8293
- const [loading, setLoading] = (0, import_react57.useState)(!!store);
8294
- const [error, setError] = (0, import_react57.useState)(null);
8386
+ const [records, setRecords] = (0, import_react58.useState)([]);
8387
+ const [loading, setLoading] = (0, import_react58.useState)(!!store);
8388
+ const [error, setError] = (0, import_react58.useState)(null);
8295
8389
  const filterKey = (0, import_generation4.stableStringify)(filter ?? {});
8296
- const refresh = (0, import_react57.useCallback)(async () => {
8390
+ const refresh = (0, import_react58.useCallback)(async () => {
8297
8391
  if (!store) {
8298
8392
  setRecords([]);
8299
8393
  setLoading(false);
@@ -8310,7 +8404,7 @@ function useGenerationRecords(store, filter) {
8310
8404
  setLoading(false);
8311
8405
  }
8312
8406
  }, [store, filterKey]);
8313
- (0, import_react57.useEffect)(() => {
8407
+ (0, import_react58.useEffect)(() => {
8314
8408
  void refresh();
8315
8409
  if (!store) return;
8316
8410
  return store.subscribe(() => void refresh());
@@ -8336,21 +8430,21 @@ var GenerationHistory = ({
8336
8430
  emptyText = "No generations yet.",
8337
8431
  className = ""
8338
8432
  }) => {
8339
- const [innerMode, setInnerMode] = (0, import_react57.useState)("exact");
8433
+ const [innerMode, setInnerMode] = (0, import_react58.useState)("exact");
8340
8434
  const mode = modeProp ?? innerMode;
8341
8435
  const setMode = (next) => {
8342
8436
  if (modeProp === void 0) setInnerMode(next);
8343
8437
  onModeChange?.(next);
8344
8438
  };
8345
- const options = (0, import_react57.useMemo)(() => ({ templates, capabilities, assets, mode }), [templates, capabilities, assets, mode]);
8346
- const results = (0, import_react57.useMemo)(() => records.map((record) => (0, import_generation4.recreateRequest)(record, options)), [records, options]);
8347
- const models = (0, import_react57.useMemo)(
8439
+ const options = (0, import_react58.useMemo)(() => ({ templates, capabilities, assets, mode }), [templates, capabilities, assets, mode]);
8440
+ const results = (0, import_react58.useMemo)(() => records.map((record) => (0, import_generation4.recreateRequest)(record, options)), [records, options]);
8441
+ const models = (0, import_react58.useMemo)(
8348
8442
  () => capabilities ? Array.isArray(capabilities) ? capabilities : [capabilities] : [],
8349
8443
  [capabilities]
8350
8444
  );
8351
- return /* @__PURE__ */ (0, import_jsx_runtime39.jsxs)("div", { className: `flex flex-col gap-2 text-sm ${className}`, "data-generation-history": "", children: [
8352
- /* @__PURE__ */ (0, import_jsx_runtime39.jsx)("div", { className: "flex items-center gap-2 text-xs", role: "radiogroup", "aria-label": "Recreate mode", children: ["exact", "latest"].map((value) => /* @__PURE__ */ (0, import_jsx_runtime39.jsxs)("label", { className: "inline-flex items-center gap-1", children: [
8353
- /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(
8445
+ return /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)("div", { className: `flex flex-col gap-2 text-sm ${className}`, "data-generation-history": "", children: [
8446
+ /* @__PURE__ */ (0, import_jsx_runtime40.jsx)("div", { className: "flex items-center gap-2 text-xs", role: "radiogroup", "aria-label": "Recreate mode", children: ["exact", "latest"].map((value) => /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)("label", { className: "inline-flex items-center gap-1", children: [
8447
+ /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(
8354
8448
  "input",
8355
8449
  {
8356
8450
  type: "radio",
@@ -8363,34 +8457,34 @@ var GenerationHistory = ({
8363
8457
  ),
8364
8458
  value === "exact" ? "Exact (recorded versions)" : "Latest templates & settings"
8365
8459
  ] }, value)) }),
8366
- records.length === 0 && /* @__PURE__ */ (0, import_jsx_runtime39.jsx)("p", { className: "text-xs text-muted-foreground", children: emptyText }),
8367
- /* @__PURE__ */ (0, import_jsx_runtime39.jsx)("ul", { className: "flex flex-col gap-2", children: records.map((record, i) => {
8460
+ records.length === 0 && /* @__PURE__ */ (0, import_jsx_runtime40.jsx)("p", { className: "text-xs text-muted-foreground", children: emptyText }),
8461
+ /* @__PURE__ */ (0, import_jsx_runtime40.jsx)("ul", { className: "flex flex-col gap-2", children: records.map((record, i) => {
8368
8462
  const result = results[i];
8369
8463
  const model = models.find((m) => m.id === record.provenance.modelId);
8370
8464
  const blocked = !result.ok;
8371
- return /* @__PURE__ */ (0, import_jsx_runtime39.jsxs)(
8465
+ return /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)(
8372
8466
  "li",
8373
8467
  {
8374
8468
  className: "rounded-md border border-border p-2",
8375
8469
  "data-record": record.id,
8376
8470
  "data-drift": result.drift.length,
8377
8471
  children: [
8378
- /* @__PURE__ */ (0, import_jsx_runtime39.jsxs)("div", { className: "flex flex-wrap items-center justify-between gap-2 text-xs", children: [
8379
- /* @__PURE__ */ (0, import_jsx_runtime39.jsx)("span", { className: "font-medium", children: model?.name ?? record.provenance.modelId }),
8380
- /* @__PURE__ */ (0, import_jsx_runtime39.jsxs)("span", { className: "text-muted-foreground", children: [
8381
- record.kind !== "generate" && /* @__PURE__ */ (0, import_jsx_runtime39.jsxs)("span", { "data-kind": "", children: [
8472
+ /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)("div", { className: "flex flex-wrap items-center justify-between gap-2 text-xs", children: [
8473
+ /* @__PURE__ */ (0, import_jsx_runtime40.jsx)("span", { className: "font-medium", children: model?.name ?? record.provenance.modelId }),
8474
+ /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)("span", { className: "text-muted-foreground", children: [
8475
+ record.kind !== "generate" && /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)("span", { "data-kind": "", children: [
8382
8476
  record.kind,
8383
8477
  " \xB7 "
8384
8478
  ] }),
8385
- /* @__PURE__ */ (0, import_jsx_runtime39.jsx)("time", { dateTime: record.createdAt, children: record.createdAt.replace("T", " ").slice(0, 16) }),
8386
- record.seed !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime39.jsxs)(import_jsx_runtime39.Fragment, { children: [
8479
+ /* @__PURE__ */ (0, import_jsx_runtime40.jsx)("time", { dateTime: record.createdAt, children: record.createdAt.replace("T", " ").slice(0, 16) }),
8480
+ record.seed !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)(import_jsx_runtime40.Fragment, { children: [
8387
8481
  " \xB7 seed ",
8388
8482
  record.seed
8389
8483
  ] })
8390
8484
  ] })
8391
8485
  ] }),
8392
- /* @__PURE__ */ (0, import_jsx_runtime39.jsx)("p", { className: "mt-1 line-clamp-3 break-words text-xs", "data-record-prompt": "", children: record.provenance.resolvedPrompt }),
8393
- record.assets.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime39.jsx)("div", { className: "mt-1 flex flex-wrap gap-1", children: record.assets.map((asset) => /* @__PURE__ */ (0, import_jsx_runtime39.jsxs)(
8486
+ /* @__PURE__ */ (0, import_jsx_runtime40.jsx)("p", { className: "mt-1 line-clamp-3 break-words text-xs", "data-record-prompt": "", children: record.provenance.resolvedPrompt }),
8487
+ record.assets.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime40.jsx)("div", { className: "mt-1 flex flex-wrap gap-1", children: record.assets.map((asset) => /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)(
8394
8488
  "span",
8395
8489
  {
8396
8490
  className: "rounded-full bg-muted px-2 py-0.5 text-[10px]",
@@ -8404,16 +8498,16 @@ var GenerationHistory = ({
8404
8498
  `${asset.role}:${asset.id}`
8405
8499
  )) }),
8406
8500
  renderPreview?.(record),
8407
- result.drift.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime39.jsx)("ul", { className: "mt-1 flex flex-col gap-0.5 text-[11px]", "data-drift-report": "", children: result.drift.map((item, j) => /* @__PURE__ */ (0, import_jsx_runtime39.jsxs)("li", { className: severityClass[item.severity], "data-drift-type": item.type, children: [
8408
- /* @__PURE__ */ (0, import_jsx_runtime39.jsxs)("strong", { children: [
8501
+ result.drift.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime40.jsx)("ul", { className: "mt-1 flex flex-col gap-0.5 text-[11px]", "data-drift-report": "", children: result.drift.map((item, j) => /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)("li", { className: severityClass[item.severity], "data-drift-type": item.type, children: [
8502
+ /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)("strong", { children: [
8409
8503
  import_generation4.DRIFT_TYPE_LABELS[item.type],
8410
8504
  ":"
8411
8505
  ] }),
8412
8506
  " ",
8413
8507
  item.message
8414
8508
  ] }, j)) }),
8415
- /* @__PURE__ */ (0, import_jsx_runtime39.jsxs)("div", { className: "mt-2 flex gap-2", children: [
8416
- onRecreate && /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(
8509
+ /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)("div", { className: "mt-2 flex gap-2", children: [
8510
+ onRecreate && /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(
8417
8511
  "button",
8418
8512
  {
8419
8513
  type: "button",
@@ -8425,7 +8519,7 @@ var GenerationHistory = ({
8425
8519
  children: "Recreate"
8426
8520
  }
8427
8521
  ),
8428
- onVariation && /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(
8522
+ onVariation && /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(
8429
8523
  "button",
8430
8524
  {
8431
8525
  type: "button",
@@ -8435,7 +8529,7 @@ var GenerationHistory = ({
8435
8529
  children: "Variation"
8436
8530
  }
8437
8531
  ),
8438
- onRemove && /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(
8532
+ onRemove && /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(
8439
8533
  "button",
8440
8534
  {
8441
8535
  type: "button",
@@ -8455,19 +8549,19 @@ var GenerationHistory = ({
8455
8549
  };
8456
8550
 
8457
8551
  // src/find-replace/useFindReplace.ts
8458
- var import_react58 = require("react");
8552
+ var import_react59 = require("react");
8459
8553
  var import_editor16 = require("@pixerate/editor");
8460
8554
  var noopUnsubscribe2 = () => {
8461
8555
  };
8462
8556
  function useFindReplace(editor) {
8463
8557
  const store = (0, import_editor16.getFindReplaceStore)(editor ?? null);
8464
- const subscribe = (0, import_react58.useCallback)(
8558
+ const subscribe = (0, import_react59.useCallback)(
8465
8559
  (onChange) => store ? store.subscribe(() => onChange()) : noopUnsubscribe2,
8466
8560
  [store]
8467
8561
  );
8468
8562
  const getSnapshot = () => store?.getSnapshot() ?? import_editor16.EMPTY_FIND_REPLACE_SNAPSHOT;
8469
- const snapshot = (0, import_react58.useSyncExternalStore)(subscribe, getSnapshot, getSnapshot);
8470
- return (0, import_react58.useMemo)(() => {
8563
+ const snapshot = (0, import_react59.useSyncExternalStore)(subscribe, getSnapshot, getSnapshot);
8564
+ return (0, import_react59.useMemo)(() => {
8471
8565
  const run = (fn) => {
8472
8566
  if (editor && !editor.isDestroyed && store) fn(editor);
8473
8567
  };
@@ -8491,9 +8585,9 @@ function useFindReplace(editor) {
8491
8585
  }
8492
8586
 
8493
8587
  // src/find-replace/FindReplaceBar.tsx
8494
- var import_react59 = require("react");
8588
+ var import_react60 = require("react");
8495
8589
  var import_editor17 = require("@pixerate/editor");
8496
- var import_jsx_runtime40 = require("react/jsx-runtime");
8590
+ var import_jsx_runtime41 = require("react/jsx-runtime");
8497
8591
  var inputClass3 = "min-w-0 flex-1 rounded border border-input bg-background px-2 py-1 text-xs text-foreground focus:outline-none focus:ring-1 focus:ring-ring";
8498
8592
  var buttonClass5 = "rounded px-2 py-1 text-xs text-foreground hover:bg-muted disabled:opacity-40 disabled:hover:bg-transparent";
8499
8593
  var toggleClass = (on) => `${buttonClass5} font-mono ${on ? "bg-primary/10 text-primary" : "text-muted-foreground"}`;
@@ -8506,10 +8600,10 @@ var FindReplaceBar = ({
8506
8600
  onClose
8507
8601
  }) => {
8508
8602
  const find = useFindReplace(editor);
8509
- const findInput = (0, import_react59.useRef)(null);
8510
- const [moreOpen, setMoreOpen] = (0, import_react59.useState)(false);
8603
+ const findInput = (0, import_react60.useRef)(null);
8604
+ const [moreOpen, setMoreOpen] = (0, import_react60.useState)(false);
8511
8605
  const visible = find.available && (alwaysOpen || find.open);
8512
- (0, import_react59.useEffect)(() => {
8606
+ (0, import_react60.useEffect)(() => {
8513
8607
  if (!visible || find.focusRequest === 0) return;
8514
8608
  findInput.current?.focus();
8515
8609
  findInput.current?.select();
@@ -8547,9 +8641,9 @@ var FindReplaceBar = ({
8547
8641
  if (isMod(e)) find.replaceAll();
8548
8642
  else find.replace();
8549
8643
  };
8550
- return /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)("div", { className, role: "search", "aria-label": "Find and replace", onKeyDown: onBarKeyDown, children: [
8551
- /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)("div", { className: "flex items-center gap-1", children: [
8552
- /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(
8644
+ return /* @__PURE__ */ (0, import_jsx_runtime41.jsxs)("div", { className, role: "search", "aria-label": "Find and replace", onKeyDown: onBarKeyDown, children: [
8645
+ /* @__PURE__ */ (0, import_jsx_runtime41.jsxs)("div", { className: "flex items-center gap-1", children: [
8646
+ /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
8553
8647
  "button",
8554
8648
  {
8555
8649
  type: "button",
@@ -8560,7 +8654,7 @@ var FindReplaceBar = ({
8560
8654
  children: showReplace ? "\u25BE" : "\u25B8"
8561
8655
  }
8562
8656
  ),
8563
- /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(
8657
+ /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
8564
8658
  "input",
8565
8659
  {
8566
8660
  ref: findInput,
@@ -8574,7 +8668,7 @@ var FindReplaceBar = ({
8574
8668
  onKeyDown: onFindKeyDown
8575
8669
  }
8576
8670
  ),
8577
- import_editor17.FIND_OPTION_TOGGLES.filter((t) => !t.advanced).map((t) => /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(
8671
+ import_editor17.FIND_OPTION_TOGGLES.filter((t) => !t.advanced).map((t) => /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
8578
8672
  "button",
8579
8673
  {
8580
8674
  type: "button",
@@ -8587,7 +8681,7 @@ var FindReplaceBar = ({
8587
8681
  },
8588
8682
  t.key
8589
8683
  )),
8590
- /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(
8684
+ /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
8591
8685
  "span",
8592
8686
  {
8593
8687
  className: `min-w-[5rem] px-1 text-center text-xs ${find.error ? "text-destructive" : "text-muted-foreground"}`,
@@ -8597,9 +8691,9 @@ var FindReplaceBar = ({
8597
8691
  children: status
8598
8692
  }
8599
8693
  ),
8600
- /* @__PURE__ */ (0, import_jsx_runtime40.jsx)("button", { type: "button", className: buttonClass5, "aria-label": "Previous match", disabled: !hasMatches, onClick: find.previous, children: "\u2191" }),
8601
- /* @__PURE__ */ (0, import_jsx_runtime40.jsx)("button", { type: "button", className: buttonClass5, "aria-label": "Next match", disabled: !hasMatches, onClick: find.next, children: "\u2193" }),
8602
- showMoreOptions && /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(
8694
+ /* @__PURE__ */ (0, import_jsx_runtime41.jsx)("button", { type: "button", className: buttonClass5, "aria-label": "Previous match", disabled: !hasMatches, onClick: find.previous, children: "\u2191" }),
8695
+ /* @__PURE__ */ (0, import_jsx_runtime41.jsx)("button", { type: "button", className: buttonClass5, "aria-label": "Next match", disabled: !hasMatches, onClick: find.next, children: "\u2193" }),
8696
+ showMoreOptions && /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
8603
8697
  "button",
8604
8698
  {
8605
8699
  type: "button",
@@ -8610,10 +8704,10 @@ var FindReplaceBar = ({
8610
8704
  children: "\u2026"
8611
8705
  }
8612
8706
  ),
8613
- /* @__PURE__ */ (0, import_jsx_runtime40.jsx)("button", { type: "button", className: buttonClass5, "aria-label": "Close find", onClick: close, children: "\xD7" })
8707
+ /* @__PURE__ */ (0, import_jsx_runtime41.jsx)("button", { type: "button", className: buttonClass5, "aria-label": "Close find", onClick: close, children: "\xD7" })
8614
8708
  ] }),
8615
- showReplace && /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)("div", { className: "flex items-center gap-1 pl-7", children: [
8616
- /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(
8709
+ showReplace && /* @__PURE__ */ (0, import_jsx_runtime41.jsxs)("div", { className: "flex items-center gap-1 pl-7", children: [
8710
+ /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
8617
8711
  "input",
8618
8712
  {
8619
8713
  type: "text",
@@ -8625,7 +8719,7 @@ var FindReplaceBar = ({
8625
8719
  onKeyDown: onReplaceKeyDown
8626
8720
  }
8627
8721
  ),
8628
- /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(
8722
+ /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
8629
8723
  "button",
8630
8724
  {
8631
8725
  type: "button",
@@ -8635,11 +8729,11 @@ var FindReplaceBar = ({
8635
8729
  children: "Replace"
8636
8730
  }
8637
8731
  ),
8638
- /* @__PURE__ */ (0, import_jsx_runtime40.jsx)("button", { type: "button", className: buttonClass5, disabled: !hasMatches, onClick: find.replaceAll, children: "Replace all" }),
8639
- find.lastReplaceCount !== null && /* @__PURE__ */ (0, import_jsx_runtime40.jsx)("span", { className: "px-1 text-xs text-muted-foreground", "aria-live": "polite", children: find.lastReplaceCount === 1 ? "1 replaced" : `${find.lastReplaceCount} replaced` })
8732
+ /* @__PURE__ */ (0, import_jsx_runtime41.jsx)("button", { type: "button", className: buttonClass5, disabled: !hasMatches, onClick: find.replaceAll, children: "Replace all" }),
8733
+ find.lastReplaceCount !== null && /* @__PURE__ */ (0, import_jsx_runtime41.jsx)("span", { className: "px-1 text-xs text-muted-foreground", "aria-live": "polite", children: find.lastReplaceCount === 1 ? "1 replaced" : `${find.lastReplaceCount} replaced` })
8640
8734
  ] }),
8641
- showMoreOptions && moreOpen && /* @__PURE__ */ (0, import_jsx_runtime40.jsx)("div", { className: "flex flex-wrap items-center gap-x-3 gap-y-1 pl-7 text-xs text-muted-foreground", children: import_editor17.FIND_OPTION_TOGGLES.filter((t) => t.advanced).map((t) => /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)("label", { className: "flex items-center gap-1", children: [
8642
- /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(
8735
+ showMoreOptions && moreOpen && /* @__PURE__ */ (0, import_jsx_runtime41.jsx)("div", { className: "flex flex-wrap items-center gap-x-3 gap-y-1 pl-7 text-xs text-muted-foreground", children: import_editor17.FIND_OPTION_TOGGLES.filter((t) => t.advanced).map((t) => /* @__PURE__ */ (0, import_jsx_runtime41.jsxs)("label", { className: "flex items-center gap-1", children: [
8736
+ /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
8643
8737
  "input",
8644
8738
  {
8645
8739
  type: "checkbox",
@@ -8653,12 +8747,12 @@ var FindReplaceBar = ({
8653
8747
  };
8654
8748
 
8655
8749
  // src/tables/useTableMenu.ts
8656
- var import_react60 = require("react");
8750
+ var import_react61 = require("react");
8657
8751
  var import_editor18 = require("@pixerate/editor");
8658
8752
  function useTableMenu(editor) {
8659
- const store = (0, import_react60.useMemo)(() => (0, import_editor18.createTableStore)(editor), [editor]);
8660
- const snapshot = (0, import_react60.useSyncExternalStore)(store.subscribe, store.getSnapshot, store.getSnapshot);
8661
- return (0, import_react60.useMemo)(
8753
+ const store = (0, import_react61.useMemo)(() => (0, import_editor18.createTableStore)(editor), [editor]);
8754
+ const snapshot = (0, import_react61.useSyncExternalStore)(store.subscribe, store.getSnapshot, store.getSnapshot);
8755
+ return (0, import_react61.useMemo)(
8662
8756
  () => ({
8663
8757
  ...snapshot,
8664
8758
  run: (action, params) => (0, import_editor18.runTableAction)(editor, action, params, { focus: true }),
@@ -8669,9 +8763,9 @@ function useTableMenu(editor) {
8669
8763
  }
8670
8764
 
8671
8765
  // src/tables/TableToolbar.tsx
8672
- var import_react61 = __toESM(require("react"), 1);
8766
+ var import_react62 = __toESM(require("react"), 1);
8673
8767
  var import_editor19 = require("@pixerate/editor");
8674
- var import_jsx_runtime41 = require("react/jsx-runtime");
8768
+ var import_jsx_runtime42 = require("react/jsx-runtime");
8675
8769
  var keepSelection2 = (event) => event.preventDefault();
8676
8770
  var TableToolbar = ({
8677
8771
  editor,
@@ -8685,14 +8779,14 @@ var TableToolbar = ({
8685
8779
  }) => {
8686
8780
  const table = useTableMenu(editor);
8687
8781
  if (!editor || !table.inTable && !showWhenOutside) return null;
8688
- return /* @__PURE__ */ (0, import_jsx_runtime41.jsx)("div", { className, role: "toolbar", "aria-label": "Table", "data-table-toolbar": "", children: items.map((item, index) => {
8782
+ return /* @__PURE__ */ (0, import_jsx_runtime42.jsx)("div", { className, role: "toolbar", "aria-label": "Table", "data-table-toolbar": "", children: items.map((item, index) => {
8689
8783
  const status = table.check(item.action, item.params);
8690
8784
  const enabled = status === true;
8691
8785
  const active = item.active?.(table);
8692
8786
  const separator = index > 0 && items[index - 1].group !== item.group;
8693
- return /* @__PURE__ */ (0, import_jsx_runtime41.jsxs)(import_react61.default.Fragment, { children: [
8694
- separator && /* @__PURE__ */ (0, import_jsx_runtime41.jsx)("span", { className: separatorClassName, "aria-hidden": "true" }),
8695
- /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
8787
+ return /* @__PURE__ */ (0, import_jsx_runtime42.jsxs)(import_react62.default.Fragment, { children: [
8788
+ separator && /* @__PURE__ */ (0, import_jsx_runtime42.jsx)("span", { className: separatorClassName, "aria-hidden": "true" }),
8789
+ /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(
8696
8790
  "button",
8697
8791
  {
8698
8792
  type: "button",
@@ -8714,8 +8808,8 @@ var TableToolbar = ({
8714
8808
  };
8715
8809
 
8716
8810
  // src/tables/InsertTableGrid.tsx
8717
- var import_react62 = require("react");
8718
- var import_jsx_runtime42 = require("react/jsx-runtime");
8811
+ var import_react63 = require("react");
8812
+ var import_jsx_runtime43 = require("react/jsx-runtime");
8719
8813
  var keepSelection3 = (event) => event.preventDefault();
8720
8814
  var InsertTableGrid = ({
8721
8815
  editor,
@@ -8728,14 +8822,14 @@ var InsertTableGrid = ({
8728
8822
  onInsert
8729
8823
  }) => {
8730
8824
  const table = useTableMenu(editor);
8731
- const [hover, setHover] = (0, import_react62.useState)(null);
8825
+ const [hover, setHover] = (0, import_react63.useState)(null);
8732
8826
  const status = table.actions.insertTable;
8733
8827
  const disabled = !editor || !status.enabled;
8734
8828
  const insert = (size) => {
8735
8829
  if (table.run("insertTable", { ...size, withHeaderRow })) onInsert?.(size);
8736
8830
  setHover(null);
8737
8831
  };
8738
- return /* @__PURE__ */ (0, import_jsx_runtime42.jsxs)(
8832
+ return /* @__PURE__ */ (0, import_jsx_runtime43.jsxs)(
8739
8833
  "div",
8740
8834
  {
8741
8835
  className,
@@ -8745,7 +8839,7 @@ var InsertTableGrid = ({
8745
8839
  "data-insert-table-grid": "",
8746
8840
  onMouseLeave: () => setHover(null),
8747
8841
  children: [
8748
- /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(
8842
+ /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(
8749
8843
  "div",
8750
8844
  {
8751
8845
  role: "grid",
@@ -8754,7 +8848,7 @@ var InsertTableGrid = ({
8754
8848
  children: Array.from({ length: rows * cols }, (_, i) => {
8755
8849
  const size = { rows: Math.floor(i / cols) + 1, cols: i % cols + 1 };
8756
8850
  const active = !!hover && size.rows <= hover.rows && size.cols <= hover.cols;
8757
- return /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(
8851
+ return /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(
8758
8852
  "button",
8759
8853
  {
8760
8854
  type: "button",
@@ -8774,7 +8868,7 @@ var InsertTableGrid = ({
8774
8868
  })
8775
8869
  }
8776
8870
  ),
8777
- /* @__PURE__ */ (0, import_jsx_runtime42.jsx)("div", { "aria-live": "polite", "data-testid": "insert-table-size", children: disabled ? status.reason : hover ? `${hover.rows} \xD7 ${hover.cols}` : "Insert table" })
8871
+ /* @__PURE__ */ (0, import_jsx_runtime43.jsx)("div", { "aria-live": "polite", "data-testid": "insert-table-size", children: disabled ? status.reason : hover ? `${hover.rows} \xD7 ${hover.cols}` : "Insert table" })
8778
8872
  ]
8779
8873
  }
8780
8874
  );
@@ -8782,31 +8876,31 @@ var InsertTableGrid = ({
8782
8876
 
8783
8877
  // src/tables/TableBubbleMenu.tsx
8784
8878
  var import_editor20 = require("@pixerate/editor");
8785
- var import_jsx_runtime43 = require("react/jsx-runtime");
8879
+ var import_jsx_runtime44 = require("react/jsx-runtime");
8786
8880
  var TableBubbleMenu = ({
8787
8881
  editor,
8788
8882
  children,
8789
8883
  toolbarProps,
8790
8884
  pluginKey = "tableBubbleMenu",
8791
8885
  ...rest
8792
- }) => /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(BubbleMenu, { editor, pluginKey, shouldShow: import_editor20.shouldShowTableBubbleMenu, ...rest, children: children ?? /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(TableToolbar, { editor, ...toolbarProps }) });
8886
+ }) => /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(BubbleMenu, { editor, pluginKey, shouldShow: import_editor20.shouldShowTableBubbleMenu, ...rest, children: children ?? /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(TableToolbar, { editor, ...toolbarProps }) });
8793
8887
 
8794
8888
  // src/chart-node/ChartNodeView.tsx
8795
8889
  var import_client = require("react-dom/client");
8796
8890
 
8797
8891
  // src/chart/ChartCanvas.tsx
8798
- var import_react64 = require("react");
8892
+ var import_react65 = require("react");
8799
8893
  var import_chart2 = require("@pixerate/editor/chart");
8800
8894
 
8801
8895
  // src/chart/useChartEditor.ts
8802
- var import_react63 = require("react");
8896
+ var import_react64 = require("react");
8803
8897
  var import_chart = require("@pixerate/editor/chart");
8804
8898
  function useChartState(controller) {
8805
- return (0, import_react63.useSyncExternalStore)(controller.subscribe, controller.getState, controller.getState);
8899
+ return (0, import_react64.useSyncExternalStore)(controller.subscribe, controller.getState, controller.getState);
8806
8900
  }
8807
8901
 
8808
8902
  // src/chart/ChartCanvas.tsx
8809
- var import_jsx_runtime44 = require("react/jsx-runtime");
8903
+ var import_jsx_runtime45 = require("react/jsx-runtime");
8810
8904
  function renderChartMark(mark, fontFamily, interactive) {
8811
8905
  const common = {
8812
8906
  "data-role": mark.role,
@@ -8818,9 +8912,9 @@ function renderChartMark(mark, fontFamily, interactive) {
8818
8912
  };
8819
8913
  switch (mark.kind) {
8820
8914
  case "rect":
8821
- return /* @__PURE__ */ (0, import_jsx_runtime44.jsx)("rect", { ...common, x: mark.x, y: mark.y, width: mark.width, height: mark.height, rx: mark.radius, style: { fill: mark.fill, stroke: mark.stroke, strokeWidth: mark.strokeWidth } }, mark.key);
8915
+ return /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("rect", { ...common, x: mark.x, y: mark.y, width: mark.width, height: mark.height, rx: mark.radius, style: { fill: mark.fill, stroke: mark.stroke, strokeWidth: mark.strokeWidth } }, mark.key);
8822
8916
  case "path":
8823
- return /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(
8917
+ return /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(
8824
8918
  "path",
8825
8919
  {
8826
8920
  ...common,
@@ -8833,11 +8927,11 @@ function renderChartMark(mark, fontFamily, interactive) {
8833
8927
  mark.key
8834
8928
  );
8835
8929
  case "circle":
8836
- return /* @__PURE__ */ (0, import_jsx_runtime44.jsx)("circle", { ...common, cx: mark.cx, cy: mark.cy, r: mark.r, style: { fill: mark.fill, stroke: mark.stroke, strokeWidth: mark.strokeWidth } }, mark.key);
8930
+ return /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("circle", { ...common, cx: mark.cx, cy: mark.cy, r: mark.r, style: { fill: mark.fill, stroke: mark.stroke, strokeWidth: mark.strokeWidth } }, mark.key);
8837
8931
  case "line":
8838
- return /* @__PURE__ */ (0, import_jsx_runtime44.jsx)("line", { ...common, x1: mark.x1, y1: mark.y1, x2: mark.x2, y2: mark.y2, strokeDasharray: mark.dash, style: { stroke: mark.stroke, strokeWidth: mark.strokeWidth } }, mark.key);
8932
+ return /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("line", { ...common, x1: mark.x1, y1: mark.y1, x2: mark.x2, y2: mark.y2, strokeDasharray: mark.dash, style: { stroke: mark.stroke, strokeWidth: mark.strokeWidth } }, mark.key);
8839
8933
  case "text":
8840
- return /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(
8934
+ return /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(
8841
8935
  "text",
8842
8936
  {
8843
8937
  ...common,
@@ -8854,23 +8948,23 @@ function renderChartMark(mark, fontFamily, interactive) {
8854
8948
  }
8855
8949
  }
8856
8950
  function ChartPresenceLayer({ presence }) {
8857
- const { actors } = (0, import_react64.useSyncExternalStore)(presence.subscribe, presence.getState, presence.getState);
8858
- return /* @__PURE__ */ (0, import_jsx_runtime44.jsx)("g", { "data-chart-presence": "", pointerEvents: "none", children: actors.map((a) => /* @__PURE__ */ (0, import_jsx_runtime44.jsxs)("g", { transform: `translate(${a.x} ${a.y})`, "data-actor": a.id, children: [
8859
- /* @__PURE__ */ (0, import_jsx_runtime44.jsx)("path", { d: "M0,0 L0,14 L4,10.5 L7,17 L9.5,16 L6.5,9.5 L11.5,9.5 Z", style: { fill: a.color, stroke: "#ffffff", strokeWidth: 1 }, transform: a.pressed ? "scale(0.9)" : void 0 }),
8860
- /* @__PURE__ */ (0, import_jsx_runtime44.jsxs)("g", { transform: "translate(13 16)", children: [
8861
- /* @__PURE__ */ (0, import_jsx_runtime44.jsx)("rect", { x: 0, y: 0, rx: 4, height: 18, width: Math.max(28, (a.message ?? a.name).length * 6.4 + 12), style: { fill: a.color } }),
8862
- /* @__PURE__ */ (0, import_jsx_runtime44.jsx)("text", { x: 6, y: 9, dominantBaseline: "central", style: { fill: "#ffffff", fontSize: 11, fontWeight: 600, fontFamily: "inherit" }, children: a.message ?? a.name })
8951
+ const { actors } = (0, import_react65.useSyncExternalStore)(presence.subscribe, presence.getState, presence.getState);
8952
+ return /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("g", { "data-chart-presence": "", pointerEvents: "none", children: actors.map((a) => /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)("g", { transform: `translate(${a.x} ${a.y})`, "data-actor": a.id, children: [
8953
+ /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("path", { d: "M0,0 L0,14 L4,10.5 L7,17 L9.5,16 L6.5,9.5 L11.5,9.5 Z", style: { fill: a.color, stroke: "#ffffff", strokeWidth: 1 }, transform: a.pressed ? "scale(0.9)" : void 0 }),
8954
+ /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)("g", { transform: "translate(13 16)", children: [
8955
+ /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("rect", { x: 0, y: 0, rx: 4, height: 18, width: Math.max(28, (a.message ?? a.name).length * 6.4 + 12), style: { fill: a.color } }),
8956
+ /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("text", { x: 6, y: 9, dominantBaseline: "central", style: { fill: "#ffffff", fontSize: 11, fontWeight: 600, fontFamily: "inherit" }, children: a.message ?? a.name })
8863
8957
  ] })
8864
8958
  ] }, a.id)) });
8865
8959
  }
8866
8960
  function ChartCanvas({ controller, width = 640, height = 400, responsive = true, theme, editable = true, measureText, emptyMessage, className, presence, sceneRef }) {
8867
8961
  const state = useChartState(controller);
8868
- const wrapper = (0, import_react64.useRef)(null);
8869
- const svg = (0, import_react64.useRef)(null);
8870
- const drag = (0, import_react64.useRef)(null);
8871
- const [measured, setMeasured] = (0, import_react64.useState)(null);
8872
- const [frozen, setFrozen] = (0, import_react64.useState)(null);
8873
- (0, import_react64.useEffect)(() => {
8962
+ const wrapper = (0, import_react65.useRef)(null);
8963
+ const svg = (0, import_react65.useRef)(null);
8964
+ const drag = (0, import_react65.useRef)(null);
8965
+ const [measured, setMeasured] = (0, import_react65.useState)(null);
8966
+ const [frozen, setFrozen] = (0, import_react65.useState)(null);
8967
+ (0, import_react65.useEffect)(() => {
8874
8968
  const el = wrapper.current;
8875
8969
  if (!responsive || !el || typeof ResizeObserver === "undefined") return;
8876
8970
  const observer = new ResizeObserver(([entry]) => {
@@ -8881,8 +8975,8 @@ function ChartCanvas({ controller, width = 640, height = 400, responsive = true,
8881
8975
  return () => observer.disconnect();
8882
8976
  }, [responsive]);
8883
8977
  const sceneWidth = responsive && measured || width;
8884
- const fullTheme = (0, import_react64.useMemo)(() => ({ ...import_chart2.CSS_VARIABLE_CHART_THEME, ...theme }), [theme]);
8885
- const scene = (0, import_react64.useMemo)(
8978
+ const fullTheme = (0, import_react65.useMemo)(() => ({ ...import_chart2.CSS_VARIABLE_CHART_THEME, ...theme }), [theme]);
8979
+ const scene = (0, import_react65.useMemo)(
8886
8980
  () => (0, import_chart2.layoutChart)(state.spec, {
8887
8981
  width: sceneWidth,
8888
8982
  height,
@@ -8898,8 +8992,8 @@ function ChartCanvas({ controller, width = 640, height = 400, responsive = true,
8898
8992
  [state.spec, state.selection, sceneWidth, height, fullTheme, editable, measureText, emptyMessage, frozen]
8899
8993
  );
8900
8994
  if (sceneRef) sceneRef.current = scene;
8901
- const byKey = (0, import_react64.useMemo)(() => new Map(scene.marks.map((m) => [m.key, m])), [scene]);
8902
- (0, import_react64.useEffect)(() => () => drag.current?.end(), []);
8995
+ const byKey = (0, import_react65.useMemo)(() => new Map(scene.marks.map((m) => [m.key, m])), [scene]);
8996
+ (0, import_react65.useEffect)(() => () => drag.current?.end(), []);
8903
8997
  const scenePoint = (e) => (0, import_chart2.chartClientToScene)(scene, svg.current.getBoundingClientRect(), e.clientX, e.clientY);
8904
8998
  const onPointerDown = (e) => {
8905
8999
  if (!editable || e.button !== 0) return;
@@ -8932,7 +9026,7 @@ function ChartCanvas({ controller, width = 640, height = 400, responsive = true,
8932
9026
  if (editable && (0, import_chart2.handleChartKey)(controller, scene, e)) e.preventDefault();
8933
9027
  };
8934
9028
  const label = state.spec.title || "Chart";
8935
- return /* @__PURE__ */ (0, import_jsx_runtime44.jsx)("div", { ref: wrapper, className: `w-full ${className ?? ""}`, "data-chart-canvas": "", children: /* @__PURE__ */ (0, import_jsx_runtime44.jsxs)(
9029
+ return /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("div", { ref: wrapper, className: `w-full ${className ?? ""}`, "data-chart-canvas": "", children: /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)(
8936
9030
  "svg",
8937
9031
  {
8938
9032
  ref: svg,
@@ -8950,14 +9044,14 @@ function ChartCanvas({ controller, width = 640, height = 400, responsive = true,
8950
9044
  onKeyDown,
8951
9045
  children: [
8952
9046
  scene.marks.map((m) => renderChartMark(m, scene.theme.fontFamily, editable)),
8953
- presence && /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(ChartPresenceLayer, { presence })
9047
+ presence && /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(ChartPresenceLayer, { presence })
8954
9048
  ]
8955
9049
  }
8956
9050
  ) });
8957
9051
  }
8958
9052
 
8959
9053
  // src/chart/ChartDataGrid.tsx
8960
- var import_react65 = require("react");
9054
+ var import_react66 = require("react");
8961
9055
  var import_chart3 = require("@pixerate/editor/chart");
8962
9056
 
8963
9057
  // src/chart/styles.ts
@@ -8970,11 +9064,11 @@ var chartSectionClass = "space-y-2 border-b border-border pb-3 last:border-b-0";
8970
9064
  var chartCellClass = "h-7 w-full min-w-[4.5rem] bg-transparent px-2 text-right text-xs tabular-nums text-foreground focus-visible:bg-background focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-inset focus-visible:ring-primary";
8971
9065
 
8972
9066
  // src/chart/ChartDataGrid.tsx
8973
- var import_jsx_runtime45 = require("react/jsx-runtime");
9067
+ var import_jsx_runtime46 = require("react/jsx-runtime");
8974
9068
  function ChartCommitInput({ value, onCommit, onKeyDown, onBlur, ...rest }) {
8975
- const [draft, setDraft] = (0, import_react65.useState)(value);
8976
- const typing = (0, import_react65.useRef)(false);
8977
- (0, import_react65.useEffect)(() => {
9069
+ const [draft, setDraft] = (0, import_react66.useState)(value);
9070
+ const typing = (0, import_react66.useRef)(false);
9071
+ (0, import_react66.useEffect)(() => {
8978
9072
  if (!typing.current) setDraft(value);
8979
9073
  }, [value]);
8980
9074
  const commit = () => {
@@ -8983,7 +9077,7 @@ function ChartCommitInput({ value, onCommit, onKeyDown, onBlur, ...rest }) {
8983
9077
  if (draft === value) return;
8984
9078
  if (onCommit(draft) === false) setDraft(value);
8985
9079
  };
8986
- return /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(
9080
+ return /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(
8987
9081
  "input",
8988
9082
  {
8989
9083
  ...rest,
@@ -9018,15 +9112,15 @@ function ChartDataGrid({ controller, categoryHeader = "Category", readOnly = fal
9018
9112
  e.preventDefault();
9019
9113
  controller.pasteCells(row, column, text);
9020
9114
  };
9021
- return /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)("div", { className: `overflow-auto rounded-md border border-border ${className ?? ""}`, "data-chart-grid": "", children: [
9022
- /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)("table", { className: "w-full border-collapse text-xs", children: [
9023
- /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("thead", { className: "bg-muted/50", children: /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)("tr", { children: [
9024
- /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("th", { className: "border-b border-r border-border px-2 py-1 text-left font-medium text-muted-foreground", children: categoryHeader }),
9115
+ return /* @__PURE__ */ (0, import_jsx_runtime46.jsxs)("div", { className: `overflow-auto rounded-md border border-border ${className ?? ""}`, "data-chart-grid": "", children: [
9116
+ /* @__PURE__ */ (0, import_jsx_runtime46.jsxs)("table", { className: "w-full border-collapse text-xs", children: [
9117
+ /* @__PURE__ */ (0, import_jsx_runtime46.jsx)("thead", { className: "bg-muted/50", children: /* @__PURE__ */ (0, import_jsx_runtime46.jsxs)("tr", { children: [
9118
+ /* @__PURE__ */ (0, import_jsx_runtime46.jsx)("th", { className: "border-b border-r border-border px-2 py-1 text-left font-medium text-muted-foreground", children: categoryHeader }),
9025
9119
  spec.series.map((s, si) => {
9026
9120
  const color = (0, import_chart3.chartSeriesColor)(spec, si);
9027
9121
  const selected = selection?.kind === "series" && selection.seriesId === s.id;
9028
- return /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("th", { "data-series-id": s.id, className: `border-b border-r border-border px-1 py-1 font-medium ${selected ? "bg-primary/10" : ""}`, children: /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)("div", { className: "flex items-center gap-1", children: [
9029
- /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(
9122
+ return /* @__PURE__ */ (0, import_jsx_runtime46.jsx)("th", { "data-series-id": s.id, className: `border-b border-r border-border px-1 py-1 font-medium ${selected ? "bg-primary/10" : ""}`, children: /* @__PURE__ */ (0, import_jsx_runtime46.jsxs)("div", { className: "flex items-center gap-1", children: [
9123
+ /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(
9030
9124
  "input",
9031
9125
  {
9032
9126
  type: "color",
@@ -9039,7 +9133,7 @@ function ChartDataGrid({ controller, categoryHeader = "Category", readOnly = fal
9039
9133
  className: "h-5 w-5 shrink-0 cursor-pointer rounded border-0 bg-transparent p-0"
9040
9134
  }
9041
9135
  ),
9042
- /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(
9136
+ /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(
9043
9137
  ChartCommitInput,
9044
9138
  {
9045
9139
  value: s.name,
@@ -9049,8 +9143,8 @@ function ChartDataGrid({ controller, categoryHeader = "Category", readOnly = fal
9049
9143
  className: `${chartInputClass} h-6 min-w-[5rem] border-transparent bg-transparent font-medium ${s.hidden ? "text-muted-foreground line-through" : ""}`
9050
9144
  }
9051
9145
  ),
9052
- !readOnly && /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)(import_jsx_runtime45.Fragment, { children: [
9053
- /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(
9146
+ !readOnly && /* @__PURE__ */ (0, import_jsx_runtime46.jsxs)(import_jsx_runtime46.Fragment, { children: [
9147
+ /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(
9054
9148
  "button",
9055
9149
  {
9056
9150
  type: "button",
@@ -9063,16 +9157,16 @@ function ChartDataGrid({ controller, categoryHeader = "Category", readOnly = fal
9063
9157
  children: s.hidden ? "\u25CB" : "\u25CF"
9064
9158
  }
9065
9159
  ),
9066
- /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("button", { type: "button", className: chartIconButtonClass, title: "Delete series", "aria-label": `Delete ${s.name}`, "data-action": "remove-series", onClick: () => controller.removeSeries(s.id), children: "\xD7" })
9160
+ /* @__PURE__ */ (0, import_jsx_runtime46.jsx)("button", { type: "button", className: chartIconButtonClass, title: "Delete series", "aria-label": `Delete ${s.name}`, "data-action": "remove-series", onClick: () => controller.removeSeries(s.id), children: "\xD7" })
9067
9161
  ] })
9068
9162
  ] }) }, s.id);
9069
9163
  }),
9070
- !readOnly && /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("th", { className: "w-8 border-b border-border px-1", children: /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("button", { type: "button", className: chartIconButtonClass, title: "Add series", "aria-label": "Add series", "data-action": "add-series", onClick: () => controller.addSeries(), children: "+" }) })
9164
+ !readOnly && /* @__PURE__ */ (0, import_jsx_runtime46.jsx)("th", { className: "w-8 border-b border-border px-1", children: /* @__PURE__ */ (0, import_jsx_runtime46.jsx)("button", { type: "button", className: chartIconButtonClass, title: "Add series", "aria-label": "Add series", "data-action": "add-series", onClick: () => controller.addSeries(), children: "+" }) })
9071
9165
  ] }) }),
9072
- /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("tbody", { children: spec.categories.map((category, i) => {
9166
+ /* @__PURE__ */ (0, import_jsx_runtime46.jsx)("tbody", { children: spec.categories.map((category, i) => {
9073
9167
  const rowSelected = selection?.kind === "category" && selection.index === i;
9074
- return /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)("tr", { "data-category-index": i, className: rowSelected ? "bg-primary/10" : void 0, children: [
9075
- /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("th", { className: "border-b border-r border-border p-0 text-left font-normal", children: /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(
9168
+ return /* @__PURE__ */ (0, import_jsx_runtime46.jsxs)("tr", { "data-category-index": i, className: rowSelected ? "bg-primary/10" : void 0, children: [
9169
+ /* @__PURE__ */ (0, import_jsx_runtime46.jsx)("th", { className: "border-b border-r border-border p-0 text-left font-normal", children: /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(
9076
9170
  ChartCommitInput,
9077
9171
  {
9078
9172
  value: category,
@@ -9086,7 +9180,7 @@ function ChartDataGrid({ controller, categoryHeader = "Category", readOnly = fal
9086
9180
  spec.series.map((s) => {
9087
9181
  const value = s.values[i];
9088
9182
  const selected = selection?.kind === "point" && selection.seriesId === s.id && selection.index === i;
9089
- return /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("td", { className: `border-b border-r border-border p-0 ${selected ? "bg-primary/10" : ""}`, children: /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(
9183
+ return /* @__PURE__ */ (0, import_jsx_runtime46.jsx)("td", { className: `border-b border-r border-border p-0 ${selected ? "bg-primary/10" : ""}`, children: /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(
9090
9184
  ChartCommitInput,
9091
9185
  {
9092
9186
  value: value === null || value === void 0 ? "" : String(value),
@@ -9101,38 +9195,38 @@ function ChartDataGrid({ controller, categoryHeader = "Category", readOnly = fal
9101
9195
  }
9102
9196
  ) }, s.id);
9103
9197
  }),
9104
- !readOnly && /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("td", { className: "border-b border-border px-1", children: /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("button", { type: "button", className: chartIconButtonClass, title: "Delete category", "aria-label": `Delete ${category}`, "data-action": "remove-category", onClick: () => controller.removeCategory(i), children: "\xD7" }) })
9198
+ !readOnly && /* @__PURE__ */ (0, import_jsx_runtime46.jsx)("td", { className: "border-b border-border px-1", children: /* @__PURE__ */ (0, import_jsx_runtime46.jsx)("button", { type: "button", className: chartIconButtonClass, title: "Delete category", "aria-label": `Delete ${category}`, "data-action": "remove-category", onClick: () => controller.removeCategory(i), children: "\xD7" }) })
9105
9199
  ] }, i);
9106
9200
  }) })
9107
9201
  ] }),
9108
- !readOnly && /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("div", { className: "p-1", children: /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("button", { type: "button", className: `${chartButtonClass} h-6 border-dashed`, "data-action": "add-category", onClick: () => controller.addCategory(), children: "+ Add category" }) })
9202
+ !readOnly && /* @__PURE__ */ (0, import_jsx_runtime46.jsx)("div", { className: "p-1", children: /* @__PURE__ */ (0, import_jsx_runtime46.jsx)("button", { type: "button", className: `${chartButtonClass} h-6 border-dashed`, "data-action": "add-category", onClick: () => controller.addCategory(), children: "+ Add category" }) })
9109
9203
  ] });
9110
9204
  }
9111
9205
 
9112
9206
  // src/chart/ChartInspector.tsx
9113
- var import_react66 = require("react");
9207
+ var import_react67 = require("react");
9114
9208
  var import_chart4 = require("@pixerate/editor/chart");
9115
- var import_jsx_runtime46 = require("react/jsx-runtime");
9209
+ var import_jsx_runtime47 = require("react/jsx-runtime");
9116
9210
  var cap = (s) => s.charAt(0).toUpperCase() + s.slice(1);
9117
9211
  function Field({ label, htmlFor, children }) {
9118
- return /* @__PURE__ */ (0, import_jsx_runtime46.jsxs)("div", { className: "flex items-center gap-2", children: [
9119
- /* @__PURE__ */ (0, import_jsx_runtime46.jsx)("label", { htmlFor, className: `${chartLabelClass} w-20 shrink-0`, children: label }),
9120
- /* @__PURE__ */ (0, import_jsx_runtime46.jsx)("div", { className: "min-w-0 flex-1", children })
9212
+ return /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)("div", { className: "flex items-center gap-2", children: [
9213
+ /* @__PURE__ */ (0, import_jsx_runtime47.jsx)("label", { htmlFor, className: `${chartLabelClass} w-20 shrink-0`, children: label }),
9214
+ /* @__PURE__ */ (0, import_jsx_runtime47.jsx)("div", { className: "min-w-0 flex-1", children })
9121
9215
  ] });
9122
9216
  }
9123
9217
  function Toggle({ label, checked, onChange, name }) {
9124
- return /* @__PURE__ */ (0, import_jsx_runtime46.jsxs)("label", { className: "flex cursor-pointer items-center gap-2 text-xs text-foreground", children: [
9125
- /* @__PURE__ */ (0, import_jsx_runtime46.jsx)("input", { type: "checkbox", className: "h-3.5 w-3.5 accent-primary", checked, "data-option": name, onChange: (e) => onChange(e.currentTarget.checked) }),
9218
+ return /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)("label", { className: "flex cursor-pointer items-center gap-2 text-xs text-foreground", children: [
9219
+ /* @__PURE__ */ (0, import_jsx_runtime47.jsx)("input", { type: "checkbox", className: "h-3.5 w-3.5 accent-primary", checked, "data-option": name, onChange: (e) => onChange(e.currentTarget.checked) }),
9126
9220
  label
9127
9221
  ] });
9128
9222
  }
9129
9223
  function Select({ id, value, options, onChange, name, labels }) {
9130
- return /* @__PURE__ */ (0, import_jsx_runtime46.jsx)("select", { id, className: chartInputClass, value, "data-option": name, onChange: (e) => onChange(e.currentTarget.value), children: options.map((o) => /* @__PURE__ */ (0, import_jsx_runtime46.jsx)("option", { value: o, children: labels?.[o] ?? cap(o) }, o)) });
9224
+ return /* @__PURE__ */ (0, import_jsx_runtime47.jsx)("select", { id, className: chartInputClass, value, "data-option": name, onChange: (e) => onChange(e.currentTarget.value), children: options.map((o) => /* @__PURE__ */ (0, import_jsx_runtime47.jsx)("option", { value: o, children: labels?.[o] ?? cap(o) }, o)) });
9131
9225
  }
9132
9226
  function AxisSection({ controller, axis, value, idBase, horizontal, numeric = false, scales = false }) {
9133
9227
  const set = (patch) => controller.setAxis(axis, patch);
9134
9228
  const setFormat = (patch) => set({ format: { ...value.format, ...patch } });
9135
- const bound = (key2) => /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(
9229
+ const bound = (key2) => /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(
9136
9230
  ChartCommitInput,
9137
9231
  {
9138
9232
  id: `${idBase}-${axis}-${key2}`,
@@ -9147,26 +9241,26 @@ function AxisSection({ controller, axis, value, idBase, horizontal, numeric = fa
9147
9241
  const name = axis === "x" ? numeric ? "X axis" : "Category axis" : axis === "y" ? "Value axis" : "Secondary axis";
9148
9242
  const valueAxis = axis !== "x" || numeric;
9149
9243
  const key = axis === "y2" ? "yAxis2" : `${axis}Axis`;
9150
- return /* @__PURE__ */ (0, import_jsx_runtime46.jsxs)("div", { className: chartSectionClass, "data-section": `axis-${axis}`, children: [
9151
- /* @__PURE__ */ (0, import_jsx_runtime46.jsxs)("div", { className: "flex items-center justify-between", children: [
9152
- /* @__PURE__ */ (0, import_jsx_runtime46.jsxs)("h4", { className: "text-xs font-semibold text-foreground", children: [
9244
+ return /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)("div", { className: chartSectionClass, "data-section": `axis-${axis}`, children: [
9245
+ /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)("div", { className: "flex items-center justify-between", children: [
9246
+ /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)("h4", { className: "text-xs font-semibold text-foreground", children: [
9153
9247
  name,
9154
- /* @__PURE__ */ (0, import_jsx_runtime46.jsxs)("span", { className: "ml-1 font-normal text-muted-foreground", children: [
9248
+ /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)("span", { className: "ml-1 font-normal text-muted-foreground", children: [
9155
9249
  "(",
9156
9250
  axis === "x" ? horizontal ? "left" : "bottom" : axis === "y2" ? horizontal ? "top" : "right" : horizontal ? "bottom" : "left",
9157
9251
  ")"
9158
9252
  ] })
9159
9253
  ] }),
9160
- /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(Toggle, { label: "Show", name: `${axis}Axis.show`, checked: value.show, onChange: (show) => set({ show }) })
9254
+ /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(Toggle, { label: "Show", name: `${axis}Axis.show`, checked: value.show, onChange: (show) => set({ show }) })
9161
9255
  ] }),
9162
- /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(Field, { label: "Title", htmlFor: `${idBase}-${axis}-title`, children: /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(ChartCommitInput, { id: `${idBase}-${axis}-title`, value: value.title, "data-option": `${axis}Axis.title`, className: chartInputClass, onCommit: (title) => void set({ title }) }) }),
9163
- /* @__PURE__ */ (0, import_jsx_runtime46.jsxs)("div", { className: "flex flex-wrap gap-x-4 gap-y-1", children: [
9164
- /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(Toggle, { label: "Grid lines", name: `${key}.gridlines`, checked: value.gridlines, onChange: (gridlines) => set({ gridlines }) }),
9165
- axis === "x" && !numeric && /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(Toggle, { label: "Dates", name: "xAxis.kind", checked: value.kind === "date", onChange: (dates) => set({ kind: dates ? "date" : void 0 }) }),
9166
- scales && /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(Toggle, { label: "Reverse", name: `${key}.reverse`, checked: !!value.reverse, onChange: (reverse) => set({ reverse }) }),
9167
- scales && valueAxis && /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(Toggle, { label: "Log scale", name: `${key}.scale`, checked: value.scale === "log", onChange: (log) => set({ scale: log ? "log" : "linear" }) })
9256
+ /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(Field, { label: "Title", htmlFor: `${idBase}-${axis}-title`, children: /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(ChartCommitInput, { id: `${idBase}-${axis}-title`, value: value.title, "data-option": `${axis}Axis.title`, className: chartInputClass, onCommit: (title) => void set({ title }) }) }),
9257
+ /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)("div", { className: "flex flex-wrap gap-x-4 gap-y-1", children: [
9258
+ /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(Toggle, { label: "Grid lines", name: `${key}.gridlines`, checked: value.gridlines, onChange: (gridlines) => set({ gridlines }) }),
9259
+ axis === "x" && !numeric && /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(Toggle, { label: "Dates", name: "xAxis.kind", checked: value.kind === "date", onChange: (dates) => set({ kind: dates ? "date" : void 0 }) }),
9260
+ scales && /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(Toggle, { label: "Reverse", name: `${key}.reverse`, checked: !!value.reverse, onChange: (reverse) => set({ reverse }) }),
9261
+ scales && valueAxis && /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(Toggle, { label: "Log scale", name: `${key}.scale`, checked: value.scale === "log", onChange: (log) => set({ scale: log ? "log" : "linear" }) })
9168
9262
  ] }),
9169
- scales && valueAxis && value.scale === "log" && /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(Field, { label: "Log base", htmlFor: `${idBase}-${axis}-log-base`, children: /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(
9263
+ scales && valueAxis && value.scale === "log" && /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(Field, { label: "Log base", htmlFor: `${idBase}-${axis}-log-base`, children: /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(
9170
9264
  ChartCommitInput,
9171
9265
  {
9172
9266
  id: `${idBase}-${axis}-log-base`,
@@ -9177,7 +9271,7 @@ function AxisSection({ controller, axis, value, idBase, horizontal, numeric = fa
9177
9271
  onCommit: (text) => set({ logBase: text.trim() === "" ? void 0 : Number(text) }).ok
9178
9272
  }
9179
9273
  ) }),
9180
- valueAxis && value.scale !== "log" && /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(Field, { label: "Step", htmlFor: `${idBase}-${axis}-step`, children: /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(
9274
+ valueAxis && value.scale !== "log" && /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(Field, { label: "Step", htmlFor: `${idBase}-${axis}-step`, children: /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(
9181
9275
  ChartCommitInput,
9182
9276
  {
9183
9277
  id: `${idBase}-${axis}-step`,
@@ -9189,14 +9283,14 @@ function AxisSection({ controller, axis, value, idBase, horizontal, numeric = fa
9189
9283
  onCommit: (text) => set({ step: text.trim() === "" ? null : Number(text) }).ok
9190
9284
  }
9191
9285
  ) }),
9192
- valueAxis && /* @__PURE__ */ (0, import_jsx_runtime46.jsxs)(import_jsx_runtime46.Fragment, { children: [
9193
- /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(Field, { label: "Min / max", children: /* @__PURE__ */ (0, import_jsx_runtime46.jsxs)("div", { className: "flex gap-1", children: [
9286
+ valueAxis && /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)(import_jsx_runtime47.Fragment, { children: [
9287
+ /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(Field, { label: "Min / max", children: /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)("div", { className: "flex gap-1", children: [
9194
9288
  bound("min"),
9195
9289
  bound("max")
9196
9290
  ] }) }),
9197
- /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(Field, { label: "Format", htmlFor: `${idBase}-${axis}-format`, children: /* @__PURE__ */ (0, import_jsx_runtime46.jsxs)("div", { className: "flex gap-1", children: [
9198
- /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(Select, { id: `${idBase}-${axis}-format`, name: `${key}.format.style`, value: value.format.style ?? "number", options: import_chart4.CHART_NUMBER_STYLES, onChange: (style) => setFormat({ style }) }),
9199
- /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(
9291
+ /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(Field, { label: "Format", htmlFor: `${idBase}-${axis}-format`, children: /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)("div", { className: "flex gap-1", children: [
9292
+ /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(Select, { id: `${idBase}-${axis}-format`, name: `${key}.format.style`, value: value.format.style ?? "number", options: import_chart4.CHART_NUMBER_STYLES, onChange: (style) => setFormat({ style }) }),
9293
+ /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(
9200
9294
  ChartCommitInput,
9201
9295
  {
9202
9296
  value: value.format.decimals === void 0 ? "" : String(value.format.decimals),
@@ -9215,8 +9309,8 @@ function AxisSection({ controller, axis, value, idBase, horizontal, numeric = fa
9215
9309
  }
9216
9310
  )
9217
9311
  ] }) }),
9218
- value.format.style === "currency" && /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(Field, { label: "Currency", htmlFor: `${idBase}-${axis}-currency`, children: /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(ChartCommitInput, { id: `${idBase}-${axis}-currency`, value: value.format.currency ?? "USD", "data-option": `${key}.format.currency`, className: chartInputClass, onCommit: (currency) => void setFormat({ currency: currency.toUpperCase() }) }) }),
9219
- /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(Field, { label: "Code", htmlFor: `${idBase}-${axis}-code`, children: /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(
9312
+ value.format.style === "currency" && /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(Field, { label: "Currency", htmlFor: `${idBase}-${axis}-currency`, children: /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(ChartCommitInput, { id: `${idBase}-${axis}-currency`, value: value.format.currency ?? "USD", "data-option": `${key}.format.currency`, className: chartInputClass, onCommit: (currency) => void setFormat({ currency: currency.toUpperCase() }) }) }),
9313
+ /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(Field, { label: "Code", htmlFor: `${idBase}-${axis}-code`, children: /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(
9220
9314
  ChartCommitInput,
9221
9315
  {
9222
9316
  id: `${idBase}-${axis}-code`,
@@ -9242,15 +9336,15 @@ function ErrorBarFields({ controller, series, which, idBase }) {
9242
9336
  const values = which === "xErrorBars" ? series.x ?? [] : series.values;
9243
9337
  const set = (next) => controller.updateSeries(series.id, { [which]: next });
9244
9338
  const patch = (p) => bars && set({ ...bars, ...p });
9245
- return /* @__PURE__ */ (0, import_jsx_runtime46.jsxs)("div", { className: "space-y-1.5", "data-section": which === "errorBars" ? "error-bars" : "x-error-bars", children: [
9246
- /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(Field, { label: which === "errorBars" ? "Error bars" : "X error bars", htmlFor: `${id}-type`, children: /* @__PURE__ */ (0, import_jsx_runtime46.jsxs)("select", { id: `${id}-type`, className: chartInputClass, value: bars?.type ?? "", "data-option": `${key}.type`, onChange: (e) => set((0, import_chart4.chartErrorBarsOfType)(e.currentTarget.value, bars, values)), children: [
9247
- /* @__PURE__ */ (0, import_jsx_runtime46.jsx)("option", { value: "", children: "None" }),
9248
- import_chart4.CHART_ERROR_BAR_TYPES.map((t) => /* @__PURE__ */ (0, import_jsx_runtime46.jsx)("option", { value: t, children: import_chart4.CHART_ERROR_BAR_LABELS[t] }, t))
9339
+ return /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)("div", { className: "space-y-1.5", "data-section": which === "errorBars" ? "error-bars" : "x-error-bars", children: [
9340
+ /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(Field, { label: which === "errorBars" ? "Error bars" : "X error bars", htmlFor: `${id}-type`, children: /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)("select", { id: `${id}-type`, className: chartInputClass, value: bars?.type ?? "", "data-option": `${key}.type`, onChange: (e) => set((0, import_chart4.chartErrorBarsOfType)(e.currentTarget.value, bars, values)), children: [
9341
+ /* @__PURE__ */ (0, import_jsx_runtime47.jsx)("option", { value: "", children: "None" }),
9342
+ import_chart4.CHART_ERROR_BAR_TYPES.map((t) => /* @__PURE__ */ (0, import_jsx_runtime47.jsx)("option", { value: t, children: import_chart4.CHART_ERROR_BAR_LABELS[t] }, t))
9249
9343
  ] }) }),
9250
- bars && (bars.type === "fixed" || bars.type === "percent" || bars.type === "stddev") && /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(Field, { label: bars.type === "percent" ? "Percent" : bars.type === "stddev" ? "Deviations" : "Amount", htmlFor: `${id}-value`, children: /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(ChartCommitInput, { id: `${id}-value`, value: String(bars.value ?? (0, import_chart4.defaultChartErrorBarValue)(bars.type)), inputMode: "decimal", "data-option": `${key}.value`, className: chartInputClass, onCommit: (text) => !!patch({ value: text.trim() === "" ? void 0 : Number(text) })?.ok }) }),
9251
- bars?.type === "custom" && /* @__PURE__ */ (0, import_jsx_runtime46.jsxs)(import_jsx_runtime46.Fragment, { children: [
9252
- /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(Field, { label: "Plus", htmlFor: `${id}-plus`, children: /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(ChartCommitInput, { id: `${id}-plus`, value: (0, import_chart4.formatChartAmountList)(bars.plus), placeholder: "1, 2, -, 0.5", "data-option": `${key}.plus`, className: chartInputClass, onCommit: (text) => !!patch({ plus: (0, import_chart4.parseChartAmountList)(text) })?.ok }) }),
9253
- /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(Field, { label: "Minus", htmlFor: `${id}-minus`, children: /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(
9344
+ bars && (bars.type === "fixed" || bars.type === "percent" || bars.type === "stddev") && /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(Field, { label: bars.type === "percent" ? "Percent" : bars.type === "stddev" ? "Deviations" : "Amount", htmlFor: `${id}-value`, children: /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(ChartCommitInput, { id: `${id}-value`, value: String(bars.value ?? (0, import_chart4.defaultChartErrorBarValue)(bars.type)), inputMode: "decimal", "data-option": `${key}.value`, className: chartInputClass, onCommit: (text) => !!patch({ value: text.trim() === "" ? void 0 : Number(text) })?.ok }) }),
9345
+ bars?.type === "custom" && /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)(import_jsx_runtime47.Fragment, { children: [
9346
+ /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(Field, { label: "Plus", htmlFor: `${id}-plus`, children: /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(ChartCommitInput, { id: `${id}-plus`, value: (0, import_chart4.formatChartAmountList)(bars.plus), placeholder: "1, 2, -, 0.5", "data-option": `${key}.plus`, className: chartInputClass, onCommit: (text) => !!patch({ plus: (0, import_chart4.parseChartAmountList)(text) })?.ok }) }),
9347
+ /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(Field, { label: "Minus", htmlFor: `${id}-minus`, children: /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(
9254
9348
  ChartCommitInput,
9255
9349
  {
9256
9350
  id: `${id}-minus`,
@@ -9267,15 +9361,15 @@ function ErrorBarFields({ controller, series, which, idBase }) {
9267
9361
  }
9268
9362
  ) })
9269
9363
  ] }),
9270
- bars && /* @__PURE__ */ (0, import_jsx_runtime46.jsxs)("div", { className: "flex items-center gap-2", children: [
9271
- /* @__PURE__ */ (0, import_jsx_runtime46.jsx)("select", { className: `${chartInputClass} flex-1`, "aria-label": "Error bar direction", value: bars.direction ?? "both", "data-option": `${key}.direction`, onChange: (e) => patch({ direction: e.currentTarget.value }), children: import_chart4.CHART_ERROR_BAR_DIRECTIONS.map((d) => /* @__PURE__ */ (0, import_jsx_runtime46.jsx)("option", { value: d, children: d === "both" ? "Both ways" : d === "plus" ? "Plus only" : "Minus only" }, d)) }),
9272
- /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(Toggle, { label: "Caps", name: `${key}.cap`, checked: bars.cap !== false, onChange: (cap2) => patch({ cap: cap2 }) })
9364
+ bars && /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)("div", { className: "flex items-center gap-2", children: [
9365
+ /* @__PURE__ */ (0, import_jsx_runtime47.jsx)("select", { className: `${chartInputClass} flex-1`, "aria-label": "Error bar direction", value: bars.direction ?? "both", "data-option": `${key}.direction`, onChange: (e) => patch({ direction: e.currentTarget.value }), children: import_chart4.CHART_ERROR_BAR_DIRECTIONS.map((d) => /* @__PURE__ */ (0, import_jsx_runtime47.jsx)("option", { value: d, children: d === "both" ? "Both ways" : d === "plus" ? "Plus only" : "Minus only" }, d)) }),
9366
+ /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(Toggle, { label: "Caps", name: `${key}.cap`, checked: bars.cap !== false, onChange: (cap2) => patch({ cap: cap2 }) })
9273
9367
  ] })
9274
9368
  ] });
9275
9369
  }
9276
9370
  function ChartInspector({ controller, sections, className }) {
9277
9371
  const { spec, selectedSeries } = useChartState(controller);
9278
- const idBase = (0, import_react66.useId)();
9372
+ const idBase = (0, import_react67.useId)();
9279
9373
  const show = (section) => !sections || sections.includes(section);
9280
9374
  const cartesian = (0, import_chart4.isCartesianChart)(spec.type);
9281
9375
  const family = (0, import_chart4.chartFamily)(spec);
@@ -9287,29 +9381,29 @@ function ChartInspector({ controller, sections, className }) {
9287
9381
  const hasLines = cartesian && types.some((t) => t === "line" || t === "area");
9288
9382
  const seriesIndex = selectedSeries ? spec.series.findIndex((s) => s.id === selectedSeries.id) : -1;
9289
9383
  const scales = family === "cartesian" || family === "xy";
9290
- return /* @__PURE__ */ (0, import_jsx_runtime46.jsxs)("div", { className: `space-y-3 text-xs ${className ?? ""}`, "data-chart-inspector": "", children: [
9291
- show("type") && /* @__PURE__ */ (0, import_jsx_runtime46.jsx)("div", { className: chartSectionClass, "data-section": "type", children: /* @__PURE__ */ (0, import_jsx_runtime46.jsx)("div", { className: "grid grid-cols-3 gap-0.5 rounded-md bg-muted p-0.5", role: "radiogroup", "aria-label": "Chart type", children: import_chart4.CHART_TYPES.map((type) => /* @__PURE__ */ (0, import_jsx_runtime46.jsx)("button", { type: "button", role: "radio", "aria-checked": spec.type === type, "data-chart-type": type, className: chartSegmentClass(spec.type === type), onClick: () => controller.setType(type), children: import_chart4.CHART_TYPE_LABELS[type] }, type)) }) }),
9292
- show("style") && /* @__PURE__ */ (0, import_jsx_runtime46.jsxs)("div", { className: chartSectionClass, "data-section": "style", children: [
9293
- /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(Field, { label: "Layout", htmlFor: `${idBase}-layout`, children: /* @__PURE__ */ (0, import_jsx_runtime46.jsxs)("select", { id: `${idBase}-layout`, className: chartInputClass, value: "", "data-option": "preset.layout", onChange: (e) => e.currentTarget.value && controller.applyPreset({ layout: e.currentTarget.value }), children: [
9294
- /* @__PURE__ */ (0, import_jsx_runtime46.jsx)("option", { value: "", children: "Quick layout\u2026" }),
9295
- import_chart4.CHART_LAYOUT_PRESETS.map((p) => /* @__PURE__ */ (0, import_jsx_runtime46.jsx)("option", { value: p.id, title: p.description, children: p.label }, p.id))
9384
+ return /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)("div", { className: `space-y-3 text-xs ${className ?? ""}`, "data-chart-inspector": "", children: [
9385
+ show("type") && /* @__PURE__ */ (0, import_jsx_runtime47.jsx)("div", { className: chartSectionClass, "data-section": "type", children: /* @__PURE__ */ (0, import_jsx_runtime47.jsx)("div", { className: "grid grid-cols-3 gap-0.5 rounded-md bg-muted p-0.5", role: "radiogroup", "aria-label": "Chart type", children: import_chart4.CHART_TYPES.map((type) => /* @__PURE__ */ (0, import_jsx_runtime47.jsx)("button", { type: "button", role: "radio", "aria-checked": spec.type === type, "data-chart-type": type, className: chartSegmentClass(spec.type === type), onClick: () => controller.setType(type), children: import_chart4.CHART_TYPE_LABELS[type] }, type)) }) }),
9386
+ show("style") && /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)("div", { className: chartSectionClass, "data-section": "style", children: [
9387
+ /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(Field, { label: "Layout", htmlFor: `${idBase}-layout`, children: /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)("select", { id: `${idBase}-layout`, className: chartInputClass, value: "", "data-option": "preset.layout", onChange: (e) => e.currentTarget.value && controller.applyPreset({ layout: e.currentTarget.value }), children: [
9388
+ /* @__PURE__ */ (0, import_jsx_runtime47.jsx)("option", { value: "", children: "Quick layout\u2026" }),
9389
+ import_chart4.CHART_LAYOUT_PRESETS.map((p) => /* @__PURE__ */ (0, import_jsx_runtime47.jsx)("option", { value: p.id, title: p.description, children: p.label }, p.id))
9296
9390
  ] }) }),
9297
- /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(Field, { label: "Colours", htmlFor: `${idBase}-colors`, children: /* @__PURE__ */ (0, import_jsx_runtime46.jsxs)("select", { id: `${idBase}-colors`, className: chartInputClass, value: import_chart4.CHART_COLOR_SCHEMES.find((c) => c.palette.join() === spec.palette.join())?.id ?? "", "data-option": "preset.colors", onChange: (e) => e.currentTarget.value && controller.applyPreset({ colors: e.currentTarget.value }), children: [
9298
- /* @__PURE__ */ (0, import_jsx_runtime46.jsx)("option", { value: "", children: "Custom" }),
9299
- import_chart4.CHART_COLOR_SCHEMES.map((c) => /* @__PURE__ */ (0, import_jsx_runtime46.jsx)("option", { value: c.id, title: c.description, children: c.label }, c.id))
9391
+ /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(Field, { label: "Colours", htmlFor: `${idBase}-colors`, children: /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)("select", { id: `${idBase}-colors`, className: chartInputClass, value: import_chart4.CHART_COLOR_SCHEMES.find((c) => c.palette.join() === spec.palette.join())?.id ?? "", "data-option": "preset.colors", onChange: (e) => e.currentTarget.value && controller.applyPreset({ colors: e.currentTarget.value }), children: [
9392
+ /* @__PURE__ */ (0, import_jsx_runtime47.jsx)("option", { value: "", children: "Custom" }),
9393
+ import_chart4.CHART_COLOR_SCHEMES.map((c) => /* @__PURE__ */ (0, import_jsx_runtime47.jsx)("option", { value: c.id, title: c.description, children: c.label }, c.id))
9300
9394
  ] }) }),
9301
- !colorCheck.ok && /* @__PURE__ */ (0, import_jsx_runtime46.jsx)("p", { className: "text-[11px] leading-snug text-amber-600 dark:text-amber-400", "data-chart-color-warning": "", children: colorCheck.issues[0] }),
9302
- /* @__PURE__ */ (0, import_jsx_runtime46.jsx)("button", { type: "button", className: chartButtonClass, "data-action": "transpose", onClick: () => controller.transpose(), children: "Switch rows and columns" })
9395
+ !colorCheck.ok && /* @__PURE__ */ (0, import_jsx_runtime47.jsx)("p", { className: "text-[11px] leading-snug text-amber-600 dark:text-amber-400", "data-chart-color-warning": "", children: colorCheck.issues[0] }),
9396
+ /* @__PURE__ */ (0, import_jsx_runtime47.jsx)("button", { type: "button", className: chartButtonClass, "data-action": "transpose", onClick: () => controller.transpose(), children: "Switch rows and columns" })
9303
9397
  ] }),
9304
- show("titles") && /* @__PURE__ */ (0, import_jsx_runtime46.jsxs)("div", { className: chartSectionClass, "data-section": "titles", children: [
9305
- /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(Field, { label: "Title", htmlFor: `${idBase}-title`, children: /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(ChartCommitInput, { id: `${idBase}-title`, value: spec.title, "data-option": "title", className: chartInputClass, onCommit: (title) => void controller.setTitle(title) }) }),
9306
- /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(Field, { label: "Subtitle", htmlFor: `${idBase}-subtitle`, children: /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(ChartCommitInput, { id: `${idBase}-subtitle`, value: spec.subtitle, "data-option": "subtitle", className: chartInputClass, onCommit: (subtitle) => void controller.setSubtitle(subtitle) }) })
9398
+ show("titles") && /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)("div", { className: chartSectionClass, "data-section": "titles", children: [
9399
+ /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(Field, { label: "Title", htmlFor: `${idBase}-title`, children: /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(ChartCommitInput, { id: `${idBase}-title`, value: spec.title, "data-option": "title", className: chartInputClass, onCommit: (title) => void controller.setTitle(title) }) }),
9400
+ /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(Field, { label: "Subtitle", htmlFor: `${idBase}-subtitle`, children: /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(ChartCommitInput, { id: `${idBase}-subtitle`, value: spec.subtitle, "data-option": "subtitle", className: chartInputClass, onCommit: (subtitle) => void controller.setSubtitle(subtitle) }) })
9307
9401
  ] }),
9308
- show("options") && /* @__PURE__ */ (0, import_jsx_runtime46.jsxs)("div", { className: chartSectionClass, "data-section": "options", children: [
9309
- cartesian && /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(Field, { label: "Stacking", htmlFor: `${idBase}-stacking`, children: /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(Select, { id: `${idBase}-stacking`, name: "stacking", value: spec.stacking, options: import_chart4.CHART_STACKINGS, labels: { none: "None", stacked: "Stacked", percent: "100%" }, onChange: (stacking) => controller.update({ stacking }) }) }),
9310
- hasBars && /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(Field, { label: "Bars", children: /* @__PURE__ */ (0, import_jsx_runtime46.jsx)("div", { className: "flex gap-0.5 rounded-md bg-muted p-0.5", children: ["vertical", "horizontal"].map((o) => /* @__PURE__ */ (0, import_jsx_runtime46.jsx)("button", { type: "button", "aria-pressed": spec.orientation === o, "data-option": `orientation.${o}`, className: chartSegmentClass(spec.orientation === o), onClick: () => controller.update({ orientation: o }), children: cap(o) }, o)) }) }),
9311
- hasLines && /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(Field, { label: "Lines", htmlFor: `${idBase}-curve`, children: /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(Select, { id: `${idBase}-curve`, name: "curve", value: spec.curve, options: import_chart4.CHART_CURVES, onChange: (curve) => controller.update({ curve }) }) }),
9312
- spec.type === "donut" && /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(Field, { label: "Hole", htmlFor: `${idBase}-hole`, children: /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(
9402
+ show("options") && /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)("div", { className: chartSectionClass, "data-section": "options", children: [
9403
+ cartesian && /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(Field, { label: "Stacking", htmlFor: `${idBase}-stacking`, children: /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(Select, { id: `${idBase}-stacking`, name: "stacking", value: spec.stacking, options: import_chart4.CHART_STACKINGS, labels: { none: "None", stacked: "Stacked", percent: "100%" }, onChange: (stacking) => controller.update({ stacking }) }) }),
9404
+ hasBars && /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(Field, { label: "Bars", children: /* @__PURE__ */ (0, import_jsx_runtime47.jsx)("div", { className: "flex gap-0.5 rounded-md bg-muted p-0.5", children: ["vertical", "horizontal"].map((o) => /* @__PURE__ */ (0, import_jsx_runtime47.jsx)("button", { type: "button", "aria-pressed": spec.orientation === o, "data-option": `orientation.${o}`, className: chartSegmentClass(spec.orientation === o), onClick: () => controller.update({ orientation: o }), children: cap(o) }, o)) }) }),
9405
+ hasLines && /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(Field, { label: "Lines", htmlFor: `${idBase}-curve`, children: /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(Select, { id: `${idBase}-curve`, name: "curve", value: spec.curve, options: import_chart4.CHART_CURVES, onChange: (curve) => controller.update({ curve }) }) }),
9406
+ spec.type === "donut" && /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(Field, { label: "Hole", htmlFor: `${idBase}-hole`, children: /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(
9313
9407
  "input",
9314
9408
  {
9315
9409
  id: `${idBase}-hole`,
@@ -9325,7 +9419,7 @@ function ChartInspector({ controller, sections, className }) {
9325
9419
  onChange: (e) => controller.update({ innerRadius: Number(e.currentTarget.value) })
9326
9420
  }
9327
9421
  ) }),
9328
- hasBars && /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(Field, { label: "Spacing", htmlFor: `${idBase}-gap`, children: /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(
9422
+ hasBars && /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(Field, { label: "Spacing", htmlFor: `${idBase}-gap`, children: /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(
9329
9423
  "input",
9330
9424
  {
9331
9425
  id: `${idBase}-gap`,
@@ -9341,31 +9435,31 @@ function ChartInspector({ controller, sections, className }) {
9341
9435
  onChange: (e) => controller.update({ gapWidth: Number(e.currentTarget.value) })
9342
9436
  }
9343
9437
  ) }),
9344
- spec.dataLabels && hasBars && /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(Field, { label: "Labels", htmlFor: `${idBase}-label-position`, children: /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(Select, { id: `${idBase}-label-position`, name: "labelPosition", value: spec.labelPosition, options: import_chart4.CHART_LABEL_POSITIONS, onChange: (labelPosition) => controller.update({ labelPosition }) }) }),
9345
- spec.type === "histogram" && /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(Field, { label: "Bins", htmlFor: `${idBase}-bins`, children: /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(ChartCommitInput, { id: `${idBase}-bins`, value: spec.bins === null ? "" : String(spec.bins), placeholder: "Auto", inputMode: "numeric", "data-option": "bins", className: chartInputClass, onCommit: (text) => controller.update({ bins: text.trim() === "" ? null : Number(text) }).ok }) }),
9346
- /* @__PURE__ */ (0, import_jsx_runtime46.jsxs)("div", { className: "flex flex-wrap gap-x-4 gap-y-1", children: [
9347
- spec.type === "waterfall" && /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(Toggle, { label: "Total bar", name: "showTotal", checked: spec.showTotal, onChange: (showTotal) => controller.update({ showTotal }) }),
9348
- hasLines && /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(Toggle, { label: "Points", name: "points", checked: spec.points, onChange: (points) => controller.update({ points }) }),
9349
- /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(Toggle, { label: "Data labels", name: "dataLabels", checked: spec.dataLabels, onChange: (dataLabels) => controller.update({ dataLabels }) })
9438
+ spec.dataLabels && hasBars && /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(Field, { label: "Labels", htmlFor: `${idBase}-label-position`, children: /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(Select, { id: `${idBase}-label-position`, name: "labelPosition", value: spec.labelPosition, options: import_chart4.CHART_LABEL_POSITIONS, onChange: (labelPosition) => controller.update({ labelPosition }) }) }),
9439
+ spec.type === "histogram" && /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(Field, { label: "Bins", htmlFor: `${idBase}-bins`, children: /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(ChartCommitInput, { id: `${idBase}-bins`, value: spec.bins === null ? "" : String(spec.bins), placeholder: "Auto", inputMode: "numeric", "data-option": "bins", className: chartInputClass, onCommit: (text) => controller.update({ bins: text.trim() === "" ? null : Number(text) }).ok }) }),
9440
+ /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)("div", { className: "flex flex-wrap gap-x-4 gap-y-1", children: [
9441
+ spec.type === "waterfall" && /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(Toggle, { label: "Total bar", name: "showTotal", checked: spec.showTotal, onChange: (showTotal) => controller.update({ showTotal }) }),
9442
+ hasLines && /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(Toggle, { label: "Points", name: "points", checked: spec.points, onChange: (points) => controller.update({ points }) }),
9443
+ /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(Toggle, { label: "Data labels", name: "dataLabels", checked: spec.dataLabels, onChange: (dataLabels) => controller.update({ dataLabels }) })
9350
9444
  ] })
9351
9445
  ] }),
9352
- show("legend") && /* @__PURE__ */ (0, import_jsx_runtime46.jsxs)("div", { className: chartSectionClass, "data-section": "legend", children: [
9353
- /* @__PURE__ */ (0, import_jsx_runtime46.jsxs)("div", { className: "flex items-center justify-between", children: [
9354
- /* @__PURE__ */ (0, import_jsx_runtime46.jsx)("h4", { className: "text-xs font-semibold text-foreground", children: "Legend" }),
9355
- /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(Toggle, { label: "Show", name: "legend.show", checked: spec.legend.show, onChange: (v) => controller.setLegend({ show: v }) })
9446
+ show("legend") && /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)("div", { className: chartSectionClass, "data-section": "legend", children: [
9447
+ /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)("div", { className: "flex items-center justify-between", children: [
9448
+ /* @__PURE__ */ (0, import_jsx_runtime47.jsx)("h4", { className: "text-xs font-semibold text-foreground", children: "Legend" }),
9449
+ /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(Toggle, { label: "Show", name: "legend.show", checked: spec.legend.show, onChange: (v) => controller.setLegend({ show: v }) })
9356
9450
  ] }),
9357
- spec.legend.show && /* @__PURE__ */ (0, import_jsx_runtime46.jsx)("div", { className: "flex gap-0.5 rounded-md bg-muted p-0.5", children: import_chart4.CHART_LEGEND_POSITIONS.map((p) => /* @__PURE__ */ (0, import_jsx_runtime46.jsx)("button", { type: "button", "aria-pressed": spec.legend.position === p, "data-option": `legend.${p}`, className: chartSegmentClass(spec.legend.position === p), onClick: () => controller.setLegend({ position: p }), children: cap(p) }, p)) })
9451
+ spec.legend.show && /* @__PURE__ */ (0, import_jsx_runtime47.jsx)("div", { className: "flex gap-0.5 rounded-md bg-muted p-0.5", children: import_chart4.CHART_LEGEND_POSITIONS.map((p) => /* @__PURE__ */ (0, import_jsx_runtime47.jsx)("button", { type: "button", "aria-pressed": spec.legend.position === p, "data-option": `legend.${p}`, className: chartSegmentClass(spec.legend.position === p), onClick: () => controller.setLegend({ position: p }), children: cap(p) }, p)) })
9358
9452
  ] }),
9359
- show("axes") && hasAxes && /* @__PURE__ */ (0, import_jsx_runtime46.jsxs)(import_jsx_runtime46.Fragment, { children: [
9360
- family !== "box" && family !== "histogram" && /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(AxisSection, { controller, axis: "x", value: spec.xAxis, idBase, horizontal: spec.orientation === "horizontal", numeric: family === "xy", scales }),
9361
- /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(AxisSection, { controller, axis: "y", value: spec.yAxis, idBase, horizontal: spec.orientation === "horizontal", scales }),
9362
- usesSecondary && /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(AxisSection, { controller, axis: "y2", value: spec.yAxis2, idBase, horizontal: spec.orientation === "horizontal", scales })
9453
+ show("axes") && hasAxes && /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)(import_jsx_runtime47.Fragment, { children: [
9454
+ family !== "box" && family !== "histogram" && /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(AxisSection, { controller, axis: "x", value: spec.xAxis, idBase, horizontal: spec.orientation === "horizontal", numeric: family === "xy", scales }),
9455
+ /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(AxisSection, { controller, axis: "y", value: spec.yAxis, idBase, horizontal: spec.orientation === "horizontal", scales }),
9456
+ usesSecondary && /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(AxisSection, { controller, axis: "y2", value: spec.yAxis2, idBase, horizontal: spec.orientation === "horizontal", scales })
9363
9457
  ] }),
9364
- show("series") && selectedSeries && /* @__PURE__ */ (0, import_jsx_runtime46.jsxs)("div", { className: chartSectionClass, "data-section": "series", "data-series-id": selectedSeries.id, children: [
9365
- /* @__PURE__ */ (0, import_jsx_runtime46.jsx)("h4", { className: "text-xs font-semibold text-foreground", children: "Series" }),
9366
- /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(Field, { label: "Name", htmlFor: `${idBase}-series-name`, children: /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(ChartCommitInput, { id: `${idBase}-series-name`, value: selectedSeries.name, "data-option": "series.name", className: chartInputClass, onCommit: (name) => void controller.updateSeries(selectedSeries.id, { name }) }) }),
9367
- /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(Field, { label: "Colour", htmlFor: `${idBase}-series-color`, children: /* @__PURE__ */ (0, import_jsx_runtime46.jsxs)("div", { className: "flex items-center gap-1", children: [
9368
- /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(
9458
+ show("series") && selectedSeries && /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)("div", { className: chartSectionClass, "data-section": "series", "data-series-id": selectedSeries.id, children: [
9459
+ /* @__PURE__ */ (0, import_jsx_runtime47.jsx)("h4", { className: "text-xs font-semibold text-foreground", children: "Series" }),
9460
+ /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(Field, { label: "Name", htmlFor: `${idBase}-series-name`, children: /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(ChartCommitInput, { id: `${idBase}-series-name`, value: selectedSeries.name, "data-option": "series.name", className: chartInputClass, onCommit: (name) => void controller.updateSeries(selectedSeries.id, { name }) }) }),
9461
+ /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(Field, { label: "Colour", htmlFor: `${idBase}-series-color`, children: /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)("div", { className: "flex items-center gap-1", children: [
9462
+ /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(
9369
9463
  "input",
9370
9464
  {
9371
9465
  id: `${idBase}-series-color`,
@@ -9378,9 +9472,9 @@ function ChartInspector({ controller, sections, className }) {
9378
9472
  onChange: (e) => controller.updateSeries(selectedSeries.id, { color: e.currentTarget.value })
9379
9473
  }
9380
9474
  ),
9381
- selectedSeries.color && /* @__PURE__ */ (0, import_jsx_runtime46.jsx)("button", { type: "button", className: chartButtonClass, "data-action": "reset-color", onClick: () => controller.updateSeries(selectedSeries.id, { color: null }), children: "Palette" })
9475
+ selectedSeries.color && /* @__PURE__ */ (0, import_jsx_runtime47.jsx)("button", { type: "button", className: chartButtonClass, "data-action": "reset-color", onClick: () => controller.updateSeries(selectedSeries.id, { color: null }), children: "Palette" })
9382
9476
  ] }) }),
9383
- cartesian && /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(Field, { label: "Draw as", htmlFor: `${idBase}-series-type`, children: /* @__PURE__ */ (0, import_jsx_runtime46.jsxs)(
9477
+ cartesian && /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(Field, { label: "Draw as", htmlFor: `${idBase}-series-type`, children: /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)(
9384
9478
  "select",
9385
9479
  {
9386
9480
  id: `${idBase}-series-type`,
@@ -9389,12 +9483,12 @@ function ChartInspector({ controller, sections, className }) {
9389
9483
  "data-option": "series.type",
9390
9484
  onChange: (e) => controller.updateSeries(selectedSeries.id, { type: e.currentTarget.value || null }),
9391
9485
  children: [
9392
- /* @__PURE__ */ (0, import_jsx_runtime46.jsx)("option", { value: "", children: "Chart type" }),
9393
- import_chart4.CHART_SERIES_TYPES.map((t) => /* @__PURE__ */ (0, import_jsx_runtime46.jsx)("option", { value: t, children: import_chart4.CHART_TYPE_LABELS[t] }, t))
9486
+ /* @__PURE__ */ (0, import_jsx_runtime47.jsx)("option", { value: "", children: "Chart type" }),
9487
+ import_chart4.CHART_SERIES_TYPES.map((t) => /* @__PURE__ */ (0, import_jsx_runtime47.jsx)("option", { value: t, children: import_chart4.CHART_TYPE_LABELS[t] }, t))
9394
9488
  ]
9395
9489
  }
9396
9490
  ) }),
9397
- (cartesian || family === "xy") && ["line", "area", "scatter"].includes((0, import_chart4.chartSeriesType)(spec, selectedSeries)) && /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(Field, { label: "Marker", htmlFor: `${idBase}-series-marker`, children: /* @__PURE__ */ (0, import_jsx_runtime46.jsxs)(
9491
+ (cartesian || family === "xy") && ["line", "area", "scatter"].includes((0, import_chart4.chartSeriesType)(spec, selectedSeries)) && /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(Field, { label: "Marker", htmlFor: `${idBase}-series-marker`, children: /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)(
9398
9492
  "select",
9399
9493
  {
9400
9494
  id: `${idBase}-series-marker`,
@@ -9403,20 +9497,20 @@ function ChartInspector({ controller, sections, className }) {
9403
9497
  "data-option": "series.marker",
9404
9498
  onChange: (e) => controller.updateSeries(selectedSeries.id, { marker: e.currentTarget.value || null }),
9405
9499
  children: [
9406
- /* @__PURE__ */ (0, import_jsx_runtime46.jsx)("option", { value: "", children: "Default" }),
9407
- import_chart4.CHART_MARKERS.map((m) => /* @__PURE__ */ (0, import_jsx_runtime46.jsx)("option", { value: m, children: cap(m) }, m))
9500
+ /* @__PURE__ */ (0, import_jsx_runtime47.jsx)("option", { value: "", children: "Default" }),
9501
+ import_chart4.CHART_MARKERS.map((m) => /* @__PURE__ */ (0, import_jsx_runtime47.jsx)("option", { value: m, children: cap(m) }, m))
9408
9502
  ]
9409
9503
  }
9410
9504
  ) }),
9411
- scales && /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(ErrorBarFields, { controller, series: selectedSeries, which: "errorBars", idBase }),
9412
- family === "xy" && /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(ErrorBarFields, { controller, series: selectedSeries, which: "xErrorBars", idBase }),
9413
- (0, import_chart4.chartSupportsTrendlines)(spec.type, spec.stacking) && /* @__PURE__ */ (0, import_jsx_runtime46.jsxs)("div", { className: "space-y-1", "data-section": "trendlines", children: [
9414
- (selectedSeries.trendlines ?? []).map((t, i) => /* @__PURE__ */ (0, import_jsx_runtime46.jsxs)("div", { className: "flex items-center gap-1", "data-trendline": i, children: [
9415
- /* @__PURE__ */ (0, import_jsx_runtime46.jsx)("span", { className: "flex-1 truncate text-muted-foreground", children: (0, import_chart4.chartTrendlineName)(t, selectedSeries.name) }),
9416
- /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(Toggle, { label: "R\xB2", name: `trendline.${i}.showR2`, checked: !!t.showR2, onChange: (showR2) => controller.updateTrendline(selectedSeries.id, i, { showR2 }) }),
9417
- /* @__PURE__ */ (0, import_jsx_runtime46.jsx)("button", { type: "button", className: chartButtonClass, "aria-label": "Delete trendline", "data-action": "trendline-delete", onClick: () => controller.removeTrendline(selectedSeries.id, i), children: "\xD7" })
9505
+ scales && /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(ErrorBarFields, { controller, series: selectedSeries, which: "errorBars", idBase }),
9506
+ family === "xy" && /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(ErrorBarFields, { controller, series: selectedSeries, which: "xErrorBars", idBase }),
9507
+ (0, import_chart4.chartSupportsTrendlines)(spec.type, spec.stacking) && /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)("div", { className: "space-y-1", "data-section": "trendlines", children: [
9508
+ (selectedSeries.trendlines ?? []).map((t, i) => /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)("div", { className: "flex items-center gap-1", "data-trendline": i, children: [
9509
+ /* @__PURE__ */ (0, import_jsx_runtime47.jsx)("span", { className: "flex-1 truncate text-muted-foreground", children: (0, import_chart4.chartTrendlineName)(t, selectedSeries.name) }),
9510
+ /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(Toggle, { label: "R\xB2", name: `trendline.${i}.showR2`, checked: !!t.showR2, onChange: (showR2) => controller.updateTrendline(selectedSeries.id, i, { showR2 }) }),
9511
+ /* @__PURE__ */ (0, import_jsx_runtime47.jsx)("button", { type: "button", className: chartButtonClass, "aria-label": "Delete trendline", "data-action": "trendline-delete", onClick: () => controller.removeTrendline(selectedSeries.id, i), children: "\xD7" })
9418
9512
  ] }, i)),
9419
- /* @__PURE__ */ (0, import_jsx_runtime46.jsxs)(
9513
+ /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)(
9420
9514
  "select",
9421
9515
  {
9422
9516
  className: chartInputClass,
@@ -9425,32 +9519,32 @@ function ChartInspector({ controller, sections, className }) {
9425
9519
  "data-option": "trendline.add",
9426
9520
  onChange: (e) => e.currentTarget.value && controller.addTrendline(selectedSeries.id, { type: e.currentTarget.value }),
9427
9521
  children: [
9428
- /* @__PURE__ */ (0, import_jsx_runtime46.jsx)("option", { value: "", children: "Add trendline\u2026" }),
9429
- import_chart4.CHART_TRENDLINE_TYPES.map((t) => /* @__PURE__ */ (0, import_jsx_runtime46.jsx)("option", { value: t, children: cap(t.replace("-", " ")) }, t))
9522
+ /* @__PURE__ */ (0, import_jsx_runtime47.jsx)("option", { value: "", children: "Add trendline\u2026" }),
9523
+ import_chart4.CHART_TRENDLINE_TYPES.map((t) => /* @__PURE__ */ (0, import_jsx_runtime47.jsx)("option", { value: t, children: cap(t.replace("-", " ")) }, t))
9430
9524
  ]
9431
9525
  }
9432
9526
  )
9433
9527
  ] }),
9434
- /* @__PURE__ */ (0, import_jsx_runtime46.jsxs)("div", { className: "flex flex-wrap items-center gap-1", children: [
9435
- /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(Toggle, { label: "Hidden", name: "series.hidden", checked: !!selectedSeries.hidden, onChange: (hidden) => controller.updateSeries(selectedSeries.id, { hidden }) }),
9436
- family === "cartesian" && /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(Toggle, { label: "Secondary axis", name: "series.axis", checked: selectedSeries.axis === "secondary", onChange: (secondary) => controller.updateSeries(selectedSeries.id, { axis: secondary ? "secondary" : null }) }),
9437
- /* @__PURE__ */ (0, import_jsx_runtime46.jsx)("span", { className: "flex-1" }),
9438
- /* @__PURE__ */ (0, import_jsx_runtime46.jsx)("button", { type: "button", className: chartButtonClass, disabled: seriesIndex <= 0, "aria-label": "Move series earlier", "data-action": "series-up", onClick: () => controller.moveSeries(selectedSeries.id, seriesIndex - 1), children: "\u2191" }),
9439
- /* @__PURE__ */ (0, import_jsx_runtime46.jsx)("button", { type: "button", className: chartButtonClass, disabled: seriesIndex >= spec.series.length - 1, "aria-label": "Move series later", "data-action": "series-down", onClick: () => controller.moveSeries(selectedSeries.id, seriesIndex + 1), children: "\u2193" }),
9440
- /* @__PURE__ */ (0, import_jsx_runtime46.jsx)("button", { type: "button", className: `${chartButtonClass} text-destructive`, "data-action": "series-delete", onClick: () => controller.removeSeries(selectedSeries.id), children: "Delete" })
9528
+ /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)("div", { className: "flex flex-wrap items-center gap-1", children: [
9529
+ /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(Toggle, { label: "Hidden", name: "series.hidden", checked: !!selectedSeries.hidden, onChange: (hidden) => controller.updateSeries(selectedSeries.id, { hidden }) }),
9530
+ family === "cartesian" && /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(Toggle, { label: "Secondary axis", name: "series.axis", checked: selectedSeries.axis === "secondary", onChange: (secondary) => controller.updateSeries(selectedSeries.id, { axis: secondary ? "secondary" : null }) }),
9531
+ /* @__PURE__ */ (0, import_jsx_runtime47.jsx)("span", { className: "flex-1" }),
9532
+ /* @__PURE__ */ (0, import_jsx_runtime47.jsx)("button", { type: "button", className: chartButtonClass, disabled: seriesIndex <= 0, "aria-label": "Move series earlier", "data-action": "series-up", onClick: () => controller.moveSeries(selectedSeries.id, seriesIndex - 1), children: "\u2191" }),
9533
+ /* @__PURE__ */ (0, import_jsx_runtime47.jsx)("button", { type: "button", className: chartButtonClass, disabled: seriesIndex >= spec.series.length - 1, "aria-label": "Move series later", "data-action": "series-down", onClick: () => controller.moveSeries(selectedSeries.id, seriesIndex + 1), children: "\u2193" }),
9534
+ /* @__PURE__ */ (0, import_jsx_runtime47.jsx)("button", { type: "button", className: `${chartButtonClass} text-destructive`, "data-action": "series-delete", onClick: () => controller.removeSeries(selectedSeries.id), children: "Delete" })
9441
9535
  ] })
9442
9536
  ] })
9443
9537
  ] });
9444
9538
  }
9445
9539
 
9446
9540
  // src/chart-node/ChartNodeView.tsx
9447
- var import_jsx_runtime47 = require("react/jsx-runtime");
9541
+ var import_jsx_runtime48 = require("react/jsx-runtime");
9448
9542
  function ChartNodeView({ state, theme, showDataGrid = true }) {
9449
9543
  const { controller, editing, editable, selected, width, height, setEditing } = state;
9450
9544
  const open = () => {
9451
9545
  if (editable && !editing) setEditing(true);
9452
9546
  };
9453
- return /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)(
9547
+ return /* @__PURE__ */ (0, import_jsx_runtime48.jsxs)(
9454
9548
  "div",
9455
9549
  {
9456
9550
  className: `not-prose my-2 rounded-md border bg-background p-1 ${selected ? "border-primary ring-1 ring-primary" : "border-border"}`,
@@ -9463,24 +9557,24 @@ function ChartNodeView({ state, theme, showDataGrid = true }) {
9463
9557
  }
9464
9558
  },
9465
9559
  children: [
9466
- editing && /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)("div", { className: "mb-1 flex items-center justify-between gap-2 px-1", "data-chart-node-toolbar": "", children: [
9467
- /* @__PURE__ */ (0, import_jsx_runtime47.jsx)("span", { className: "text-xs text-muted-foreground", children: "Editing chart" }),
9468
- /* @__PURE__ */ (0, import_jsx_runtime47.jsx)("button", { type: "button", className: chartButtonClass, "data-action": "done", onClick: () => setEditing(false), children: "Done" })
9560
+ editing && /* @__PURE__ */ (0, import_jsx_runtime48.jsxs)("div", { className: "mb-1 flex items-center justify-between gap-2 px-1", "data-chart-node-toolbar": "", children: [
9561
+ /* @__PURE__ */ (0, import_jsx_runtime48.jsx)("span", { className: "text-xs text-muted-foreground", children: "Editing chart" }),
9562
+ /* @__PURE__ */ (0, import_jsx_runtime48.jsx)("button", { type: "button", className: chartButtonClass, "data-action": "done", onClick: () => setEditing(false), children: "Done" })
9469
9563
  ] }),
9470
- /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(
9564
+ /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(
9471
9565
  "div",
9472
9566
  {
9473
9567
  className: editable && !editing ? "cursor-pointer" : void 0,
9474
9568
  onClick: open,
9475
9569
  title: editable && !editing ? "Click to edit the chart" : void 0,
9476
9570
  "data-chart-node-canvas": "",
9477
- children: /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(ChartCanvas, { controller, width: width ?? 640, height, responsive: width === null, editable: editing, theme })
9571
+ children: /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(ChartCanvas, { controller, width: width ?? 640, height, responsive: width === null, editable: editing, theme })
9478
9572
  }
9479
9573
  ),
9480
9574
  editing && // Wraps by the document's width, not the viewport's: side by side when there is room.
9481
- /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)("div", { className: "mt-2 flex flex-wrap items-start gap-2", "data-chart-node-panel": "", children: [
9482
- showDataGrid && /* @__PURE__ */ (0, import_jsx_runtime47.jsx)("div", { className: "min-w-0 flex-[1_1_20rem] overflow-x-auto", children: /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(ChartDataGrid, { controller }) }),
9483
- /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(ChartInspector, { controller, className: "max-h-96 min-w-0 flex-[1_1_16rem] overflow-y-auto rounded-md border border-border p-3" })
9575
+ /* @__PURE__ */ (0, import_jsx_runtime48.jsxs)("div", { className: "mt-2 flex flex-wrap items-start gap-2", "data-chart-node-panel": "", children: [
9576
+ showDataGrid && /* @__PURE__ */ (0, import_jsx_runtime48.jsx)("div", { className: "min-w-0 flex-[1_1_20rem] overflow-x-auto", children: /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(ChartDataGrid, { controller }) }),
9577
+ /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(ChartInspector, { controller, className: "max-h-96 min-w-0 flex-[1_1_16rem] overflow-y-auto rounded-md border border-border p-3" })
9484
9578
  ] })
9485
9579
  ]
9486
9580
  }
@@ -9498,7 +9592,7 @@ function createReactChartNodeView(options = {}) {
9498
9592
  scheduled = true;
9499
9593
  queueMicrotask(() => {
9500
9594
  scheduled = false;
9501
- if (!destroyed) root.render(/* @__PURE__ */ (0, import_jsx_runtime47.jsx)(Component, { ...props, state: latest }));
9595
+ if (!destroyed) root.render(/* @__PURE__ */ (0, import_jsx_runtime48.jsx)(Component, { ...props, state: latest }));
9502
9596
  });
9503
9597
  };
9504
9598
  schedule();
@@ -9521,6 +9615,7 @@ function createReactChartNodeView(options = {}) {
9521
9615
  BrushOptionsBar,
9522
9616
  BubbleMenu,
9523
9617
  ChartNodeView,
9618
+ ColorProfilePanel,
9524
9619
  CommandPalette,
9525
9620
  CommentButton,
9526
9621
  CommentsPanel,