@pixerate/editor 0.22.0 → 0.24.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.
Files changed (188) hide show
  1. package/README.md +175 -2
  2. package/THIRD_PARTY_NOTICES.md +139 -0
  3. package/dist/agent/index.cjs +87 -111
  4. package/dist/agent/index.cjs.map +1 -1
  5. package/dist/agent/index.d.cts +70 -211
  6. package/dist/agent/index.d.ts +70 -211
  7. package/dist/agent/index.js +78 -102
  8. package/dist/agent/index.js.map +1 -1
  9. package/dist/arrangeShortcuts-B8O3f8-P.d.cts +184 -0
  10. package/dist/arrangeShortcuts-sLlD2rSX.d.ts +184 -0
  11. package/dist/canvas/index.cjs +2075 -86
  12. package/dist/canvas/index.cjs.map +1 -1
  13. package/dist/canvas/index.d.cts +608 -186
  14. package/dist/canvas/index.d.ts +608 -186
  15. package/dist/canvas/index.js +2060 -71
  16. package/dist/canvas/index.js.map +1 -1
  17. package/dist/chunk-26BVFKHU.cjs +453 -0
  18. package/dist/chunk-26BVFKHU.cjs.map +1 -0
  19. package/dist/chunk-2H7ZHPEJ.js +762 -0
  20. package/dist/chunk-2H7ZHPEJ.js.map +1 -0
  21. package/dist/{chunk-DENSCKFC.js → chunk-3CN2WD3X.js} +1730 -189
  22. package/dist/chunk-3CN2WD3X.js.map +1 -0
  23. package/dist/{chunk-JJDLPEWL.js → chunk-3LV6RRPH.js} +2 -2
  24. package/dist/{chunk-MJZBNWG7.js → chunk-5S3Z4PPF.js} +78 -557
  25. package/dist/chunk-5S3Z4PPF.js.map +1 -0
  26. package/dist/chunk-664LQYFJ.js +115 -0
  27. package/dist/chunk-664LQYFJ.js.map +1 -0
  28. package/dist/chunk-7DWMJCAT.js +453 -0
  29. package/dist/chunk-7DWMJCAT.js.map +1 -0
  30. package/dist/chunk-ARRTP33I.js +101 -0
  31. package/dist/chunk-ARRTP33I.js.map +1 -0
  32. package/dist/chunk-CPOKFNBG.cjs +101 -0
  33. package/dist/chunk-CPOKFNBG.cjs.map +1 -0
  34. package/dist/{chunk-AA4ZEVCC.cjs → chunk-D27YFC46.cjs} +101 -580
  35. package/dist/chunk-D27YFC46.cjs.map +1 -0
  36. package/dist/chunk-D6FH2YAX.cjs +131 -0
  37. package/dist/chunk-D6FH2YAX.cjs.map +1 -0
  38. package/dist/{chunk-4SUNJZWB.cjs → chunk-FD4LPFAE.cjs} +48 -200
  39. package/dist/chunk-FD4LPFAE.cjs.map +1 -0
  40. package/dist/chunk-FODNLX5N.js +749 -0
  41. package/dist/chunk-FODNLX5N.js.map +1 -0
  42. package/dist/{chunk-OYXSKQFR.js → chunk-FPENXAEJ.js} +35 -187
  43. package/dist/chunk-FPENXAEJ.js.map +1 -0
  44. package/dist/chunk-G2I4QJOT.cjs +762 -0
  45. package/dist/chunk-G2I4QJOT.cjs.map +1 -0
  46. package/dist/chunk-HLIMTC6N.js +1 -0
  47. package/dist/chunk-HLIMTC6N.js.map +1 -0
  48. package/dist/{chunk-QGHGJ56O.js → chunk-ITBSKI26.js} +1483 -19
  49. package/dist/chunk-ITBSKI26.js.map +1 -0
  50. package/dist/{chunk-6M3BCTBD.cjs → chunk-MA2F5KHF.cjs} +470 -242
  51. package/dist/chunk-MA2F5KHF.cjs.map +1 -0
  52. package/dist/{chunk-SAZRENEZ.cjs → chunk-MCSJFWAO.cjs} +1733 -192
  53. package/dist/chunk-MCSJFWAO.cjs.map +1 -0
  54. package/dist/chunk-MKA3AHLV.cjs +256 -0
  55. package/dist/chunk-MKA3AHLV.cjs.map +1 -0
  56. package/dist/chunk-OLZJXL4R.cjs +749 -0
  57. package/dist/chunk-OLZJXL4R.cjs.map +1 -0
  58. package/dist/chunk-OXSV64JX.js +689 -0
  59. package/dist/chunk-OXSV64JX.js.map +1 -0
  60. package/dist/chunk-P3RQ5UJE.cjs +689 -0
  61. package/dist/chunk-P3RQ5UJE.cjs.map +1 -0
  62. package/dist/chunk-P6ODPZ4W.js +256 -0
  63. package/dist/chunk-P6ODPZ4W.js.map +1 -0
  64. package/dist/chunk-PGNZKFQS.js +685 -0
  65. package/dist/chunk-PGNZKFQS.js.map +1 -0
  66. package/dist/chunk-PL4JB3BF.cjs +1 -0
  67. package/dist/chunk-PL4JB3BF.cjs.map +1 -0
  68. package/dist/{chunk-GVSMRPHB.cjs → chunk-SBCZ6RN5.cjs} +1568 -104
  69. package/dist/chunk-SBCZ6RN5.cjs.map +1 -0
  70. package/dist/{chunk-CL37JGFW.cjs → chunk-SML64VJG.cjs} +4 -4
  71. package/dist/{chunk-CL37JGFW.cjs.map → chunk-SML64VJG.cjs.map} +1 -1
  72. package/dist/chunk-TNNJXF46.cjs +115 -0
  73. package/dist/chunk-TNNJXF46.cjs.map +1 -0
  74. package/dist/chunk-U5HZSFCS.js +131 -0
  75. package/dist/chunk-U5HZSFCS.js.map +1 -0
  76. package/dist/{chunk-RU52I7QO.js → chunk-U5KWZU4X.js} +388 -160
  77. package/dist/chunk-U5KWZU4X.js.map +1 -0
  78. package/dist/chunk-XNORY7M6.cjs +685 -0
  79. package/dist/chunk-XNORY7M6.cjs.map +1 -0
  80. package/dist/commands/index.cjs +860 -0
  81. package/dist/commands/index.cjs.map +1 -0
  82. package/dist/commands/index.d.cts +244 -0
  83. package/dist/commands/index.d.ts +244 -0
  84. package/dist/commands/index.js +860 -0
  85. package/dist/commands/index.js.map +1 -0
  86. package/dist/comment-store-BEMgVlAA.d.cts +135 -0
  87. package/dist/comment-store-BEMgVlAA.d.ts +135 -0
  88. package/dist/compare/index.cjs +15 -0
  89. package/dist/compare/index.cjs.map +1 -0
  90. package/dist/compare/index.d.cts +58 -0
  91. package/dist/compare/index.d.ts +58 -0
  92. package/dist/compare/index.js +15 -0
  93. package/dist/compare/index.js.map +1 -0
  94. package/dist/{controller-B7GIybc4.d.cts → controller-BhLLAoi8.d.cts} +119 -5
  95. package/dist/{controller-B7GIybc4.d.ts → controller-BhLLAoi8.d.ts} +119 -5
  96. package/dist/documents-BQjzJNe2.d.ts +76 -0
  97. package/dist/documents-KRTPhvst.d.cts +76 -0
  98. package/dist/extensions/index.cjs +53 -5
  99. package/dist/extensions/index.cjs.map +1 -1
  100. package/dist/extensions/index.d.cts +7 -3
  101. package/dist/extensions/index.d.ts +7 -3
  102. package/dist/extensions/index.js +52 -4
  103. package/dist/generation/index.cjs +1373 -0
  104. package/dist/generation/index.cjs.map +1 -0
  105. package/dist/generation/index.d.cts +554 -0
  106. package/dist/generation/index.d.ts +554 -0
  107. package/dist/generation/index.js +1373 -0
  108. package/dist/generation/index.js.map +1 -0
  109. package/dist/grammar/index.cjs +48 -3
  110. package/dist/grammar/index.cjs.map +1 -1
  111. package/dist/grammar/index.d.cts +322 -100
  112. package/dist/grammar/index.d.ts +322 -100
  113. package/dist/grammar/index.js +54 -9
  114. package/dist/history/index.cjs +12 -2
  115. package/dist/history/index.cjs.map +1 -1
  116. package/dist/history/index.d.cts +211 -7
  117. package/dist/history/index.d.ts +211 -7
  118. package/dist/history/index.js +13 -3
  119. package/dist/image-editor/index.cjs +2244 -38
  120. package/dist/image-editor/index.cjs.map +1 -1
  121. package/dist/image-editor/index.d.cts +742 -4
  122. package/dist/image-editor/index.d.ts +742 -4
  123. package/dist/image-editor/index.js +2222 -16
  124. package/dist/image-editor/index.js.map +1 -1
  125. package/dist/{index-CCr_z9kF.d.cts → index-BhJBSm2d.d.cts} +370 -4
  126. package/dist/{index-Ck6ajwXh.d.ts → index-fJrlkJCd.d.ts} +370 -4
  127. package/dist/index.cjs +193 -98
  128. package/dist/index.cjs.map +1 -1
  129. package/dist/index.d.cts +17 -48
  130. package/dist/index.d.ts +17 -48
  131. package/dist/index.js +198 -103
  132. package/dist/index.js.map +1 -1
  133. package/dist/migrate-iTlm3a8h.d.cts +112 -0
  134. package/dist/migrate-iTlm3a8h.d.ts +112 -0
  135. package/dist/persistence/index.cjs +676 -0
  136. package/dist/persistence/index.cjs.map +1 -0
  137. package/dist/persistence/index.d.cts +347 -0
  138. package/dist/persistence/index.d.ts +347 -0
  139. package/dist/persistence/index.js +676 -0
  140. package/dist/persistence/index.js.map +1 -0
  141. package/dist/registry-BDe-vlv3.d.ts +171 -0
  142. package/dist/registry-D32LpIc4.d.cts +354 -0
  143. package/dist/registry-DnzpgY27.d.cts +171 -0
  144. package/dist/registry-evKTP4ls.d.ts +354 -0
  145. package/dist/schema-DYDGdYL9.d.cts +41 -0
  146. package/dist/schema-DYDGdYL9.d.ts +41 -0
  147. package/dist/serializers/index.cjs +4 -3
  148. package/dist/serializers/index.cjs.map +1 -1
  149. package/dist/serializers/index.d.cts +2 -1
  150. package/dist/serializers/index.d.ts +2 -1
  151. package/dist/serializers/index.js +3 -2
  152. package/dist/sourcemap-C8AH3MBQ.d.cts +91 -0
  153. package/dist/sourcemap-DA1Evhrv.d.ts +91 -0
  154. package/dist/spreadsheet/index.cjs +53 -3
  155. package/dist/spreadsheet/index.cjs.map +1 -1
  156. package/dist/spreadsheet/index.d.cts +247 -18
  157. package/dist/spreadsheet/index.d.ts +247 -18
  158. package/dist/spreadsheet/index.js +58 -8
  159. package/dist/{tokens-CyLZmIei.d.cts → tokens-D7yXvUU6.d.cts} +15 -2
  160. package/dist/{tokens-CyLZmIei.d.ts → tokens-D7yXvUU6.d.ts} +15 -2
  161. package/dist/{track-changes-BSF58RK0.d.cts → track-changes-BK5sVf4_.d.cts} +18 -136
  162. package/dist/{track-changes-BSF58RK0.d.ts → track-changes-CDjCrwKe.d.ts} +18 -136
  163. package/dist/{types-CJ4U-HHI.d.ts → types-DX4Mh4SL.d.cts} +1 -1
  164. package/dist/{types-CJ4U-HHI.d.cts → types-DX4Mh4SL.d.ts} +1 -1
  165. package/dist/types-GT5a5YAX.d.cts +86 -0
  166. package/dist/types-GT5a5YAX.d.ts +86 -0
  167. package/package.json +23 -2
  168. package/dist/chunk-2TWGLC5K.cjs +0 -262
  169. package/dist/chunk-2TWGLC5K.cjs.map +0 -1
  170. package/dist/chunk-4SUNJZWB.cjs.map +0 -1
  171. package/dist/chunk-6M3BCTBD.cjs.map +0 -1
  172. package/dist/chunk-AA4ZEVCC.cjs.map +0 -1
  173. package/dist/chunk-AXV2ZW34.cjs +0 -118
  174. package/dist/chunk-AXV2ZW34.cjs.map +0 -1
  175. package/dist/chunk-B2ZRLN4S.js +0 -118
  176. package/dist/chunk-B2ZRLN4S.js.map +0 -1
  177. package/dist/chunk-DENSCKFC.js.map +0 -1
  178. package/dist/chunk-GVSMRPHB.cjs.map +0 -1
  179. package/dist/chunk-KAADNAPF.js +0 -262
  180. package/dist/chunk-KAADNAPF.js.map +0 -1
  181. package/dist/chunk-MJZBNWG7.js.map +0 -1
  182. package/dist/chunk-OYXSKQFR.js.map +0 -1
  183. package/dist/chunk-QGHGJ56O.js.map +0 -1
  184. package/dist/chunk-RU52I7QO.js.map +0 -1
  185. package/dist/chunk-SAZRENEZ.cjs.map +0 -1
  186. package/dist/types-BZgcDsC5.d.cts +0 -42
  187. package/dist/types-BZgcDsC5.d.ts +0 -42
  188. /package/dist/{chunk-JJDLPEWL.js.map → chunk-3LV6RRPH.js.map} +0 -0
