@eigenpal/docx-editor-agents 0.0.28 → 0.0.30

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 (40) hide show
  1. package/dist/bridge.js +3 -1
  2. package/dist/bridge.js.map +1 -1
  3. package/dist/bridge.mjs +8 -0
  4. package/dist/bridge.mjs.map +1 -0
  5. package/dist/chunk-5D2V7VK3.js +976 -0
  6. package/dist/chunk-5D2V7VK3.js.map +1 -0
  7. package/dist/chunk-5E3CFYZ4.mjs +249 -0
  8. package/dist/chunk-5E3CFYZ4.mjs.map +1 -0
  9. package/dist/chunk-GACRQVPW.js +11680 -0
  10. package/dist/chunk-GACRQVPW.js.map +1 -0
  11. package/dist/chunk-OFUT6WUQ.mjs +969 -0
  12. package/dist/chunk-OFUT6WUQ.mjs.map +1 -0
  13. package/dist/chunk-Q2HHIVUL.js +266 -0
  14. package/dist/chunk-Q2HHIVUL.js.map +1 -0
  15. package/dist/chunk-R4MIGZEJ.mjs +11587 -0
  16. package/dist/chunk-R4MIGZEJ.mjs.map +1 -0
  17. package/dist/executor-6ZG2VUZS.mjs +3 -0
  18. package/dist/executor-6ZG2VUZS.mjs.map +1 -0
  19. package/dist/executor-ZRVQSXRT.js +16 -0
  20. package/dist/executor-ZRVQSXRT.js.map +1 -0
  21. package/dist/headless-O2RRWYCB.js +422 -0
  22. package/dist/headless-O2RRWYCB.js.map +1 -0
  23. package/dist/headless-UKRSG32U.mjs +5 -0
  24. package/dist/headless-UKRSG32U.mjs.map +1 -0
  25. package/dist/index.d.mts +2013 -0
  26. package/dist/index.d.ts +1776 -1
  27. package/dist/index.js +26 -19
  28. package/dist/index.js.map +1 -1
  29. package/dist/{index.cjs → index.mjs} +23 -26
  30. package/dist/index.mjs.map +1 -0
  31. package/dist/processTemplate-7M6KZ6GR.mjs +3 -0
  32. package/dist/processTemplate-7M6KZ6GR.mjs.map +1 -0
  33. package/dist/processTemplate-H4X2MH5R.js +54 -0
  34. package/dist/processTemplate-H4X2MH5R.js.map +1 -0
  35. package/package.json +11 -9
  36. package/dist/bridge.cjs +0 -10
  37. package/dist/bridge.cjs.map +0 -1
  38. package/dist/index.cjs.map +0 -1
  39. package/dist/index.d.cts +0 -238
  40. /package/dist/{bridge.d.cts → bridge.d.mts} +0 -0