@@ -0,0 +1,860 @@
1
+ "use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } } function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; } var _class;
2
+
3
+
4
+
5
+
6
+
7
+
8
+
9
+
10
+
11
+
12
+
13
+
14
+
15
+
16
+
17
+
18
+
19
+ var _chunk26BVFKHUcjs = require('../chunk-26BVFKHU.cjs');
20
+
21
+
22
+ var _chunkCPOKFNBGcjs = require('../chunk-CPOKFNBG.cjs');
23
+
24
+ // src/commands/registry.ts
25
+ var CommandRegistryError = class extends Error {
26
+
27
+ constructor(code, message) {
28
+ super(message);
29
+ this.name = "CommandRegistryError";
30
+ this.code = code;
31
+ }
32
+ };
33
+ var COMMAND_ID_REGEX = /^[A-Za-z0-9_.:-]{1,128}$/;
34
+ function enablement(result) {
35
+ if (result === void 0 || result === true) return { enabled: true };
36
+ if (result === false) return { enabled: false, reason: "This command is not available right now." };
37
+ return { enabled: false, reason: String(result) };
38
+ }
39
+ function unknownParams(spec, params) {
40
+ const keys = Object.keys(params).filter((k) => params[k] !== void 0);
41
+ if (keys.length === 0) return null;
42
+ const schema = spec.params;
43
+ if (schema && schema.additionalProperties !== void 0 && schema.additionalProperties !== false) return null;
44
+ const accepted = Object.keys(_nullishCoalesce(_optionalChain([schema, 'optionalAccess', _2 => _2.properties]), () => ( {})));
45
+ const bad = keys.find((k) => !accepted.includes(k));
46
+ if (!bad) return null;
47
+ return `Unknown parameter "${bad}" for command "${spec.id}"; expected ${accepted.length ? accepted.map((k) => `"${k}"`).join(", ") : "no parameters"}.`;
48
+ }
49
+ var isThenable = (value) => !!value && (typeof value === "object" || typeof value === "function") && typeof value.then === "function";
50
+ var CommandRegistry = (_class = class {
51
+ /** Shortcut bindings of the registered commands (plus any user overrides). */
52
+
53
+ __init() {this.commands = /* @__PURE__ */ new Map()}
54
+ __init2() {this.listeners = /* @__PURE__ */ new Set()}
55
+
56
+ __init3() {this.version = 0}
57
+ // Set while register/unregister change the shortcut map, so they notify once.
58
+ __init4() {this.muted = false}
59
+ constructor(options = {}) {;_class.prototype.__init.call(this);_class.prototype.__init2.call(this);_class.prototype.__init3.call(this);_class.prototype.__init4.call(this);
60
+ this.options = options;
61
+ this.shortcuts = new (0, _chunk26BVFKHUcjs.ShortcutMap)([], options.shortcuts);
62
+ this.shortcuts.subscribe(() => {
63
+ if (!this.muted) this.notify();
64
+ });
65
+ }
66
+ /** Monotonic counter bumped on every change (useful as a snapshot key). */
67
+ getVersion() {
68
+ return this.version;
69
+ }
70
+ /** The default context. */
71
+ get context() {
72
+ const ctx = this.options.context;
73
+ return typeof ctx === "function" ? ctx() : ctx;
74
+ }
75
+ /**
76
+ * Registers a command (or several) and returns a function that unregisters it.
77
+ * Throws a `CommandRegistryError` for a duplicate or invalid id, or invalid chord text.
78
+ */
79
+ register(spec) {
80
+ const specs = Array.isArray(spec) ? spec : [spec];
81
+ const seen = /* @__PURE__ */ new Set();
82
+ for (const s of specs) {
83
+ if (!s || typeof s.id !== "string" || !COMMAND_ID_REGEX.test(s.id)) {
84
+ throw new CommandRegistryError("invalid_command", `Invalid command id "${_optionalChain([s, 'optionalAccess', _3 => _3.id])}".`);
85
+ }
86
+ if (typeof s.run !== "function") {
87
+ throw new CommandRegistryError("invalid_command", `Command "${s.id}" has no run function.`);
88
+ }
89
+ if (this.commands.has(s.id) || seen.has(s.id)) {
90
+ throw new CommandRegistryError("duplicate_command", `Command "${s.id}" is already registered.`);
91
+ }
92
+ seen.add(s.id);
93
+ }
94
+ const bindings = specs.map((s) => _chunk26BVFKHUcjs.toShortcutBindings.call(void 0, s.id, s.shortcut, s.scope));
95
+ const unbinds = [];
96
+ this.muted = true;
97
+ try {
98
+ for (const b of bindings) unbinds.push(this.shortcuts.bind(b));
99
+ } catch (error) {
100
+ unbinds.forEach((u) => u());
101
+ throw new CommandRegistryError("invalid_command", error instanceof Error ? error.message : String(error));
102
+ } finally {
103
+ this.muted = false;
104
+ }
105
+ specs.forEach((s, i) => this.commands.set(s.id, { spec: s, unbind: unbinds[i] }));
106
+ this.notify();
107
+ let registered = true;
108
+ return () => {
109
+ if (!registered) return;
110
+ registered = false;
111
+ let changed = false;
112
+ for (const s of specs) {
113
+ const entry = this.commands.get(s.id);
114
+ if (entry && entry.spec === s) {
115
+ this.commands.delete(s.id);
116
+ this.unbindQuietly(entry);
117
+ changed = true;
118
+ }
119
+ }
120
+ if (changed) this.notify();
121
+ };
122
+ }
123
+ /** Removes a command by id. Returns whether it was registered. */
124
+ unregister(id) {
125
+ const entry = this.commands.get(id);
126
+ if (!entry) return false;
127
+ this.commands.delete(id);
128
+ this.unbindQuietly(entry);
129
+ this.notify();
130
+ return true;
131
+ }
132
+ unbindQuietly(entry) {
133
+ this.muted = true;
134
+ try {
135
+ entry.unbind();
136
+ } finally {
137
+ this.muted = false;
138
+ }
139
+ }
140
+ has(id) {
141
+ return this.commands.has(id);
142
+ }
143
+ get(id) {
144
+ return _optionalChain([this, 'access', _4 => _4.commands, 'access', _5 => _5.get, 'call', _6 => _6(id), 'optionalAccess', _7 => _7.spec]);
145
+ }
146
+ /** Registered ids in registration order. */
147
+ ids() {
148
+ return [...this.commands.keys()];
149
+ }
150
+ /** Whether `id` can run now (`{ enabled, reason }`); `params` are the targets a caller named. */
151
+ isEnabled(id, params, context = this.context) {
152
+ const spec = this.get(id);
153
+ if (!spec) return { enabled: false, reason: `Unknown command "${id}".` };
154
+ if (!spec.enabled) return { enabled: true };
155
+ try {
156
+ return enablement(spec.enabled(context, params));
157
+ } catch (error) {
158
+ return { enabled: false, reason: error instanceof Error ? error.message : String(error) };
159
+ }
160
+ }
161
+ /** Commands for menus, palettes and agents, with their current enablement. */
162
+ list(options = {}) {
163
+ const scopes = options.scope === void 0 ? null : typeof options.scope === "string" ? [options.scope] : options.scope;
164
+ const context = "context" in options ? options.context : this.context;
165
+ const platform = this.shortcuts.platform;
166
+ const out = [];
167
+ for (const { spec } of this.commands.values()) {
168
+ if (spec.hidden && !options.includeHidden) continue;
169
+ if (scopes && spec.scope !== void 0 && !scopes.includes(spec.scope)) continue;
170
+ const { enabled, reason } = this.isEnabled(spec.id, void 0, context);
171
+ if (options.enabledOnly && !enabled) continue;
172
+ out.push({
173
+ id: spec.id,
174
+ label: spec.label,
175
+ ...spec.group !== void 0 ? { group: spec.group } : {},
176
+ ...spec.keywords ? { keywords: spec.keywords } : {},
177
+ ...spec.description !== void 0 ? { description: spec.description } : {},
178
+ ...spec.params ? { params: spec.params } : {},
179
+ ...spec.scope !== void 0 ? { scope: spec.scope } : {},
180
+ shortcuts: this.shortcuts.forCommand(spec.id, platform),
181
+ enabled,
182
+ ...enabled ? {} : { disabledReason: reason },
183
+ undoable: !!spec.undoable,
184
+ readOnly: !!spec.readOnly
185
+ });
186
+ }
187
+ return out;
188
+ }
189
+ check(id, params, context) {
190
+ const spec = this.get(id);
191
+ if (!spec) return { ok: false, id, code: "unknown_command", message: `Unknown command "${id}".` };
192
+ const input = _nullishCoalesce(params, () => ( {}));
193
+ if (typeof input !== "object" || Array.isArray(input)) {
194
+ return { ok: false, id, code: "invalid_params", message: `Parameters for command "${id}" must be an object.` };
195
+ }
196
+ const unknown = unknownParams(spec, input);
197
+ if (unknown) return { ok: false, id, code: "invalid_params", message: unknown };
198
+ if (spec.params) {
199
+ const details = _chunkCPOKFNBGcjs.validateJsonSchema.call(void 0, input, spec.params);
200
+ if (details.length > 0) {
201
+ return {
202
+ ok: false,
203
+ id,
204
+ code: "invalid_params",
205
+ message: `Invalid parameters for command "${id}": ${details.map((d) => `${d.path} ${d.message}`).join("; ")}`,
206
+ details
207
+ };
208
+ }
209
+ }
210
+ const { enabled, reason } = this.isEnabled(id, params === void 0 ? void 0 : input, context);
211
+ if (!enabled) return { ok: false, id, code: "disabled", message: _nullishCoalesce(reason, () => ( "Disabled.")) };
212
+ return { spec, params: input };
213
+ }
214
+ invoke(spec, params, context) {
215
+ const history = this.options.history;
216
+ if (!spec.undoable || !history) return spec.run(context, params);
217
+ let value;
218
+ history.batch(spec.label, () => {
219
+ value = spec.run(context, params);
220
+ });
221
+ return value;
222
+ }
223
+ /**
224
+ * Runs a command synchronously and returns a structured result; never throws.
225
+ * A command whose `run` returns a promise yields `{ ok: true, result: promise }`
226
+ * (use `executeAsync` to await it and catch its rejection).
227
+ */
228
+ execute(id, params, context = this.context) {
229
+ const checked = this.check(id, params, context);
230
+ if ("ok" in checked) return checked;
231
+ try {
232
+ const result = this.invoke(checked.spec, checked.params, context);
233
+ this.notify();
234
+ return { ok: true, id, result };
235
+ } catch (error) {
236
+ this.notify();
237
+ return { ok: false, id, code: "failed", message: error instanceof Error ? error.message : String(error) };
238
+ }
239
+ }
240
+ /** Like `execute`, but awaits async commands (rejections become `failed` results). */
241
+ async executeAsync(id, params, context = this.context) {
242
+ const outcome = this.execute(id, params, context);
243
+ if (!outcome.ok || !isThenable(outcome.result)) return outcome;
244
+ try {
245
+ const result = await outcome.result;
246
+ this.notify();
247
+ return { ok: true, id, result };
248
+ } catch (error) {
249
+ this.notify();
250
+ return { ok: false, id, code: "failed", message: error instanceof Error ? error.message : String(error) };
251
+ }
252
+ }
253
+ /**
254
+ * Resolves a keydown event to a command (see `ShortcutMap.resolve`) and runs it when
255
+ * enabled, calling `preventDefault()`. Disabled commands leave the event alone, so the
256
+ * browser or a focused editor can still handle it. Returns the result, or `null`.
257
+ */
258
+ handleKeyDown(event, options = {}) {
259
+ if (event.defaultPrevented) return null;
260
+ const match = this.shortcuts.resolve(event, options);
261
+ if (!match) return null;
262
+ const context = "context" in options ? options.context : this.context;
263
+ if (!this.isEnabled(match.command, void 0, context).enabled) return null;
264
+ _optionalChain([event, 'access', _8 => _8.preventDefault, 'optionalCall', _9 => _9()]);
265
+ return this.execute(match.command, void 0, context);
266
+ }
267
+ /** Display-ready primary shortcut of a command (`⇧⌘Z` / `Ctrl+Shift+Z`), or `undefined`. */
268
+ shortcutFor(id, platform = this.shortcuts.platform) {
269
+ return this.shortcuts.forCommand(id, platform)[0];
270
+ }
271
+ /**
272
+ * Subscribes to changes: commands registered or removed, shortcut overrides, executed
273
+ * commands and `invalidate()` calls (e.g. when enablement inputs change).
274
+ */
275
+ subscribe(listener) {
276
+ this.listeners.add(listener);
277
+ return () => {
278
+ this.listeners.delete(listener);
279
+ };
280
+ }
281
+ /** Tells subscribers that enablement may have changed (e.g. the selection changed). */
282
+ invalidate() {
283
+ this.notify();
284
+ }
285
+ notify() {
286
+ this.version++;
287
+ for (const listener of Array.from(this.listeners)) {
288
+ try {
289
+ listener();
290
+ } catch (error) {
291
+ console.error("[CommandRegistry] Error in listener:", error);
292
+ }
293
+ }
294
+ }
295
+ }, _class);
296
+ function createCommandRegistry(options) {
297
+ return new CommandRegistry(options);
298
+ }
299
+ function defineCommand(spec) {
300
+ return spec;
301
+ }
302
+
303
+ // src/commands/palette.ts
304
+ var WORD_SEPARATORS = /* @__PURE__ */ new Set([" ", "-", "_", ".", "/", ":", "\u203A", "("]);
305
+ function fuzzyMatch(query, text) {
306
+ const q = query.trim().toLowerCase();
307
+ if (!q) return { score: 0, indices: [] };
308
+ const t = text.toLowerCase();
309
+ let score = 0;
310
+ let ti = 0;
311
+ let last = -2;
312
+ const indices = [];
313
+ for (const qc of q) {
314
+ if (qc === " ") continue;
315
+ let found = false;
316
+ while (ti < t.length) {
317
+ if (t[ti] === qc) {
318
+ score += last === ti - 1 ? 8 : 1;
319
+ if (ti === 0 || WORD_SEPARATORS.has(t[ti - 1])) score += 5;
320
+ last = ti;
321
+ indices.push(ti);
322
+ ti++;
323
+ found = true;
324
+ break;
325
+ }
326
+ ti++;
327
+ }
328
+ if (!found) return null;
329
+ }
330
+ return { score: score - Math.floor(t.length / 8), indices };
331
+ }
332
+ function fuzzyScore(query, text) {
333
+ return _nullishCoalesce(_optionalChain([fuzzyMatch, 'call', _10 => _10(query, text), 'optionalAccess', _11 => _11.score]), () => ( null));
334
+ }
335
+ function exactBonus(query, names) {
336
+ const q = query.trim().toLowerCase();
337
+ if (!q) return 0;
338
+ return names.some((n) => n.replace(/(…|\.\.\.)$/, "").trim().toLowerCase() === q) ? 1e3 : 0;
339
+ }
340
+ var DEFAULT_RECENT_LIMIT = 8;
341
+ function pushRecent(list, id, cap = DEFAULT_RECENT_LIMIT) {
342
+ return [id, ...list.filter((x) => x !== id)].slice(0, Math.max(0, cap));
343
+ }
344
+ function rankCommands(query, entries, options = {}) {
345
+ const recents = _nullishCoalesce(options.recents, () => ( []));
346
+ const disabledLast = _nullishCoalesce(options.disabledLast, () => ( true));
347
+ const q = query.trim();
348
+ let ranked;
349
+ if (!q) {
350
+ const byId = new Map(entries.map((e) => [e.id, e]));
351
+ const recentIds = [...new Set(recents)].filter((id) => byId.has(id)).slice(0, _nullishCoalesce(options.recentLimit, () => ( DEFAULT_RECENT_LIMIT)));
352
+ const recentSet = new Set(recentIds);
353
+ ranked = recentIds.map((id, i) => ({ entry: byId.get(id), score: 1e3 - i, labelIndices: [], recent: true, order: i }));
354
+ if ((_nullishCoalesce(options.emptyQuery, () => ( "all"))) === "all") {
355
+ entries.forEach((entry, i) => {
356
+ if (!recentSet.has(entry.id)) ranked.push({ entry, score: 0, labelIndices: [], recent: false, order: recentIds.length + i });
357
+ });
358
+ }
359
+ } else {
360
+ ranked = [];
361
+ entries.forEach((entry, order) => {
362
+ const label = fuzzyMatch(q, entry.label);
363
+ const candidates = [];
364
+ if (label) candidates.push(label.score);
365
+ if (entry.group) {
366
+ const grouped = fuzzyScore(q, `${entry.group} ${entry.label}`);
367
+ if (grouped !== null) candidates.push(grouped - 1);
368
+ }
369
+ for (const keyword of _nullishCoalesce(entry.keywords, () => ( []))) {
370
+ const s = fuzzyScore(q, keyword);
371
+ if (s !== null) candidates.push(s - 2);
372
+ }
373
+ const byId = fuzzyScore(q, entry.id);
374
+ if (byId !== null) candidates.push(byId - 3);
375
+ if (candidates.length === 0) return;
376
+ const recentIndex = recents.indexOf(entry.id);
377
+ const score = Math.max(...candidates) + exactBonus(q, [entry.label, ..._nullishCoalesce(entry.keywords, () => ( []))]) + (recentIndex >= 0 ? Math.max(1, 4 - recentIndex) : 0);
378
+ ranked.push({ entry, score, labelIndices: _nullishCoalesce(_optionalChain([label, 'optionalAccess', _12 => _12.indices]), () => ( [])), recent: false, order });
379
+ });
380
+ ranked.sort((a, b) => b.score - a.score || a.entry.label.length - b.entry.label.length || a.order - b.order);
381
+ }
382
+ if (disabledLast) {
383
+ ranked = [...ranked.filter((r) => r.entry.enabled !== false), ...ranked.filter((r) => r.entry.enabled === false)];
384
+ }
385
+ const out = ranked.map(({ order: _order, ...rest }) => rest);
386
+ return options.limit !== void 0 ? out.slice(0, options.limit) : out;
387
+ }
388
+
389
+ // src/commands/paletteController.ts
390
+ function createCommandPaletteController(registry, options = {}) {
391
+ const listeners = /* @__PURE__ */ new Set();
392
+ let open = false;
393
+ let query = "";
394
+ let activeIndex = 0;
395
+ let recents = [..._nullishCoalesce(options.recents, () => ( []))];
396
+ let lastResult = null;
397
+ let state;
398
+ const context = () => {
399
+ const c = options.context;
400
+ if (c === void 0) return registry.context;
401
+ return typeof c === "function" ? c() : c;
402
+ };
403
+ const scope = () => typeof options.scope === "function" ? options.scope() : options.scope;
404
+ function computeItems() {
405
+ if (!open) return [];
406
+ const entries = registry.list({ scope: scope(), context: context() });
407
+ const platform = _nullishCoalesce(options.platform, () => ( registry.shortcuts.platform));
408
+ return rankCommands(query, entries, {
409
+ recents,
410
+ recentLimit: options.recentLimit,
411
+ limit: _nullishCoalesce(options.limit, () => ( 50))
412
+ }).map((ranked) => ({
413
+ ...ranked,
414
+ id: ranked.entry.id,
415
+ label: ranked.entry.label,
416
+ ...ranked.entry.group !== void 0 ? { group: ranked.entry.group } : {},
417
+ ...ranked.entry.shortcuts[0] ? { shortcut: _chunk26BVFKHUcjs.formatShortcut.call(void 0, ranked.entry.shortcuts[0], platform) } : {},
418
+ enabled: ranked.entry.enabled,
419
+ ...ranked.entry.disabledReason ? { disabledReason: ranked.entry.disabledReason } : {}
420
+ }));
421
+ }
422
+ function update() {
423
+ const items = computeItems();
424
+ activeIndex = items.length === 0 ? 0 : Math.min(Math.max(activeIndex, 0), items.length - 1);
425
+ state = { open, query, activeIndex, items, recents, lastResult };
426
+ for (const listener of Array.from(listeners)) listener(state);
427
+ }
428
+ state = { open, query, activeIndex, items: [], recents, lastResult };
429
+ let unsubscribeRegistry = null;
430
+ const onRegistryChange = () => {
431
+ if (open) update();
432
+ };
433
+ const controller = {
434
+ getState: () => state,
435
+ subscribe(listener) {
436
+ listeners.add(listener);
437
+ unsubscribeRegistry ??= registry.subscribe(onRegistryChange);
438
+ if (open) update();
439
+ return () => {
440
+ listeners.delete(listener);
441
+ if (listeners.size === 0) {
442
+ _optionalChain([unsubscribeRegistry, 'optionalCall', _13 => _13()]);
443
+ unsubscribeRegistry = null;
444
+ }
445
+ };
446
+ },
447
+ setOpen(next) {
448
+ if (next === open) return;
449
+ open = next;
450
+ query = "";
451
+ activeIndex = 0;
452
+ update();
453
+ },
454
+ toggle() {
455
+ controller.setOpen(!open);
456
+ },
457
+ setQuery(next) {
458
+ if (next === query) return;
459
+ query = next;
460
+ activeIndex = 0;
461
+ update();
462
+ },
463
+ setActiveIndex(index) {
464
+ activeIndex = index;
465
+ update();
466
+ },
467
+ /** Moves the active row by `delta`, wrapping around. */
468
+ move(delta) {
469
+ const n = state.items.length;
470
+ if (n === 0) return;
471
+ activeIndex = ((activeIndex + delta) % n + n) % n;
472
+ update();
473
+ },
474
+ /** Runs a command by id, closes the palette and records it as recent. Disabled commands do nothing. */
475
+ run(id) {
476
+ if (!registry.isEnabled(id, void 0, context()).enabled) return null;
477
+ open = false;
478
+ query = "";
479
+ activeIndex = 0;
480
+ recents = pushRecent(recents, id, _nullishCoalesce(options.recentLimit, () => ( DEFAULT_RECENT_LIMIT)));
481
+ _optionalChain([options, 'access', _14 => _14.onRecentsChange, 'optionalCall', _15 => _15(recents)]);
482
+ const result = registry.execute(id, void 0, context());
483
+ lastResult = result;
484
+ update();
485
+ _optionalChain([options, 'access', _16 => _16.onRun, 'optionalCall', _17 => _17(result)]);
486
+ return result;
487
+ },
488
+ runActive() {
489
+ const item = state.items[state.activeIndex];
490
+ return item ? controller.run(item.id) : null;
491
+ },
492
+ /**
493
+ * Keyboard handling for the palette input: ArrowUp/ArrowDown (wrap), Home/End,
494
+ * Enter (run the active row) and Escape (close). Returns whether it handled the key.
495
+ */
496
+ handleKeyDown(event) {
497
+ if (!open) return false;
498
+ switch (event.key) {
499
+ case "ArrowDown":
500
+ controller.move(1);
501
+ break;
502
+ case "ArrowUp":
503
+ controller.move(-1);
504
+ break;
505
+ case "Home":
506
+ controller.setActiveIndex(0);
507
+ break;
508
+ case "End":
509
+ controller.setActiveIndex(state.items.length - 1);
510
+ break;
511
+ case "Enter":
512
+ controller.runActive();
513
+ break;
514
+ case "Escape":
515
+ controller.setOpen(false);
516
+ break;
517
+ default:
518
+ return false;
519
+ }
520
+ _optionalChain([event, 'access', _18 => _18.preventDefault, 'optionalCall', _19 => _19()]);
521
+ return true;
522
+ },
523
+ /** Re-reads commands and enablement. */
524
+ refresh() {
525
+ update();
526
+ },
527
+ destroy() {
528
+ _optionalChain([unsubscribeRegistry, 'optionalCall', _20 => _20()]);
529
+ unsubscribeRegistry = null;
530
+ listeners.clear();
531
+ }
532
+ };
533
+ return controller;
534
+ }
535
+ function matchPaletteHotkey(event, hotkey, platform) {
536
+ const map = new (0, _chunk26BVFKHUcjs.ShortcutMap)([{ command: "palette", chord: hotkey, allowInEditable: true }], platform ? { platform } : {});
537
+ return map.resolve(event) !== null;
538
+ }
539
+
540
+ // src/commands/agentTools.ts
541
+ var toJson = (value) => {
542
+ if (value === void 0) return null;
543
+ try {
544
+ return JSON.parse(JSON.stringify(value));
545
+ } catch (e2) {
546
+ return String(value);
547
+ }
548
+ };
549
+ function errorResult(result) {
550
+ return {
551
+ isError: true,
552
+ content: [{ type: "text", text: `${result.code}: ${result.message}` }],
553
+ structuredContent: {
554
+ error: { code: result.code, message: result.message, command: result.id, ...result.details ? { details: result.details } : {} }
555
+ }
556
+ };
557
+ }
558
+ function createCommandToolProvider(registry, options = {}) {
559
+ const context = () => {
560
+ const c = options.context;
561
+ if (c === void 0) return registry.context;
562
+ return typeof c === "function" ? c() : c;
563
+ };
564
+ const visible = () => registry.list({ scope: options.scope, context: context() }).filter((e) => !_optionalChain([options, 'access', _21 => _21.exclude, 'optionalCall', _22 => _22(e.id)]));
565
+ const allowed = (id) => registry.has(id) && !_optionalChain([options, 'access', _23 => _23.exclude, 'optionalCall', _24 => _24(id)]) && visible().some((e) => e.id === id);
566
+ async function runOne(id, params) {
567
+ if (!allowed(id)) return { ok: false, id, code: "unknown_command", message: `Unknown command "${id}".` };
568
+ return registry.executeAsync(id, _nullishCoalesce(params, () => ( {})), context());
569
+ }
570
+ const listCommands = {
571
+ name: "list_commands",
572
+ title: "List commands",
573
+ description: "Lists the commands you can run with run_command: id, label, group, params (JSON Schema), shortcuts, and whether each is enabled now (with the reason when it is not).",
574
+ inputSchema: {
575
+ type: "object",
576
+ properties: {
577
+ query: { type: "string", description: "Fuzzy filter on label, keywords, group and id." },
578
+ enabledOnly: { type: "boolean", description: "Only commands that can run now (default false)." }
579
+ },
580
+ additionalProperties: false
581
+ },
582
+ annotations: { title: "List commands", readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: false },
583
+ handler: ({ query = "", enabledOnly = false }) => {
584
+ let entries = visible();
585
+ if (enabledOnly) entries = entries.filter((e) => e.enabled);
586
+ if (String(query).trim()) entries = rankCommands(String(query), entries, { disabledLast: false }).map((r) => r.entry);
587
+ return {
588
+ commands: entries.map((e) => ({
589
+ id: e.id,
590
+ label: e.label,
591
+ ...e.group ? { group: e.group } : {},
592
+ ...e.description ? { description: e.description } : {},
593
+ ...e.params ? { params: e.params } : {},
594
+ ...e.shortcuts.length ? { shortcuts: e.shortcuts } : {},
595
+ enabled: e.enabled,
596
+ ...e.disabledReason ? { disabledReason: e.disabledReason } : {},
597
+ readOnly: e.readOnly
598
+ }))
599
+ };
600
+ }
601
+ };
602
+ const runCommandTool = () => {
603
+ const ids = visible().map((e) => e.id);
604
+ return {
605
+ name: "run_command",
606
+ title: "Run a command",
607
+ description: "Runs one command by id with optional params (see list_commands for each command's params schema). Unknown params are rejected.",
608
+ inputSchema: {
609
+ type: "object",
610
+ properties: {
611
+ id: { type: "string", description: "Command id from list_commands.", ...ids.length ? { enum: ids } : {} },
612
+ params: { type: "object", description: "Command parameters." }
613
+ },
614
+ required: ["id"],
615
+ additionalProperties: false
616
+ },
617
+ annotations: { title: "Run a command", readOnlyHint: false, destructiveHint: true, idempotentHint: false, openWorldHint: false },
618
+ handler: async ({ id, params }) => {
619
+ const result = await runOne(String(id), params);
620
+ return result.ok ? { id: result.id, ok: true, result: toJson(result.result) } : errorResult(result);
621
+ }
622
+ };
623
+ };
624
+ const runCommands = {
625
+ name: "run_commands",
626
+ title: "Run several commands",
627
+ description: "Runs several commands in order: {steps: [{id, params?}], stopOnError?: true}. Each step is its own command and undo step; the batch is NOT atomic (steps before a failure stay applied). Returns {completed, failed, results: [{id, ok, result | code, message}]}.",
628
+ inputSchema: {
629
+ type: "object",
630
+ properties: {
631
+ steps: {
632
+ type: "array",
633
+ minItems: 1,
634
+ items: {
635
+ type: "object",
636
+ properties: {
637
+ id: { type: "string", description: "Command id." },
638
+ params: { type: "object", description: "Command parameters." }
639
+ },
640
+ required: ["id"],
641
+ additionalProperties: false
642
+ }
643
+ },
644
+ stopOnError: { type: "boolean", description: "Stop at the first failing step (default true)." }
645
+ },
646
+ required: ["steps"],
647
+ additionalProperties: false
648
+ },
649
+ annotations: {
650
+ title: "Run several commands",
651
+ readOnlyHint: false,
652
+ destructiveHint: true,
653
+ idempotentHint: false,
654
+ openWorldHint: false
655
+ },
656
+ handler: async ({ steps, stopOnError = true }) => {
657
+ let completed = 0;
658
+ let failed = 0;
659
+ const results = [];
660
+ for (const step of steps) {
661
+ const result = await runOne(step.id, step.params);
662
+ if (result.ok) {
663
+ completed++;
664
+ results.push({ id: result.id, ok: true, result: toJson(result.result) });
665
+ } else {
666
+ failed++;
667
+ results.push({ id: result.id, ok: false, code: result.code, message: result.message });
668
+ if (stopOnError) break;
669
+ }
670
+ }
671
+ const summary = { completed, failed, skipped: steps.length - completed - failed, results };
672
+ return failed > 0 ? { isError: true, content: [{ type: "text", text: JSON.stringify(summary) }], structuredContent: summary } : summary;
673
+ }
674
+ };
675
+ return {
676
+ id: _nullishCoalesce(options.id, () => ( "commands")),
677
+ namespace: options.namespace,
678
+ tools: () => [listCommands, runCommandTool(), runCommands],
679
+ subscribe: (notify) => registry.subscribe(notify)
680
+ };
681
+ }
682
+
683
+ // src/commands/builtins.ts
684
+ var DEFAULT_HISTORY_SHORTCUTS = [
685
+ { command: "undo", chord: "Mod+Z" },
686
+ { command: "redo", chord: "Mod+Shift+Z" },
687
+ { command: "redo", chord: "Mod+Y", platforms: ["windows", "linux"] }
688
+ ];
689
+ function createHistoryCommands(history, options = {}) {
690
+ const prefix = _nullishCoalesce(options.prefix, () => ( "history."));
691
+ const group = _nullishCoalesce(options.group, () => ( "Edit"));
692
+ const shortcutsOf = (command) => DEFAULT_HISTORY_SHORTCUTS.filter((b) => b.command === command).map(({ command: _c, ...rest }) => rest);
693
+ return [
694
+ {
695
+ id: `${prefix}undo`,
696
+ label: "Undo",
697
+ group,
698
+ keywords: ["revert", "back"],
699
+ description: "Reverts the last change.",
700
+ shortcut: shortcutsOf("undo"),
701
+ ...options.scope ? { scope: options.scope } : {},
702
+ enabled: () => history.getState().canUndo ? true : "Nothing to undo.",
703
+ run: () => {
704
+ history.undo();
705
+ return { undone: true, state: history.getState() };
706
+ }
707
+ },
708
+ {
709
+ id: `${prefix}redo`,
710
+ label: "Redo",
711
+ group,
712
+ keywords: ["repeat", "forward"],
713
+ description: "Re-applies the last undone change.",
714
+ shortcut: shortcutsOf("redo"),
715
+ ...options.scope ? { scope: options.scope } : {},
716
+ enabled: () => history.getState().canRedo ? true : "Nothing to redo.",
717
+ run: () => {
718
+ history.redo();
719
+ return { redone: true, state: history.getState() };
720
+ }
721
+ }
722
+ ];
723
+ }
724
+ var historyShortcutMap = null;
725
+ function matchHistoryShortcut(event, options = {}) {
726
+ historyShortcutMap ??= new (0, _chunk26BVFKHUcjs.ShortcutMap)(DEFAULT_HISTORY_SHORTCUTS);
727
+ return _nullishCoalesce(_optionalChain([historyShortcutMap, 'access', _25 => _25.resolve, 'call', _26 => _26(event, options), 'optionalAccess', _27 => _27.command]), () => ( null));
728
+ }
729
+ var ARRANGE_LABELS = {
730
+ alignLeft: "Align Left",
731
+ alignCenter: "Align Horizontal Centers",
732
+ alignRight: "Align Right",
733
+ alignTop: "Align Top",
734
+ alignMiddle: "Align Vertical Centers",
735
+ alignBottom: "Align Bottom",
736
+ distributeHorizontal: "Distribute Horizontally",
737
+ distributeVertical: "Distribute Vertically",
738
+ lock: "Lock",
739
+ unlock: "Unlock",
740
+ bringForward: "Bring Forward",
741
+ sendBackward: "Send Backward",
742
+ bringToFront: "Bring to Front",
743
+ sendToBack: "Send to Back",
744
+ nextScene: "Next Scene",
745
+ previousScene: "Previous Scene"
746
+ };
747
+ var IDS_PARAMS = {
748
+ type: "object",
749
+ properties: {
750
+ ids: {
751
+ type: "array",
752
+ items: { type: "string" },
753
+ description: "Node ids to act on (default: the selection)."
754
+ }
755
+ }
756
+ };
757
+ function createArrangeCommands(controller, options = {}) {
758
+ const prefix = _nullishCoalesce(options.prefix, () => ( "canvas."));
759
+ const group = _nullishCoalesce(options.group, () => ( "Arrange"));
760
+ const scope = options.scope === null ? void 0 : _nullishCoalesce(options.scope, () => ( "canvas"));
761
+ const bindings = _nullishCoalesce(options.bindings, () => ( _chunk26BVFKHUcjs.DEFAULT_ARRANGE_SHORTCUTS));
762
+ const count = (params) => _nullishCoalesce(_optionalChain([params, 'optionalAccess', _28 => _28.ids, 'optionalAccess', _29 => _29.length]), () => ( _optionalChain([options, 'access', _30 => _30.getSelectedIds, 'optionalCall', _31 => _31(), 'access', _32 => _32.length])));
763
+ const needs = (min, what) => (_, params) => {
764
+ const n = count(params);
765
+ if (n === void 0 || n >= min) return true;
766
+ return min === 1 ? `Select a ${what} first.` : `Select at least ${min} ${what}s.`;
767
+ };
768
+ const run = {
769
+ alignLeft: (ids) => controller.align("left", ids),
770
+ alignCenter: (ids) => controller.align("center", ids),
771
+ alignRight: (ids) => controller.align("right", ids),
772
+ alignTop: (ids) => controller.align("top", ids),
773
+ alignMiddle: (ids) => controller.align("middle", ids),
774
+ alignBottom: (ids) => controller.align("bottom", ids),
775
+ distributeHorizontal: (ids) => controller.distribute("horizontal", "gaps", ids),
776
+ distributeVertical: (ids) => controller.distribute("vertical", "gaps", ids),
777
+ lock: (ids) => controller.lock(ids),
778
+ unlock: (ids) => controller.unlock(ids),
779
+ bringForward: (ids) => controller.reorder("bringForward", ids),
780
+ sendBackward: (ids) => controller.reorder("sendBackward", ids),
781
+ bringToFront: (ids) => controller.reorder("bringToFront", ids),
782
+ sendToBack: (ids) => controller.reorder("sendToBack", ids),
783
+ nextScene: () => _optionalChain([options, 'access', _33 => _33.scenes, 'optionalAccess', _34 => _34.next, 'call', _35 => _35()]),
784
+ previousScene: () => _optionalChain([options, 'access', _36 => _36.scenes, 'optionalAccess', _37 => _37.previous, 'call', _38 => _38()])
785
+ };
786
+ const actions = Object.keys(ARRANGE_LABELS);
787
+ return actions.filter((action) => options.scenes || action !== "nextScene" && action !== "previousScene").map((action) => {
788
+ const isScene = action === "nextScene" || action === "previousScene";
789
+ const enabled = isScene ? void 0 : action.startsWith("align") ? needs(2, "node") : action.startsWith("distribute") ? needs(3, "node") : needs(1, "node");
790
+ return {
791
+ id: `${prefix}${action}`,
792
+ label: ARRANGE_LABELS[action],
793
+ group: isScene ? "Scenes" : group,
794
+ keywords: isScene ? ["scene", "slide", "page"] : action.startsWith("align") ? ["align"] : ["arrange", "layer", "order"],
795
+ ...scope ? { scope } : {},
796
+ shortcut: bindings.filter((b) => b.action === action).map((b) => b.label),
797
+ ...isScene ? {} : { params: IDS_PARAMS },
798
+ ...enabled ? { enabled } : {},
799
+ run: (_ctx, params) => run[action](_optionalChain([params, 'optionalAccess', _39 => _39.ids]))
800
+ };
801
+ });
802
+ }
803
+ function createSpreadsheetCommands(controller, options = {}) {
804
+ const prefix = _nullishCoalesce(options.prefix, () => ( "spreadsheet."));
805
+ const scope = options.scope === null ? void 0 : _nullishCoalesce(options.scope, () => ( "spreadsheet"));
806
+ const hasRange = () => controller.selectedRange ? true : "Select a range first.";
807
+ const base = { group: "Table", ...scope ? { scope } : {} };
808
+ return [
809
+ { ...base, id: `${prefix}toggleFilters`, label: "Toggle Filters", keywords: ["filter"], run: () => controller.toggleFilters() },
810
+ {
811
+ ...base,
812
+ id: `${prefix}clearFilters`,
813
+ label: "Clear Filters",
814
+ keywords: ["filter", "reset"],
815
+ enabled: () => controller.getFilterState().rules.length > 0 ? true : "No filters to clear.",
816
+ run: () => controller.clearFilters()
817
+ },
818
+ { ...base, id: `${prefix}unhideAll`, label: "Unhide All Rows and Columns", keywords: ["show", "hidden"], run: () => controller.unhideAll() },
819
+ { ...base, id: `${prefix}mergeCells`, label: "Merge Cells", keywords: ["combine"], enabled: hasRange, run: () => controller.mergeCells() },
820
+ { ...base, id: `${prefix}unmergeCells`, label: "Unmerge Cells", keywords: ["split"], enabled: hasRange, run: () => controller.unmergeCells() },
821
+ { ...base, id: `${prefix}transposeRange`, label: "Transpose Range", keywords: ["rotate", "swap rows columns"], enabled: hasRange, run: () => controller.transposeRange() }
822
+ ];
823
+ }
824
+
825
+
826
+
827
+
828
+
829
+
830
+
831
+
832
+
833
+
834
+
835
+
836
+
837
+
838
+
839
+
840
+
841
+
842
+
843
+
844
+
845
+
846
+
847
+
848
+
849
+
850
+
851
+
852
+
853
+
854
+
855
+
856
+
857
+
858
+
859
+ exports.CommandRegistry = CommandRegistry; exports.CommandRegistryError = CommandRegistryError; exports.DEFAULT_HISTORY_SHORTCUTS = DEFAULT_HISTORY_SHORTCUTS; exports.DEFAULT_RECENT_LIMIT = DEFAULT_RECENT_LIMIT; exports.PLATFORMS = _chunk26BVFKHUcjs.PLATFORMS; exports.ShortcutMap = _chunk26BVFKHUcjs.ShortcutMap; exports.chordToString = _chunk26BVFKHUcjs.chordToString; exports.codeFromKey = _chunk26BVFKHUcjs.codeFromKey; exports.codeToKeyText = _chunk26BVFKHUcjs.codeToKeyText; exports.createArrangeCommands = createArrangeCommands; exports.createCommandPaletteController = createCommandPaletteController; exports.createCommandRegistry = createCommandRegistry; exports.createCommandToolProvider = createCommandToolProvider; exports.createHistoryCommands = createHistoryCommands; exports.createSpreadsheetCommands = createSpreadsheetCommands; exports.defineCommand = defineCommand; exports.detectPlatform = _chunk26BVFKHUcjs.detectPlatform; exports.effectiveChord = _chunk26BVFKHUcjs.effectiveChord; exports.effectiveChordKey = _chunk26BVFKHUcjs.effectiveChordKey; exports.eventCode = _chunk26BVFKHUcjs.eventCode; exports.exactBonus = exactBonus; exports.formatShortcut = _chunk26BVFKHUcjs.formatShortcut; exports.fuzzyMatch = fuzzyMatch; exports.fuzzyScore = fuzzyScore; exports.isEditableEventTarget = _chunk26BVFKHUcjs.isEditableEventTarget; exports.keyToCode = _chunk26BVFKHUcjs.keyToCode; exports.matchHistoryShortcut = matchHistoryShortcut; exports.matchPaletteHotkey = matchPaletteHotkey; exports.normalizeChord = _chunk26BVFKHUcjs.normalizeChord; exports.parseChord = _chunk26BVFKHUcjs.parseChord; exports.pushRecent = pushRecent; exports.rankCommands = rankCommands; exports.shortcutCode = _chunk26BVFKHUcjs.shortcutCode; exports.toShortcutBindings = _chunk26BVFKHUcjs.toShortcutBindings;
860
+ //# sourceMappingURL=index.cjs.map