@@ -0,0 +1,976 @@
1
+ 'use strict';
2
+
3
+ // ../core/src/core-plugins/registry.ts
4
+ var PluginRegistry = class {
5
+ constructor() {
6
+ this.plugins = /* @__PURE__ */ new Map();
7
+ this.commandHandlers = /* @__PURE__ */ new Map();
8
+ this.eventListeners = /* @__PURE__ */ new Set();
9
+ this.initialized = /* @__PURE__ */ new Set();
10
+ }
11
+ // ==========================================================================
12
+ // REGISTRATION
13
+ // ==========================================================================
14
+ /**
15
+ * Register a plugin
16
+ *
17
+ * @param plugin - The plugin to register
18
+ * @param options - Optional configuration
19
+ * @returns Registration result
20
+ */
21
+ register(plugin, options) {
22
+ const warnings = [];
23
+ if (!plugin.id) {
24
+ return { success: false, error: "Plugin must have an id" };
25
+ }
26
+ if (this.plugins.has(plugin.id)) {
27
+ return { success: false, error: `Plugin '${plugin.id}' is already registered` };
28
+ }
29
+ if (plugin.dependencies) {
30
+ for (const depId of plugin.dependencies) {
31
+ if (!this.plugins.has(depId)) {
32
+ return {
33
+ success: false,
34
+ error: `Plugin '${plugin.id}' requires '${depId}' which is not registered`
35
+ };
36
+ }
37
+ }
38
+ }
39
+ if (plugin.commandHandlers) {
40
+ for (const [commandType, handler] of Object.entries(plugin.commandHandlers)) {
41
+ if (this.commandHandlers.has(commandType)) {
42
+ const existing = this.commandHandlers.get(commandType);
43
+ warnings.push(
44
+ `Command '${commandType}' from '${plugin.id}' overrides handler from '${existing.pluginId}'`
45
+ );
46
+ }
47
+ this.commandHandlers.set(commandType, { pluginId: plugin.id, handler });
48
+ }
49
+ }
50
+ this.plugins.set(plugin.id, plugin);
51
+ if (plugin.initialize && !this.initialized.has(plugin.id)) {
52
+ try {
53
+ const result = plugin.initialize();
54
+ if (result instanceof Promise) {
55
+ result.then(() => {
56
+ this.initialized.add(plugin.id);
57
+ }).catch((err) => {
58
+ this.emit({ type: "error", pluginId: plugin.id, error: err });
59
+ });
60
+ } else {
61
+ this.initialized.add(plugin.id);
62
+ }
63
+ } catch (err) {
64
+ this.emit({ type: "error", pluginId: plugin.id, error: err });
65
+ }
66
+ }
67
+ if (options?.debug) {
68
+ console.log(`[PluginRegistry] Registered plugin: ${plugin.id}`);
69
+ }
70
+ this.emit({ type: "registered", plugin });
71
+ return {
72
+ success: true,
73
+ plugin,
74
+ warnings: warnings.length > 0 ? warnings : void 0
75
+ };
76
+ }
77
+ /**
78
+ * Unregister a plugin
79
+ *
80
+ * @param pluginId - ID of the plugin to unregister
81
+ * @returns Whether unregistration succeeded
82
+ */
83
+ unregister(pluginId) {
84
+ const plugin = this.plugins.get(pluginId);
85
+ if (!plugin) {
86
+ return false;
87
+ }
88
+ for (const [id, p] of this.plugins) {
89
+ if (p.dependencies?.includes(pluginId)) {
90
+ console.warn(`Cannot unregister '${pluginId}': '${id}' depends on it`);
91
+ return false;
92
+ }
93
+ }
94
+ for (const [commandType, { pluginId: pid }] of this.commandHandlers) {
95
+ if (pid === pluginId) {
96
+ this.commandHandlers.delete(commandType);
97
+ }
98
+ }
99
+ if (plugin.destroy) {
100
+ try {
101
+ const result = plugin.destroy();
102
+ if (result instanceof Promise) {
103
+ result.catch((err) => {
104
+ this.emit({ type: "error", pluginId, error: err });
105
+ });
106
+ }
107
+ } catch (err) {
108
+ this.emit({ type: "error", pluginId, error: err });
109
+ }
110
+ }
111
+ this.plugins.delete(pluginId);
112
+ this.initialized.delete(pluginId);
113
+ this.emit({ type: "unregistered", pluginId });
114
+ return true;
115
+ }
116
+ // ==========================================================================
117
+ // QUERIES
118
+ // ==========================================================================
119
+ /**
120
+ * Get a registered plugin by ID
121
+ *
122
+ * @param id - Plugin ID
123
+ * @returns The plugin or undefined
124
+ */
125
+ get(id) {
126
+ return this.plugins.get(id);
127
+ }
128
+ /**
129
+ * Get all registered plugins
130
+ *
131
+ * @returns Array of all plugins
132
+ */
133
+ getAll() {
134
+ return Array.from(this.plugins.values());
135
+ }
136
+ /**
137
+ * Check if a plugin is registered
138
+ *
139
+ * @param id - Plugin ID
140
+ * @returns Whether the plugin is registered
141
+ */
142
+ has(id) {
143
+ return this.plugins.has(id);
144
+ }
145
+ /**
146
+ * Get number of registered plugins
147
+ */
148
+ get size() {
149
+ return this.plugins.size;
150
+ }
151
+ // ==========================================================================
152
+ // COMMAND HANDLERS
153
+ // ==========================================================================
154
+ /**
155
+ * Get a command handler for a command type
156
+ *
157
+ * @param commandType - The command type
158
+ * @returns The handler or undefined
159
+ */
160
+ getCommandHandler(commandType) {
161
+ const entry = this.commandHandlers.get(commandType);
162
+ return entry?.handler;
163
+ }
164
+ /**
165
+ * Get all registered command types
166
+ *
167
+ * @returns Array of command type strings
168
+ */
169
+ getCommandTypes() {
170
+ return Array.from(this.commandHandlers.keys());
171
+ }
172
+ /**
173
+ * Check if a command type has a handler
174
+ *
175
+ * @param commandType - The command type
176
+ * @returns Whether a handler exists
177
+ */
178
+ hasCommandHandler(commandType) {
179
+ return this.commandHandlers.has(commandType);
180
+ }
181
+ // ==========================================================================
182
+ // MCP TOOLS
183
+ // ==========================================================================
184
+ /**
185
+ * Get all MCP tools from all registered plugins
186
+ *
187
+ * @returns Array of MCP tool definitions
188
+ */
189
+ getMcpTools() {
190
+ const tools = [];
191
+ for (const plugin of this.plugins.values()) {
192
+ if (plugin.mcpTools) {
193
+ tools.push(...plugin.mcpTools);
194
+ }
195
+ }
196
+ return tools;
197
+ }
198
+ /**
199
+ * Get MCP tools from a specific plugin
200
+ *
201
+ * @param pluginId - Plugin ID
202
+ * @returns Array of MCP tool definitions
203
+ */
204
+ getMcpToolsForPlugin(pluginId) {
205
+ const plugin = this.plugins.get(pluginId);
206
+ return plugin?.mcpTools || [];
207
+ }
208
+ /**
209
+ * Get an MCP tool by name
210
+ *
211
+ * @param toolName - Tool name
212
+ * @returns The tool definition or undefined
213
+ */
214
+ getMcpTool(toolName) {
215
+ for (const plugin of this.plugins.values()) {
216
+ if (plugin.mcpTools) {
217
+ const tool = plugin.mcpTools.find((t) => t.name === toolName);
218
+ if (tool) return tool;
219
+ }
220
+ }
221
+ return void 0;
222
+ }
223
+ // ==========================================================================
224
+ // EVENTS
225
+ // ==========================================================================
226
+ /**
227
+ * Add an event listener
228
+ *
229
+ * @param listener - Event listener function
230
+ */
231
+ addEventListener(listener) {
232
+ this.eventListeners.add(listener);
233
+ }
234
+ /**
235
+ * Remove an event listener
236
+ *
237
+ * @param listener - Event listener function
238
+ */
239
+ removeEventListener(listener) {
240
+ this.eventListeners.delete(listener);
241
+ }
242
+ /**
243
+ * Emit an event to all listeners
244
+ */
245
+ emit(event) {
246
+ for (const listener of this.eventListeners) {
247
+ try {
248
+ listener(event);
249
+ } catch (err) {
250
+ console.error("[PluginRegistry] Event listener error:", err);
251
+ }
252
+ }
253
+ }
254
+ // ==========================================================================
255
+ // UTILITIES
256
+ // ==========================================================================
257
+ /**
258
+ * Clear all registered plugins
259
+ *
260
+ * Useful for testing or resetting state.
261
+ */
262
+ clear() {
263
+ for (const plugin of this.plugins.values()) {
264
+ if (plugin.destroy) {
265
+ try {
266
+ plugin.destroy();
267
+ } catch {
268
+ }
269
+ }
270
+ }
271
+ this.plugins.clear();
272
+ this.commandHandlers.clear();
273
+ this.initialized.clear();
274
+ }
275
+ /**
276
+ * Get registry state for debugging
277
+ */
278
+ getDebugInfo() {
279
+ return {
280
+ plugins: Array.from(this.plugins.keys()),
281
+ commandTypes: Array.from(this.commandHandlers.keys()),
282
+ mcpTools: this.getMcpTools().map((t) => t.name),
283
+ initialized: Array.from(this.initialized)
284
+ };
285
+ }
286
+ };
287
+ var pluginRegistry = new PluginRegistry();
288
+ function registerPlugins(plugins, options) {
289
+ return plugins.map((plugin) => pluginRegistry.register(plugin, options));
290
+ }
291
+ function createPluginRegistrar(options) {
292
+ return (plugin) => pluginRegistry.register(plugin, options);
293
+ }
294
+
295
+ // ../core/src/agent/executor.ts
296
+ function executeCommand(doc, command) {
297
+ const pluginHandler = pluginRegistry.getCommandHandler(command.type);
298
+ if (pluginHandler) {
299
+ return pluginHandler(doc, command);
300
+ }
301
+ switch (command.type) {
302
+ case "insertText":
303
+ return executeInsertText(doc, command);
304
+ case "replaceText":
305
+ return executeReplaceText(doc, command);
306
+ case "deleteText":
307
+ return executeDeleteText(doc, command);
308
+ case "formatText":
309
+ return executeFormatText(doc, command);
310
+ case "formatParagraph":
311
+ return executeFormatParagraph(doc, command);
312
+ case "applyStyle":
313
+ return executeApplyStyle(doc, command);
314
+ case "insertTable":
315
+ return executeInsertTable(doc, command);
316
+ case "insertImage":
317
+ return executeInsertImage(doc, command);
318
+ case "insertHyperlink":
319
+ return executeInsertHyperlink(doc, command);
320
+ case "removeHyperlink":
321
+ return executeRemoveHyperlink(doc, command);
322
+ case "insertParagraphBreak":
323
+ return executeInsertParagraphBreak(doc, command);
324
+ case "mergeParagraphs":
325
+ return executeMergeParagraphs(doc, command);
326
+ case "splitParagraph":
327
+ return executeSplitParagraph(doc, command);
328
+ case "setVariable":
329
+ return executeSetVariable(doc, command);
330
+ case "applyVariables":
331
+ return executeApplyVariables(doc, command);
332
+ default:
333
+ const _exhaustive = command;
334
+ throw new Error(`Unknown command type: ${_exhaustive.type}`);
335
+ }
336
+ }
337
+ function executeCommands(doc, commands) {
338
+ return commands.reduce((currentDoc, command) => executeCommand(currentDoc, command), doc);
339
+ }
340
+ function cloneDocument(doc) {
341
+ return JSON.parse(JSON.stringify(doc));
342
+ }
343
+ function getBlockIndexForParagraph(body, paragraphIndex) {
344
+ let currentParagraphIndex = 0;
345
+ for (let i = 0; i < body.content.length; i++) {
346
+ if (body.content[i].type === "paragraph") {
347
+ if (currentParagraphIndex === paragraphIndex) {
348
+ return i;
349
+ }
350
+ currentParagraphIndex++;
351
+ }
352
+ }
353
+ return -1;
354
+ }
355
+ function getParagraphText(paragraph) {
356
+ let text = "";
357
+ for (const item of paragraph.content) {
358
+ if (item.type === "run") {
359
+ for (const content of item.content) {
360
+ if (content.type === "text") {
361
+ text += content.text;
362
+ }
363
+ }
364
+ } else if (item.type === "hyperlink") {
365
+ for (const child of item.children) {
366
+ if (child.type === "run") {
367
+ for (const content of child.content) {
368
+ if (content.type === "text") {
369
+ text += content.text;
370
+ }
371
+ }
372
+ }
373
+ }
374
+ }
375
+ }
376
+ return text;
377
+ }
378
+ function createTextRun(text, formatting) {
379
+ return {
380
+ type: "run",
381
+ formatting,
382
+ content: [
383
+ {
384
+ type: "text",
385
+ text
386
+ }
387
+ ]
388
+ };
389
+ }
390
+ function insertTextAtOffset(paragraph, offset, text, formatting) {
391
+ const newContent = [];
392
+ let currentOffset = 0;
393
+ let inserted = false;
394
+ for (const item of paragraph.content) {
395
+ if (item.type === "run") {
396
+ const runText = item.content.filter((c) => c.type === "text").map((c) => c.text).join("");
397
+ const runStart = currentOffset;
398
+ const runEnd = currentOffset + runText.length;
399
+ if (!inserted && offset >= runStart && offset <= runEnd) {
400
+ const insertPos = offset - runStart;
401
+ if (insertPos > 0) {
402
+ newContent.push({
403
+ ...item,
404
+ content: [{ type: "text", text: runText.slice(0, insertPos) }]
405
+ });
406
+ }
407
+ newContent.push(createTextRun(text, formatting || item.formatting));
408
+ if (insertPos < runText.length) {
409
+ newContent.push({
410
+ ...item,
411
+ content: [{ type: "text", text: runText.slice(insertPos) }]
412
+ });
413
+ }
414
+ inserted = true;
415
+ } else {
416
+ newContent.push(item);
417
+ }
418
+ currentOffset = runEnd;
419
+ } else {
420
+ newContent.push(item);
421
+ }
422
+ }
423
+ if (!inserted) {
424
+ newContent.push(createTextRun(text, formatting));
425
+ }
426
+ return newContent;
427
+ }
428
+ function deleteTextInParagraph(paragraph, startOffset, endOffset) {
429
+ const newContent = [];
430
+ let currentOffset = 0;
431
+ for (const item of paragraph.content) {
432
+ if (item.type === "run") {
433
+ const runText = item.content.filter((c) => c.type === "text").map((c) => c.text).join("");
434
+ const runStart = currentOffset;
435
+ const runEnd = currentOffset + runText.length;
436
+ if (runEnd <= startOffset || runStart >= endOffset) {
437
+ newContent.push(item);
438
+ } else {
439
+ let newText = "";
440
+ if (runStart < startOffset) {
441
+ newText += runText.slice(0, startOffset - runStart);
442
+ }
443
+ if (runEnd > endOffset) {
444
+ newText += runText.slice(endOffset - runStart);
445
+ }
446
+ if (newText.length > 0) {
447
+ newContent.push({
448
+ ...item,
449
+ content: [{ type: "text", text: newText }]
450
+ });
451
+ }
452
+ }
453
+ currentOffset = runEnd;
454
+ } else {
455
+ newContent.push(item);
456
+ }
457
+ }
458
+ return newContent;
459
+ }
460
+ function applyFormattingInParagraph(paragraph, startOffset, endOffset, formatting) {
461
+ const newContent = [];
462
+ let currentOffset = 0;
463
+ for (const item of paragraph.content) {
464
+ if (item.type === "run") {
465
+ const runText = item.content.filter((c) => c.type === "text").map((c) => c.text).join("");
466
+ const runStart = currentOffset;
467
+ const runEnd = currentOffset + runText.length;
468
+ if (runEnd <= startOffset || runStart >= endOffset) {
469
+ newContent.push(item);
470
+ } else if (runStart >= startOffset && runEnd <= endOffset) {
471
+ newContent.push({
472
+ ...item,
473
+ formatting: { ...item.formatting, ...formatting }
474
+ });
475
+ } else {
476
+ const overlapStart = Math.max(startOffset, runStart);
477
+ const overlapEnd = Math.min(endOffset, runEnd);
478
+ if (runStart < overlapStart) {
479
+ newContent.push({
480
+ ...item,
481
+ content: [{ type: "text", text: runText.slice(0, overlapStart - runStart) }]
482
+ });
483
+ }
484
+ newContent.push({
485
+ ...item,
486
+ formatting: { ...item.formatting, ...formatting },
487
+ content: [
488
+ {
489
+ type: "text",
490
+ text: runText.slice(overlapStart - runStart, overlapEnd - runStart)
491
+ }
492
+ ]
493
+ });
494
+ if (runEnd > overlapEnd) {
495
+ newContent.push({
496
+ ...item,
497
+ content: [{ type: "text", text: runText.slice(overlapEnd - runStart) }]
498
+ });
499
+ }
500
+ }
501
+ currentOffset = runEnd;
502
+ } else {
503
+ newContent.push(item);
504
+ }
505
+ }
506
+ return newContent;
507
+ }
508
+ function executeInsertText(doc, command) {
509
+ const newDoc = cloneDocument(doc);
510
+ const body = newDoc.package.document;
511
+ const blockIndex = getBlockIndexForParagraph(body, command.position.paragraphIndex);
512
+ if (blockIndex === -1) {
513
+ throw new Error(`Paragraph index ${command.position.paragraphIndex} not found`);
514
+ }
515
+ const paragraph = body.content[blockIndex];
516
+ paragraph.content = insertTextAtOffset(
517
+ paragraph,
518
+ command.position.offset,
519
+ command.text,
520
+ command.formatting
521
+ );
522
+ return newDoc;
523
+ }
524
+ function executeReplaceText(doc, command) {
525
+ const newDoc = cloneDocument(doc);
526
+ const body = newDoc.package.document;
527
+ const { start, end } = command.range;
528
+ if (start.paragraphIndex === end.paragraphIndex) {
529
+ const blockIndex = getBlockIndexForParagraph(body, start.paragraphIndex);
530
+ if (blockIndex === -1) {
531
+ throw new Error(`Paragraph index ${start.paragraphIndex} not found`);
532
+ }
533
+ const paragraph = body.content[blockIndex];
534
+ paragraph.content = deleteTextInParagraph(paragraph, start.offset, end.offset);
535
+ paragraph.content = insertTextAtOffset(
536
+ paragraph,
537
+ start.offset,
538
+ command.text,
539
+ command.formatting
540
+ );
541
+ } else {
542
+ const startBlockIndex = getBlockIndexForParagraph(body, start.paragraphIndex);
543
+ const startParagraph = body.content[startBlockIndex];
544
+ const startText = getParagraphText(startParagraph);
545
+ startParagraph.content = deleteTextInParagraph(startParagraph, start.offset, startText.length);
546
+ startParagraph.content = insertTextAtOffset(
547
+ startParagraph,
548
+ start.offset,
549
+ command.text,
550
+ command.formatting
551
+ );
552
+ const paragraphsToRemove = [];
553
+ for (let i = start.paragraphIndex + 1; i <= end.paragraphIndex; i++) {
554
+ paragraphsToRemove.push(getBlockIndexForParagraph(body, i));
555
+ }
556
+ for (let i = paragraphsToRemove.length - 1; i >= 0; i--) {
557
+ if (paragraphsToRemove[i] !== -1) {
558
+ body.content.splice(paragraphsToRemove[i], 1);
559
+ }
560
+ }
561
+ }
562
+ return newDoc;
563
+ }
564
+ function executeDeleteText(doc, command) {
565
+ const newDoc = cloneDocument(doc);
566
+ const body = newDoc.package.document;
567
+ const { start, end } = command.range;
568
+ if (start.paragraphIndex === end.paragraphIndex) {
569
+ const blockIndex = getBlockIndexForParagraph(body, start.paragraphIndex);
570
+ if (blockIndex === -1) {
571
+ throw new Error(`Paragraph index ${start.paragraphIndex} not found`);
572
+ }
573
+ const paragraph = body.content[blockIndex];
574
+ paragraph.content = deleteTextInParagraph(paragraph, start.offset, end.offset);
575
+ } else {
576
+ const startBlockIndex = getBlockIndexForParagraph(body, start.paragraphIndex);
577
+ const startParagraph = body.content[startBlockIndex];
578
+ const startText = getParagraphText(startParagraph);
579
+ startParagraph.content = deleteTextInParagraph(startParagraph, start.offset, startText.length);
580
+ const endBlockIndex = getBlockIndexForParagraph(body, end.paragraphIndex);
581
+ const endParagraph = body.content[endBlockIndex];
582
+ endParagraph.content = deleteTextInParagraph(endParagraph, 0, end.offset);
583
+ startParagraph.content.push(...endParagraph.content);
584
+ const indicesToRemove = [];
585
+ for (let i = start.paragraphIndex + 1; i <= end.paragraphIndex; i++) {
586
+ indicesToRemove.push(getBlockIndexForParagraph(body, i));
587
+ }
588
+ for (let i = indicesToRemove.length - 1; i >= 0; i--) {
589
+ if (indicesToRemove[i] !== -1) {
590
+ body.content.splice(indicesToRemove[i], 1);
591
+ }
592
+ }
593
+ }
594
+ return newDoc;
595
+ }
596
+ function executeFormatText(doc, command) {
597
+ const newDoc = cloneDocument(doc);
598
+ const body = newDoc.package.document;
599
+ const { start, end } = command.range;
600
+ if (start.paragraphIndex === end.paragraphIndex) {
601
+ const blockIndex = getBlockIndexForParagraph(body, start.paragraphIndex);
602
+ if (blockIndex === -1) {
603
+ throw new Error(`Paragraph index ${start.paragraphIndex} not found`);
604
+ }
605
+ const paragraph = body.content[blockIndex];
606
+ paragraph.content = applyFormattingInParagraph(
607
+ paragraph,
608
+ start.offset,
609
+ end.offset,
610
+ command.formatting
611
+ );
612
+ } else {
613
+ for (let i = start.paragraphIndex; i <= end.paragraphIndex; i++) {
614
+ const blockIndex = getBlockIndexForParagraph(body, i);
615
+ if (blockIndex === -1) continue;
616
+ const paragraph = body.content[blockIndex];
617
+ const paragraphText = getParagraphText(paragraph);
618
+ let startOffset = 0;
619
+ let endOffset = paragraphText.length;
620
+ if (i === start.paragraphIndex) {
621
+ startOffset = start.offset;
622
+ }
623
+ if (i === end.paragraphIndex) {
624
+ endOffset = end.offset;
625
+ }
626
+ paragraph.content = applyFormattingInParagraph(
627
+ paragraph,
628
+ startOffset,
629
+ endOffset,
630
+ command.formatting
631
+ );
632
+ }
633
+ }
634
+ return newDoc;
635
+ }
636
+ function executeFormatParagraph(doc, command) {
637
+ const newDoc = cloneDocument(doc);
638
+ const body = newDoc.package.document;
639
+ const blockIndex = getBlockIndexForParagraph(body, command.paragraphIndex);
640
+ if (blockIndex === -1) {
641
+ throw new Error(`Paragraph index ${command.paragraphIndex} not found`);
642
+ }
643
+ const paragraph = body.content[blockIndex];
644
+ paragraph.formatting = { ...paragraph.formatting, ...command.formatting };
645
+ if ("numPr" in command.formatting) {
646
+ const numPr = command.formatting.numPr;
647
+ if (numPr && numPr.numId !== void 0 && numPr.numId !== 0) {
648
+ const ilvl = numPr.ilvl ?? 0;
649
+ const isBullet = numPr.numId === 1;
650
+ let marker = isBullet ? "\u2022" : `${1}.`;
651
+ if (newDoc.package.numbering) {
652
+ const num = newDoc.package.numbering.nums.find((n) => n.numId === numPr.numId);
653
+ if (num) {
654
+ const abstractNum = newDoc.package.numbering.abstractNums.find(
655
+ (a) => a.abstractNumId === num.abstractNumId
656
+ );
657
+ if (abstractNum) {
658
+ const level = abstractNum.levels.find((l) => l.ilvl === ilvl);
659
+ if (level) {
660
+ marker = level.lvlText || marker;
661
+ }
662
+ }
663
+ }
664
+ }
665
+ paragraph.listRendering = {
666
+ level: ilvl,
667
+ numId: numPr.numId,
668
+ marker,
669
+ isBullet
670
+ };
671
+ } else {
672
+ delete paragraph.listRendering;
673
+ }
674
+ }
675
+ return newDoc;
676
+ }
677
+ function executeApplyStyle(doc, command) {
678
+ const newDoc = cloneDocument(doc);
679
+ const body = newDoc.package.document;
680
+ const blockIndex = getBlockIndexForParagraph(body, command.paragraphIndex);
681
+ if (blockIndex === -1) {
682
+ throw new Error(`Paragraph index ${command.paragraphIndex} not found`);
683
+ }
684
+ const paragraph = body.content[blockIndex];
685
+ paragraph.formatting = {
686
+ ...paragraph.formatting,
687
+ styleId: command.styleId
688
+ };
689
+ return newDoc;
690
+ }
691
+ function executeInsertTable(doc, command) {
692
+ const newDoc = cloneDocument(doc);
693
+ const body = newDoc.package.document;
694
+ const rows = [];
695
+ for (let r = 0; r < command.rows; r++) {
696
+ const cells = [];
697
+ for (let c = 0; c < command.columns; c++) {
698
+ const cellText = command.data?.[r]?.[c] || "";
699
+ cells.push({
700
+ type: "tableCell",
701
+ content: [
702
+ {
703
+ type: "paragraph",
704
+ content: cellText ? [createTextRun(cellText)] : []
705
+ }
706
+ ]
707
+ });
708
+ }
709
+ rows.push({
710
+ type: "tableRow",
711
+ formatting: r === 0 && command.hasHeader ? { header: true } : void 0,
712
+ cells
713
+ });
714
+ }
715
+ const table = {
716
+ type: "table",
717
+ rows
718
+ };
719
+ const blockIndex = getBlockIndexForParagraph(body, command.position.paragraphIndex);
720
+ if (blockIndex === -1) {
721
+ body.content.push(table);
722
+ } else {
723
+ body.content.splice(blockIndex + 1, 0, table);
724
+ }
725
+ return newDoc;
726
+ }
727
+ function executeInsertImage(doc, command) {
728
+ const newDoc = cloneDocument(doc);
729
+ const body = newDoc.package.document;
730
+ const blockIndex = getBlockIndexForParagraph(body, command.position.paragraphIndex);
731
+ if (blockIndex === -1) {
732
+ throw new Error(`Paragraph index ${command.position.paragraphIndex} not found`);
733
+ }
734
+ const paragraph = body.content[blockIndex];
735
+ const image = {
736
+ type: "image",
737
+ rId: `rId_img_${Date.now()}`,
738
+ src: command.src,
739
+ alt: command.alt,
740
+ size: {
741
+ width: (command.width || 100) * 914400,
742
+ // Convert pixels to EMU
743
+ height: (command.height || 100) * 914400
744
+ },
745
+ wrap: { type: "inline" }
746
+ };
747
+ const imageRun = {
748
+ type: "run",
749
+ content: [
750
+ {
751
+ type: "drawing",
752
+ image
753
+ }
754
+ ]
755
+ };
756
+ const newContent = insertTextAtOffset(paragraph, command.position.offset, "", void 0);
757
+ let inserted = false;
758
+ let currentOffset = 0;
759
+ for (let i = 0; i < newContent.length; i++) {
760
+ const item = newContent[i];
761
+ if (item.type === "run") {
762
+ const runText = item.content.filter((c) => c.type === "text").map((c) => c.text).join("");
763
+ currentOffset += runText.length;
764
+ if (!inserted && currentOffset >= command.position.offset) {
765
+ newContent.splice(i + 1, 0, imageRun);
766
+ inserted = true;
767
+ break;
768
+ }
769
+ }
770
+ }
771
+ if (!inserted) {
772
+ newContent.push(imageRun);
773
+ }
774
+ paragraph.content = newContent;
775
+ return newDoc;
776
+ }
777
+ function executeInsertHyperlink(doc, command) {
778
+ const newDoc = cloneDocument(doc);
779
+ const body = newDoc.package.document;
780
+ const { start, end } = command.range;
781
+ if (start.paragraphIndex !== end.paragraphIndex) {
782
+ throw new Error("Hyperlinks cannot span multiple paragraphs");
783
+ }
784
+ const blockIndex = getBlockIndexForParagraph(body, start.paragraphIndex);
785
+ if (blockIndex === -1) {
786
+ throw new Error(`Paragraph index ${start.paragraphIndex} not found`);
787
+ }
788
+ const paragraph = body.content[blockIndex];
789
+ const paragraphText = getParagraphText(paragraph);
790
+ const linkText = command.displayText || paragraphText.slice(start.offset, end.offset);
791
+ paragraph.content = deleteTextInParagraph(paragraph, start.offset, end.offset);
792
+ const hyperlink = {
793
+ type: "hyperlink",
794
+ href: command.url,
795
+ tooltip: command.tooltip,
796
+ children: [createTextRun(linkText)]
797
+ };
798
+ let inserted = false;
799
+ let currentOffset = 0;
800
+ const newContent = [];
801
+ for (const item of paragraph.content) {
802
+ if (item.type === "run") {
803
+ const runText = item.content.filter((c) => c.type === "text").map((c) => c.text).join("");
804
+ const runEnd = currentOffset + runText.length;
805
+ if (!inserted && currentOffset <= start.offset && start.offset <= runEnd) {
806
+ const insertPos = start.offset - currentOffset;
807
+ if (insertPos > 0) {
808
+ newContent.push({
809
+ ...item,
810
+ content: [{ type: "text", text: runText.slice(0, insertPos) }]
811
+ });
812
+ }
813
+ newContent.push(hyperlink);
814
+ if (insertPos < runText.length) {
815
+ newContent.push({
816
+ ...item,
817
+ content: [{ type: "text", text: runText.slice(insertPos) }]
818
+ });
819
+ }
820
+ inserted = true;
821
+ } else {
822
+ newContent.push(item);
823
+ }
824
+ currentOffset = runEnd;
825
+ } else {
826
+ newContent.push(item);
827
+ }
828
+ }
829
+ if (!inserted) {
830
+ newContent.push(hyperlink);
831
+ }
832
+ paragraph.content = newContent;
833
+ return newDoc;
834
+ }
835
+ function executeRemoveHyperlink(doc, command) {
836
+ const newDoc = cloneDocument(doc);
837
+ const body = newDoc.package.document;
838
+ const { start } = command.range;
839
+ const blockIndex = getBlockIndexForParagraph(body, start.paragraphIndex);
840
+ if (blockIndex === -1) {
841
+ throw new Error(`Paragraph index ${start.paragraphIndex} not found`);
842
+ }
843
+ const paragraph = body.content[blockIndex];
844
+ const newContent = [];
845
+ for (const item of paragraph.content) {
846
+ if (item.type === "hyperlink") {
847
+ for (const child of item.children) {
848
+ if (child.type === "run") {
849
+ newContent.push(child);
850
+ }
851
+ }
852
+ } else {
853
+ newContent.push(item);
854
+ }
855
+ }
856
+ paragraph.content = newContent;
857
+ return newDoc;
858
+ }
859
+ function executeInsertParagraphBreak(doc, command) {
860
+ const newDoc = cloneDocument(doc);
861
+ const body = newDoc.package.document;
862
+ const blockIndex = getBlockIndexForParagraph(body, command.position.paragraphIndex);
863
+ if (blockIndex === -1) {
864
+ throw new Error(`Paragraph index ${command.position.paragraphIndex} not found`);
865
+ }
866
+ const paragraph = body.content[blockIndex];
867
+ const paragraphText = getParagraphText(paragraph);
868
+ const beforeContent = deleteTextInParagraph(
869
+ { ...paragraph, content: [...paragraph.content] },
870
+ command.position.offset,
871
+ paragraphText.length
872
+ );
873
+ const afterContent = deleteTextInParagraph(
874
+ { ...paragraph, content: [...paragraph.content] },
875
+ 0,
876
+ command.position.offset
877
+ );
878
+ paragraph.content = beforeContent;
879
+ const newParagraph = {
880
+ type: "paragraph",
881
+ formatting: paragraph.formatting,
882
+ content: afterContent
883
+ };
884
+ body.content.splice(blockIndex + 1, 0, newParagraph);
885
+ return newDoc;
886
+ }
887
+ function executeMergeParagraphs(doc, command) {
888
+ const newDoc = cloneDocument(doc);
889
+ const body = newDoc.package.document;
890
+ const startBlockIndex = getBlockIndexForParagraph(body, command.paragraphIndex);
891
+ if (startBlockIndex === -1) {
892
+ throw new Error(`Paragraph index ${command.paragraphIndex} not found`);
893
+ }
894
+ const baseParagraph = body.content[startBlockIndex];
895
+ const indicesToRemove = [];
896
+ for (let i = 1; i <= command.count; i++) {
897
+ const blockIndex = getBlockIndexForParagraph(body, command.paragraphIndex + i);
898
+ if (blockIndex !== -1) {
899
+ const para = body.content[blockIndex];
900
+ baseParagraph.content.push(...para.content);
901
+ indicesToRemove.push(blockIndex);
902
+ }
903
+ }
904
+ for (let i = indicesToRemove.length - 1; i >= 0; i--) {
905
+ body.content.splice(indicesToRemove[i], 1);
906
+ }
907
+ return newDoc;
908
+ }
909
+ function executeSplitParagraph(doc, command) {
910
+ return executeInsertParagraphBreak(doc, {
911
+ position: command.position
912
+ });
913
+ }
914
+ function executeSetVariable(doc, command) {
915
+ const newDoc = cloneDocument(doc);
916
+ if (!newDoc.templateVariables) {
917
+ newDoc.templateVariables = [];
918
+ }
919
+ if (!newDoc.templateVariables.includes(command.name)) {
920
+ newDoc.templateVariables.push(command.name);
921
+ }
922
+ return newDoc;
923
+ }
924
+ function executeApplyVariables(doc, command) {
925
+ const newDoc = cloneDocument(doc);
926
+ const body = newDoc.package.document;
927
+ function replaceVariablesInRun(run) {
928
+ for (const content of run.content) {
929
+ if (content.type === "text") {
930
+ for (const [name, value] of Object.entries(command.values)) {
931
+ const pattern = new RegExp(`\\{${name}\\}`, "g");
932
+ content.text = content.text.replace(pattern, value);
933
+ }
934
+ }
935
+ }
936
+ }
937
+ function replaceVariablesInParagraph(paragraph) {
938
+ for (const item of paragraph.content) {
939
+ if (item.type === "run") {
940
+ replaceVariablesInRun(item);
941
+ } else if (item.type === "hyperlink") {
942
+ for (const child of item.children) {
943
+ if (child.type === "run") {
944
+ replaceVariablesInRun(child);
945
+ }
946
+ }
947
+ }
948
+ }
949
+ }
950
+ function replaceVariablesInBlock(block) {
951
+ if (block.type === "paragraph") {
952
+ replaceVariablesInParagraph(block);
953
+ } else if (block.type === "table") {
954
+ for (const row of block.rows) {
955
+ for (const cell of row.cells) {
956
+ for (const cellBlock of cell.content) {
957
+ replaceVariablesInBlock(cellBlock);
958
+ }
959
+ }
960
+ }
961
+ }
962
+ }
963
+ for (const block of body.content) {
964
+ replaceVariablesInBlock(block);
965
+ }
966
+ return newDoc;
967
+ }
968
+
969
+ exports.PluginRegistry = PluginRegistry;
970
+ exports.createPluginRegistrar = createPluginRegistrar;
971
+ exports.executeCommand = executeCommand;
972
+ exports.executeCommands = executeCommands;
973
+ exports.pluginRegistry = pluginRegistry;
974
+ exports.registerPlugins = registerPlugins;
975
+ //# sourceMappingURL=chunk-5D2V7VK3.js.map
976
+ //# sourceMappingURL=chunk-5D2V7VK3.js.map