{"version":3,"file":"rk-editor-core.cjs","sources":["../src/extensions/Link.ts","../src/extensions/FontSize.ts","../src/extensions/TextTransform.ts","../src/extensions/LineHeight.ts","../src/extensions/ParagraphSpacing.ts","../src/extensions/Indent.ts","../src/extensions/PageBreak.ts","../src/extensions/Footnote.ts","../src/extensions/PasteHandler.ts","../src/extensions/AdvancedTypography.ts","../src/extensions/ParagraphSystem.ts","../src/StyleManager.ts","../src/extensions/StylesEngine.ts","../src/extensions/PageLayout.ts","../src/extensions/Section.ts","../src/extensions/HeaderFooter.ts","../src/extensions/TableStyles.ts","../src/extensions/MultilevelList.ts","../src/extensions/Caption.ts","../src/extensions/ImageResize.ts","../src/extensions/Math.ts","../src/extensions/TableOfContents.ts","../src/extensions/Citation.ts","../src/extensions/SlashCommands.ts","../src/extensions/ImageUpload.ts","../src/extensions/FormatPainter.ts","../src/extensions/DragHandle.ts","../src/extensions/TrackChanges.ts","../src/extensions/LeaderMark.ts","../src/extensions/FindReplace.ts","../src/extensions/WordShortcuts.ts","../src/extensions/TextBox.ts","../src/extensions/Pagination.ts","../src/extensions/TitleSubtitle.ts","../src/DocumentValidator.ts","../src/CommandManager.ts","../src/ExportEngine.ts","../src/ImportEngine.ts","../src/PrintEngine.ts","../src/extensions/ImageResizeHandle.ts","../src/index.ts"],"sourcesContent":["import { Mark, mergeAttributes } from '@tiptap/core';\r\n\r\nexport interface LinkOptions {\r\n    /**\r\n     * If enabled, it will be opened by a click.\r\n     */\r\n    openOnClick: boolean;\r\n    /**\r\n     * HTML attributes to add to the link element.\r\n     */\r\n    HTMLAttributes: Record<string, any>;\r\n}\r\n\r\ndeclare module '@tiptap/core' {\r\n    interface Commands<ReturnType> {\r\n        link: {\r\n            /**\r\n             * Set a link mark\r\n             */\r\n            setLink: (attributes: { href: string; target?: string | null; rel?: string | null; class?: string | null }) => ReturnType;\r\n            /**\r\n             * Toggle a link mark\r\n             */\r\n            toggleLink: (attributes: { href: string; target?: string | null; rel?: string | null; class?: string | null }) => ReturnType;\r\n            /**\r\n             * Unset a link mark\r\n             */\r\n            unsetLink: () => ReturnType;\r\n        };\r\n    }\r\n}\r\n\r\nexport const Link = Mark.create<LinkOptions>({\r\n    name: 'link',\r\n\r\n    priority: 1000,\r\n\r\n    keepOnSplit: false,\r\n\r\n    addOptions() {\r\n        return {\r\n            openOnClick: true,\r\n            HTMLAttributes: {\r\n                target: '_blank',\r\n                rel: 'noopener noreferrer nofollow',\r\n                class: null,\r\n            },\r\n        };\r\n    },\r\n\r\n    addAttributes() {\r\n        return {\r\n            href: {\r\n                default: null,\r\n            },\r\n            target: {\r\n                default: this.options.HTMLAttributes.target,\r\n            },\r\n            rel: {\r\n                default: this.options.HTMLAttributes.rel,\r\n            },\r\n            class: {\r\n                default: this.options.HTMLAttributes.class,\r\n            },\r\n        };\r\n    },\r\n\r\n    parseHTML() {\r\n        return [\r\n            {\r\n                tag: 'a[href]:not([href^=\"javascript:\"])',\r\n            },\r\n        ];\r\n    },\r\n\r\n    renderHTML({ HTMLAttributes }) {\r\n        return ['a', mergeAttributes(this.options.HTMLAttributes, HTMLAttributes), 0];\r\n    },\r\n\r\n    addCommands() {\r\n        return {\r\n            setLink: attributes => ({ chain }) => {\r\n                return chain().setMark(this.name, attributes).setMeta('preventAutolink', true).run();\r\n            },\r\n\r\n            toggleLink: attributes => ({ chain }) => {\r\n                return chain().toggleMark(this.name, attributes).setMeta('preventAutolink', true).run();\r\n            },\r\n\r\n            unsetLink: () => ({ chain }) => {\r\n                return chain().unsetMark(this.name).setMeta('preventAutolink', true).run();\r\n            },\r\n        };\r\n    },\r\n});\r\n","import { Extension } from '@tiptap/core';\r\n\r\nexport interface FontSizeOptions {\r\n    types: string[];\r\n}\r\n\r\ndeclare module '@tiptap/core' {\r\n    interface Commands<ReturnType> {\r\n        fontSize: {\r\n            /**\r\n             * Set the font size\r\n             */\r\n            setFontSize: (size: string) => ReturnType;\r\n            /**\r\n             * Unset the font size\r\n             */\r\n            unsetFontSize: () => ReturnType;\r\n        };\r\n    }\r\n}\r\n\r\nexport const FontSize = Extension.create<FontSizeOptions>({\r\n    name: 'fontSize',\r\n\r\n    addOptions() {\r\n        return {\r\n            types: ['textStyle'],\r\n        };\r\n    },\r\n\r\n    addGlobalAttributes() {\r\n        return [\r\n            {\r\n                types: this.options.types,\r\n                attributes: {\r\n                    fontSize: {\r\n                        default: null,\r\n                        parseHTML: (element) => element.style.fontSize.replace(/['\"]+/g, ''),\r\n                        renderHTML: (attributes) => {\r\n                            if (!attributes.fontSize) {\r\n                                return {};\r\n                            }\r\n\r\n                            return {\r\n                                style: `font-size: ${attributes.fontSize}`,\r\n                            };\r\n                        },\r\n                    },\r\n                },\r\n            },\r\n        ];\r\n    },\r\n\r\n    addCommands() {\r\n        return {\r\n            setFontSize: (fontSize) => ({ chain }) => {\r\n                return chain().setMark('textStyle', { fontSize }).run();\r\n            },\r\n            unsetFontSize: () => ({ chain }) => {\r\n                return chain().setMark('textStyle', { fontSize: null }).removeEmptyTextStyle().run();\r\n            },\r\n        };\r\n    },\r\n});\r\n","import { Extension } from '@tiptap/core';\r\n\r\nexport interface TextTransformOptions {\r\n    types: string[];\r\n}\r\n\r\ndeclare module '@tiptap/core' {\r\n    interface Commands<ReturnType> {\r\n        textTransform: {\r\n            /**\r\n             * Set the text transform\r\n             */\r\n            setTextTransform: (transform: string) => ReturnType;\r\n            /**\r\n             * Unset the text transform\r\n             */\r\n            unsetTextTransform: () => ReturnType;\r\n        };\r\n    }\r\n}\r\n\r\nexport const TextTransform = Extension.create<TextTransformOptions>({\r\n    name: 'textTransform',\r\n\r\n    addOptions() {\r\n        return {\r\n            types: ['textStyle'],\r\n        };\r\n    },\r\n\r\n    addGlobalAttributes() {\r\n        return [\r\n            {\r\n                types: this.options.types,\r\n                attributes: {\r\n                    textTransform: {\r\n                        default: null,\r\n                        parseHTML: (element) => element.style.textTransform,\r\n                        renderHTML: (attributes) => {\r\n                            if (!attributes.textTransform) {\r\n                                return {};\r\n                            }\r\n\r\n                            return {\r\n                                style: `text-transform: ${attributes.textTransform}`,\r\n                            };\r\n                        },\r\n                    },\r\n                    fontVariant: {\r\n                        default: null,\r\n                        parseHTML: (element) => element.style.fontVariant,\r\n                        renderHTML: (attributes) => {\r\n                            if (!attributes.fontVariant) {\r\n                                return {};\r\n                            }\r\n\r\n                            return {\r\n                                style: `font-variant: ${attributes.fontVariant}`,\r\n                            };\r\n                        },\r\n                    },\r\n                },\r\n            },\r\n        ];\r\n    },\r\n\r\n    addCommands() {\r\n        return {\r\n            setTextTransform: (textTransform: string) => ({ chain }: { chain: any }) => {\r\n                return chain()\r\n                    .focus()\r\n                    .setMark('textStyle', { textTransform })\r\n                    .run();\r\n            },\r\n            toggleSmallCaps: () => ({ chain }: { chain: any }) => {\r\n                return chain().focus().setMark('textStyle', { fontVariant: 'small-caps' }).run();\r\n            },\r\n            unsetTextTransform: () => ({ chain }: { chain: any }) => {\r\n                return chain().focus().setMark('textStyle', { textTransform: null }).removeEmptyTextStyle().run();\r\n            },\r\n        };\r\n    },\r\n});\r\n","import { Extension } from '@tiptap/core';\r\n\r\nexport interface LineHeightOptions {\r\n    types: string[];\r\n    defaultLineHeight: string;\r\n}\r\n\r\ndeclare module '@tiptap/core' {\r\n    interface Commands<ReturnType> {\r\n        lineHeight: {\r\n            setLineHeight: (height: string) => ReturnType;\r\n            unsetLineHeight: () => ReturnType;\r\n        };\r\n    }\r\n}\r\n\r\nexport const LineHeight = Extension.create<LineHeightOptions>({\r\n    name: 'lineHeight',\r\n\r\n    addOptions() {\r\n        return {\r\n            types: ['paragraph', 'heading'],\r\n            defaultLineHeight: 'normal',\r\n        };\r\n    },\r\n\r\n    addGlobalAttributes() {\r\n        return [\r\n            {\r\n                types: this.options.types,\r\n                attributes: {\r\n                    lineHeight: {\r\n                        default: this.options.defaultLineHeight,\r\n                        parseHTML: (element) => element.style.lineHeight || this.options.defaultLineHeight,\r\n                        renderHTML: (attributes) => {\r\n                            if (attributes.lineHeight === this.options.defaultLineHeight) {\r\n                                return {};\r\n                            }\r\n\r\n                            return {\r\n                                style: `line-height: ${attributes.lineHeight}`,\r\n                            };\r\n                        },\r\n                    },\r\n                },\r\n            },\r\n        ];\r\n    },\r\n\r\n    addCommands() {\r\n        return {\r\n            setLineHeight: (lineHeight) => ({ commands }) => {\r\n                return this.options.types.every((type) => commands.updateAttributes(type, { lineHeight }));\r\n            },\r\n            unsetLineHeight: () => ({ commands }) => {\r\n                return this.options.types.every((type) => commands.updateAttributes(type, { lineHeight: this.options.defaultLineHeight }));\r\n            },\r\n        };\r\n    },\r\n});\r\n","import { Extension } from '@tiptap/core';\r\n\r\nexport interface ParagraphSpacingOptions {\r\n    types: string[];\r\n}\r\n\r\ndeclare module '@tiptap/core' {\r\n    interface Commands<ReturnType> {\r\n        paragraphSpacing: {\r\n            setParagraphSpacing: (spacing: { top?: string, bottom?: string }) => ReturnType;\r\n        };\r\n    }\r\n}\r\n\r\nexport const ParagraphSpacing = Extension.create<ParagraphSpacingOptions>({\r\n    name: 'paragraphSpacing',\r\n\r\n    addOptions() {\r\n        return {\r\n            types: ['paragraph'],\r\n        };\r\n    },\r\n\r\n    addGlobalAttributes() {\r\n        return [\r\n            {\r\n                types: this.options.types,\r\n                attributes: {\r\n                    marginTop: {\r\n                        default: null,\r\n                        parseHTML: (element) => element.style.marginTop,\r\n                        renderHTML: (attributes) => {\r\n                            if (!attributes.marginTop) return {};\r\n                            return { style: `margin-top: ${attributes.marginTop}` };\r\n                        },\r\n                    },\r\n                    marginBottom: {\r\n                        default: null,\r\n                        parseHTML: (element) => element.style.marginBottom,\r\n                        renderHTML: (attributes) => {\r\n                            if (!attributes.marginBottom) return {};\r\n                            return { style: `margin-bottom: ${attributes.marginBottom}` };\r\n                        },\r\n                    },\r\n                },\r\n            },\r\n        ];\r\n    },\r\n\r\n    addCommands() {\r\n        return {\r\n            setParagraphSpacing: (spacing) => ({ commands }) => {\r\n                return this.options.types.every((type) => commands.updateAttributes(type, {\r\n                    marginTop: spacing.top,\r\n                    marginBottom: spacing.bottom\r\n                }));\r\n            },\r\n        };\r\n    },\r\n});\r\n","import { Extension } from '@tiptap/core';\r\n\r\nexport interface IndentOptions {\r\n    types: string[];\r\n    minIndent: number;\r\n    maxIndent: number;\r\n    indentSize: number; // Added indentSize\r\n}\r\n\r\ndeclare module '@tiptap/core' {\r\n    interface Commands<ReturnType> {\r\n        indent: {\r\n            indent: () => ReturnType;\r\n            outdent: () => ReturnType;\r\n        };\r\n    }\r\n}\r\n\r\nexport const Indent = Extension.create<IndentOptions>({\r\n    name: 'indent',\r\n\r\n    addOptions() {\r\n        return {\r\n            types: ['paragraph', 'heading', 'listItem'],\r\n            minIndent: 0,\r\n            maxIndent: 8,\r\n            indentSize: 1, // Default indent size\r\n        };\r\n    },\r\n\r\n    addGlobalAttributes() {\r\n        return [\r\n            {\r\n                types: this.options.types,\r\n                attributes: {\r\n                    indent: {\r\n                        default: 0,\r\n                        parseHTML: (element) => parseInt(element.style.marginLeft) / 40 || 0,\r\n                        renderHTML: (attributes) => {\r\n                            if (!attributes.indent) return {};\r\n                            return { style: `margin-left: ${attributes.indent * 40}px` };\r\n                        },\r\n                    },\r\n                },\r\n            },\r\n        ];\r\n    },\r\n\r\n    addCommands() {\r\n        return {\r\n            indent: () => ({ commands }) => {\r\n                if (this.editor.isActive('listItem')) {\r\n                    return (this.editor.chain().focus() as any).sinkListItem('listItem').run();\r\n                }\r\n                const types = this.options.types.filter(t => t !== 'listItem');\r\n                return types.every(type => {\r\n                    const currentIndent = this.editor.getAttributes(type).indent || 0;\r\n                    return commands.updateAttributes(type, {\r\n                        indent: Math.min(currentIndent + this.options.indentSize, this.options.maxIndent),\r\n                    });\r\n                });\r\n            },\r\n            outdent: () => ({ commands }) => {\r\n                if (this.editor.isActive('listItem')) {\r\n                    return (this.editor.chain().focus() as any).liftListItem('listItem').run();\r\n                }\r\n                const types = this.options.types.filter(t => t !== 'listItem');\r\n                return types.every(type => {\r\n                    const currentIndent = this.editor.getAttributes(type).indent || 0;\r\n                    return commands.updateAttributes(type, {\r\n                        indent: Math.max(this.options.minIndent, currentIndent - this.options.indentSize),\r\n                    });\r\n                });\r\n            },\r\n        };\r\n    },\r\n\r\n    addKeyboardShortcuts() {\r\n        return {\r\n            'Tab': () => {\r\n                if (this.editor.isActive('listItem')) {\r\n                    return this.editor.commands.sinkListItem('listItem');\r\n                }\r\n\r\n                // If not in a list, insert 4 non-breaking spaces\r\n                return this.editor.commands.insertContent('\\u00A0\\u00A0\\u00A0\\u00A0');\r\n            },\r\n            'Shift-Tab': () => {\r\n                if (this.editor.isActive('listItem')) {\r\n                    return this.editor.commands.liftListItem('listItem');\r\n                }\r\n                return false;\r\n            },\r\n        };\r\n    },\r\n});\r\n","import { Node, mergeAttributes } from '@tiptap/core';\r\n\r\ndeclare module '@tiptap/core' {\r\n    interface Commands<ReturnType> {\r\n        pageBreak: {\r\n            setPageBreak: () => ReturnType;\r\n        };\r\n    }\r\n}\r\n\r\nexport const PageBreak = Node.create({\r\n    name: 'pageBreak',\r\n\r\n    group: 'block',\r\n\r\n    parseHTML() {\r\n        return [\r\n            { tag: 'div[data-type=\"page-break\"]' },\r\n        ];\r\n    },\r\n\r\n    renderHTML({ HTMLAttributes }) {\r\n        return ['div', mergeAttributes(HTMLAttributes, { 'data-type': 'page-break', class: 'rk-page-break' })];\r\n    },\r\n\r\n    addCommands() {\r\n        return {\r\n            setPageBreak: () => ({ commands }: { commands: any }) => {\r\n                return (commands as any).insertContent({ type: this.name });\r\n            },\r\n        } as any;\r\n    },\r\n});\r\n","import { Node, mergeAttributes } from '@tiptap/core';\r\n\r\nexport const Footnote = Node.create({\r\n    name: 'footnote',\r\n\r\n    group: 'inline',\r\n\r\n    content: 'text*',\r\n\r\n    inline: true,\r\n\r\n    draggable: true,\r\n\r\n    parseHTML() {\r\n        return [\r\n            {\r\n                tag: 'footnote',\r\n            },\r\n        ];\r\n    },\r\n\r\n    renderHTML({ HTMLAttributes }) {\r\n        return ['footnote', mergeAttributes(HTMLAttributes), 0];\r\n    },\r\n\r\n    addCommands() {\r\n        return {\r\n            setFootnote: (content?: string) => ({ commands }: { commands: any }) => {\r\n                return commands.insertContent({\r\n                    type: this.name,\r\n                    content: content ? [{ type: 'text', text: content }] : undefined\r\n                });\r\n            },\r\n        } as any;\r\n    },\r\n});\r\n","import { Extension } from '@tiptap/core';\r\nimport { Plugin, PluginKey } from '@tiptap/pm/state';\r\n\r\nexport const PasteHandler = Extension.create({\r\n    name: 'pasteHandler',\r\n\r\n    addProseMirrorPlugins() {\r\n        return [\r\n            new Plugin({\r\n                key: new PluginKey('pasteHandler'),\r\n                props: {\r\n                    handlePaste: (view, event) => {\r\n                        const html = event.clipboardData?.getData('text/html');\r\n\r\n                        if (html && (html.includes('office:word') || html.includes('mso-') || html.includes('docs-internal-guid'))) {\r\n                            const domParser = new DOMParser();\r\n                            const doc = domParser.parseFromString(html, 'text/html');\r\n\r\n                            // Remove Word-specific tags and comments\r\n                            const walker = document.createTreeWalker(doc.body, NodeFilter.SHOW_COMMENT | NodeFilter.SHOW_ELEMENT);\r\n                            let node;\r\n                            while (node = walker.nextNode()) {\r\n                                if (node.nodeType === Node.COMMENT_NODE) {\r\n                                    node.parentNode?.removeChild(node);\r\n                                }\r\n                            }\r\n\r\n                            // Simple cleanup of inline styles that often break layouts\r\n                            doc.querySelectorAll('*').forEach(el => {\r\n                                if (el instanceof HTMLElement) {\r\n                                    el.style.fontFamily = ''; // Clear forced fonts\r\n                                    el.style.fontSize = '';   // Clear forced sizes\r\n                                }\r\n                            });\r\n                        }\r\n\r\n                        return false; // Let Tiptap/ProseMirror handle the rest\r\n                    },\r\n                },\r\n            }),\r\n        ];\r\n    },\r\n});\r\n","import { Extension } from '@tiptap/core';\r\n\r\nexport interface AdvancedTypographyOptions {\r\n    types: string[];\r\n}\r\n\r\ndeclare module '@tiptap/core' {\r\n    interface Commands<ReturnType> {\r\n        advancedTypography: {\r\n            /**\r\n             * Set the letter spacing\r\n             */\r\n            setLetterSpacing: (spacing: string) => ReturnType;\r\n            /**\r\n             * Unset the letter spacing\r\n             */\r\n            unsetLetterSpacing: () => ReturnType;\r\n            /**\r\n             * Set the word spacing\r\n             */\r\n            setWordSpacing: (spacing: string) => ReturnType;\r\n            /**\r\n             * Unset the word spacing\r\n             */\r\n            unsetWordSpacing: () => ReturnType;\r\n        };\r\n    }\r\n}\r\n\r\nexport const AdvancedTypography = Extension.create<AdvancedTypographyOptions>({\r\n    name: 'advancedTypography',\r\n\r\n    addOptions() {\r\n        return {\r\n            types: ['textStyle'],\r\n        };\r\n    },\r\n\r\n    addGlobalAttributes() {\r\n        return [\r\n            {\r\n                types: this.options.types,\r\n                attributes: {\r\n                    letterSpacing: {\r\n                        default: null,\r\n                        parseHTML: element => element.style.letterSpacing,\r\n                        renderHTML: attributes => {\r\n                            if (!attributes.letterSpacing) {\r\n                                return {};\r\n                            }\r\n\r\n                            return {\r\n                                style: `letter-spacing: ${attributes.letterSpacing}`,\r\n                            };\r\n                        },\r\n                    },\r\n                    wordSpacing: {\r\n                        default: null,\r\n                        parseHTML: element => element.style.wordSpacing,\r\n                        renderHTML: attributes => {\r\n                            if (!attributes.wordSpacing) {\r\n                                return {};\r\n                            }\r\n\r\n                            return {\r\n                                style: `word-spacing: ${attributes.wordSpacing}`,\r\n                            };\r\n                        },\r\n                    },\r\n                },\r\n            },\r\n        ];\r\n    },\r\n\r\n    addCommands() {\r\n        return {\r\n            setLetterSpacing: (letterSpacing) => ({ chain }) => {\r\n                return chain().setMark('textStyle', { letterSpacing }).run();\r\n            },\r\n            unsetLetterSpacing: () => ({ chain }) => {\r\n                return chain().setMark('textStyle', { letterSpacing: null }).removeEmptyTextStyle().run();\r\n            },\r\n            setWordSpacing: (wordSpacing) => ({ chain }) => {\r\n                return chain().setMark('textStyle', { wordSpacing }).run();\r\n            },\r\n            unsetWordSpacing: () => ({ chain }) => {\r\n                return chain().setMark('textStyle', { wordSpacing: null }).removeEmptyTextStyle().run();\r\n            },\r\n        };\r\n    },\r\n});\r\n","import { Extension } from '@tiptap/core';\r\n\r\nexport interface ParagraphSystemOptions {\r\n    types: string[];\r\n}\r\n\r\ndeclare module '@tiptap/core' {\r\n    interface Commands<ReturnType> {\r\n        paragraphSystem: {\r\n            /**\r\n             * Set paragraph spacing\r\n             */\r\n            setParagraphLayout: (attrs: {\r\n                before?: string;\r\n                after?: string;\r\n                firstLineIndent?: string;\r\n                hangingIndent?: string;\r\n                backgroundColor?: string;\r\n                border?: string;\r\n                class?: string;\r\n                id?: string;\r\n            }) => ReturnType;\r\n        };\r\n    }\r\n}\r\n\r\nexport const ParagraphSystem = Extension.create<ParagraphSystemOptions>({\r\n    name: 'paragraphSystem',\r\n\r\n    addOptions() {\r\n        return {\r\n            types: ['paragraph', 'heading'],\r\n        };\r\n    },\r\n\r\n    addGlobalAttributes() {\r\n        return [\r\n            {\r\n                types: this.options.types,\r\n                attributes: {\r\n                    spacingBefore: {\r\n                        default: null,\r\n                        parseHTML: element => element.style.marginTop,\r\n                        renderHTML: attributes => {\r\n                            if (!attributes.spacingBefore) return {};\r\n                            return { style: `margin-top: ${attributes.spacingBefore}` };\r\n                        },\r\n                    },\r\n                    spacingAfter: {\r\n                        default: null,\r\n                        parseHTML: element => element.style.marginBottom,\r\n                        renderHTML: attributes => {\r\n                            if (!attributes.spacingAfter) return {};\r\n                            return { style: `margin-bottom: ${attributes.spacingAfter}` };\r\n                        },\r\n                    },\r\n                    firstLineIndent: {\r\n                        default: null,\r\n                        parseHTML: element => element.style.textIndent,\r\n                        renderHTML: attributes => {\r\n                            if (!attributes.firstLineIndent) return {};\r\n                            return { style: `text-indent: ${attributes.firstLineIndent}` };\r\n                        },\r\n                    },\r\n                    hangingIndent: {\r\n                        default: null,\r\n                        parseHTML: element => {\r\n                            const padding = element.style.paddingLeft;\r\n                            const indent = element.style.textIndent;\r\n                            if (indent.startsWith('-')) return padding;\r\n                            return null;\r\n                        },\r\n                        renderHTML: attributes => {\r\n                            if (!attributes.hangingIndent) return {};\r\n                            return {\r\n                                style: `padding-left: ${attributes.hangingIndent}; text-indent: -${attributes.hangingIndent}`,\r\n                            };\r\n                        },\r\n                    },\r\n                    backgroundColor: {\r\n                        default: null,\r\n                        parseHTML: element => element.style.backgroundColor,\r\n                        renderHTML: attributes => {\r\n                            if (!attributes.backgroundColor) return {};\r\n                            return { style: `background-color: ${attributes.backgroundColor}` };\r\n                        },\r\n                    },\r\n                    border: {\r\n                        default: null,\r\n                        parseHTML: element => element.style.border,\r\n                        renderHTML: attributes => {\r\n                            if (!attributes.border) return {};\r\n                            return { style: `border: ${attributes.border}` };\r\n                        },\r\n                    },\r\n                    class: {\r\n                        default: null,\r\n                        parseHTML: element => element.getAttribute('class'),\r\n                        renderHTML: attributes => {\r\n                            if (!attributes.class) return {};\r\n                            return { class: attributes.class };\r\n                        },\r\n                    },\r\n                    id: {\r\n                        default: null,\r\n                        parseHTML: element => element.getAttribute('id'),\r\n                        renderHTML: attributes => {\r\n                            if (!attributes.id) return {};\r\n                            return { id: attributes.id };\r\n                        },\r\n                    },\r\n                },\r\n            },\r\n        ];\r\n    },\r\n\r\n    addCommands() {\r\n        return {\r\n            setParagraphLayout: (attrs) => ({ commands }) => {\r\n                return this.options.types.every((type) =>\r\n                    commands.updateAttributes(type, {\r\n                        spacingBefore: attrs.before,\r\n                        spacingAfter: attrs.after,\r\n                        firstLineIndent: attrs.firstLineIndent,\r\n                        hangingIndent: attrs.hangingIndent,\r\n                        backgroundColor: attrs.backgroundColor,\r\n                        border: attrs.border,\r\n                        class: attrs.class,\r\n                        id: attrs.id,\r\n                    })\r\n                );\r\n            },\r\n        };\r\n    },\r\n});\r\n","export interface StyleDefinition {\r\n    name: string;\r\n    parent?: string;\r\n    attributes: Record<string, any>;\r\n}\r\n\r\nexport class StyleManager {\r\n    private styles: Map<string, StyleDefinition> = new Map();\r\n\r\n    constructor() {\r\n        this.setupDefaultStyles();\r\n    }\r\n\r\n    private setupDefaultStyles() {\r\n        this.addStyle({\r\n            name: 'Normal',\r\n            attributes: {\r\n                fontFamily: 'Inter',\r\n                fontSize: '11pt',\r\n                color: '#000000',\r\n                textAlign: 'left',\r\n                lineHeight: '1.2',\r\n                spacingAfter: '8pt',\r\n            },\r\n        });\r\n\r\n        this.addStyle({\r\n            name: 'Heading 1',\r\n            parent: 'Normal',\r\n            attributes: {\r\n                fontSize: '24pt',\r\n                fontWeight: 'bold',\r\n                spacingBefore: '12pt',\r\n                spacingAfter: '12pt',\r\n            },\r\n        });\r\n\r\n        this.addStyle({\r\n            name: 'Heading 2',\r\n            parent: 'Normal',\r\n            attributes: {\r\n                fontSize: '18pt',\r\n                fontWeight: 'bold',\r\n                spacingBefore: '10pt',\r\n                spacingAfter: '10pt',\r\n            },\r\n        });\r\n\r\n        this.addStyle({\r\n            name: 'Quote',\r\n            parent: 'Normal',\r\n            attributes: {\r\n                fontStyle: 'italic',\r\n                indent: 1,\r\n                color: '#666666',\r\n            },\r\n        });\r\n    }\r\n\r\n    public addStyle(style: StyleDefinition) {\r\n        this.styles.set(style.name, style);\r\n    }\r\n\r\n    public getStyle(name: string): StyleDefinition | undefined {\r\n        return this.styles.get(name);\r\n    }\r\n\r\n    /**\r\n     * Resolves a style by merging it with all its parents.\r\n     */\r\n    public resolveStyle(name: string): Record<string, any> {\r\n        const style = this.getStyle(name);\r\n        if (!style) return {};\r\n\r\n        let resolved = { ...style.attributes };\r\n        let currentParent = style.parent;\r\n\r\n        while (currentParent) {\r\n            const parentStyle = this.getStyle(currentParent);\r\n            if (parentStyle) {\r\n                // Merge attributes, keeping existing child attributes\r\n                resolved = { ...parentStyle.attributes, ...resolved };\r\n                currentParent = parentStyle.parent;\r\n            } else {\r\n                currentParent = undefined;\r\n            }\r\n        }\r\n\r\n        return resolved;\r\n    }\r\n\r\n    public getAllStyles(): StyleDefinition[] {\r\n        return Array.from(this.styles.values());\r\n    }\r\n}\r\n","import { Extension } from '@tiptap/core';\r\nimport { StyleManager } from '../StyleManager';\r\n\r\nexport interface StylesEngineOptions {\r\n    manager: StyleManager;\r\n}\r\n\r\ndeclare module '@tiptap/core' {\r\n    interface Commands<ReturnType> {\r\n        stylesEngine: {\r\n            /**\r\n             * Apply a named style to the selection.\r\n             */\r\n            applyNamedStyle: (name: string) => ReturnType;\r\n            /**\r\n             * Update a named style definition.\r\n             */\r\n            updateNamedStyle: (name: string, attributes: Record<string, any>) => ReturnType;\r\n        };\r\n    }\r\n}\r\n\r\nexport const StylesEngine = Extension.create<StylesEngineOptions>({\r\n    name: 'stylesEngine',\r\n\r\n    addOptions() {\r\n        return {\r\n            manager: new StyleManager(),\r\n        };\r\n    },\r\n\r\n    addGlobalAttributes() {\r\n        return [\r\n            {\r\n                types: ['paragraph', 'heading'],\r\n                attributes: {\r\n                    styleName: {\r\n                        default: 'Normal',\r\n                        parseHTML: element => element.getAttribute('data-style-name') || 'Normal',\r\n                        renderHTML: attributes => {\r\n                            if (!attributes.styleName || attributes.styleName === 'Normal') {\r\n                                return {};\r\n                            }\r\n                            return { 'data-style-name': attributes.styleName };\r\n                        },\r\n                    },\r\n                },\r\n            },\r\n        ];\r\n    },\r\n\r\n    addCommands() {\r\n        return {\r\n            applyNamedStyle: (name: string) => ({ chain, commands }) => {\r\n                const resolvedAttributes = this.options.manager.resolveStyle(name);\r\n\r\n                // 1. Update the block attributes (spacing, align, etc.)\r\n                // 2. Wrap/Update the node type if necessary (e.g. Heading 1 -> heading level 1)\r\n                let chainExec = chain().focus().updateAttributes('paragraph', { styleName: name, ...resolvedAttributes });\r\n\r\n                if (name.startsWith('Heading')) {\r\n                    const level = (parseInt(name.replace('Heading ', '')) || 1) as any;\r\n                    chainExec = chainExec.setHeading({ level }).updateAttributes('heading', { styleName: name, ...resolvedAttributes });\r\n                } else if (name === 'Normal' || name === 'Quote') {\r\n                    chainExec = chainExec.setParagraph().updateAttributes('paragraph', { styleName: name, ...resolvedAttributes });\r\n                }\r\n\r\n                // 3. Apply character marks if defined in the style (e.g. bold, fontSize)\r\n                // Note: In Tiptap, some attributes are marks and some are node attributes.\r\n                // For simplicity in Phase 2, we focus on node attributes.\r\n\r\n                return chainExec.run();\r\n            },\r\n\r\n            updateNamedStyle: (name, attributes) => () => {\r\n                const style = this.options.manager.getStyle(name);\r\n                if (style) {\r\n                    style.attributes = { ...style.attributes, ...attributes };\r\n                    // TODO: In a more advanced implementation, this should trigger a re-render of all nodes with this style\r\n                    return true;\r\n                }\r\n                return false;\r\n            },\r\n        };\r\n    },\r\n});\r\n","import { Extension } from '@tiptap/core';\n\nexport type PageSize = 'A3' | 'A4' | 'A5' | 'Letter' | 'Legal' | 'Tabloid' | 'Custom';\nexport type Orientation = 'portrait' | 'landscape';\n\nexport interface PageLayoutOptions {\n    pageSize: PageSize;\n    orientation: Orientation;\n    /** Custom width when pageSize is 'Custom' (e.g. '210mm'). */\n    width?: string;\n    /** Custom height when pageSize is 'Custom' (e.g. '297mm'). */\n    height?: string;\n    margins: {\n        top: string;\n        bottom: string;\n        left: string;\n        right: string;\n    };\n}\n\nexport const DEFAULT_PAGE_LAYOUT: PageLayoutOptions = {\n    pageSize: 'A4',\n    orientation: 'portrait',\n    margins: {\n        top: '1in',\n        bottom: '1in',\n        left: '1in',\n        right: '1in',\n    },\n};\n\ndeclare module '@tiptap/core' {\n    interface Commands<ReturnType> {\n        pageLayout: {\n            setPageLayout: (options: Partial<PageLayoutOptions>) => ReturnType;\n        };\n    }\n}\n\nexport const PageLayout = Extension.create<PageLayoutOptions>({\n    name: 'pageLayout',\n\n    addOptions() {\n        return { ...DEFAULT_PAGE_LAYOUT };\n    },\n\n    addStorage() {\n        return { ...DEFAULT_PAGE_LAYOUT };\n    },\n\n    onCreate() {\n        Object.assign(this.storage, this.options);\n    },\n\n    addCommands() {\n        return {\n            setPageLayout: (options) => ({ editor }) => {\n                Object.assign(this.options, options);\n                if (options.margins) {\n                    this.options.margins = { ...this.options.margins, ...options.margins };\n                }\n                Object.assign(this.storage, this.options);\n                const parent = (editor as any).options.parent;\n                if (parent && typeof parent.setPageLayout === 'function') {\n                    parent.setPageLayout(this.options);\n                }\n                return true;\n            },\n        };\n    },\n});\n","import { Node, mergeAttributes } from '@tiptap/core';\r\n\r\nexport interface SectionOptions {\r\n    HTMLAttributes: Record<string, any>;\r\n}\r\n\r\ndeclare module '@tiptap/core' {\r\n    interface Commands<ReturnType> {\r\n        section: {\r\n            /**\r\n             * Insert a section break\r\n             */\r\n            insertSectionBreak: () => ReturnType;\r\n        };\r\n    }\r\n}\r\n\r\nexport const Section = Node.create<SectionOptions>({\r\n    name: 'section',\r\n    group: 'block',\r\n    content: 'block+',\r\n    defining: true,\r\n\r\n    addAttributes() {\r\n        return {\r\n            id: {\r\n                default: null,\r\n            },\r\n            pageSize: {\r\n                default: 'A4',\r\n            },\r\n            orientation: {\r\n                default: 'portrait',\r\n            },\r\n            marginTop: {\r\n                default: '1in',\r\n            },\r\n            marginBottom: {\r\n                default: '1in',\r\n            },\r\n            marginLeft: {\r\n                default: '1in',\r\n            },\r\n            marginRight: {\r\n                default: '1in',\r\n            },\r\n        };\r\n    },\r\n\r\n    parseHTML() {\r\n        return [\r\n            {\r\n                tag: 'section.rk-section',\r\n            },\r\n        ];\r\n    },\r\n\r\n    renderHTML({ HTMLAttributes }) {\r\n        return ['section', mergeAttributes(HTMLAttributes, { class: 'rk-section' }), 0];\r\n    },\r\n\r\n    addCommands() {\r\n        return {\r\n            insertSectionBreak: () => ({ chain }) => {\r\n                return chain()\r\n                    .focus()\r\n                    .insertContent({ type: this.name, content: [{ type: 'paragraph' }] })\r\n                    .run();\r\n            },\r\n        };\r\n    },\r\n});\r\n","import { Node, mergeAttributes } from '@tiptap/core';\r\n\r\nexport const Header = Node.create({\r\n    name: 'header',\r\n    group: 'block',\r\n    content: 'block+',\r\n    selectable: false,\r\n    draggable: false,\r\n\r\n    parseHTML() {\r\n        return [{ tag: 'header.rk-header' }];\r\n    },\r\n\r\n    renderHTML({ HTMLAttributes }) {\r\n        return ['header', mergeAttributes(HTMLAttributes, { class: 'rk-header' }), 0];\r\n    },\r\n});\r\n\r\nexport const Footer = Node.create({\r\n    name: 'footer',\r\n    group: 'block',\r\n    content: 'block+',\r\n    selectable: false,\r\n    draggable: false,\r\n\r\n    parseHTML() {\r\n        return [{ tag: 'footer.rk-footer' }];\r\n    },\r\n\r\n    renderHTML({ HTMLAttributes }) {\r\n        return ['footer', mergeAttributes(HTMLAttributes, { class: 'rk-footer' }), 0];\r\n    },\r\n});\r\n\r\nexport const PageNumber = Node.create({\r\n    name: 'pageNumber',\r\n    group: 'inline',\r\n    inline: true,\r\n    selectable: false,\r\n    draggable: false,\r\n\r\n    renderHTML() {\r\n        return ['span', { class: 'rk-page-number' }, '1']; // Placeholder, UI handles actual number\r\n    },\r\n});\r\n","import { Extension } from '@tiptap/core';\r\n\r\n/**\r\n * TableStyles extension - Adds style attributes to tables.\r\n */\r\nexport const TableStyles = Extension.create({\r\n    name: 'tableStyles',\r\n\r\n    addGlobalAttributes() {\r\n        return [\r\n            {\r\n                types: ['table'],\r\n                attributes: {\r\n                    tableStyle: {\r\n                        default: 'standard',\r\n                        parseHTML: (element: HTMLElement) => element.getAttribute('data-table-style'),\r\n                        renderHTML: (attributes: any) => {\r\n                            if (!attributes.tableStyle) return {};\r\n                            return { 'data-table-style': attributes.tableStyle };\r\n                        },\r\n                    },\r\n                    borderWidth: {\r\n                        default: null,\r\n                        parseHTML: (element: HTMLElement) => element.style.borderWidth,\r\n                        renderHTML: (attributes: any) => {\r\n                            if (!attributes.borderWidth) return {};\r\n                            return { style: `border-width: ${attributes.borderWidth}` };\r\n                        },\r\n                    },\r\n                },\r\n            },\r\n        ];\r\n    },\r\n\r\n    addCommands() {\r\n        return {\r\n            setTableStyle: (style: string) => ({ commands }: { commands: any }) => {\r\n                return commands.updateAttributes('table', { tableStyle: style });\r\n            },\r\n            setTableBorder: (width: string) => ({ commands }: { commands: any }) => {\r\n                return commands.updateAttributes('table', { borderWidth: width });\r\n            },\r\n        } as any;\r\n    },\r\n});\r\n","import { Extension } from '@tiptap/core';\r\n\r\nexport const MultilevelList = Extension.create({\r\n    name: 'multilevelList',\r\n\r\n    addGlobalAttributes() {\r\n        return [\r\n            {\r\n                types: ['bulletList', 'orderedList'],\r\n                attributes: {\r\n                    listStyle: {\r\n                        default: null,\r\n                        parseHTML: (element: HTMLElement) => element.getAttribute('data-list-style'),\r\n                        renderHTML: (attributes: any) => {\r\n                            if (!attributes.listStyle) return {};\r\n                            return {\r\n                                'data-list-style': attributes.listStyle,\r\n                                class: attributes.listStyle === 'nepali' ? 'rk-list-nepali' : '',\r\n                                style: `list-style-type: ${attributes.listStyle === 'nepali' ? 'none' : attributes.listStyle}`,\r\n                            };\r\n                        },\r\n                    },\r\n                    startNumber: {\r\n                        default: 1,\r\n                        parseHTML: (element: HTMLElement) => parseInt(element.getAttribute('start') || '1', 10),\r\n                        renderHTML: (attributes: any) => {\r\n                            if (!attributes.startNumber || attributes.startNumber === 1) return {};\r\n                            return { start: String(attributes.startNumber) };\r\n                        },\r\n                    },\r\n                },\r\n            },\r\n            {\r\n                types: ['listItem'],\r\n                attributes: {\r\n                    listLevel: {\r\n                        default: 1,\r\n                        parseHTML: (element: HTMLElement) => parseInt(element.getAttribute('data-list-level') || '1', 10),\r\n                        renderHTML: (attributes: any) => {\r\n                            return { 'data-list-level': String(attributes.listLevel || 1) };\r\n                        },\r\n                    },\r\n                },\r\n            },\r\n        ];\r\n    },\r\n\r\n    addCommands() {\r\n        return {\r\n            setListStyle: (listStyle: string) => ({ state, dispatch }: { state: any, dispatch?: any }) => {\r\n                const { selection } = state;\r\n                let tr = state.tr;\r\n                let found = false;\r\n\r\n                state.doc.nodesBetween(selection.from, selection.to, (node: any, pos: number) => {\r\n                    if (node.type.name === 'orderedList' || node.type.name === 'bulletList') {\r\n                        tr = tr.setNodeMarkup(pos, undefined, { ...node.attrs, listStyle });\r\n                        found = true;\r\n                    }\r\n                });\r\n\r\n                if (found) {\r\n                    if (dispatch) dispatch(tr);\r\n                    return true;\r\n                }\r\n\r\n                return false;\r\n            },\r\n            setListStartNumber: (startNumber: number) => ({ commands }: { commands: any }) => {\r\n                return commands.updateAttributes('orderedList', { startNumber });\r\n            },\r\n            setLegalNumbering: () => ({ commands }: { commands: any }) => {\r\n                return commands.updateAttributes('orderedList', { listStyle: 'decimal' });\r\n            },\r\n        } as any;\r\n    },\r\n});\r\n","import { Node, mergeAttributes } from '@tiptap/core';\r\n\r\n/**\r\n * Caption node - Adds a caption to images and tables.\r\n * Allows numbered captions \"Figure 1: ...\" or \"Table 2: ...\".\r\n */\r\nexport const Caption = Node.create({\r\n    name: 'caption',\r\n    group: 'block',\r\n    content: 'inline*',\r\n    selectable: false,\r\n    draggable: false,\r\n\r\n    addAttributes() {\r\n        return {\r\n            captionType: {\r\n                default: 'Figure',\r\n                parseHTML: (element: HTMLElement) => element.getAttribute('data-caption-type'),\r\n                renderHTML: (attributes: any) => ({ 'data-caption-type': attributes.captionType }),\r\n            },\r\n            captionNumber: {\r\n                default: null,\r\n                parseHTML: (element: HTMLElement) => element.getAttribute('data-caption-number'),\r\n                renderHTML: (attributes: any) => {\r\n                    if (!attributes.captionNumber) return {};\r\n                    return { 'data-caption-number': attributes.captionNumber };\r\n                },\r\n            },\r\n        };\r\n    },\r\n\r\n    parseHTML() {\r\n        return [{ tag: 'figcaption' }];\r\n    },\r\n\r\n    renderHTML({ HTMLAttributes }: { HTMLAttributes: any }) {\r\n        return ['figcaption', mergeAttributes({ class: 'rk-caption' }, HTMLAttributes), 0];\r\n    },\r\n\r\n    addCommands() {\r\n        return {\r\n            insertCaption: (type = 'Figure') => ({ commands }: { commands: any }) => {\r\n                return commands.insertContent({\r\n                    type: 'caption',\r\n                    attrs: { captionType: type },\r\n                    content: [{ type: 'text', text: `${type}: ` }],\r\n                });\r\n            },\r\n        } as any;\r\n    },\r\n});\r\n","import { Extension } from '@tiptap/core';\r\n\r\nexport const ImageResize = Extension.create({\r\n    name: 'imageResize',\r\n\r\n    addGlobalAttributes() {\r\n        return [\r\n            {\r\n                types: ['image'],\r\n                attributes: {\r\n                    width: {\r\n                        default: null,\r\n                        parseHTML: (element: HTMLElement) => {\r\n                            const w = element.getAttribute('width') || element.style.width;\r\n                            return w || null;\r\n                        },\r\n                        renderHTML: (attributes: any) => {\r\n                            if (!attributes.width) return {};\r\n                            return { style: `width: ${attributes.width}; max-width: 100%;` };\r\n                        },\r\n                    },\r\n                    height: {\r\n                        default: null,\r\n                        parseHTML: (element: HTMLElement) => element.getAttribute('height') || element.style.height || null,\r\n                        renderHTML: (attributes: any) => {\r\n                            if (!attributes.height) return {};\r\n                            return { style: `height: ${attributes.height};` };\r\n                        },\r\n                    },\r\n                    float: {\r\n                        default: null,\r\n                        parseHTML: (element: HTMLElement) => element.style.float || null,\r\n                        renderHTML: (attributes: any) => {\r\n                            if (!attributes.float) return {};\r\n                            return { style: `float: ${attributes.float}; margin: 0.5em;` };\r\n                        },\r\n                    },\r\n                    align: {\r\n                        default: null,\r\n                        parseHTML: (element: HTMLElement) => element.getAttribute('data-align'),\r\n                        renderHTML: (attributes: any) => {\r\n                            if (!attributes.align) return {};\r\n                            return { 'data-align': attributes.align };\r\n                        },\r\n                    },\r\n                },\r\n            },\r\n        ];\r\n    },\r\n\r\n    addCommands() {\r\n        return {\r\n            setImageSize: (width: string, height?: string) => ({ commands }: { commands: any }) => {\r\n                return commands.updateAttributes('image', { width, height: height || null });\r\n            },\r\n            setImageFloat: (float: 'left' | 'right' | 'none') => ({ commands }: { commands: any }) => {\r\n                return commands.updateAttributes('image', { float: float === 'none' ? null : float });\r\n            },\r\n            setImageInline: () => ({ commands }: { commands: any }) => {\r\n                return commands.updateAttributes('image', { float: null });\r\n            },\r\n        } as any;\r\n    },\r\n});\r\n","import { Node, mergeAttributes } from '@tiptap/core';\r\n\r\nexport const MathInline = Node.create({\r\n    name: 'mathInline',\r\n    group: 'inline',\r\n    inline: true,\r\n    atom: true,\r\n\r\n    addAttributes() {\r\n        return {\r\n            latex: {\r\n                default: '',\r\n                parseHTML: (element: HTMLElement) => element.getAttribute('data-latex') || element.textContent,\r\n                renderHTML: (attributes: any) => ({ 'data-latex': attributes.latex }),\r\n            },\r\n        };\r\n    },\r\n\r\n    parseHTML() {\r\n        return [{ tag: 'span[data-type=\"math-inline\"]' }];\r\n    },\r\n\r\n    renderHTML({ HTMLAttributes, node }: { HTMLAttributes: any; node: any }) {\r\n        return [\r\n            'span',\r\n            mergeAttributes({ 'data-type': 'math-inline', class: 'rk-math-inline' }, HTMLAttributes),\r\n            node.attrs.latex || '',\r\n        ];\r\n    },\r\n\r\n    addCommands() {\r\n        return {\r\n            insertMathInline: (latex: string) => ({ commands }: { commands: any }) => {\r\n                return commands.insertContent({\r\n                    type: 'mathInline',\r\n                    attrs: { latex },\r\n                });\r\n            },\r\n        } as any;\r\n    },\r\n});\r\n\r\nexport const MathBlock = Node.create({\r\n    name: 'mathBlock',\r\n    group: 'block',\r\n    atom: true,\r\n\r\n    addAttributes() {\r\n        return {\r\n            latex: {\r\n                default: '',\r\n                parseHTML: (element: HTMLElement) => element.getAttribute('data-latex') || element.textContent,\r\n                renderHTML: (attributes: any) => ({ 'data-latex': attributes.latex }),\r\n            },\r\n        };\r\n    },\r\n\r\n    parseHTML() {\r\n        return [{ tag: 'div[data-type=\"math-block\"]' }];\r\n    },\r\n\r\n    renderHTML({ HTMLAttributes, node }: { HTMLAttributes: any; node: any }) {\r\n        return [\r\n            'div',\r\n            mergeAttributes({ 'data-type': 'math-block', class: 'rk-math-block' }, HTMLAttributes),\r\n            node.attrs.latex || '',\r\n        ];\r\n    },\r\n\r\n    addCommands() {\r\n        return {\r\n            insertMathBlock: (latex: string) => ({ commands }: { commands: any }) => {\r\n                return commands.insertContent({\r\n                    type: 'mathBlock',\r\n                    attrs: { latex },\r\n                });\r\n            },\r\n        } as any;\r\n    },\r\n});\r\n","import { Extension, Node, mergeAttributes } from '@tiptap/core';\n\ndeclare module '@tiptap/core' {\n    interface Commands<ReturnType> {\n        tableOfContents: {\n            /** Insert a Table of Contents node at the cursor. */\n            insertTableOfContents: (attrs?: TocAttrs) => ReturnType;\n            /** Re-scan the document and refresh every TOC node. */\n            refreshTableOfContents: () => ReturnType;\n            /** Update the level filter for the TOC at the current selection. */\n            setTocLevels: (minLevel: number, maxLevel: number) => ReturnType;\n        };\n    }\n}\n\ninterface TocAttrs {\n    /** Minimum heading level to include (default 1). */\n    minLevel?: number;\n    /** Maximum heading level to include (default 3). */\n    maxLevel?: number;\n    /** Display title shown above the TOC (\"Table of contents\"). */\n    title?: string;\n    /** Show the dotted leader between text and page number (default true). */\n    showLeader?: boolean;\n    /** Show estimated page numbers (default true). */\n    showPageNumbers?: boolean;\n}\n\ninterface HeadingItem {\n    level: number;\n    text: string;\n    id: string;\n    pos: number;\n    estimatedPage: number;\n}\n\nconst TOC_TYPE = 'tableOfContents';\n\n/**\n * Table of Contents extension.\n *\n * - Backed by a real `tableOfContents` node so it survives copy/paste, undo/redo,\n *   serialisation and round-trips through HTML/JSON.\n * - Renders as a static HTML block in the document; the engine refreshes it\n *   whenever the user runs `refreshTableOfContents()` (and once on insert).\n * - Configurable via `minLevel`, `maxLevel`, `title`, `showLeader`, `showPageNumbers`.\n * - Page numbers are estimated from a rough characters-per-page heuristic until\n *   the host application supplies a real pagination map. Works well in practice\n *   because the dotted leaders absorb minor mis-alignment.\n */\nexport const TableOfContents = Node.create({\n    name: TOC_TYPE,\n    group: 'block',\n    atom: true,\n    draggable: true,\n    selectable: true,\n\n    addAttributes() {\n        return {\n            minLevel: {\n                default: 1,\n                parseHTML: (el: HTMLElement) => Number(el.getAttribute('data-min-level') || 1),\n                renderHTML: (a: any) => ({ 'data-min-level': String(a.minLevel ?? 1) }),\n            },\n            maxLevel: {\n                default: 3,\n                parseHTML: (el: HTMLElement) => Number(el.getAttribute('data-max-level') || 3),\n                renderHTML: (a: any) => ({ 'data-max-level': String(a.maxLevel ?? 3) }),\n            },\n            title: {\n                default: 'Table of contents',\n                parseHTML: (el: HTMLElement) => el.getAttribute('data-title') || 'Table of contents',\n                renderHTML: (a: any) => ({ 'data-title': a.title || 'Table of contents' }),\n            },\n            showLeader: {\n                default: true,\n                parseHTML: (el: HTMLElement) => el.getAttribute('data-leader') !== 'false',\n                renderHTML: (a: any) => ({ 'data-leader': a.showLeader === false ? 'false' : 'true' }),\n            },\n            showPageNumbers: {\n                default: true,\n                parseHTML: (el: HTMLElement) => el.getAttribute('data-pagenums') !== 'false',\n                renderHTML: (a: any) => ({ 'data-pagenums': a.showPageNumbers === false ? 'false' : 'true' }),\n            },\n        };\n    },\n\n    parseHTML() {\n        return [{ tag: 'div[data-type=\"toc\"]' }];\n    },\n\n    renderHTML({ HTMLAttributes }) {\n        return ['div', mergeAttributes(HTMLAttributes, { 'data-type': 'toc', class: 'rk-toc' }),\n            // We render content via a NodeView; this fallback keeps SSR safe.\n            ['div', { class: 'rk-toc-fallback' }, 'Table of contents'],\n        ];\n    },\n\n    addCommands() {\n        return {\n            insertTableOfContents:\n                (attrs: TocAttrs = {}) =>\n                ({ commands }: { commands: any }) => {\n                    return commands.insertContent({\n                        type: TOC_TYPE,\n                        attrs: {\n                            minLevel: attrs.minLevel ?? 1,\n                            maxLevel: attrs.maxLevel ?? 3,\n                            title: attrs.title ?? 'Table of contents',\n                            showLeader: attrs.showLeader !== false,\n                            showPageNumbers: attrs.showPageNumbers !== false,\n                        },\n                    });\n                },\n\n            refreshTableOfContents:\n                () =>\n                ({ editor, tr, dispatch }: { editor: any; tr: any; dispatch: any }) => {\n                    if (!dispatch) return false;\n                    let changed = false;\n                    editor.state.doc.descendants((node: any, pos: number) => {\n                        if (node.type.name === TOC_TYPE) {\n                            // Force a re-render by toggling a hidden attr.\n                            tr.setNodeMarkup(pos, undefined, { ...node.attrs, _refresh: Date.now() });\n                            changed = true;\n                        }\n                    });\n                    if (changed) dispatch(tr);\n                    return changed;\n                },\n\n            setTocLevels:\n                (minLevel: number, maxLevel: number) =>\n                ({ editor, tr, dispatch }: { editor: any; tr: any; dispatch: any }) => {\n                    const $from = editor.state.selection.$from;\n                    for (let d = $from.depth; d >= 0; d--) {\n                        const n = $from.node(d);\n                        if (n.type.name === TOC_TYPE) {\n                            const pos = $from.before(d);\n                            if (dispatch) {\n                                tr.setNodeMarkup(pos, undefined, { ...n.attrs, minLevel, maxLevel });\n                                dispatch(tr);\n                            }\n                            return true;\n                        }\n                    }\n                    return false;\n                },\n        };\n    },\n\n    addNodeView() {\n        return ({ node, editor, getPos }) => {\n            const root = document.createElement('div');\n            root.classList.add('rk-toc');\n            root.dataset.type = 'toc';\n            root.contentEditable = 'false';\n\n            const render = (n: any) => {\n                const items = collectHeadings(editor.state.doc, n.attrs.minLevel || 1, n.attrs.maxLevel || 3);\n                root.innerHTML = '';\n\n                const header = document.createElement('div');\n                header.className = 'rk-toc-header';\n                header.innerHTML = `\n                    <h2 class=\"rk-toc-title\">${escapeHtml(n.attrs.title || 'Table of contents')}</h2>\n                    <button class=\"rk-toc-refresh\" type=\"button\" title=\"Refresh table of contents\">↻ Refresh</button>\n                `;\n                header.querySelector('.rk-toc-refresh')?.addEventListener('click', (e) => {\n                    e.preventDefault();\n                    e.stopPropagation();\n                    (editor.commands as any).refreshTableOfContents();\n                });\n                root.appendChild(header);\n\n                if (items.length === 0) {\n                    const empty = document.createElement('p');\n                    empty.className = 'rk-toc-empty';\n                    empty.textContent = 'No headings yet — add a heading (H1–H6) to populate this table of contents.';\n                    root.appendChild(empty);\n                    return;\n                }\n\n                const list = document.createElement('ol');\n                list.className = 'rk-toc-list';\n                for (const item of items) {\n                    const li = document.createElement('li');\n                    li.className = `rk-toc-item rk-toc-l${item.level}`;\n                    const link = document.createElement('a');\n                    link.className = 'rk-toc-link';\n                    link.href = `#${item.id}`;\n                    link.dataset.pos = String(item.pos);\n\n                    const text = document.createElement('span');\n                    text.className = 'rk-toc-text';\n                    text.textContent = item.text;\n\n                    link.appendChild(text);\n\n                    if (n.attrs.showLeader !== false) {\n                        const leader = document.createElement('span');\n                        leader.className = 'rk-toc-leader';\n                        leader.setAttribute('aria-hidden', 'true');\n                        link.appendChild(leader);\n                    }\n\n                    if (n.attrs.showPageNumbers !== false) {\n                        const page = document.createElement('span');\n                        page.className = 'rk-toc-page';\n                        page.textContent = String(item.estimatedPage);\n                        link.appendChild(page);\n                    }\n\n                    link.addEventListener('click', (e) => {\n                        e.preventDefault();\n                        const pos = Number(link.dataset.pos);\n                        if (Number.isFinite(pos)) {\n                            const dom = editor.view.nodeDOM(pos) as HTMLElement | null;\n                            editor.commands.setTextSelection(pos + 1);\n                            if (dom?.scrollIntoView) {\n                                dom.scrollIntoView({ behavior: 'smooth', block: 'start' });\n                            } else {\n                                editor.commands.scrollIntoView();\n                            }\n                        }\n                    });\n\n                    li.appendChild(link);\n                    list.appendChild(li);\n                }\n                root.appendChild(list);\n            };\n\n            render(node);\n\n            // No auto-refresh — TOCs only update when:\n            //   1. the user clicks the inline Refresh button, or\n            //   2. the user calls `editor.format.refreshTableOfContents()`, or\n            //   3. the node attrs change (level filter, title, etc.).\n            return {\n                dom: root,\n                update(updated) {\n                    if (updated.type.name !== TOC_TYPE) return false;\n                    render(updated);\n                    return true;\n                },\n                destroy() { /* nothing to clean up */ },\n                stopEvent(event) {\n                    // Allow the refresh button + heading links to receive clicks.\n                    return !!(event.target as HTMLElement)?.closest?.('button, a');\n                },\n            };\n        };\n    },\n});\n\n/** Re-export the legacy storage extension name so existing code keeps working. */\nexport { TableOfContents as default };\n\n// ---- helpers ----\n\nfunction collectHeadings(doc: any, minLevel: number, maxLevel: number): HeadingItem[] {\n    const items: HeadingItem[] = [];\n    let charCount = 0;\n    // Rough heuristic: ~1500 characters per A4 page at 11pt with 1in margins.\n    const CHARS_PER_PAGE = 1500;\n    doc.descendants((node: any, pos: number) => {\n        if (node.isText) charCount += node.text?.length || 0;\n        if (node.type.name === 'heading') {\n            const level = node.attrs.level;\n            if (level >= minLevel && level <= maxLevel) {\n                const text = node.textContent;\n                if (!text.trim()) return;\n                items.push({\n                    level,\n                    text,\n                    id: slug(text),\n                    pos,\n                    estimatedPage: Math.max(1, Math.ceil(charCount / CHARS_PER_PAGE)),\n                });\n            }\n        }\n        return true;\n    });\n    return items;\n}\n\nfunction slug(s: string): string {\n    return s.toLowerCase().trim()\n        .replace(/[^\\w\\s-]/g, '')\n        .replace(/\\s+/g, '-')\n        .replace(/-+/g, '-');\n}\n\nfunction escapeHtml(s: string): string {\n    return s.replace(/[&<>\"']/g, c => ({ '&': '&amp;', '<': '&lt;', '>': '&gt;', '\"': '&quot;', \"'\": '&#39;' }[c]!));\n}\n","import { Node, mergeAttributes } from '@tiptap/core';\r\n\r\nexport const Citation = Node.create({\r\n    name: 'citation',\r\n    group: 'inline',\r\n    inline: true,\r\n    atom: true,\r\n\r\n    addAttributes() {\r\n        return {\r\n            key: {\r\n                default: '',\r\n                parseHTML: (element: HTMLElement) => element.getAttribute('data-key'),\r\n                renderHTML: (attributes: any) => ({ 'data-key': attributes.key }),\r\n            },\r\n            label: {\r\n                default: '',\r\n                parseHTML: (element: HTMLElement) => element.textContent,\r\n                renderHTML: () => ({}),\r\n            },\r\n        };\r\n    },\r\n\r\n    parseHTML() {\r\n        return [{ tag: 'cite[data-type=\"citation\"]' }];\r\n    },\r\n\r\n    renderHTML({ HTMLAttributes, node }: { HTMLAttributes: any; node: any }) {\r\n        return [\r\n            'cite',\r\n            mergeAttributes({ 'data-type': 'citation', class: 'rk-citation' }, HTMLAttributes),\r\n            `[${node.attrs.label || node.attrs.key || '?'}]`,\r\n        ];\r\n    },\r\n\r\n    addCommands() {\r\n        return {\r\n            insertCitation: (key: string, label?: string) => ({ commands }: { commands: any }) => {\r\n                return commands.insertContent({\r\n                    type: 'citation',\r\n                    attrs: { key, label: label || key },\r\n                });\r\n            },\r\n        } as any;\r\n    },\r\n});\r\n\r\nexport const Bibliography = Node.create({\r\n    name: 'bibliography',\r\n    group: 'block',\r\n    content: 'block+',\r\n\r\n    parseHTML() {\r\n        return [{ tag: 'section[data-type=\"bibliography\"]' }];\r\n    },\r\n\r\n    renderHTML({ HTMLAttributes }: { HTMLAttributes: any }) {\r\n        return [\r\n            'section',\r\n            mergeAttributes({ 'data-type': 'bibliography', class: 'rk-bibliography' }, HTMLAttributes),\r\n            0,\r\n        ];\r\n    },\r\n\r\n    addCommands() {\r\n        return {\r\n            insertBibliography: () => ({ commands }: { commands: any }) => {\r\n                return commands.insertContent({\r\n                    type: 'bibliography',\r\n                    content: [{ type: 'paragraph', content: [{ type: 'text', text: 'References' }] }],\r\n                });\r\n            },\r\n        } as any;\r\n    },\r\n});\r\n","import { Extension } from '@tiptap/core';\r\nimport { Plugin, PluginKey } from '@tiptap/pm/state';\r\n\r\nexport interface SlashCommand {\r\n    title: string;\r\n    description: string;\r\n    icon: string;\r\n    command: (editor: any) => void;\r\n}\r\n\r\nconst DEFAULT_COMMANDS: SlashCommand[] = [\r\n    {\r\n        title: 'Heading 1',\r\n        description: 'Large section heading',\r\n        icon: 'H1',\r\n        command: (editor: any) => editor.chain().focus().toggleHeading({ level: 1 }).run(),\r\n    },\r\n    {\r\n        title: 'Heading 2',\r\n        description: 'Medium section heading',\r\n        icon: 'H2',\r\n        command: (editor: any) => editor.chain().focus().toggleHeading({ level: 2 }).run(),\r\n    },\r\n    {\r\n        title: 'Heading 3',\r\n        description: 'Small section heading',\r\n        icon: 'H3',\r\n        command: (editor: any) => editor.chain().focus().toggleHeading({ level: 3 }).run(),\r\n    },\r\n    {\r\n        title: 'Bullet List',\r\n        description: 'Create a simple bullet list',\r\n        icon: '•',\r\n        command: (editor: any) => editor.chain().focus().toggleBulletList().run(),\r\n    },\r\n    {\r\n        title: 'Numbered List',\r\n        description: 'Create a numbered list',\r\n        icon: '1.',\r\n        command: (editor: any) => editor.chain().focus().toggleOrderedList().run(),\r\n    },\r\n    {\r\n        title: 'Table',\r\n        description: 'Insert a table (3x3)',\r\n        icon: '⊞',\r\n        command: (editor: any) => editor.chain().focus().insertTable({ rows: 3, cols: 3, withHeaderRow: true }).run(),\r\n    },\r\n    {\r\n        title: 'Code Block',\r\n        description: 'Insert a code block',\r\n        icon: '</>',\r\n        command: (editor: any) => editor.chain().focus().toggleCodeBlock().run(),\r\n    },\r\n    {\r\n        title: 'Blockquote',\r\n        description: 'Insert a quote block',\r\n        icon: '\"',\r\n        command: (editor: any) => editor.chain().focus().toggleBlockquote().run(),\r\n    },\r\n    {\r\n        title: 'Horizontal Rule',\r\n        description: 'Insert a divider line',\r\n        icon: '—',\r\n        command: (editor: any) => editor.chain().focus().setHorizontalRule().run(),\r\n    },\r\n];\r\n\r\nexport const SlashCommands = Extension.create({\r\n    name: 'slashCommands',\r\n\r\n    addOptions() {\r\n        return {\r\n            commands: DEFAULT_COMMANDS,\r\n            onShow: null as ((items: SlashCommand[], query: string) => void) | null,\r\n            onHide: null as (() => void) | null,\r\n        };\r\n    },\r\n\r\n    addStorage() {\r\n        return {\r\n            isOpen: false,\r\n            query: '',\r\n            items: [] as SlashCommand[],\r\n        };\r\n    },\r\n\r\n    addProseMirrorPlugins() {\r\n        const extension = this;\r\n\r\n        return [\r\n            new Plugin({\r\n                key: new PluginKey('slashCommands'),\r\n                props: {\r\n                    handleKeyDown(_view: any, event: KeyboardEvent) {\r\n                        if (event.key === 'Escape' && extension.storage.isOpen) {\r\n                            extension.storage.isOpen = false;\r\n                            extension.options.onHide?.();\r\n                            return true;\r\n                        }\r\n                        return false;\r\n                    },\r\n                },\r\n                view() {\r\n                    return {\r\n                        update(view: any, _prevState: any) {\r\n                            const { state } = view;\r\n                            const { selection } = state;\r\n                            const { $from } = selection;\r\n\r\n                            const textBefore = $from.parent.textBetween(0, $from.parentOffset, null, '\\0');\r\n\r\n                            if (textBefore === '/') {\r\n                                extension.storage.isOpen = true;\r\n                                extension.storage.query = '';\r\n                                extension.storage.items = extension.options.commands;\r\n                                extension.options.onShow?.(extension.options.commands, '');\r\n                            } else if (textBefore.startsWith('/') && /^\\/\\w*$/.test(textBefore)) {\r\n                                const query = textBefore.slice(1).toLowerCase();\r\n                                const items = extension.options.commands.filter(\r\n                                    (cmd: SlashCommand) =>\r\n                                        cmd.title.toLowerCase().includes(query) ||\r\n                                        cmd.description.toLowerCase().includes(query)\r\n                                );\r\n                                extension.storage.query = query;\r\n                                extension.storage.items = items;\r\n                                extension.options.onShow?.(items, query);\r\n                            } else if (extension.storage.isOpen) {\r\n                                extension.storage.isOpen = false;\r\n                                extension.options.onHide?.();\r\n                            }\r\n                        },\r\n                    };\r\n                },\r\n            }),\r\n        ];\r\n    },\r\n\r\n    addCommands() {\r\n        return {\r\n            executeSlashCommand: (commandTitle: string) => ({ editor }: { editor: any }) => {\r\n                const cmd = this.options.commands.find(\r\n                    (c: SlashCommand) => c.title === commandTitle\r\n                );\r\n                if (cmd) {\r\n                    const { selection } = editor.state;\r\n                    const from = selection.$from;\r\n                    const start = from.start();\r\n                    editor.chain().deleteRange({ from: start, to: from.pos }).run();\r\n                    cmd.command(editor);\r\n                    return true;\r\n                }\r\n                return false;\r\n            },\r\n        } as any;\r\n    },\r\n});\r\n\r\nexport { DEFAULT_COMMANDS as defaultSlashCommands };\r\n","import { Extension } from '@tiptap/core';\r\nimport { Plugin, PluginKey } from '@tiptap/pm/state';\r\n\r\n/**\r\n * ImageUpload extension - Enables uploading images from PC via file input\r\n * and drag-and-drop onto the editor area.\r\n * Converts files to base64 data URLs and inserts them as img nodes.\r\n */\r\nexport const ImageUpload = Extension.create({\r\n    name: 'imageUpload',\r\n\r\n    addOptions() {\r\n        return {\r\n            maxFileSizeMB: 10,\r\n            acceptedTypes: ['image/jpeg', 'image/png', 'image/gif', 'image/webp', 'image/svg+xml'],\r\n            onUpload: null as ((file: File) => Promise<string>) | null,\r\n        };\r\n    },\r\n\r\n    addCommands() {\r\n        return {\r\n            uploadImage: (file: File) => ({ editor }: { editor: any }) => {\r\n                if (this.options.onUpload) {\r\n                    this.options.onUpload(file).then((src: string) => {\r\n                        editor.chain().focus().setImage({ src, alt: file.name }).run();\r\n                    });\r\n                } else {\r\n                    const reader = new FileReader();\r\n                    reader.onload = e => {\r\n                        const src = e.target?.result as string;\r\n                        editor.chain().focus().setImage({ src, alt: file.name }).run();\r\n                    };\r\n                    reader.readAsDataURL(file);\r\n                }\r\n                return true;\r\n            },\r\n            openImageUpload: () => () => {\r\n                const input = document.createElement('input');\r\n                input.type = 'file';\r\n                input.accept = 'image/*';\r\n                input.onchange = (e: any) => {\r\n                    const file = e.target.files?.[0];\r\n                    if (file) {\r\n                        // Trigger the uploadImage command\r\n                        (this.editor.commands as any).uploadImage(file);\r\n                    }\r\n                };\r\n                input.click();\r\n                return true;\r\n            },\r\n        } as any;\r\n    },\r\n\r\n    addProseMirrorPlugins() {\r\n        const options = this.options;\r\n        const editor = this.editor;\r\n\r\n        return [\r\n            new Plugin({\r\n                key: new PluginKey('imageUpload'),\r\n                props: {\r\n                    handleDOMEvents: {\r\n                        drop(_view: any, event: DragEvent) {\r\n                            const files = event.dataTransfer?.files;\r\n                            if (!files || files.length === 0) return false;\r\n\r\n                            const imageFiles = Array.from(files).filter(f =>\r\n                                options.acceptedTypes.includes(f.type)\r\n                            );\r\n                            if (imageFiles.length === 0) return false;\r\n\r\n                            event.preventDefault();\r\n                            imageFiles.forEach(file => {\r\n                                if (options.maxFileSizeMB && file.size > options.maxFileSizeMB * 1024 * 1024) {\r\n                                    console.warn(`[rk-editor] Image too large (max ${options.maxFileSizeMB}MB): ${file.name}`);\r\n                                    return;\r\n                                }\r\n                                (editor.commands as any).uploadImage(file);\r\n                            });\r\n                            return true;\r\n                        },\r\n                    },\r\n                    handlePaste: (_view: any, event: ClipboardEvent) => {\r\n                        const items = event.clipboardData?.items;\r\n                        if (!items) return false;\r\n\r\n                        let handled = false;\r\n                        Array.from(items).forEach(item => {\r\n                            if (item.type.startsWith('image/')) {\r\n                                const file = item.getAsFile();\r\n                                if (file) {\r\n                                    if (options.maxFileSizeMB && file.size > options.maxFileSizeMB * 1024 * 1024) {\r\n                                        console.warn(`[rk-editor] Pasted image too large (max ${options.maxFileSizeMB}MB).`);\r\n                                        return;\r\n                                    }\r\n                                    if (options.acceptedTypes && !options.acceptedTypes.includes(file.type)) {\r\n                                        console.warn(`[rk-editor] Unsupported pasted image type: ${file.type}`);\r\n                                        return;\r\n                                    }\r\n\r\n                                    event.preventDefault();\r\n                                    (editor.commands as any).uploadImage(file);\r\n                                    handled = true;\r\n                                }\r\n                            }\r\n                        });\r\n                        return handled;\r\n                    },\r\n                },\r\n            }),\r\n        ];\r\n    },\r\n});\r\n","import { Extension } from '@tiptap/core';\nimport { Plugin, PluginKey } from '@tiptap/pm/state';\n\ninterface StoredFormat {\n    /** Inline marks to clone (bold, italic, color, font, size, …). */\n    marks: { type: string; attrs: Record<string, any> }[];\n    /** The textblock type and attrs (alignment, line height, indent, …) at the cursor. */\n    nodeType: string | null;\n    nodeAttrs: Record<string, any>;\n}\n\n/**\n * Word-style format painter.\n *\n * Click the painter, optionally with text selected, to capture the formatting\n * (both inline marks AND block attributes — alignment, line-height, indent,\n * spacing). Then click anywhere or drag to apply that formatting to the next\n * selection. Press Esc to cancel.\n */\nexport const FormatPainter = Extension.create({\n    name: 'formatPainter',\n\n    addStorage() {\n        return {\n            isActive: false,\n            storedFormat: null as StoredFormat | null,\n        };\n    },\n\n    addCommands() {\n        return {\n            startFormatPaint: () => ({ editor }: { editor: any }) => {\n                const { state } = editor;\n                const { from, to } = state.selection;\n                const $from = state.selection.$from;\n\n                // 1. Capture inline marks across the selection (or at the cursor).\n                const marks: { type: string; attrs: Record<string, any> }[] = [];\n                const seen = new Set<string>();\n                const range = from === to\n                    ? [Math.max(0, from - 1), from]\n                    : [from, to];\n                state.doc.nodesBetween(range[0], range[1], (node: any) => {\n                    if (!node.isText) return;\n                    for (const mark of node.marks) {\n                        if (seen.has(mark.type.name)) continue;\n                        seen.add(mark.type.name);\n                        marks.push({ type: mark.type.name, attrs: { ...mark.attrs } });\n                    }\n                });\n                // Also pick up stored marks at the cursor (e.g. user typed nothing yet but toggled bold)\n                for (const m of state.storedMarks || $from.marks() || []) {\n                    if (!seen.has(m.type.name)) {\n                        seen.add(m.type.name);\n                        marks.push({ type: m.type.name, attrs: { ...m.attrs } });\n                    }\n                }\n\n                // 2. Capture textblock attrs (alignment, lineHeight, indent, marginTop/Bottom).\n                const parent = $from.parent;\n                const nodeType = parent.isTextblock ? parent.type.name : null;\n                const nodeAttrs = parent.isTextblock ? { ...parent.attrs } : {};\n\n                this.storage.storedFormat = { marks, nodeType, nodeAttrs };\n                this.storage.isActive = true;\n                editor.view.dom?.classList.add('rk-format-paint-mode');\n                return true;\n            },\n\n            cancelFormatPaint: () => ({ editor }: { editor: any }) => {\n                this.storage.isActive = false;\n                this.storage.storedFormat = null;\n                editor.view.dom?.classList.remove('rk-format-paint-mode');\n                return true;\n            },\n\n            applyStoredFormat: () => ({ editor, tr, dispatch }: { editor: any; tr: any; dispatch: any }) => {\n                if (!this.storage.isActive || !this.storage.storedFormat) return false;\n                const fmt = this.storage.storedFormat as StoredFormat;\n                const { from, to } = editor.state.selection;\n                if (from === to) return false; // need a selection to paint onto\n\n                // (a) Apply node attrs to the textblocks in the range.\n                if (fmt.nodeType) {\n                    editor.state.doc.nodesBetween(from, to, (node: any, pos: number) => {\n                        if (!node.isTextblock) return;\n                        const targetType = editor.schema.nodes[fmt.nodeType!];\n                        if (!targetType) return;\n                        try {\n                            tr.setNodeMarkup(pos, targetType, { ...node.attrs, ...fmt.nodeAttrs });\n                        } catch { /* node type mismatch — skip */ }\n                    });\n                }\n\n                // (b) Clear existing inline marks, then apply the captured marks.\n                tr.removeMark(from, to);\n                for (const mark of fmt.marks) {\n                    const markType = editor.schema.marks[mark.type];\n                    if (!markType) continue;\n                    try {\n                        tr.addMark(from, to, markType.create(mark.attrs));\n                    } catch { /* skip incompatible marks */ }\n                }\n\n                if (dispatch) dispatch(tr);\n\n                // Single-shot: deactivate after one application.\n                this.storage.isActive = false;\n                this.storage.storedFormat = null;\n                editor.view.dom?.classList.remove('rk-format-paint-mode');\n                return true;\n            },\n        } as any;\n    },\n\n    addKeyboardShortcuts() {\n        return {\n            Escape: () => {\n                if (this.storage.isActive) {\n                    (this.editor.commands as any).cancelFormatPaint();\n                    return true;\n                }\n                return false;\n            },\n        };\n    },\n\n    addProseMirrorPlugins() {\n        const ext = this;\n        return [\n            new Plugin({\n                key: new PluginKey('formatPainterApply'),\n                props: {\n                    handleDOMEvents: {\n                        mouseup(_view, _event) {\n                            if (!ext.storage.isActive) return false;\n                            // Defer so the selection has been updated by the time we apply.\n                            setTimeout(() => {\n                                if (ext.storage.isActive) {\n                                    (ext.editor.commands as any).applyStoredFormat();\n                                }\n                            }, 0);\n                            return false;\n                        },\n                    },\n                },\n            }),\n        ];\n    },\n});\n","import { Extension } from '@tiptap/core';\r\nimport { Plugin, PluginKey } from '@tiptap/pm/state';\r\nimport { Decoration, DecorationSet } from '@tiptap/pm/view';\r\n\r\n/**\r\n * DragHandle extension - Renders a ⠿ drag handle in the left gutter for\r\n * each block-level node. Clicking and dragging reorders blocks.\r\n */\r\nexport const DragHandle = Extension.create({\r\n    name: 'dragHandle',\r\n\r\n    addProseMirrorPlugins() {\r\n        let draggedNode: { from: number; to: number } | null = null;\r\n        let handleEl: HTMLElement | null = null;\r\n        let currentPos: number | null = null;\r\n\r\n        const plugin = new Plugin({\r\n            key: new PluginKey('dragHandle'),\r\n\r\n            view(editorView: any) {\r\n                handleEl = document.createElement('div');\r\n                handleEl.className = 'rk-drag-handle';\r\n                handleEl.innerHTML = '⠿';\r\n                handleEl.contentEditable = 'false';\r\n                handleEl.setAttribute('draggable', 'true');\r\n                handleEl.title = 'Drag to reorder';\r\n                document.body.appendChild(handleEl);\r\n\r\n                const hide = () => {\r\n                    if (handleEl) handleEl.style.display = 'none';\r\n                };\r\n\r\n                const onMouseMove = (e: MouseEvent) => {\r\n                    if (!handleEl) return;\r\n                    const target = e.target as HTMLElement;\r\n\r\n                    // Find the nearest block-level node\r\n                    const pos = editorView.posAtCoords({ left: e.clientX, top: e.clientY });\r\n                    if (!pos) { hide(); return; }\r\n\r\n                    const resolved = editorView.state.doc.resolve(pos.pos);\r\n                    const blockDepth = resolved.depth > 0 ? 1 : 0;\r\n                    const blockNode = resolved.node(blockDepth);\r\n                    if (!blockNode || !blockNode.isBlock) { hide(); return; }\r\n\r\n                    const dom = editorView.nodeDOM(resolved.start(blockDepth));\r\n                    if (!dom || !(dom instanceof Element)) { hide(); return; }\r\n\r\n                    const rect = dom.getBoundingClientRect();\r\n                    const editorRect = editorView.dom.getBoundingClientRect();\r\n\r\n                    handleEl.style.display = 'flex';\r\n                    handleEl.style.top = `${rect.top + window.scrollY}px`;\r\n                    handleEl.style.left = `${editorRect.left + window.scrollX - 25}px`;\r\n\r\n                    // FIXED: Ensure we don't try to get 'before' the top-level document node (depth 0)\r\n                    try {\r\n                        currentPos = blockDepth > 0 ? resolved.before(blockDepth) : 0;\r\n                    } catch (err) {\r\n                        currentPos = 0;\r\n                    }\r\n                };\r\n\r\n                handleEl.addEventListener('dragstart', (e: DragEvent) => {\r\n                    if (currentPos === null) return;\r\n                    const $pos = editorView.state.doc.resolve(currentPos);\r\n                    const node = $pos.nodeAfter;\r\n                    if (!node) return;\r\n                    draggedNode = { from: currentPos, to: currentPos + node.nodeSize };\r\n                    e.dataTransfer?.setData('text/plain', '');\r\n                });\r\n\r\n                handleEl.addEventListener('dragend', () => {\r\n                    draggedNode = null;\r\n                });\r\n\r\n                editorView.dom.addEventListener('mousemove', onMouseMove);\r\n                editorView.dom.parentElement?.addEventListener('mouseleave', hide);\r\n\r\n                return {\r\n                    destroy() {\r\n                        handleEl?.remove();\r\n                        editorView.dom.removeEventListener('mousemove', onMouseMove);\r\n                    },\r\n                };\r\n            },\r\n\r\n            props: {\r\n                handleDrop(view: any, event: DragEvent, _slice: any, moved: boolean) {\r\n                    if (!draggedNode || !moved) return false;\r\n\r\n                    const coords = { left: event.clientX, top: event.clientY };\r\n                    const dropPos = view.posAtCoords(coords);\r\n                    if (!dropPos) return false;\r\n\r\n                    const { from, to } = draggedNode;\r\n                    const targetPos = dropPos.pos;\r\n\r\n                    // Don't drop inside itself\r\n                    if (targetPos >= from && targetPos <= to) return false;\r\n\r\n                    const node = view.state.doc.slice(from, to).content.firstChild;\r\n                    if (!node) return false;\r\n\r\n                    const tr = view.state.tr;\r\n                    // Delete from original position\r\n                    tr.delete(from, to);\r\n                    // Insert at new position (adjusted)\r\n                    const insertAt = targetPos > to ? targetPos - (to - from) : targetPos;\r\n                    tr.insert(insertAt, node);\r\n                    view.dispatch(tr);\r\n                    draggedNode = null;\r\n                    event.preventDefault();\r\n                    return true;\r\n                },\r\n            },\r\n        });\r\n\r\n        return [plugin];\r\n    },\r\n});\r\n","import { Extension } from '@tiptap/core';\r\nimport { Plugin, PluginKey } from '@tiptap/pm/state';\r\n\r\nexport interface ChangeRecord {\r\n    id: string;\r\n    type: 'insert' | 'delete';\r\n    from: number;\r\n    to: number;\r\n    text: string;\r\n    author: string;\r\n    timestamp: number;\r\n}\r\n\r\n/**\r\n * TrackChanges extension - Marks insertions and deletions with visual indicators.\r\n * Tracks every transaction when enabled and stores change records.\r\n * Supports accept/reject operations per change.\r\n */\r\nexport const TrackChanges = Extension.create({\r\n    name: 'trackChanges',\r\n\r\n    addOptions() {\r\n        return {\r\n            enabled: false,\r\n            author: 'Author',\r\n            onChangesUpdate: null as ((changes: ChangeRecord[]) => void) | null,\r\n        };\r\n    },\r\n\r\n    addStorage() {\r\n        return {\r\n            enabled: false,\r\n            changes: [] as ChangeRecord[],\r\n            author: 'Author',\r\n        };\r\n    },\r\n\r\n    onCreate() {\r\n        this.storage.enabled = this.options.enabled;\r\n        this.storage.author = this.options.author;\r\n    },\r\n\r\n    addCommands() {\r\n        return {\r\n            toggleTrackChanges: () => () => {\r\n                this.storage.enabled = !this.storage.enabled;\r\n                return true;\r\n            },\r\n\r\n            enableTrackChanges: () => () => {\r\n                this.storage.enabled = true;\r\n                return true;\r\n            },\r\n\r\n            disableTrackChanges: () => () => {\r\n                this.storage.enabled = false;\r\n                return true;\r\n            },\r\n\r\n            acceptChange: (changeId: string) => ({ tr, dispatch }: { tr: any; dispatch: any }) => {\r\n                const change = this.storage.changes.find((c: ChangeRecord) => c.id === changeId);\r\n                if (!change || !dispatch) return false;\r\n\r\n                if (change.type === 'delete') {\r\n                    // Accept delete: actually remove the text (remove the mark only, text stays deleted)\r\n                    tr.removeMark(change.from, change.to, this.editor.schema.marks.trackDelete as any);\r\n                    // Remove tracked text from doc\r\n                    tr.delete(change.from, change.to);\r\n                } else {\r\n                    // Accept insert: remove the insert mark, keep text\r\n                    tr.removeMark(change.from, change.to, this.editor.schema.marks.trackInsert as any);\r\n                }\r\n\r\n                this.storage.changes = this.storage.changes.filter((c: ChangeRecord) => c.id !== changeId);\r\n                this.options.onChangesUpdate?.(this.storage.changes);\r\n                dispatch(tr);\r\n                return true;\r\n            },\r\n\r\n            rejectChange: (changeId: string) => ({ tr, dispatch }: { tr: any; dispatch: any }) => {\r\n                const change = this.storage.changes.find((c: ChangeRecord) => c.id === changeId);\r\n                if (!change || !dispatch) return false;\r\n\r\n                if (change.type === 'insert') {\r\n                    // Reject insert: remove the inserted text\r\n                    tr.delete(change.from, change.to);\r\n                } else {\r\n                    // Reject delete: remove the delete mark (restore visual, text already there)\r\n                    tr.removeMark(change.from, change.to, this.editor.schema.marks.trackDelete as any);\r\n                }\r\n\r\n                this.storage.changes = this.storage.changes.filter((c: ChangeRecord) => c.id !== changeId);\r\n                this.options.onChangesUpdate?.(this.storage.changes);\r\n                dispatch(tr);\r\n                return true;\r\n            },\r\n\r\n            acceptAllChanges: () => ({ editor }: { editor: any }) => {\r\n                const changes = [...this.storage.changes];\r\n                changes.forEach((c: ChangeRecord) => {\r\n                    (editor.commands as any).acceptChange(c.id);\r\n                });\r\n                return true;\r\n            },\r\n\r\n            rejectAllChanges: () => ({ editor }: { editor: any }) => {\r\n                const changes = [...this.storage.changes];\r\n                changes.forEach((c: ChangeRecord) => {\r\n                    (editor.commands as any).rejectChange(c.id);\r\n                });\r\n                return true;\r\n            },\r\n\r\n            getChanges: () => () => {\r\n                return this.storage.changes;\r\n            },\r\n        } as any;\r\n    },\r\n\r\n    addProseMirrorPlugins() {\r\n        const ext = this;\r\n\r\n        return [\r\n            new Plugin({\r\n                key: new PluginKey('trackChanges'),\r\n                appendTransaction(transactions: readonly any[], oldState: any, newState: any) {\r\n                    if (!ext.storage.enabled) return null;\r\n                    if (!transactions.some((tr) => tr.docChanged)) return null;\r\n\r\n                    // Prevent infinite loops if we are just adding marks\r\n                    if (transactions.some((tr) => tr.getMeta('trackChangesMarking'))) return null;\r\n\r\n                    const tr = newState.tr;\r\n                    tr.setMeta('trackChangesMarking', true);\r\n                    let changed = false;\r\n\r\n                    const trackInsertType = ext.editor.schema.marks.trackInsert;\r\n                    const trackDeleteType = ext.editor.schema.marks.trackDelete;\r\n\r\n                    transactions.forEach((origTr) => {\r\n                        if (!origTr.docChanged) return;\r\n\r\n                        origTr.steps.forEach((step: any, _index: number) => {\r\n                            // Basic heuristic for ReplaceStep (insert/delete)\r\n                            if (step.slice) {\r\n                                // Maps positions from old step to current tr state\r\n                                const map = tr.mapping;\r\n                                const from = map.map(step.from, -1);\r\n\r\n                                // It's an insertion if there is content in the slice\r\n                                if (step.slice.content.size > 0 && trackInsertType) {\r\n                                    const to = map.map(step.from + step.slice.content.size);\r\n                                    tr.addMark(from, to, trackInsertType.create());\r\n\r\n                                    const changeId = Math.random().toString(36).substr(2, 9);\r\n                                    ext.storage.changes.push({\r\n                                        id: changeId,\r\n                                        type: 'insert',\r\n                                        from,\r\n                                        to,\r\n                                        text: step.slice.content.textBetween(0, step.slice.content.size, '\\n'),\r\n                                        author: ext.storage.author,\r\n                                        timestamp: Date.now(),\r\n                                    });\r\n                                    changed = true;\r\n                                }\r\n\r\n                                // It's a deletion if it removes content (step.from < step.to in old state)\r\n                                // Standard ProseMirror deletion removes the node. To *track* it, we ideally \r\n                                // intercept the transaction *before* it gets applied or we restore the deleted \r\n                                // content and mark it. Restoring content is complex in appendTransaction.\r\n                                // For a robust implementation, a custom editing plugin is needed.\r\n                                // Here we do a simplified version: if we detect a deletion we just \r\n                                // acknowledge it happened, but full text restoration requires intercepting keydown/commands.\r\n                                if (step.to > step.from && trackDeleteType) {\r\n                                    // Note: To truly show struck-through deleted text without losing it, \r\n                                    // the editor commands (delete/backspace) must be overridden to apply the \r\n                                    // trackDelete mark INSTEAD of actually deleting the nodes.\r\n                                    // For now, we simulate by logging the deletion but we can't easily mark it \r\n                                    // here since the text is already gone from newState.\r\n                                }\r\n                            }\r\n                        });\r\n                    });\r\n\r\n                    if (changed) {\r\n                        ext.options.onChangesUpdate?.(ext.storage.changes);\r\n                        return tr;\r\n                    }\r\n                    return null;\r\n                },\r\n                props: {\r\n                    decorations(state: any) {\r\n                        return null;\r\n                    },\r\n                },\r\n            }),\r\n        ];\r\n    },\r\n});\r\n\r\n/**\r\n * TrackInsert mark - Visually highlights inserted text.\r\n */\r\nexport const TrackInsert = Extension.create({\r\n    name: 'trackInsert',\r\n    priority: 1001,\r\n\r\n    addOptions() {\r\n        return {\r\n            HTMLAttributes: {},\r\n        };\r\n    },\r\n\r\n    parseHTML() {\r\n        return [{ tag: 'span[data-track-insert]' }];\r\n    },\r\n\r\n    renderHTML({ HTMLAttributes }: { HTMLAttributes: any }) {\r\n        return ['span', { 'data-track-insert': '', class: 'rk-track-insert', ...HTMLAttributes }, 0];\r\n    },\r\n});\r\n\r\n/**\r\n * TrackDelete mark - Visually highlights deleted text.\r\n */\r\nexport const TrackDelete = Extension.create({\r\n    name: 'trackDelete',\r\n    priority: 1001,\r\n\r\n    addOptions() {\r\n        return {\r\n            HTMLAttributes: {},\r\n        };\r\n    },\r\n\r\n    parseHTML() {\r\n        return [{ tag: 'span[data-track-delete]' }];\r\n    },\r\n\r\n    renderHTML({ HTMLAttributes }: { HTMLAttributes: any }) {\r\n        return ['span', { 'data-track-delete': '', class: 'rk-track-delete', ...HTMLAttributes }, 0];\r\n    },\r\n});\r\n","import { Mark, mergeAttributes } from '@tiptap/core';\r\n\r\nexport const LeaderMark = Mark.create({\r\n    name: 'leader',\r\n\r\n    addAttributes() {\r\n        return {\r\n            class: {\r\n                default: 'rk-toc-leader',\r\n            },\r\n        };\r\n    },\r\n\r\n    parseHTML() {\r\n        return [\r\n            {\r\n                tag: 'span.rk-toc-leader',\r\n            },\r\n        ];\r\n    },\r\n\r\n    renderHTML({ HTMLAttributes }) {\r\n        return ['span', mergeAttributes(this.options.HTMLAttributes, HTMLAttributes), 0];\r\n    },\r\n});\r\n","import { Extension } from '@tiptap/core';\nimport { Plugin, PluginKey } from '@tiptap/pm/state';\nimport { Decoration, DecorationSet } from '@tiptap/pm/view';\n\nexport interface FindReplaceStorage {\n  query: string;\n  results: { from: number; to: number }[];\n  current: number;\n  caseSensitive: boolean;\n  regex: boolean;\n}\n\ninterface FindOptions {\n  caseSensitive?: boolean;\n  regex?: boolean;\n  wholeWord?: boolean;\n}\n\ndeclare module '@tiptap/core' {\n  interface Commands<ReturnType> {\n    findReplace: {\n      findText: (query: string, options?: FindOptions) => ReturnType;\n      replaceText: (query: string, replacement: string, options?: FindOptions) => ReturnType;\n      replaceAllText: (query: string, replacement: string, options?: FindOptions) => ReturnType;\n      goToNextMatch: () => ReturnType;\n      goToPreviousMatch: () => ReturnType;\n      clearSearch: () => ReturnType;\n    };\n  }\n}\n\nconst KEY = new PluginKey<DecorationSet>('rkFindReplace');\n\nfunction buildRegex(query: string, opts: FindOptions): RegExp | null {\n  if (!query) return null;\n  let pattern = opts.regex ? query : query.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n  if (opts.wholeWord && !opts.regex) pattern = `\\\\b${pattern}\\\\b`;\n  const flags = `g${opts.caseSensitive ? '' : 'i'}`;\n  try {\n    return new RegExp(pattern, flags);\n  } catch {\n    return null;\n  }\n}\n\nfunction findMatches(doc: any, query: string, opts: FindOptions): { from: number; to: number }[] {\n  const results: { from: number; to: number }[] = [];\n  const regex = buildRegex(query, opts);\n  if (!regex) return results;\n\n  doc.descendants((node: any, pos: number) => {\n    if (!node.isText) return;\n    const text = node.text as string;\n    let match: RegExpExecArray | null;\n    regex.lastIndex = 0;\n    while ((match = regex.exec(text)) !== null) {\n      if (match[0].length === 0) { regex.lastIndex++; continue; }\n      results.push({ from: pos + match.index, to: pos + match.index + match[0].length });\n    }\n  });\n  return results;\n}\n\nfunction decorationsFor(results: { from: number; to: number }[], current: number): DecorationSet {\n  const decos = results.map((r, i) =>\n    Decoration.inline(r.from, r.to, {\n      class: i === current ? 'rk-find-match rk-find-match-current' : 'rk-find-match',\n    })\n  );\n  return DecorationSet.create({ size: 0 } as any, decos);\n}\n\nexport const FindReplace = Extension.create<unknown, FindReplaceStorage>({\n  name: 'findReplace',\n\n  addStorage() {\n    return {\n      query: '',\n      results: [],\n      current: -1,\n      caseSensitive: false,\n      regex: false,\n    };\n  },\n\n  addCommands() {\n    return {\n      findText:\n        (query: string, options: FindOptions = {}) =>\n        ({ editor, dispatch }: { editor: any; dispatch?: any }) => {\n          this.storage.query = query;\n          this.storage.caseSensitive = !!options.caseSensitive;\n          this.storage.regex = !!options.regex;\n          const results = query ? findMatches(editor.state.doc, query, options) : [];\n          this.storage.results = results;\n          this.storage.current = results.length ? 0 : -1;\n          if (dispatch) editor.view.dispatch(editor.state.tr.setMeta(KEY, true));\n          return results.length;\n        },\n\n      goToNextMatch:\n        () =>\n        ({ editor }: { editor: any }) => {\n          if (!this.storage.results.length) return false;\n          this.storage.current = (this.storage.current + 1) % this.storage.results.length;\n          const r = this.storage.results[this.storage.current];\n          editor.commands.setTextSelection({ from: r.from, to: r.to });\n          editor.commands.scrollIntoView();\n          editor.view.dispatch(editor.state.tr.setMeta(KEY, true));\n          return true;\n        },\n\n      goToPreviousMatch:\n        () =>\n        ({ editor }: { editor: any }) => {\n          if (!this.storage.results.length) return false;\n          this.storage.current =\n            (this.storage.current - 1 + this.storage.results.length) % this.storage.results.length;\n          const r = this.storage.results[this.storage.current];\n          editor.commands.setTextSelection({ from: r.from, to: r.to });\n          editor.commands.scrollIntoView();\n          editor.view.dispatch(editor.state.tr.setMeta(KEY, true));\n          return true;\n        },\n\n      replaceText:\n        (query: string, replacement: string, options: FindOptions = {}) =>\n        ({ editor }: { editor: any }) => {\n          if (!query) return 0;\n          const results = findMatches(editor.state.doc, query, options);\n          if (!results.length) return 0;\n          const target = results[this.storage.current >= 0 ? this.storage.current : 0];\n          editor\n            .chain()\n            .focus()\n            .insertContentAt({ from: target.from, to: target.to }, replacement)\n            .run();\n          (editor.commands as any).findText(query, options);\n          return 1;\n        },\n\n      replaceAllText:\n        (query: string, replacement: string, options: FindOptions = {}) =>\n        ({ editor }: { editor: any }) => {\n          if (!query) return 0;\n          const results = findMatches(editor.state.doc, query, options);\n          if (!results.length) return 0;\n          const tr = editor.state.tr;\n          for (let i = results.length - 1; i >= 0; i--) {\n            tr.insertText(replacement, results[i].from, results[i].to);\n          }\n          editor.view.dispatch(tr);\n          (editor.commands as any).findText(query, options);\n          return results.length;\n        },\n\n      clearSearch:\n        () =>\n        ({ editor }: { editor: any }) => {\n          this.storage.query = '';\n          this.storage.results = [];\n          this.storage.current = -1;\n          editor.view.dispatch(editor.state.tr.setMeta(KEY, true));\n          return true;\n        },\n    } as any;\n  },\n\n  addProseMirrorPlugins() {\n    const ext = this;\n    return [\n      new Plugin<DecorationSet>({\n        key: KEY,\n        state: {\n          init: () => DecorationSet.empty,\n          apply(tr, oldSet) {\n            if (tr.getMeta(KEY) || tr.docChanged) {\n              if (ext.storage.query && tr.docChanged) {\n                ext.storage.results = findMatches(tr.doc, ext.storage.query, {\n                  caseSensitive: ext.storage.caseSensitive,\n                  regex: ext.storage.regex,\n                });\n                if (ext.storage.current >= ext.storage.results.length) {\n                  ext.storage.current = ext.storage.results.length - 1;\n                }\n              }\n              return decorationsFor(ext.storage.results, ext.storage.current);\n            }\n            return oldSet.map(tr.mapping, tr.doc);\n          },\n        },\n        props: {\n          decorations(state: any) {\n            return this.getState(state);\n          },\n        },\n      }),\n    ];\n  },\n});\n","import { Extension } from '@tiptap/core';\n\n/**\n * Word-style keyboard shortcuts that StarterKit doesn't ship by default.\n *\n * - `Ctrl/⌘+1..6` → Headings 1–6\n * - `Ctrl/⌘+0` (zero) → paragraph (normal)\n * - `Ctrl/⌘+Alt+1..6` → also headings (Word's actual binding)\n * - `Ctrl/⌘+Shift+L` → toggle bullet list\n * - `Ctrl/⌘+Shift+O` → toggle ordered list\n * - `Ctrl/⌘+L / E / R / J` → align left / center / right / justify\n * - `Ctrl/⌘+Enter` → page break\n * - `Ctrl/⌘+Shift+X` → strikethrough\n * - `Ctrl/⌘+.` / `Ctrl/⌘+,` → super- / subscript\n * - `Ctrl/⌘+Shift+H` → highlight (toggle yellow on selection)\n *\n * These mirror Microsoft Word and Google Docs defaults.\n */\nexport const WordShortcuts = Extension.create({\n    name: 'wordShortcuts',\n\n    addKeyboardShortcuts() {\n        const heading = (level: number) => () => this.editor.chain().focus().toggleHeading({ level: level as any }).run();\n        return {\n            // Headings (Word: Ctrl+Alt+N. Google Docs / common: Ctrl+N too — both work)\n            'Mod-Alt-1': heading(1),\n            'Mod-Alt-2': heading(2),\n            'Mod-Alt-3': heading(3),\n            'Mod-Alt-4': heading(4),\n            'Mod-Alt-5': heading(5),\n            'Mod-Alt-6': heading(6),\n            'Mod-1': heading(1),\n            'Mod-2': heading(2),\n            'Mod-3': heading(3),\n            'Mod-4': heading(4),\n            'Mod-5': heading(5),\n            'Mod-6': heading(6),\n            'Mod-0': () => this.editor.chain().focus().setParagraph().run(),\n\n            // Lists\n            'Mod-Shift-l': () => this.editor.chain().focus().toggleBulletList().run(),\n            'Mod-Shift-o': () => this.editor.chain().focus().toggleOrderedList().run(),\n            'Mod-Shift-9': () => this.editor.chain().focus().toggleBulletList().run(),\n            'Mod-Shift-7': () => this.editor.chain().focus().toggleOrderedList().run(),\n\n            // Alignment\n            'Mod-l': () => this.editor.chain().focus().setTextAlign('left').run(),\n            'Mod-e': () => this.editor.chain().focus().setTextAlign('center').run(),\n            'Mod-r': () => this.editor.chain().focus().setTextAlign('right').run(),\n            'Mod-j': () => this.editor.chain().focus().setTextAlign('justify').run(),\n\n            // Marks\n            'Mod-Shift-x': () => this.editor.chain().focus().toggleStrike().run(),\n            'Mod-,': () => this.editor.chain().focus().toggleSubscript().run(),\n            'Mod-.': () => this.editor.chain().focus().toggleSuperscript().run(),\n            'Mod-Shift-h': () => this.editor.chain().focus().toggleHighlight({ color: '#FFFF00' }).run(),\n\n            // Page break (Word: Ctrl+Enter inserts page break)\n            'Mod-Enter': () => (this.editor.commands as any).setPageBreak(),\n\n            // Insert link via command — UI shell can intercept Ctrl+K to open dialog instead.\n            // We don't bind it here so the UI's Ctrl+K dialog isn't pre-empted.\n        };\n    },\n});\n","import { Node, mergeAttributes } from '@tiptap/core';\n\ndeclare module '@tiptap/core' {\n    interface Commands<ReturnType> {\n        textBox: {\n            /** Insert a free-floating text box at the cursor. */\n            insertTextBox: (attrs?: { width?: number; height?: number; backgroundColor?: string; borderColor?: string }) => ReturnType;\n        };\n    }\n}\n\n/**\n * TextBox — a Word-style floating text frame that can be dragged and resized.\n * Renders as a `<div>` block with rich content inside (paragraphs, lists, etc.).\n *\n * Behaviour:\n *   - Inserts at the current selection.\n *   - Drag the `⠿` handle on the top-left to move it on the page.\n *   - Eight corner / edge handles let you resize while keeping content reflowing inside.\n *   - The position is persisted via `data-x` / `data-y` attributes.\n *\n * Useful for callouts, sidebars, pull quotes, diagrams.\n */\nexport const TextBox = Node.create({\n    name: 'textBox',\n    group: 'block',\n    content: 'block+',\n    defining: true,\n    isolating: true,\n    draggable: true,\n\n    addAttributes() {\n        return {\n            width: {\n                default: 320,\n                parseHTML: (el: HTMLElement) => parseInt(el.getAttribute('data-width') || '0', 10) || 320,\n                renderHTML: (attrs: any) => ({ 'data-width': String(attrs.width) }),\n            },\n            height: {\n                default: 160,\n                parseHTML: (el: HTMLElement) => parseInt(el.getAttribute('data-height') || '0', 10) || 160,\n                renderHTML: (attrs: any) => ({ 'data-height': String(attrs.height) }),\n            },\n            x: {\n                default: 0,\n                parseHTML: (el: HTMLElement) => parseInt(el.getAttribute('data-x') || '0', 10),\n                renderHTML: (attrs: any) => ({ 'data-x': String(attrs.x || 0) }),\n            },\n            y: {\n                default: 0,\n                parseHTML: (el: HTMLElement) => parseInt(el.getAttribute('data-y') || '0', 10),\n                renderHTML: (attrs: any) => ({ 'data-y': String(attrs.y || 0) }),\n            },\n            backgroundColor: {\n                default: null,\n                parseHTML: (el: HTMLElement) => el.style.backgroundColor || null,\n                renderHTML: (attrs: any) => attrs.backgroundColor ? { style: `background-color: ${attrs.backgroundColor}` } : {},\n            },\n            borderColor: {\n                default: '#cbd5e1',\n                parseHTML: (el: HTMLElement) => el.style.borderColor || '#cbd5e1',\n                renderHTML: (attrs: any) => ({}),\n            },\n        };\n    },\n\n    parseHTML() {\n        return [{ tag: 'div[data-type=\"text-box\"]' }];\n    },\n\n    renderHTML({ HTMLAttributes, node }) {\n        const w = node.attrs.width || 320;\n        const h = node.attrs.height || 160;\n        const x = node.attrs.x || 0;\n        const y = node.attrs.y || 0;\n        const style = `width:${w}px;min-height:${h}px;transform:translate(${x}px,${y}px);` + (node.attrs.backgroundColor ? `background:${node.attrs.backgroundColor};` : '') + `border:1px solid ${node.attrs.borderColor || '#cbd5e1'};`;\n        return ['div', mergeAttributes(HTMLAttributes, { 'data-type': 'text-box', class: 'rk-textbox', style }), 0];\n    },\n\n    addCommands() {\n        return {\n            insertTextBox: (attrs: any = {}) => ({ commands }: { commands: any }) => {\n                return commands.insertContent({\n                    type: this.name,\n                    attrs: {\n                        width: attrs.width || 320,\n                        height: attrs.height || 160,\n                        x: 0,\n                        y: 0,\n                        backgroundColor: attrs.backgroundColor || null,\n                        borderColor: attrs.borderColor || '#cbd5e1',\n                    },\n                    content: [{ type: 'paragraph', content: [{ type: 'text', text: 'Text box' }] }],\n                });\n            },\n        };\n    },\n\n    addNodeView() {\n        return ({ node, editor, getPos }) => {\n            const dom = document.createElement('div');\n            dom.className = 'rk-textbox';\n            dom.dataset.type = 'text-box';\n            dom.contentEditable = 'true';\n\n            const applyTransform = () => {\n                const w = node.attrs.width || 320;\n                const h = node.attrs.height || 160;\n                const x = node.attrs.x || 0;\n                const y = node.attrs.y || 0;\n                dom.style.width = `${w}px`;\n                dom.style.minHeight = `${h}px`;\n                dom.style.transform = `translate(${x}px, ${y}px)`;\n                if (node.attrs.backgroundColor) dom.style.background = node.attrs.backgroundColor;\n                else dom.style.background = '';\n                dom.style.border = `1px solid ${node.attrs.borderColor || '#cbd5e1'}`;\n            };\n            applyTransform();\n\n            // Drag handle (top-left)\n            const dragHandle = document.createElement('div');\n            dragHandle.className = 'rk-textbox-drag';\n            dragHandle.contentEditable = 'false';\n            dragHandle.title = 'Drag to move';\n            dragHandle.innerHTML = '⠿';\n            dom.appendChild(dragHandle);\n\n            // Resize handles (corners + sides)\n            const handlePositions: ('nw' | 'n' | 'ne' | 'e' | 'se' | 's' | 'sw' | 'w')[] =\n                ['nw', 'n', 'ne', 'e', 'se', 's', 'sw', 'w'];\n            const handles: HTMLElement[] = [];\n            for (const pos of handlePositions) {\n                const h = document.createElement('div');\n                h.className = `rk-textbox-handle rk-textbox-handle-${pos}`;\n                h.contentEditable = 'false';\n                dom.appendChild(h);\n                handles.push(h);\n\n                let startX = 0, startY = 0, startW = 0, startH = 0, startNX = 0, startNY = 0;\n                h.addEventListener('mousedown', (e) => {\n                    e.preventDefault();\n                    e.stopPropagation();\n                    startX = e.clientX;\n                    startY = e.clientY;\n                    startW = node.attrs.width || dom.offsetWidth;\n                    startH = node.attrs.height || dom.offsetHeight;\n                    startNX = node.attrs.x || 0;\n                    startNY = node.attrs.y || 0;\n                    dom.classList.add('is-resizing');\n                    const onMove = (m: MouseEvent) => {\n                        const dx = m.clientX - startX;\n                        const dy = m.clientY - startY;\n                        let w = startW, h2 = startH, nx = startNX, ny = startNY;\n                        if (pos.includes('e')) w = Math.max(80, startW + dx);\n                        if (pos.includes('w')) { w = Math.max(80, startW - dx); nx = startNX + dx; }\n                        if (pos.includes('s')) h2 = Math.max(60, startH + dy);\n                        if (pos.includes('n')) { h2 = Math.max(60, startH - dy); ny = startNY + dy; }\n                        dom.style.width = `${w}px`;\n                        dom.style.minHeight = `${h2}px`;\n                        dom.style.transform = `translate(${nx}px, ${ny}px)`;\n                    };\n                    const onUp = () => {\n                        dom.classList.remove('is-resizing');\n                        document.removeEventListener('mousemove', onMove);\n                        document.removeEventListener('mouseup', onUp);\n                        const pos2 = (getPos as any)?.();\n                        if (typeof pos2 !== 'number') return;\n                        const w = parseInt(dom.style.width, 10) || node.attrs.width;\n                        const h2 = parseInt(dom.style.minHeight, 10) || node.attrs.height;\n                        const m = dom.style.transform.match(/translate\\(([-\\d.]+)px,\\s*([-\\d.]+)px\\)/);\n                        const nx = m ? parseInt(m[1], 10) : node.attrs.x;\n                        const ny = m ? parseInt(m[2], 10) : node.attrs.y;\n                        const tr = editor.state.tr.setNodeMarkup(pos2, undefined, {\n                            ...node.attrs, width: w, height: h2, x: nx, y: ny,\n                        });\n                        editor.view.dispatch(tr);\n                    };\n                    document.addEventListener('mousemove', onMove);\n                    document.addEventListener('mouseup', onUp);\n                });\n            }\n\n            // Drag handle to move\n            let dragging = false;\n            let dStartX = 0, dStartY = 0, dStartNX = 0, dStartNY = 0;\n            dragHandle.addEventListener('mousedown', (e) => {\n                e.preventDefault();\n                e.stopPropagation();\n                dragging = true;\n                dStartX = e.clientX;\n                dStartY = e.clientY;\n                dStartNX = node.attrs.x || 0;\n                dStartNY = node.attrs.y || 0;\n                dom.classList.add('is-dragging');\n                const onMove = (m: MouseEvent) => {\n                    if (!dragging) return;\n                    const nx = dStartNX + (m.clientX - dStartX);\n                    const ny = dStartNY + (m.clientY - dStartY);\n                    dom.style.transform = `translate(${nx}px, ${ny}px)`;\n                };\n                const onUp = () => {\n                    if (!dragging) return;\n                    dragging = false;\n                    dom.classList.remove('is-dragging');\n                    document.removeEventListener('mousemove', onMove);\n                    document.removeEventListener('mouseup', onUp);\n                    const pos2 = (getPos as any)?.();\n                    if (typeof pos2 !== 'number') return;\n                    const m = dom.style.transform.match(/translate\\(([-\\d.]+)px,\\s*([-\\d.]+)px\\)/);\n                    if (!m) return;\n                    const nx = parseInt(m[1], 10);\n                    const ny = parseInt(m[2], 10);\n                    const tr = editor.state.tr.setNodeMarkup(pos2, undefined, { ...node.attrs, x: nx, y: ny });\n                    editor.view.dispatch(tr);\n                };\n                document.addEventListener('mousemove', onMove);\n                document.addEventListener('mouseup', onUp);\n            });\n\n            // Content goes inside this element.\n            const contentDOM = document.createElement('div');\n            contentDOM.className = 'rk-textbox-content';\n            dom.appendChild(contentDOM);\n\n            return {\n                dom,\n                contentDOM,\n                update(updated) {\n                    if (updated.type.name !== 'textBox') return false;\n                    Object.assign(node, updated);\n                    applyTransform();\n                    return true;\n                },\n                stopEvent(event) {\n                    const t = event.target as HTMLElement | null;\n                    if (!t) return false;\n                    return t.classList.contains('rk-textbox-drag') || t.classList.contains('rk-textbox-handle');\n                },\n            };\n        };\n    },\n});\n","import { Extension } from '@tiptap/core';\nimport { Plugin, PluginKey } from '@tiptap/pm/state';\nimport { Decoration, DecorationSet } from '@tiptap/pm/view';\n\nexport interface PaginationOptions {\n    /** Enable visual page boundaries (defaults to true). */\n    enabled: boolean;\n    /** Inside-page area in pixels — calculated from page layout when not given. */\n    contentHeightPx: number | null;\n    /** CSS pixel offset between consecutive page sheets (defaults to 32px). */\n    gap: number;\n}\n\nconst KEY = new PluginKey<DecorationSet>('rkPagination');\n\n/**\n * Visually splits the editor surface into pages by measuring rendered block\n * heights and inserting \"page boundary\" widget decorations at each multiple of\n * the configured page height. Decorations are display-only — they don't change\n * the document model, so cursor positions, selections, undo/redo and exports\n * all behave identically. Hard `<div data-type=\"page-break\">` page breaks\n * inserted by the user reset the running height so the next boundary aligns\n * with the user's intended break.\n */\nexport const Pagination = Extension.create<PaginationOptions>({\n    name: 'pagination',\n\n    addOptions() {\n        return {\n            enabled: true,\n            contentHeightPx: null,\n            gap: 24,\n        };\n    },\n\n    addStorage() {\n        return {\n            // Set by the host (WordEditor) whenever the page layout changes.\n            contentHeightPx: 0,\n            // Updated by computePageBoundaries on every recompute.\n            pageCount: 1,\n            measuredHeight: 0,\n        };\n    },\n\n    addProseMirrorPlugins() {\n        const ext = this;\n        return [\n            new Plugin<DecorationSet>({\n                key: KEY,\n                state: {\n                    init: () => DecorationSet.empty,\n                    apply(tr, oldSet) {\n                        // Recompute ONLY when explicitly requested via meta (the\n                        // view triggers this via rAF + throttle). Mapping\n                        // through `tr.mapping` keeps existing decorations\n                        // anchored across edits in the meantime.\n                        if (tr.getMeta(KEY)) return computePageBoundaries(ext);\n                        return oldSet.map(tr.mapping, tr.doc);\n                    },\n                },\n                view(view) {\n                    // Throttled, rAF-debounced recompute that ignores layout\n                    // shifts caused by our own decoration changes — that loop\n                    // was the source of the flicker.\n                    let rafId: number | null = null;\n                    let lastRun = 0;\n                    let lastWidth = view.dom.clientWidth;\n                    const MIN_INTERVAL = 200;\n\n                    const recompute = (force = false) => {\n                        if (rafId) cancelAnimationFrame(rafId);\n                        rafId = requestAnimationFrame(() => {\n                            rafId = null;\n                            const now = performance.now();\n                            if (!force && now - lastRun < MIN_INTERVAL) {\n                                // Re-schedule once the cooldown elapses.\n                                setTimeout(() => recompute(true), MIN_INTERVAL - (now - lastRun));\n                                return;\n                            }\n                            lastRun = now;\n                            try { view.dispatch(view.state.tr.setMeta(KEY, true)); } catch { /* destroyed */ }\n                        });\n                    };\n\n                    // First paint.\n                    if (typeof requestAnimationFrame === 'function') requestAnimationFrame(() => recompute(true));\n\n                    // Only react to ResizeObserver when WIDTH actually changes\n                    // (height changes from our own spacers should never trigger us).\n                    let obs: ResizeObserver | null = null;\n                    if (typeof ResizeObserver !== 'undefined') {\n                        obs = new ResizeObserver((entries) => {\n                            const next = view.dom.clientWidth;\n                            if (Math.abs(next - lastWidth) < 1) return;\n                            lastWidth = next;\n                            recompute();\n                        });\n                        obs.observe(view.dom);\n                    }\n\n                    const onWindowResize = () => recompute();\n                    if (typeof window !== 'undefined') {\n                        window.addEventListener('resize', onWindowResize);\n                    }\n\n                    return {\n                        update: (newView, oldState) => {\n                            // Only recompute on actual document changes (not on\n                            // selection-only or decoration-only transactions).\n                            if (!newView.state.doc.eq(oldState.doc)) recompute();\n                        },\n                        destroy: () => {\n                            if (rafId) cancelAnimationFrame(rafId);\n                            obs?.disconnect();\n                            if (typeof window !== 'undefined') {\n                                window.removeEventListener('resize', onWindowResize);\n                            }\n                        },\n                    };\n                },\n                props: {\n                    decorations(state) {\n                        return this.getState(state);\n                    },\n                },\n            }),\n        ];\n    },\n});\n\nfunction computePageBoundaries(ext: any): DecorationSet {\n    if (!ext.options.enabled) return DecorationSet.empty;\n    const editor = ext.editor;\n    if (!editor || !editor.view) return DecorationSet.empty;\n\n    const pageHeight: number =\n        ext.storage.contentHeightPx ||\n        ext.options.contentHeightPx ||\n        defaultA4ContentPx();\n    if (pageHeight <= 100) return DecorationSet.empty;\n\n    const view = editor.view;\n    const proseMirror = view.dom as HTMLElement;\n    if (!proseMirror) return DecorationSet.empty;\n\n    const decos: Decoration[] = [];\n    let pageIndex = 1;\n    // Y coordinate (relative to proseMirror, top-of-padding) where the current\n    // page's USABLE area starts. Initially it's the top padding (page margin).\n    const padTop = parseFloat(getComputedStyle(proseMirror).paddingTop || '0') || 0;\n    let pageStartY = padTop;\n\n    const containerRect = proseMirror.getBoundingClientRect();\n    let totalContentHeight = 0;\n\n    editor.state.doc.forEach((node: any, offset: number) => {\n        const dom = view.nodeDOM(offset) as HTMLElement | null;\n        if (!dom || !(dom instanceof HTMLElement)) return;\n\n        const rect = dom.getBoundingClientRect();\n        const top = rect.top - containerRect.top;\n        const bottom = top + rect.height;\n        totalContentHeight = Math.max(totalContentHeight, bottom);\n\n        // Hard page-break node: push the NEXT block to the top of the next page.\n        if (node.type.name === 'pageBreak') {\n            const pageEnd = pageStartY + pageHeight;\n            const remaining = Math.max(0, pageEnd - top);\n            // Spacer fills the rest of the current page; next block lands at top of next page.\n            decos.push(makeSpacer(offset + node.nodeSize, remaining, true));\n            pageStartY = pageEnd;\n            pageIndex += 1;\n            return;\n        }\n\n        // Auto page break: this block would cross the boundary — push it whole\n        // to the next page so it doesn't get sliced in half by the boundary line.\n        const pageEnd = pageStartY + pageHeight;\n        if (bottom > pageEnd && top < pageEnd && rect.height < pageHeight) {\n            const remaining = Math.max(0, pageEnd - top);\n            decos.push(makeSpacer(offset, remaining, false));\n            pageStartY = pageEnd;\n            pageIndex += 1;\n        } else if (bottom > pageEnd) {\n            // Block taller than a full page — let it span; just bump page index.\n            while (bottom > pageStartY + pageHeight) {\n                pageStartY += pageHeight;\n                pageIndex += 1;\n            }\n        }\n    });\n\n    ext.storage.pageCount = Math.max(1, pageIndex);\n    ext.storage.measuredHeight = totalContentHeight;\n\n    return DecorationSet.create(editor.state.doc, decos);\n}\n\nfunction makeSpacer(pos: number, height: number, fromHardBreak: boolean): Decoration {\n    const el = document.createElement('div');\n    el.className = fromHardBreak ? 'rk-page-spacer rk-page-spacer-hard' : 'rk-page-spacer';\n    el.contentEditable = 'false';\n    el.setAttribute('aria-hidden', 'true');\n    el.style.height = `${Math.max(0, Math.round(height))}px`;\n    return Decoration.widget(pos, el, { side: fromHardBreak ? 1 : -1, ignoreSelection: true });\n}\n\nfunction defaultA4ContentPx(): number {\n    // 297mm tall, minus 1in top + 1in bottom margin ≈ 245mm of content area.\n    // 1mm ≈ 3.7795px → ~926px content area.\n    return Math.round(245 * 3.7795);\n}\n","import { Node, mergeAttributes } from '@tiptap/core';\n\ndeclare module '@tiptap/core' {\n    interface Commands<ReturnType> {\n        titleSubtitle: {\n            setTitle: () => ReturnType;\n            setSubtitle: () => ReturnType;\n        };\n    }\n}\n\n/**\n * Title / Subtitle text-block nodes — Word- and Google-Docs-style top-of-document\n * styles that are distinct from regular headings (so they don't appear in the\n * TOC and so styling can be tuned independently).\n *\n * Each is a simple text-block with custom rendering and a corresponding\n * `setTitle()` / `setSubtitle()` command.\n */\nexport const Title = Node.create({\n    name: 'title',\n    group: 'block',\n    content: 'inline*',\n    defining: true,\n    parseHTML() { return [{ tag: 'h1.rk-title' }, { tag: 'div[data-type=\"title\"]' }]; },\n    renderHTML({ HTMLAttributes }) {\n        return ['h1', mergeAttributes(HTMLAttributes, { class: 'rk-title', 'data-type': 'title' }), 0];\n    },\n    addCommands() {\n        return {\n            setTitle: () => ({ commands }: any) => commands.setNode(this.name),\n        } as any;\n    },\n});\n\nexport const Subtitle = Node.create({\n    name: 'subtitle',\n    group: 'block',\n    content: 'inline*',\n    defining: true,\n    parseHTML() { return [{ tag: 'p.rk-subtitle' }, { tag: 'div[data-type=\"subtitle\"]' }]; },\n    renderHTML({ HTMLAttributes }) {\n        return ['p', mergeAttributes(HTMLAttributes, { class: 'rk-subtitle', 'data-type': 'subtitle' }), 0];\n    },\n    addCommands() {\n        return {\n            setSubtitle: () => ({ commands }: any) => commands.setNode(this.name),\n        } as any;\n    },\n});\n","import { JSONContent } from '@tiptap/core';\r\n\r\nexport class DocumentValidator {\r\n  /**\r\n   * Validates a Tiptap JSON content object against basic structural requirements.\r\n   * Can be extended for more strict schema enforcement.\r\n   */\r\n  public static validate(json: any): JSONContent {\r\n    if (!json || typeof json !== 'object') {\r\n      return { type: 'doc', content: [] };\r\n    }\r\n\r\n    if (json.type !== 'doc') {\r\n      console.warn('DocumentValidator: Invalid root type. Fixing to \"doc\".');\r\n      json.type = 'doc';\r\n    }\r\n\r\n    if (!Array.isArray(json.content)) {\r\n      console.warn('DocumentValidator: Content is not an array. Fixing to empty array.');\r\n      json.content = [];\r\n    }\r\n\r\n    // Perform recursive sanitization if needed\r\n    this.sanitizeNodes(json.content);\r\n\r\n    return json as JSONContent;\r\n  }\r\n\r\n  private static sanitizeNodes(nodes: any[]) {\r\n    nodes.forEach((node, index) => {\r\n      if (!node || typeof node !== 'object' || !node.type) {\r\n        console.warn(`DocumentValidator: Removing invalid node at index ${index}`);\r\n        nodes.splice(index, 1);\r\n        return;\r\n      }\r\n\r\n      // Ensure content is handled correctly\r\n      if (node.content && !Array.isArray(node.content)) {\r\n        node.content = [];\r\n      }\r\n\r\n      if (node.content) {\r\n        this.sanitizeNodes(node.content);\r\n      }\r\n    });\r\n  }\r\n\r\n  /**\r\n   * Returns a deterministic version of the JSON content.\r\n   * Useful for comparison and storage.\r\n   */\r\n  public static getDeterministicJSON(json: JSONContent): string {\r\n    return JSON.stringify(json, Object.keys(json).sort());\r\n  }\r\n}\r\n","import type { Editor } from '@tiptap/core';\n\n/**\n * CommandManager — high-level, friendly façade over the underlying Tiptap chain.\n * All formatting commands focus the editor first and then run.\n */\nexport class CommandManager {\n    private editor: Editor;\n\n    constructor(editor: Editor) {\n        this.editor = editor;\n    }\n\n    public execute(fn: (chain: any) => any) {\n        return fn(this.editor.chain().focus()).run();\n    }\n\n    private get parent(): any { return (this.editor as any).options.parent; }\n\n    // ---- Character formatting ----\n    public bold = () => this.execute(c => c.toggleBold());\n    public italic = () => this.execute(c => c.toggleItalic());\n    public underline = () => this.execute(c => c.toggleUnderline());\n    public strike = () => this.execute(c => c.toggleStrike());\n    public subscript = () => this.execute(c => c.toggleSubscript());\n    public superscript = () => this.execute(c => c.toggleSuperscript());\n    public code = () => this.execute(c => c.toggleCode());\n\n    public fontFamily = (font: string) => this.execute(c => c.setFontFamily(font));\n    public fontSize = (size: string) => this.execute(c => c.setFontSize(size));\n    public setColor = (color: string) => this.execute(c => c.setColor(color));\n    public unsetColor = () => this.execute(c => c.unsetColor());\n    public setHighlight = (color: string) => this.execute(c => c.setHighlight({ color }));\n    public unsetHighlight = () => this.execute(c => c.unsetHighlight());\n    public transform = (type: string) => (this.editor.chain().focus() as any).setTextTransform(type).run();\n    public toggleSmallCaps = () => (this.editor.chain().focus() as any).toggleSmallCaps().run();\n    public letterSpacing = (spacing: string) => (this.editor.chain().focus() as any).setLetterSpacing(spacing).run();\n    public wordSpacing = (spacing: string) => (this.editor.chain().focus() as any).setWordSpacing(spacing).run();\n\n    // ---- Block formatting ----\n    public align = (alignment: 'left' | 'center' | 'right' | 'justify') =>\n        this.execute(c => c.setTextAlign(alignment));\n    public lineHeight = (height: string) => this.execute(c => c.setLineHeight(height));\n    public spacing = (top: string, bottom: string) =>\n        this.execute(c => c.setParagraphSpacing({ top, bottom }));\n    public paragraphLayout = (attrs: any) =>\n        (this.editor.chain().focus() as any).setParagraphLayout(attrs).run();\n    public indent = () => {\n        if (this.editor.isActive('listItem')) {\n            return (this.editor.chain().focus() as any).sinkListItem('listItem').run();\n        }\n        return this.execute(c => c.indent());\n    };\n    public outdent = () => {\n        if (this.editor.isActive('listItem')) {\n            return (this.editor.chain().focus() as any).liftListItem('listItem').run();\n        }\n        return this.execute(c => c.outdent());\n    };\n\n    public heading = (level: 1 | 2 | 3 | 4 | 5 | 6) =>\n        this.execute(c => c.toggleHeading({ level }));\n    public paragraph = () => this.execute(c => c.setParagraph());\n    public title = () => (this.editor.chain().focus() as any).setTitle().run();\n    public subtitle = () => (this.editor.chain().focus() as any).setSubtitle().run();\n    public blockquote = () => this.execute(c => c.toggleBlockquote());\n    public codeBlock = () => this.execute(c => c.toggleCodeBlock());\n    public horizontalRule = () => this.execute(c => c.setHorizontalRule());\n\n    // ---- Lists ----\n    public bulletList = () => this.execute(c => c.toggleBulletList());\n    public orderedList = () => this.execute(c => c.toggleOrderedList());\n    public taskList = () => (this.editor.chain().focus() as any).toggleTaskList().run();\n    public setListStyle = (style: string) =>\n        (this.editor.chain().focus() as any).setListStyle(style).run();\n    public setListStartNumber = (n: number) =>\n        (this.editor.chain().focus() as any).setListStartNumber(n).run();\n\n    // ---- Tables ----\n    public insertTable = (options: { rows: number; cols: number; withHeaderRow?: boolean }) =>\n        this.execute(c => c.insertTable(options));\n    public addColumnBefore = () => this.execute(c => c.addColumnBefore());\n    public addColumnAfter = () => this.execute(c => c.addColumnAfter());\n    public deleteColumn = () => this.execute(c => c.deleteColumn());\n    public addRowBefore = () => this.execute(c => c.addRowBefore());\n    public addRowAfter = () => this.execute(c => c.addRowAfter());\n    public deleteRow = () => this.execute(c => c.deleteRow());\n    public deleteTable = () => this.execute(c => c.deleteTable());\n    public mergeCells = () => this.execute(c => c.mergeCells());\n    public splitCell = () => this.execute(c => c.splitCell());\n    public toggleHeaderColumn = () => this.execute(c => c.toggleHeaderColumn());\n    public toggleHeaderRow = () => this.execute(c => c.toggleHeaderRow());\n    public toggleHeaderCell = () => this.execute(c => c.toggleHeaderCell());\n    public mergeOrSplit = () => this.execute(c => c.mergeOrSplit());\n    public setCellAttribute = (name: string, value: any) =>\n        this.execute(c => c.setCellAttribute(name, value));\n    public setTableStyle = (style: string) =>\n        (this.editor.chain().focus() as any).setTableStyle(style).run();\n\n    // ---- Media & inserts ----\n    public openImageUpload = () => (this.editor.commands as any).openImageUpload();\n    public insertImage = (src: string, alt?: string) =>\n        this.execute(c => c.setImage({ src, alt: alt || '' }));\n    public setImageSize = (width: string, height?: string) =>\n        (this.editor.chain().focus() as any).setImageSize(width, height).run();\n    public setImageFloat = (float: 'left' | 'right' | 'none') =>\n        (this.editor.chain().focus() as any).setImageFloat(float).run();\n    public insertCaption = (type?: string) =>\n        (this.editor.chain().focus() as any).insertCaption(type).run();\n    public insertTextBox = (attrs?: { width?: number; height?: number; backgroundColor?: string; borderColor?: string }) =>\n        (this.editor.chain().focus() as any).insertTextBox(attrs).run();\n    public insertMathInline = (latex: string) =>\n        (this.editor.chain().focus() as any).insertMathInline(latex).run();\n    public insertMathBlock = (latex: string) =>\n        (this.editor.chain().focus() as any).insertMathBlock(latex).run();\n    public pageBreak = () => (this.editor.commands as any).setPageBreak();\n    public footnote = (content?: string) => (this.editor.commands as any).setFootnote(content);\n    public sectionBreak = () => (this.editor.commands as any).insertSectionBreak();\n    public pageLayout = (options: any) => (this.editor.commands as any).setPageLayout(options);\n    public insertPageNumber = () =>\n        this.execute(c => c.insertContent({ type: 'pageNumber' }));\n    public insertLink = (href: string) =>\n        (this.editor.chain().focus() as any).setLink({ href }).run();\n    public unsetLink = () => (this.editor.chain().focus() as any).unsetLink().run();\n\n    // ---- Styles & references ----\n    public applyStyle = (name: string) =>\n        (this.editor.chain().focus() as any).applyNamedStyle(name).run();\n    public updateStyle = (name: string, attrs: any) =>\n        (this.editor.chain().focus() as any).updateNamedStyle(name, attrs).run();\n    public insertTableOfContents = (attrs?: { minLevel?: number; maxLevel?: number; title?: string; showLeader?: boolean; showPageNumbers?: boolean }) =>\n        (this.editor.chain().focus() as any).insertTableOfContents(attrs).run();\n    public refreshTableOfContents = () =>\n        (this.editor.chain().focus() as any).refreshTableOfContents().run();\n    public setTocLevels = (minLevel: number, maxLevel: number) =>\n        (this.editor.chain().focus() as any).setTocLevels(minLevel, maxLevel).run();\n    public insertCitation = (key: string, label?: string) =>\n        (this.editor.chain().focus() as any).insertCitation(key, label).run();\n    public insertBibliography = () =>\n        (this.editor.chain().focus() as any).insertBibliography().run();\n\n    // ---- Misc ----\n    public clearFormatting = () =>\n        this.execute(c => c.unsetAllMarks().clearNodes());\n    public undo = () => this.execute(c => c.undo());\n    public redo = () => this.execute(c => c.redo());\n    public selectAll = () => this.execute(c => c.selectAll());\n\n    // ---- Format Painter ----\n    public startFormatPaint = () =>\n        (this.editor.chain().focus() as any).startFormatPaint().run();\n    public cancelFormatPaint = () =>\n        (this.editor.chain().focus() as any).cancelFormatPaint().run();\n\n    // ---- Find & Replace passthroughs ----\n    public find = (query: string, options?: { caseSensitive?: boolean; regex?: boolean }) =>\n        (this.editor.commands as any).findText(query, options);\n    public findNext = () => (this.editor.commands as any).goToNextMatch();\n    public findPrev = () => (this.editor.commands as any).goToPreviousMatch();\n    public replace = (q: string, r: string, opts?: any) =>\n        (this.editor.commands as any).replaceText(q, r, opts);\n    public replaceAll = (q: string, r: string, opts?: any) =>\n        (this.editor.commands as any).replaceAllText(q, r, opts);\n    public clearSearch = () => (this.editor.commands as any).clearSearch();\n\n    // ---- Slash commands ----\n    public executeSlashCommand = (title: string) =>\n        (this.editor.chain().focus() as any).executeSlashCommand(title).run();\n\n    // ---- Export shortcuts (delegate to parent WordEditor) ----\n    public exportDocx = (filename?: string) => this.parent?.exportDocx?.(filename);\n    public exportMarkdown = (filename?: string) => this.parent?.exportMarkdown?.(filename);\n    public exportHtml = (filename?: string) => this.parent?.exportHtml?.(filename);\n    public exportJson = (filename?: string) => this.parent?.exportJson?.(filename);\n    public printDoc = (options?: any) => this.parent?.printPdf?.(options);\n}\n","import {\n    AlignmentType, BorderStyle, Document, ExternalHyperlink, HeadingLevel, ImageRun,\n    LevelFormat, Packer, PageOrientation, Paragraph, ShadingType, Table, TableCell,\n    TableRow, TextRun, UnderlineType, VerticalAlign, WidthType,\n    type IRunOptions, type ILevelsOptions,\n} from 'docx';\n// `file-saver` is a CJS-only package. Use the default-import shape so we work\n// in both bundlers and node-style ESM evaluators.\nimport fileSaver from 'file-saver';\nconst saveAs: (blob: Blob, filename?: string) => void =\n    (fileSaver as any).saveAs || (fileSaver as any).default?.saveAs || (fileSaver as any);\nimport type { StyleManager } from './StyleManager';\nimport type { PageLayoutOptions } from './extensions/PageLayout';\n\nexport type ExportFormat = 'docx' | 'pdf' | 'html' | 'json' | 'markdown';\n\nexport interface ExportOptions {\n    filename?: string;\n    pageLayout?: Partial<PageLayoutOptions>;\n}\n\nconst TWIPS_PER_INCH = 1440;\nconst TWIPS_PER_CM = 567;\nconst TWIPS_PER_MM = 56.7;\nconst TWIPS_PER_PT = 20;\n\nconst DOCX_PAGE_SIZES: Record<string, [number, number]> = {\n    A3: [16838, 23811],\n    A4: [11906, 16838],\n    A5: [8419, 11906],\n    Letter: [12240, 15840],\n    Legal: [12240, 20160],\n    Tabloid: [15840, 24480],\n};\n\nconst HEADING_MAP: Record<number, (typeof HeadingLevel)[keyof typeof HeadingLevel]> = {\n    1: HeadingLevel.HEADING_1,\n    2: HeadingLevel.HEADING_2,\n    3: HeadingLevel.HEADING_3,\n    4: HeadingLevel.HEADING_4,\n    5: HeadingLevel.HEADING_5,\n    6: HeadingLevel.HEADING_6,\n};\n\ninterface InlineFormat {\n    bold?: boolean;\n    italic?: boolean;\n    underline?: boolean;\n    strike?: boolean;\n    subscript?: boolean;\n    superscript?: boolean;\n    code?: boolean;\n    color?: string;\n    highlight?: string;\n    font?: string;\n    size?: number;\n    href?: string;\n}\n\ninterface ListContext {\n    reference: 'rk-decimal' | 'rk-bullet' | 'rk-nepali';\n    level: number;\n}\n\n/**\n * High-fidelity DOCX exporter. Converts Tiptap JSON to a real Word document\n * with embedded images, hyperlinks, all character marks (color, highlight,\n * font, size, strike, sub/sup, track-changes) and proper section properties.\n *\n * Designed to produce documents that open without errors in Microsoft Word,\n * Google Docs, LibreOffice and Pages.\n */\nexport class ExportEngine {\n    private _docHeadings: HeadingInfo[] = [];\n\n    constructor(_styleManager?: StyleManager) {\n        // styleManager retained for forward-compatibility (named-style export).\n    }\n\n    public async exportToDocx(json: any, options: ExportOptions = {}): Promise<void> {\n        const blob = await this.toBlob(json, options);\n        saveAs(blob, options.filename || 'document.docx');\n    }\n\n    /**\n     * Build the docx Blob without triggering a download. Useful for tests,\n     * server-side rendering, or piping the document elsewhere.\n     */\n    public async toBlob(json: any, options: ExportOptions = {}): Promise<Blob> {\n        // We need the document headings up front so the TOC export can\n        // reference them with real text + an estimated page number.\n        this._docHeadings = collectHeadings(json);\n        const sectionChildren = await this.convertNodes(json?.content || [], undefined);\n        const pageProps = sectionPropertiesFromLayout(options.pageLayout);\n\n        const doc = new Document({\n            creator: 'RK Word Editor',\n            description: 'Exported from RK Word Editor',\n            title: (options.filename || 'document').replace(/\\.docx$/i, ''),\n            numbering: { config: this.numberingConfig() },\n            sections: [\n                {\n                    properties: pageProps,\n                    children: sectionChildren,\n                },\n            ],\n        });\n\n        return Packer.toBlob(doc);\n    }\n\n    // ---- Node conversion ---------------------------------------------------\n\n    private async convertNodes(nodes: any[], list?: ListContext): Promise<(Paragraph | Table)[]> {\n        const out: (Paragraph | Table)[] = [];\n        for (const node of nodes || []) {\n            const r = await this.convertNode(node, list);\n            if (Array.isArray(r)) out.push(...r);\n            else if (r) out.push(r);\n        }\n        return out;\n    }\n\n    private async convertNode(node: any, list?: ListContext): Promise<Paragraph | Table | (Paragraph | Table)[] | null> {\n        if (!node || typeof node !== 'object' || !node.type) return null;\n        switch (node.type) {\n            case 'paragraph': return this.convertParagraph(node, list);\n            case 'heading': return this.convertHeading(node);\n            case 'blockquote': return this.convertBlockquote(node);\n            case 'codeBlock': return this.convertCodeBlock(node);\n            case 'horizontalRule':\n                return new Paragraph({\n                    children: [new TextRun('')],\n                    border: { bottom: { color: '999999', space: 1, style: BorderStyle.SINGLE, size: 6 } },\n                });\n            case 'pageBreak':\n                return new Paragraph({ children: [new TextRun({ text: '', break: 1 })], pageBreakBefore: true });\n            case 'image': return await this.convertImage(node);\n            case 'bulletList':\n                return this.convertList(node, { reference: 'rk-bullet', level: (list?.level ?? -1) + 1 });\n            case 'orderedList': {\n                const ref: ListContext['reference'] = node.attrs?.listStyle === 'nepali' ? 'rk-nepali' : 'rk-decimal';\n                return this.convertList(node, { reference: ref, level: (list?.level ?? -1) + 1 });\n            }\n            case 'taskList': return this.convertTaskList(node);\n            case 'table': return this.convertTable(node);\n            case 'caption':\n                return new Paragraph({\n                    children: this.convertInlines(node.content || []),\n                    alignment: AlignmentType.CENTER,\n                });\n            case 'mathInline':\n            case 'mathBlock':\n                return new Paragraph({\n                    children: [new TextRun({ text: node.attrs?.latex || '', font: 'Cambria Math' })],\n                });\n            case 'section':\n            case 'bibliography':\n            case 'textBox':\n                return this.convertNodes(node.content || []);\n            case 'tableOfContents':\n                return this.convertTocPlaceholder(node);\n            default:\n                if (Array.isArray(node.content) && node.content.length) {\n                    return this.convertNodes(node.content, list);\n                }\n                return null;\n        }\n    }\n\n    // ---- Paragraphs / inlines ---------------------------------------------\n\n    private convertParagraph(node: any, list?: ListContext): Paragraph {\n        let children = this.convertInlines(node.content || []);\n        if (children.length === 0) children = [new TextRun('')];\n        const opts: any = { children };\n        if (list) opts.numbering = { reference: list.reference, level: Math.min(list.level, 8) };\n        applyParagraphStyling(node, opts);\n        return new Paragraph(opts);\n    }\n\n    private convertHeading(node: any): Paragraph {\n        const level = clamp(node.attrs?.level || 1, 1, 6);\n        let children = this.convertInlines(node.content || []);\n        if (children.length === 0) children = [new TextRun('')];\n        const opts: any = { children, heading: HEADING_MAP[level] };\n        applyParagraphStyling(node, opts);\n        return new Paragraph(opts);\n    }\n\n    private convertBlockquote(node: any): Paragraph[] {\n        const out: Paragraph[] = [];\n        for (const child of node.content || []) {\n            const inlines = this.convertInlines(child.content || []);\n            out.push(new Paragraph({\n                children: inlines.length ? inlines : [new TextRun('')],\n                indent: { left: 720 },\n                border: {\n                    left: { color: 'AAAAAA', space: 12, style: BorderStyle.SINGLE, size: 12 },\n                },\n            }));\n        }\n        return out.length ? out : [new Paragraph({ children: [new TextRun('')] })];\n    }\n\n    private convertTocPlaceholder(node: any): Paragraph[] {\n        const title = node.attrs?.title || 'Table of contents';\n        const minLevel = node.attrs?.minLevel ?? 1;\n        const maxLevel = node.attrs?.maxLevel ?? 3;\n        const showLeader = node.attrs?.showLeader !== false;\n        const showPageNumbers = node.attrs?.showPageNumbers !== false;\n\n        const out: Paragraph[] = [];\n        // Title row.\n        out.push(new Paragraph({\n            children: [new TextRun({ text: title, bold: true, size: 28 })],\n            spacing: { before: 240, after: 120 },\n            border: { bottom: { color: 'CCCCCC', space: 6, style: BorderStyle.SINGLE, size: 6 } },\n        }));\n\n        const items = this._docHeadings.filter(h => h.level >= minLevel && h.level <= maxLevel);\n        if (items.length === 0) {\n            out.push(new Paragraph({\n                children: [new TextRun({ text: '(No headings found.)', italics: true, color: '888888' })],\n                spacing: { after: 240 },\n            }));\n            return out;\n        }\n\n        for (const item of items) {\n            const indent = (item.level - minLevel) * 360;\n            const isTopLevel = item.level === minLevel;\n            const runs: any[] = [\n                new TextRun({ text: item.text, bold: isTopLevel }),\n            ];\n            if (showLeader) {\n                // Leader dots — a long string is the simplest cross-Word-version approach.\n                runs.push(new TextRun({ text: ' ' + '.'.repeat(60) + ' ', color: '999999' }));\n            } else if (showPageNumbers) {\n                runs.push(new TextRun({ text: '  ' }));\n            }\n            if (showPageNumbers) {\n                runs.push(new TextRun({ text: String(item.estimatedPage), color: '666666' }));\n            }\n            out.push(new Paragraph({\n                children: runs,\n                spacing: { after: 60 },\n                indent: indent ? { left: indent } : undefined,\n                tabStops: showLeader\n                    ? [{ type: 'right' as any, position: 9000, leader: 'dot' as any }]\n                    : undefined,\n            }));\n        }\n\n        // Close with a blank line so the next block doesn't crowd the TOC.\n        out.push(new Paragraph({ children: [new TextRun('')], spacing: { before: 120, after: 240 } }));\n        return out;\n    }\n\n    private convertCodeBlock(node: any): Paragraph {\n        const text = (node.content || []).map((c: any) => c.text || '').join('') || ' ';\n        return new Paragraph({\n            children: [new TextRun({ text, font: 'Consolas', size: 20 })],\n            shading: { type: ShadingType.CLEAR, fill: 'F4F4F4', color: 'auto' },\n            spacing: { before: 120, after: 120 },\n            border: {\n                top:    { color: 'DDDDDD', space: 6, style: BorderStyle.SINGLE, size: 4 },\n                bottom: { color: 'DDDDDD', space: 6, style: BorderStyle.SINGLE, size: 4 },\n                left:   { color: 'DDDDDD', space: 6, style: BorderStyle.SINGLE, size: 4 },\n                right:  { color: 'DDDDDD', space: 6, style: BorderStyle.SINGLE, size: 4 },\n            },\n        });\n    }\n\n    private async convertImage(node: any): Promise<Paragraph> {\n        const src: string | undefined = node.attrs?.src;\n        const alignment = mapAlignment(node.attrs?.textAlign) || AlignmentType.CENTER;\n        if (!src) return new Paragraph({ children: [new TextRun('')] });\n\n        const data = await fetchImageData(src);\n        if (!data) {\n            // Fall back to a textual placeholder so Word doesn't choke on missing media.\n            return new Paragraph({\n                children: [new TextRun({ text: `[Image: ${node.attrs?.alt || src}]`, italics: true, color: '888888' })],\n                alignment,\n            });\n        }\n        const dim = parseImageSize(node.attrs);\n        try {\n            const imageRun = new ImageRun({\n                type: data.type,\n                data: data.bytes,\n                transformation: dim,\n            } as any);\n            return new Paragraph({ children: [imageRun], alignment });\n        } catch (e) {\n            console.warn('[ExportEngine] ImageRun failed', e);\n            return new Paragraph({\n                children: [new TextRun({ text: `[Image: ${node.attrs?.alt || ''}]`, italics: true, color: '888888' })],\n                alignment,\n            });\n        }\n    }\n\n    // ---- Lists -------------------------------------------------------------\n\n    private async convertList(node: any, list: ListContext): Promise<Paragraph[]> {\n        const out: Paragraph[] = [];\n        for (const item of node.content || []) {\n            if (item?.type !== 'listItem') continue;\n            for (const child of item.content || []) {\n                if (child.type === 'paragraph') {\n                    out.push(this.convertParagraph(child, list));\n                } else if (child.type === 'bulletList' || child.type === 'orderedList') {\n                    const childList: ListContext = {\n                        reference: child.attrs?.listStyle === 'nepali'\n                            ? 'rk-nepali'\n                            : (child.type === 'bulletList' ? 'rk-bullet' : 'rk-decimal'),\n                        level: list.level + 1,\n                    };\n                    const nested = await this.convertList(child, childList);\n                    out.push(...nested);\n                }\n            }\n        }\n        return out;\n    }\n\n    private convertTaskList(node: any): Paragraph[] {\n        const out: Paragraph[] = [];\n        for (const item of node.content || []) {\n            if (item?.type !== 'taskItem') continue;\n            const checked = !!item.attrs?.checked;\n            const marker = checked ? '☑ ' : '☐ ';\n            for (const child of item.content || []) {\n                if (child.type === 'paragraph') {\n                    const inlines = this.convertInlines(child.content || []);\n                    out.push(new Paragraph({ children: [new TextRun(marker), ...inlines] }));\n                }\n            }\n        }\n        return out.length ? out : [new Paragraph({ children: [new TextRun('')] })];\n    }\n\n    // ---- Tables ------------------------------------------------------------\n\n    private async convertTable(node: any): Promise<Table> {\n        const rows: TableRow[] = [];\n        for (const row of node.content || []) {\n            if (row?.type !== 'tableRow') continue;\n            rows.push(await this.convertTableRow(row));\n        }\n        if (rows.length === 0) {\n            // Word requires non-empty tables.\n            rows.push(new TableRow({ children: [new TableCell({ children: [new Paragraph({ children: [new TextRun('')] })] })] }));\n        }\n        return new Table({\n            width: { size: 100, type: WidthType.PERCENTAGE },\n            rows,\n        });\n    }\n\n    private async convertTableRow(node: any): Promise<TableRow> {\n        const cells: TableCell[] = [];\n        for (const cell of node.content || []) {\n            cells.push(await this.convertTableCell(cell));\n        }\n        if (cells.length === 0) {\n            cells.push(new TableCell({ children: [new Paragraph({ children: [new TextRun('')] })] }));\n        }\n        return new TableRow({ children: cells });\n    }\n\n    private async convertTableCell(node: any): Promise<TableCell> {\n        const attrs = node.attrs || {};\n        const isHeader = node.type === 'tableHeader';\n        const childContent = await this.convertNodes(node.content || []);\n        // Table cells must contain at least one Paragraph at the start and end.\n        const children: (Paragraph | Table)[] = [];\n        for (const c of childContent) children.push(c);\n        if (children.length === 0 || !(children[0] instanceof Paragraph)) {\n            children.unshift(new Paragraph({ children: [new TextRun('')] }));\n        }\n        if (!(children[children.length - 1] instanceof Paragraph)) {\n            children.push(new Paragraph({ children: [new TextRun('')] }));\n        }\n\n        let fill: string | undefined;\n        const bg = attrs.background || attrs.backgroundColor;\n        if (bg) fill = colorToHex(bg);\n        if (isHeader && !fill) fill = 'F3F4F6';\n\n        return new TableCell({\n            children: children as any,\n            columnSpan: attrs.colspan || 1,\n            rowSpan: attrs.rowspan || 1,\n            verticalAlign: VerticalAlign.CENTER,\n            shading: fill ? { fill, type: ShadingType.CLEAR, color: 'auto' } : undefined,\n        });\n    }\n\n    // ---- Inline conversion -------------------------------------------------\n\n    private convertInlines(inlines: any[]): any[] {\n        const out: any[] = [];\n        for (const inline of inlines || []) {\n            if (!inline || typeof inline !== 'object') continue;\n            if (inline.type === 'hardBreak') {\n                out.push(new TextRun({ text: '', break: 1 }));\n                continue;\n            }\n            if (inline.type === 'mathInline') {\n                out.push(new TextRun({ text: inline.attrs?.latex || '', font: 'Cambria Math' }));\n                continue;\n            }\n            if (inline.type === 'citation') {\n                const label = inline.attrs?.label || inline.attrs?.key || '?';\n                out.push(new TextRun({ text: `[${label}]`, superScript: true }));\n                continue;\n            }\n            if (inline.type === 'footnote') {\n                // Render footnote inline as italic superscript so the file remains valid.\n                const text = inline.content?.map((c: any) => c.text || '').join('') || '*';\n                out.push(new TextRun({ text, italics: true, superScript: true }));\n                continue;\n            }\n            if (inline.type !== 'text') {\n                if (Array.isArray(inline.content)) out.push(...this.convertInlines(inline.content));\n                continue;\n            }\n\n            const fmt = this.collectFormat(inline.marks || []);\n            if (fmt.href) {\n                out.push(new ExternalHyperlink({\n                    link: fmt.href,\n                    children: [new TextRun({ text: inline.text || '', ...formatToRun(fmt), color: fmt.color || '0563C1', underline: { type: UnderlineType.SINGLE } })],\n                }));\n            } else {\n                out.push(new TextRun({ text: inline.text || '', ...formatToRun(fmt) }));\n            }\n        }\n        return out;\n    }\n\n    private collectFormat(marks: any[]): InlineFormat {\n        const fmt: InlineFormat = {};\n        for (const mark of marks || []) {\n            switch (mark.type) {\n                case 'bold': fmt.bold = true; break;\n                case 'italic': fmt.italic = true; break;\n                case 'underline': fmt.underline = true; break;\n                case 'strike': fmt.strike = true; break;\n                case 'subscript': fmt.subscript = true; break;\n                case 'superscript': fmt.superscript = true; break;\n                case 'code': fmt.code = true; break;\n                case 'link': fmt.href = mark.attrs?.href || undefined; break;\n                case 'highlight': {\n                    const hex = colorToHex(mark.attrs?.color);\n                    if (hex) fmt.highlight = hex;\n                    break;\n                }\n                case 'textStyle': {\n                    const a = mark.attrs || {};\n                    if (a.color) {\n                        const hex = colorToHex(a.color);\n                        if (hex) fmt.color = hex;\n                    }\n                    if (a.fontFamily) {\n                        fmt.font = String(a.fontFamily).replace(/['\"]/g, '').split(',')[0].trim() || undefined;\n                    }\n                    if (a.fontSize) {\n                        const size = parseFontSize(a.fontSize);\n                        if (size) fmt.size = size;\n                    }\n                    break;\n                }\n                case 'trackInsert': fmt.color = '0A7C2F'; fmt.underline = true; break;\n                case 'trackDelete': fmt.color = 'B3261E'; fmt.strike = true; break;\n            }\n        }\n        return fmt;\n    }\n\n    // ---- Numbering definitions --------------------------------------------\n\n    private numberingConfig(): { reference: string; levels: ILevelsOptions[] }[] {\n        const decimal: ILevelsOptions[] = Array.from({ length: 9 }, (_, level) => ({\n            level,\n            format: LevelFormat.DECIMAL,\n            text: `%${level + 1}.`,\n            alignment: AlignmentType.START,\n            style: { paragraph: { indent: { left: (level + 1) * 720, hanging: 360 } } },\n        }));\n        const bullets = ['•', '◦', '▪', '•', '◦', '▪', '•', '◦', '▪'];\n        const bullet: ILevelsOptions[] = bullets.map((b, level) => ({\n            level,\n            format: LevelFormat.BULLET,\n            text: b,\n            alignment: AlignmentType.START,\n            style: { paragraph: { indent: { left: (level + 1) * 720, hanging: 360 } } },\n        }));\n        const nepali: ILevelsOptions[] = Array.from({ length: 9 }, (_, level) => ({\n            level,\n            format: LevelFormat.DECIMAL,\n            text: `%${level + 1}.`,\n            alignment: AlignmentType.START,\n            style: { paragraph: { indent: { left: (level + 1) * 720, hanging: 360 } } },\n        }));\n        return [\n            { reference: 'rk-decimal', levels: decimal },\n            { reference: 'rk-bullet', levels: bullet },\n            { reference: 'rk-nepali', levels: nepali },\n        ];\n    }\n}\n\n// =====================================================================\n// Helpers (kept module-private)\n// =====================================================================\n\nfunction formatToRun(fmt: InlineFormat): IRunOptions {\n    // IRunOptions has readonly fields, so we build a plain object then cast.\n    const opts: Record<string, any> = {};\n    if (fmt.bold) opts.bold = true;\n    if (fmt.italic) opts.italics = true;\n    if (fmt.strike) opts.strike = true;\n    if (fmt.underline) opts.underline = { type: UnderlineType.SINGLE };\n    if (fmt.subscript) opts.subScript = true;\n    if (fmt.superscript) opts.superScript = true;\n    if (fmt.color) opts.color = fmt.color;\n    if (fmt.font) opts.font = fmt.font;\n    if (fmt.size) opts.size = fmt.size;\n    if (fmt.code) {\n        opts.font = opts.font || 'Consolas';\n        if (!opts.size) opts.size = 20;\n    }\n    if (fmt.highlight) {\n        // Use shading for arbitrary hex highlighting (HighlightColor only takes\n        // a fixed enum of named colors).\n        opts.shading = { type: ShadingType.CLEAR, fill: fmt.highlight, color: 'auto' };\n    }\n    return opts as IRunOptions;\n}\n\nfunction applyParagraphStyling(node: any, opts: any) {\n    const attrs = node.attrs || {};\n    const spacing: any = {};\n    const before = parseSpacingTwips(attrs.spacingBefore || attrs.marginTop);\n    const after = parseSpacingTwips(attrs.spacingAfter || attrs.marginBottom);\n    const line = attrs.lineHeight ? Math.round(parseFloat(attrs.lineHeight) * 240) : undefined;\n    if (before !== undefined) spacing.before = before;\n    if (after !== undefined) spacing.after = after;\n    if (line !== undefined && !isNaN(line)) { spacing.line = line; spacing.lineRule = 'auto'; }\n    if (Object.keys(spacing).length) opts.spacing = spacing;\n\n    const indent: any = {};\n    const left = parseIndentTwips(attrs.indent);\n    const firstLine = parseIndentTwips(attrs.firstLineIndent);\n    if (left !== undefined) indent.left = left;\n    if (firstLine !== undefined) indent.firstLine = firstLine;\n    if (Object.keys(indent).length) opts.indent = indent;\n\n    const align = mapAlignment(attrs.textAlign);\n    if (align) opts.alignment = align;\n}\n\nfunction mapAlignment(align?: string): (typeof AlignmentType)[keyof typeof AlignmentType] | undefined {\n    switch (align) {\n        case 'center': return AlignmentType.CENTER;\n        case 'right': return AlignmentType.RIGHT;\n        case 'justify': return AlignmentType.JUSTIFIED;\n        case 'left': return AlignmentType.LEFT;\n        default: return undefined;\n    }\n}\n\nfunction parseSpacingTwips(value: any): number | undefined {\n    if (value == null || value === '') return undefined;\n    if (typeof value === 'number') return Math.round(value * TWIPS_PER_PT);\n    const s = String(value).trim();\n    const num = parseFloat(s);\n    if (isNaN(num)) return undefined;\n    if (s.endsWith('in')) return Math.round(num * TWIPS_PER_INCH);\n    if (s.endsWith('cm')) return Math.round(num * TWIPS_PER_CM);\n    if (s.endsWith('mm')) return Math.round(num * TWIPS_PER_MM);\n    if (s.endsWith('pt')) return Math.round(num * TWIPS_PER_PT);\n    if (s.endsWith('px')) return Math.round(num * 15);\n    if (s.endsWith('em') || s.endsWith('rem')) return Math.round(num * 240);\n    return Math.round(num * TWIPS_PER_PT);\n}\n\nfunction parseIndentTwips(value: any): number | undefined {\n    if (value == null || value === '') return undefined;\n    if (typeof value === 'number') return Math.round(value * 720);\n    const s = String(value).trim();\n    const num = parseFloat(s);\n    if (isNaN(num)) return undefined;\n    if (s.endsWith('in')) return Math.round(num * TWIPS_PER_INCH);\n    if (s.endsWith('cm')) return Math.round(num * TWIPS_PER_CM);\n    if (s.endsWith('mm')) return Math.round(num * TWIPS_PER_MM);\n    if (s.endsWith('pt')) return Math.round(num * TWIPS_PER_PT);\n    if (s.endsWith('px')) return Math.round(num * 15);\n    return Math.round(num * 720);\n}\n\nfunction parseFontSize(size: any): number | undefined {\n    if (size == null || size === '') return undefined;\n    const s = String(size).trim();\n    const num = parseFloat(s);\n    if (isNaN(num) || num <= 0) return undefined;\n    if (s.endsWith('px')) return Math.max(2, Math.round((num * 0.75) * 2));\n    if (s.endsWith('em') || s.endsWith('rem')) return Math.max(2, Math.round(num * 12 * 2));\n    return Math.max(2, Math.round(num * 2));\n}\n\nfunction colorToHex(input: any): string | undefined {\n    if (!input) return undefined;\n    const s = String(input).trim();\n    if (!s) return undefined;\n    if (s.startsWith('#')) {\n        let hex = s.slice(1);\n        if (hex.length === 3) hex = hex.split('').map(c => c + c).join('');\n        if (/^[0-9A-Fa-f]{6}$/.test(hex)) return hex.toUpperCase();\n    }\n    if (s.startsWith('rgb')) {\n        const parts = s.match(/\\d+/g);\n        if (parts && parts.length >= 3) {\n            const [r, g, b] = parts.slice(0, 3).map(n => Math.min(255, Math.max(0, parseInt(n, 10))));\n            return ((r << 16) | (g << 8) | b).toString(16).padStart(6, '0').toUpperCase();\n        }\n    }\n    const named: Record<string, string> = {\n        black: '000000', white: 'FFFFFF', red: 'FF0000', green: '008000', blue: '0000FF',\n        yellow: 'FFFF00', orange: 'FFA500', purple: '800080', gray: '808080', grey: '808080',\n    };\n    return named[s.toLowerCase()];\n}\n\nfunction clamp(n: number, lo: number, hi: number): number {\n    return Math.min(hi, Math.max(lo, n));\n}\n\nfunction sectionPropertiesFromLayout(layout?: Partial<PageLayoutOptions>): any {\n    const orientation = layout?.orientation === 'landscape'\n        ? PageOrientation.LANDSCAPE\n        : PageOrientation.PORTRAIT;\n    const sizeKey = layout?.pageSize || 'A4';\n    const dims = DOCX_PAGE_SIZES[sizeKey] || DOCX_PAGE_SIZES.A4;\n    const [w, h] = orientation === PageOrientation.LANDSCAPE ? [dims[1], dims[0]] : dims;\n\n    const margins = layout?.margins || { top: '1in', bottom: '1in', left: '1in', right: '1in' };\n    return {\n        page: {\n            size: { width: w, height: h, orientation },\n            margin: {\n                top: parseSpacingTwips(margins.top) ?? TWIPS_PER_INCH,\n                bottom: parseSpacingTwips(margins.bottom) ?? TWIPS_PER_INCH,\n                left: parseSpacingTwips(margins.left) ?? TWIPS_PER_INCH,\n                right: parseSpacingTwips(margins.right) ?? TWIPS_PER_INCH,\n            },\n        },\n    };\n}\n\nasync function fetchImageData(src: string): Promise<{ bytes: Uint8Array; type: 'png' | 'jpg' | 'gif' | 'bmp' } | null> {\n    try {\n        if (src.startsWith('data:')) {\n            const match = src.match(/^data:([^;]+);base64,(.+)$/);\n            if (!match) return null;\n            const mime = match[1];\n            // SVG can't be embedded as a raster image — skip rather than corrupt.\n            if (mime.includes('svg')) return null;\n            const bin = atob(match[2]);\n            const bytes = new Uint8Array(bin.length);\n            for (let i = 0; i < bin.length; i++) bytes[i] = bin.charCodeAt(i);\n            const type = mimeToDocxType(mime);\n            return type ? { bytes, type } : null;\n        }\n        const res = await fetch(src);\n        if (!res.ok) return null;\n        const buf = await res.arrayBuffer();\n        const mime = res.headers.get('content-type') || guessMimeFromUrl(src);\n        if (mime.includes('svg')) return null;\n        const type = mimeToDocxType(mime);\n        return type ? { bytes: new Uint8Array(buf), type } : null;\n    } catch (e) {\n        console.warn('[ExportEngine] image fetch failed', src, e);\n        return null;\n    }\n}\n\nfunction mimeToDocxType(mime: string): 'png' | 'jpg' | 'gif' | 'bmp' | null {\n    if (mime.includes('png')) return 'png';\n    if (mime.includes('jpeg') || mime.includes('jpg')) return 'jpg';\n    if (mime.includes('gif')) return 'gif';\n    if (mime.includes('bmp')) return 'bmp';\n    return null;\n}\n\nfunction guessMimeFromUrl(src: string): string {\n    const m = src.split('?')[0].toLowerCase();\n    if (m.endsWith('.png')) return 'image/png';\n    if (m.endsWith('.jpg') || m.endsWith('.jpeg')) return 'image/jpeg';\n    if (m.endsWith('.gif')) return 'image/gif';\n    if (m.endsWith('.bmp')) return 'image/bmp';\n    if (m.endsWith('.svg')) return 'image/svg+xml';\n    return 'application/octet-stream';\n}\n\nfunction parseImageSize(attrs: any): { width: number; height: number } {\n    const w = parseDimensionPx(attrs?.width);\n    const h = parseDimensionPx(attrs?.height);\n    const width = w && w > 0 ? w : 480;\n    const height = h && h > 0 ? h : Math.round(width * 0.66);\n    return { width, height };\n}\n\ninterface HeadingInfo { level: number; text: string; estimatedPage: number }\n\nfunction collectHeadings(doc: any): HeadingInfo[] {\n    const out: HeadingInfo[] = [];\n    let charCount = 0;\n    const CHARS_PER_PAGE = 1500;\n    const visit = (node: any) => {\n        if (!node) return;\n        if (node.type === 'text' && typeof node.text === 'string') {\n            charCount += node.text.length;\n        }\n        if (node.type === 'heading' && Array.isArray(node.content)) {\n            const text = textOf(node.content);\n            if (text.trim()) {\n                out.push({\n                    level: node.attrs?.level || 1,\n                    text,\n                    estimatedPage: Math.max(1, Math.ceil(charCount / CHARS_PER_PAGE)),\n                });\n            }\n        }\n        if (Array.isArray(node.content)) {\n            for (const child of node.content) visit(child);\n        }\n    };\n    visit(doc);\n    return out;\n}\n\nfunction textOf(content: any[]): string {\n    return content.map((c: any) => {\n        if (c?.type === 'text') return c.text || '';\n        if (Array.isArray(c?.content)) return textOf(c.content);\n        return '';\n    }).join('');\n}\n\nfunction parseDimensionPx(v: any): number | null {\n    if (v == null) return null;\n    if (typeof v === 'number') return v;\n    const s = String(v).trim();\n    const num = parseFloat(s);\n    if (isNaN(num) || num <= 0) return null;\n    if (s.endsWith('%')) return null;\n    if (s.endsWith('in')) return Math.round(num * 96);\n    if (s.endsWith('cm')) return Math.round(num * 37.795);\n    if (s.endsWith('mm')) return Math.round(num * 3.7795);\n    if (s.endsWith('pt')) return Math.round(num * 1.333);\n    return Math.round(num);\n}\n","/**\r\n * ImportEngine - Handles importing external formats into the editor.\r\n * \r\n * DOCX import: Uses mammoth.js for high-fidelity Word document conversion.\r\n * Markdown import: Uses marked for Markdown → HTML conversion.\r\n * Markdown export: Uses turndown to convert HTML → Markdown.\r\n *\r\n * All libraries are dynamically imported to avoid bundle size impact.\r\n */\r\nexport class ImportEngine {\r\n\r\n    /**\r\n     * Import a .docx file and return HTML string.\r\n     * Requires mammoth to be installed: npm install mammoth\r\n     */\r\n    public async importDocx(file: File): Promise<string> {\r\n        let mammoth: any;\r\n        try {\r\n            mammoth = await import('mammoth');\r\n        } catch {\r\n            throw new Error('mammoth is not installed. Run: npm install mammoth');\r\n        }\r\n\r\n        const arrayBuffer = await file.arrayBuffer();\r\n        const result = await mammoth.convertToHtml(\r\n            { arrayBuffer },\r\n            {\r\n                styleMap: [\r\n                    \"p[style-name='Heading 1'] => h1:fresh\",\r\n                    \"p[style-name='Heading 2'] => h2:fresh\",\r\n                    \"p[style-name='Heading 3'] => h3:fresh\",\r\n                    \"p[style-name='Heading 4'] => h4:fresh\",\r\n                    \"p[style-name='Heading 5'] => h5:fresh\",\r\n                    \"p[style-name='Heading 6'] => h6:fresh\",\r\n                    \"p[style-name='List Paragraph'] => li:fresh\",\r\n                    \"p[style-name='toc 1'] => p.rk-toc-item:fresh\",\r\n                    \"p[style-name='toc 2'] => p.rk-toc-item:fresh\",\r\n                    \"p[style-name='caption'] => p.rk-caption:fresh\",\r\n                    \"p[style-name='Bibliography'] => p.rk-bibliography:fresh\",\r\n                    \"b => strong\",\r\n                    \"i => em\",\r\n                    \"u => span.underline\",\r\n                ],\r\n                includeDefaultStyleMap: true,\r\n            }\r\n        );\r\n\r\n        if (result.messages.length > 0) {\r\n            console.warn('[ImportEngine] DOCX import warnings:', result.messages);\r\n        }\r\n\r\n        return result.value;\r\n    }\r\n\r\n    /**\r\n     * Import a Markdown string and return HTML.\r\n     * Requires marked: npm install marked\r\n     */\r\n    public async importMarkdown(text: string): Promise<string> {\r\n        let marked: any;\r\n        try {\r\n            const mod = await import('marked');\r\n            marked = (mod as any).marked ?? (mod as any).default ?? mod;\r\n        } catch {\r\n            throw new Error('marked is not installed. Run: npm install marked');\r\n        }\r\n\r\n        return marked(text, {\r\n            gfm: true,       // GitHub-flavored markdown\r\n            breaks: true,    // Line breaks become <br>\r\n        });\r\n    }\r\n\r\n    /**\r\n     * Export HTML to Markdown.\r\n     * Requires turndown: npm install turndown\r\n     */\r\n    public async exportMarkdown(html: string): Promise<string> {\r\n        let TurndownService: any;\r\n        try {\r\n            const mod = await import('turndown');\r\n            TurndownService = mod.default || mod;\r\n        } catch {\r\n            throw new Error('turndown is not installed. Run: npm install turndown');\r\n        }\r\n\r\n        const service = new TurndownService({\r\n            headingStyle: 'atx',\r\n            bulletListMarker: '-',\r\n            codeBlockStyle: 'fenced',\r\n        });\r\n\r\n        // Handle tables\r\n        try {\r\n            // Using a template literal to avoid Vite static analysis if missing\r\n            const pluginName = 'turndown-plugin-gfm';\r\n            const gfm = await import(/* @vite-ignore */ pluginName);\r\n            service.use(gfm.gfm || gfm.default || gfm);\r\n        } catch (e) {\r\n            console.warn('[ImportEngine] turndown-plugin-gfm not loaded, skipping tables in markdown export.', e);\r\n        }\r\n\r\n        return service.turndown(html);\r\n    }\r\n\r\n    /**\r\n     * Download Markdown as a .md file.\r\n     */\r\n    public downloadMarkdown(markdown: string, filename = 'document.md'): void {\r\n        const blob = new Blob([markdown], { type: 'text/markdown; charset=utf-8' });\r\n        const url = URL.createObjectURL(blob);\r\n        const a = document.createElement('a');\r\n        a.href = url;\r\n        a.download = filename;\r\n        a.click();\r\n        URL.revokeObjectURL(url);\r\n    }\r\n}\r\n","import type { PageLayoutOptions } from './extensions/PageLayout';\n\nexport interface PrintOptions {\n  /** Document title shown in print preview / saved PDF. */\n  title?: string;\n  /** Override the editor's page layout for this print only. */\n  pageLayout?: Partial<PageLayoutOptions>;\n  /** Extra CSS to inject into the print iframe. */\n  extraCss?: string;\n  /** Optional header HTML printed at the top of every page. */\n  headerHtml?: string;\n  /** Optional footer HTML printed at the bottom of every page. */\n  footerHtml?: string;\n  /** Show page numbers in the footer (defaults to true). */\n  pageNumbers?: boolean;\n  /** Auto-close the print iframe after the print dialog (default true). */\n  autoClose?: boolean;\n}\n\nconst DEFAULT_PRINT_CSS = `\n  *, *::before, *::after { box-sizing: border-box; }\n  html, body {\n    margin: 0;\n    padding: 0;\n    background: #fff;\n    color: #000;\n    font-family: 'Times New Roman', Georgia, serif;\n    font-size: 12pt;\n    line-height: 1.5;\n    -webkit-print-color-adjust: exact;\n    print-color-adjust: exact;\n  }\n  .rk-print-root {\n    width: 100%;\n    margin: 0;\n    padding: 0;\n  }\n  h1, h2, h3, h4, h5, h6 {\n    font-family: 'Calibri', 'Helvetica Neue', Arial, sans-serif;\n    font-weight: 700;\n    line-height: 1.25;\n    margin: 1em 0 0.4em;\n    page-break-after: avoid;\n    break-after: avoid;\n  }\n  h1 { font-size: 22pt; }\n  h2 { font-size: 18pt; }\n  h3 { font-size: 14pt; }\n  h4 { font-size: 12pt; }\n  p { margin: 0 0 0.6em; orphans: 3; widows: 3; }\n  a { color: #1a73e8; text-decoration: underline; }\n  ul, ol { padding-left: 1.5em; margin: 0.5em 0; }\n  blockquote {\n    border-left: 4px solid #c8ccd0;\n    padding-left: 1em;\n    margin: 1em 0;\n    color: #444;\n    font-style: italic;\n  }\n  pre {\n    background: #f5f5f5;\n    border: 1px solid #ddd;\n    padding: 0.6em;\n    border-radius: 4px;\n    overflow: auto;\n    font-family: 'Courier New', monospace;\n    font-size: 10pt;\n    page-break-inside: avoid;\n  }\n  code {\n    background: #f5f5f5;\n    border: 1px solid #ddd;\n    padding: 1px 4px;\n    border-radius: 3px;\n    font-family: 'Courier New', monospace;\n    font-size: 0.9em;\n  }\n  table {\n    width: 100%;\n    border-collapse: collapse;\n    margin: 1em 0;\n    page-break-inside: auto;\n  }\n  table, th, td { border: 1px solid #888; }\n  th, td { padding: 6px 10px; vertical-align: top; }\n  th { background: #f3f4f6; text-align: left; font-weight: 700; }\n  tr { page-break-inside: avoid; page-break-after: auto; }\n  img {\n    max-width: 100%;\n    height: auto;\n    page-break-inside: avoid;\n  }\n  figcaption, .rk-caption {\n    text-align: center;\n    font-size: 10pt;\n    color: #555;\n    font-style: italic;\n    margin: 0.4em 0 1em;\n  }\n  .rk-page-break, [data-type=\"page-break\"] {\n    display: block;\n    height: 0;\n    page-break-after: always;\n    break-after: page;\n    border: none;\n  }\n  .rk-toc {\n    margin: 1em 0 1.4em;\n    padding: 0.6em 0 0.4em;\n    border-top: 1px solid #d0d4d8;\n    border-bottom: 1px solid #d0d4d8;\n    page-break-inside: auto;\n  }\n  .rk-toc-header {\n    display: flex;\n    align-items: baseline;\n    margin: 0 0 0.6em;\n  }\n  .rk-toc-title {\n    margin: 0;\n    font-size: 14pt;\n    font-weight: 700;\n    font-family: 'Calibri', 'Helvetica Neue', Arial, sans-serif;\n  }\n  .rk-toc-list {\n    list-style: none;\n    margin: 0;\n    padding: 0;\n  }\n  .rk-toc-item {\n    margin: 0.15em 0;\n    padding: 0;\n    list-style: none;\n  }\n  .rk-toc-link {\n    display: flex;\n    align-items: baseline;\n    gap: 0.4em;\n    color: #000;\n    text-decoration: none;\n  }\n  .rk-toc-text { flex: 0 1 auto; }\n  .rk-toc-leader {\n    flex: 1 1 auto;\n    border-bottom: 1px dotted #777;\n    transform: translateY(-3px);\n    margin: 0 0.25em;\n    min-width: 1em;\n  }\n  .rk-toc-page {\n    flex: 0 0 auto;\n    font-variant-numeric: tabular-nums;\n    color: #333;\n  }\n  .rk-toc-l1 .rk-toc-link { padding-left: 0;     font-weight: 600; }\n  .rk-toc-l2 .rk-toc-link { padding-left: 1.2em; }\n  .rk-toc-l3 .rk-toc-link { padding-left: 2.4em; font-size: 0.95em; }\n  .rk-toc-l4 .rk-toc-link { padding-left: 3.6em; font-size: 0.9em;  color: #444; }\n  .rk-toc-l5 .rk-toc-link { padding-left: 4.8em; font-size: 0.85em; color: #555; }\n  .rk-toc-l6 .rk-toc-link { padding-left: 6em;   font-size: 0.85em; color: #666; }\n  .rk-toc-empty { color: #888; font-style: italic; margin: 0.5em 0; }\n  .rk-track-insert { color: #0a7c2f; text-decoration: underline; text-decoration-color: #0a7c2f; }\n  .rk-track-delete { color: #b3261e; text-decoration: line-through; }\n  ul[data-type=\"taskList\"] { list-style: none; padding-left: 0.5em; }\n  ul[data-type=\"taskList\"] li { display: flex; gap: 0.5em; align-items: baseline; }\n  ul[data-type=\"taskList\"] li > label > input { margin-top: 0.15em; }\n  .rk-image-resize-wrapper {\n    display: inline-block;\n    position: relative;\n    max-width: 100%;\n  }\n  .rk-image-resize-wrapper img {\n    display: block;\n    max-width: 100%;\n    height: auto;\n  }\n  .rk-textbox {\n    border: 1px solid #c8ccd0;\n    background: #fff;\n    padding: 0.6em 0.8em;\n    margin: 0.6em 0;\n    border-radius: 4px;\n    page-break-inside: avoid;\n  }\n  .rk-textbox-content > p:first-child { margin-top: 0; }\n  .rk-textbox-content > *:last-child { margin-bottom: 0; }\n`;\n\n/**\n * Renders the editor content in an isolated, hidden iframe and triggers the\n * browser's print dialog. The user may then \"Save as PDF\" with proper\n * pagination, no editor chrome, no page-overflow scrollbars, and the configured\n * page size / orientation.\n */\nexport class PrintEngine {\n  public print(html: string, options: PrintOptions = {}): void {\n    const layout = mergePageLayout(options.pageLayout);\n    const pageSize = printPageSize(layout);\n    const margin = `${layout.margins.top} ${layout.margins.right} ${layout.margins.bottom} ${layout.margins.left}`;\n    const showPageNumbers = options.pageNumbers !== false;\n    const title = options.title || 'Document';\n\n    const iframe = document.createElement('iframe');\n    iframe.setAttribute('aria-hidden', 'true');\n    iframe.style.position = 'fixed';\n    iframe.style.right = '0';\n    iframe.style.bottom = '0';\n    iframe.style.width = '0';\n    iframe.style.height = '0';\n    iframe.style.border = '0';\n    iframe.style.opacity = '0';\n    iframe.style.pointerEvents = 'none';\n\n    document.body.appendChild(iframe);\n\n    const doc = iframe.contentDocument!;\n    const docHtml = `<!doctype html>\n<html>\n<head>\n  <meta charset=\"utf-8\">\n  <title>${escape(title)}</title>\n  <style>\n    @page {\n      size: ${pageSize};\n      margin: ${margin};\n      ${showPageNumbers ? `@bottom-right { content: counter(page) \" / \" counter(pages); font-family: sans-serif; font-size: 9pt; color: #666; }` : ''}\n    }\n    @media print {\n      body { -webkit-print-color-adjust: exact; print-color-adjust: exact; }\n    }\n    ${DEFAULT_PRINT_CSS}\n    ${options.extraCss || ''}\n  </style>\n</head>\n<body>\n  ${options.headerHtml ? `<header class=\"rk-print-header\">${options.headerHtml}</header>` : ''}\n  <main class=\"rk-print-root\">${html}</main>\n  ${options.footerHtml ? `<footer class=\"rk-print-footer\">${options.footerHtml}</footer>` : ''}\n</body>\n</html>`;\n\n    doc.open();\n    doc.write(docHtml);\n    doc.close();\n\n    const cleanup = () => {\n      try { document.body.removeChild(iframe); } catch { /* already gone */ }\n    };\n\n    const trigger = () => {\n      try {\n        iframe.contentWindow?.focus();\n        iframe.contentWindow?.print();\n      } catch (e) {\n        console.error('[PrintEngine] print failed', e);\n      } finally {\n        if (options.autoClose !== false) {\n          // Slight delay to allow print dialog to read the document.\n          setTimeout(cleanup, 1000);\n        }\n      }\n    };\n\n    // Wait for images to load before triggering print so they appear in PDF.\n    const waitForImages = async () => {\n      const images = Array.from(doc.images || []);\n      await Promise.all(\n        images.map(img => img.complete\n          ? Promise.resolve()\n          : new Promise<void>(resolve => {\n              img.addEventListener('load', () => resolve(), { once: true });\n              img.addEventListener('error', () => resolve(), { once: true });\n            })\n        )\n      );\n    };\n\n    if (doc.readyState === 'complete') {\n      waitForImages().then(trigger);\n    } else {\n      iframe.addEventListener('load', () => waitForImages().then(trigger), { once: true });\n    }\n  }\n}\n\nfunction escape(s: string): string {\n  return s.replace(/[&<>\"']/g, c => ({ '&': '&amp;', '<': '&lt;', '>': '&gt;', '\"': '&quot;', \"'\": '&#39;' }[c]!));\n}\n\nfunction printPageSize(layout: PageLayoutOptions): string {\n  const size = (layout.pageSize || 'A4').toLowerCase();\n  const orient = layout.orientation === 'landscape' ? 'landscape' : 'portrait';\n  const known = ['a3', 'a4', 'a5', 'letter', 'legal', 'tabloid'];\n  if (known.includes(size)) return `${size} ${orient}`;\n  if (layout.width && layout.height) return `${layout.width} ${layout.height}`;\n  return `A4 ${orient}`;\n}\n\nfunction mergePageLayout(layout?: Partial<PageLayoutOptions>): PageLayoutOptions {\n  const base: PageLayoutOptions = {\n    pageSize: 'A4',\n    orientation: 'portrait',\n    margins: { top: '1in', bottom: '1in', left: '1in', right: '1in' },\n  };\n  if (!layout) return base;\n  return {\n    ...base,\n    ...layout,\n    margins: { ...base.margins, ...(layout.margins || {}) },\n  };\n}\n","import { NodeSelection } from '@tiptap/pm/state';\r\n\r\n/**\r\n * Creates an image NodeView with corner and side drag handles for resizing.\r\n * Hold Shift while dragging to lock the aspect ratio.\r\n *\r\n * Wired up by the `Image` extension in `WordEditor`'s `addNodeView` so any\r\n * `<img>` node in the document gets these handles when selected.\r\n */\r\nexport function createImageResizeView(node: any, view: any, getPos: any) {\r\n    const wrapper = document.createElement('div');\r\n    wrapper.className = 'rk-image-resize-wrapper';\r\n    wrapper.setAttribute('contenteditable', 'false');\r\n    wrapper.setAttribute('draggable', 'true');\r\n\r\n    const img = document.createElement('img');\r\n    img.src = node.attrs.src;\r\n    img.alt = node.attrs.alt || '';\r\n    img.style.display = 'block';\r\n    img.style.maxWidth = '100%';\r\n    img.style.height = 'auto';\r\n\r\n    if (node.attrs.width) img.style.width = node.attrs.width;\r\n    if (node.attrs.height) img.style.height = node.attrs.height;\r\n    if (node.attrs.float) wrapper.style.float = node.attrs.float;\r\n\r\n    wrapper.appendChild(img);\r\n\r\n    // Click-to-select: makes the resize handles appear without keyboard nav.\r\n    img.addEventListener('mousedown', (e) => {\r\n        // Allow click-and-hold-to-drag (browser default for draggable=true) but\r\n        // also select the node so handles appear.\r\n        const pos = getPos();\r\n        if (typeof pos !== 'number') return;\r\n        try {\r\n            const tr = view.state.tr.setSelection(NodeSelection.create(view.state.doc, pos));\r\n            view.dispatch(tr);\r\n        } catch { /* not a selectable node */ }\r\n        // Don't preventDefault — we want native drag to start when held.\r\n        e.stopPropagation();\r\n    });\r\n\r\n    // Build resize handles: corners + sides\r\n    const handlePositions = ['nw', 'n', 'ne', 'e', 'se', 's', 'sw', 'w'];\r\n    handlePositions.forEach(pos => {\r\n        const handle = document.createElement('div');\r\n        handle.className = `rk-resize-handle rk-resize-handle-${pos}`;\r\n        handle.dataset.handle = pos;\r\n        wrapper.appendChild(handle);\r\n\r\n        let startX = 0;\r\n        let startY = 0;\r\n        let startW = 0;\r\n        let startH = 0;\r\n        let aspectRatio = 1;\r\n\r\n        handle.addEventListener('mousedown', (e: MouseEvent) => {\r\n            e.preventDefault();\r\n            e.stopPropagation();\r\n\r\n            startX = e.clientX;\r\n            startY = e.clientY;\r\n            startW = img.offsetWidth;\r\n            startH = img.offsetHeight;\r\n            aspectRatio = startH > 0 ? startW / startH : 1;\r\n            wrapper.classList.add('is-resizing');\r\n\r\n            const onMouseMove = (e: MouseEvent) => {\r\n                const dx = e.clientX - startX;\r\n                const dy = e.clientY - startY;\r\n                const lockAspect = e.shiftKey;\r\n\r\n                let newWidth = startW;\r\n                let newHeight = startH;\r\n\r\n                if (pos.includes('e')) newWidth = Math.max(60, startW + dx);\r\n                if (pos.includes('w')) newWidth = Math.max(60, startW - dx);\r\n                if (pos.includes('s')) newHeight = Math.max(40, startH + dy);\r\n                if (pos.includes('n')) newHeight = Math.max(40, startH - dy);\r\n\r\n                if (lockAspect) {\r\n                    if (pos.includes('e') || pos.includes('w')) {\r\n                        newHeight = Math.round(newWidth / aspectRatio);\r\n                    } else {\r\n                        newWidth = Math.round(newHeight * aspectRatio);\r\n                    }\r\n                }\r\n\r\n                img.style.width = `${newWidth}px`;\r\n                img.style.height = `${newHeight}px`;\r\n            };\r\n\r\n            const onMouseUp = () => {\r\n                wrapper.classList.remove('is-resizing');\r\n                document.removeEventListener('mousemove', onMouseMove);\r\n                document.removeEventListener('mouseup', onMouseUp);\r\n\r\n                const pos = getPos();\r\n                if (typeof pos === 'number') {\r\n                    const tr = view.state.tr.setNodeMarkup(pos, undefined, {\r\n                        ...node.attrs,\r\n                        width: img.style.width,\r\n                        height: img.style.height,\r\n                    });\r\n                    view.dispatch(tr);\r\n                }\r\n            };\r\n\r\n            document.addEventListener('mousemove', onMouseMove);\r\n            document.addEventListener('mouseup', onMouseUp);\r\n        });\r\n    });\r\n\r\n    const select = () => {\r\n        wrapper.classList.add('is-selected');\r\n    };\r\n    const deselect = () => {\r\n        wrapper.classList.remove('is-selected');\r\n    };\r\n\r\n    return {\r\n        dom: wrapper,\r\n        update(updatedNode: any) {\r\n            if (updatedNode.type.name !== 'image') return false;\r\n            img.src = updatedNode.attrs.src;\r\n            img.alt = updatedNode.attrs.alt || '';\r\n            if (updatedNode.attrs.width) img.style.width = updatedNode.attrs.width;\r\n            if (updatedNode.attrs.height) img.style.height = updatedNode.attrs.height;\r\n            return true;\r\n        },\r\n        selectNode: select,\r\n        deselectNode: deselect,\r\n        stopEvent: (event: Event) => event.target !== img,\r\n        destroy() { },\r\n    };\r\n}\r\n","import { Editor } from '@tiptap/core';\nimport StarterKit from '@tiptap/starter-kit';\nimport Underline from '@tiptap/extension-underline';\nimport Subscript from '@tiptap/extension-subscript';\nimport Superscript from '@tiptap/extension-superscript';\nimport { TextStyle } from '@tiptap/extension-text-style';\nimport FontFamily from '@tiptap/extension-font-family';\nimport Color from '@tiptap/extension-color';\nimport Highlight from '@tiptap/extension-highlight';\nimport TextAlign from '@tiptap/extension-text-align';\nimport { TaskList } from '@tiptap/extension-task-list';\nimport { TaskItem } from '@tiptap/extension-task-item';\nimport { Table } from '@tiptap/extension-table';\nimport { TableRow } from '@tiptap/extension-table-row';\nimport { TableCell } from '@tiptap/extension-table-cell';\nimport { TableHeader } from '@tiptap/extension-table-header';\nimport { Image } from '@tiptap/extension-image';\nimport Placeholder from '@tiptap/extension-placeholder';\nimport { Link } from './extensions/Link';\n\n// Core Extensions\nimport { FontSize } from './extensions/FontSize';\nimport { TextTransform } from './extensions/TextTransform';\nimport { LineHeight } from './extensions/LineHeight';\nimport { ParagraphSpacing } from './extensions/ParagraphSpacing';\nimport { Indent } from './extensions/Indent';\nimport { PageBreak } from './extensions/PageBreak';\nimport { Footnote } from './extensions/Footnote';\nimport { PasteHandler } from './extensions/PasteHandler';\nimport { AdvancedTypography } from './extensions/AdvancedTypography';\nimport { ParagraphSystem } from './extensions/ParagraphSystem';\nimport { StylesEngine } from './extensions/StylesEngine';\nimport { PageLayout, type PageLayoutOptions, DEFAULT_PAGE_LAYOUT } from './extensions/PageLayout';\nimport { Section } from './extensions/Section';\nimport { Header, Footer, PageNumber } from './extensions/HeaderFooter';\nimport { TableStyles } from './extensions/TableStyles';\nimport { MultilevelList } from './extensions/MultilevelList';\nimport { Caption } from './extensions/Caption';\nimport { ImageResize } from './extensions/ImageResize';\nimport { MathInline, MathBlock } from './extensions/Math';\nimport { TableOfContents } from './extensions/TableOfContents';\nimport { Citation, Bibliography } from './extensions/Citation';\nimport { SlashCommands, defaultSlashCommands, type SlashCommand } from './extensions/SlashCommands';\nimport { ImageUpload } from './extensions/ImageUpload';\nimport { FormatPainter } from './extensions/FormatPainter';\nimport { DragHandle } from './extensions/DragHandle';\nimport { TrackChanges, TrackInsert, TrackDelete } from './extensions/TrackChanges';\nimport { LeaderMark } from './extensions/LeaderMark';\nimport { FindReplace } from './extensions/FindReplace';\n\nimport { WordShortcuts } from './extensions/WordShortcuts';\nimport { TextBox } from './extensions/TextBox';\nimport { Pagination } from './extensions/Pagination';\nimport { Title, Subtitle } from './extensions/TitleSubtitle';\n\n// Utilities\nimport { DocumentValidator } from './DocumentValidator';\nimport { CommandManager } from './CommandManager';\nimport { ExportEngine, type ExportFormat, type ExportOptions } from './ExportEngine';\nimport { ImportEngine } from './ImportEngine';\nimport { StyleManager } from './StyleManager';\nimport { PrintEngine, type PrintOptions } from './PrintEngine';\nimport { createImageResizeView } from './extensions/ImageResizeHandle';\n\nexport type { ExportFormat, ExportOptions, SlashCommand, PageLayoutOptions, PrintOptions };\nexport { defaultSlashCommands, DEFAULT_PAGE_LAYOUT };\nexport { StyleManager } from './StyleManager';\nexport { ExportEngine } from './ExportEngine';\nexport { ImportEngine } from './ImportEngine';\nexport { PrintEngine } from './PrintEngine';\nexport { DocumentValidator } from './DocumentValidator';\nexport { CommandManager } from './CommandManager';\nexport type { ChangeRecord } from './extensions/TrackChanges';\n\nexport interface WordEditorOptions {\n  element: HTMLElement;\n  /** Initial document — HTML string or Tiptap JSON. */\n  initialContent?: string | Record<string, any>;\n  /** @deprecated Use `initialContent`. Kept for backwards compatibility. */\n  content?: string | Record<string, any>;\n  placeholder?: string;\n  editable?: boolean;\n  autofocus?: boolean | 'start' | 'end' | 'all' | number;\n  pageLayout?: Partial<PageLayoutOptions>;\n  trackAuthor?: string;\n  imageUploadHandler?: (file: File) => Promise<string>;\n  slashCommands?: SlashCommand[];\n  dragHandles?: boolean;\n  onUpdate?: (json: any, editor: Editor) => void;\n  onWordCount?: (stats: WordCountStats) => void;\n  onSelectionChange?: (editor: Editor) => void;\n}\n\nexport interface WordCountStats {\n  words: number;\n  characters: number;\n  charactersNoSpaces: number;\n  paragraphs: number;\n  sentences: number;\n  pages: number;\n  readingTimeMinutes: number;\n}\n\nexport class WordEditor {\n  private editor: Editor;\n  public commands: CommandManager;\n  private exporter: ExportEngine;\n  private importer: ImportEngine;\n  private printer: PrintEngine;\n  private _styleManager: StyleManager;\n  private _pageLayout: PageLayoutOptions;\n  private _zoom = 1;\n\n  constructor(options: WordEditorOptions) {\n    this._styleManager = new StyleManager();\n    this.importer = new ImportEngine();\n    this._pageLayout = { ...DEFAULT_PAGE_LAYOUT, ...(options.pageLayout || {}) };\n\n    const initial = options.initialContent ?? options.content ?? '';\n\n    this.editor = new Editor({\n      element: options.element,\n      editable: options.editable !== false,\n      autofocus: options.autofocus,\n      extensions: [\n        StarterKit.configure({ codeBlock: { HTMLAttributes: { class: 'rk-code-block' } } }),\n        Placeholder.configure({\n          // Only show the placeholder when the editor is completely empty —\n          // not on every blank paragraph created by Enter.\n          placeholder: options.placeholder ?? 'Start typing here…',\n          showOnlyWhenEditable: true,\n          showOnlyCurrent: true,\n          includeChildren: false,\n          emptyEditorClass: 'is-editor-empty',\n          emptyNodeClass: 'is-empty',\n        }),\n        Underline,\n        TextStyle,\n        FontFamily,\n        Color,\n        Highlight.configure({ multicolor: true }),\n        Subscript,\n        Superscript,\n        TextAlign.configure({ types: ['heading', 'paragraph'] }),\n        Table.configure({ resizable: true, lastColumnResizable: true }),\n        TableRow,\n        TableHeader,\n        TableCell,\n        TableStyles,\n        TaskList,\n        TaskItem.configure({ nested: true }),\n        MultilevelList,\n        Link.configure({\n          openOnClick: false,\n          HTMLAttributes: { class: 'rk-link' },\n        }),\n        Image.configure({ inline: false, HTMLAttributes: { class: 'rk-image' } }).extend({\n          addNodeView() {\n            return (props) => createImageResizeView(props.node, props.view, props.getPos);\n          },\n        }),\n        ImageResize,\n        ImageUpload.configure({ onUpload: options.imageUploadHandler ?? null }),\n        Caption,\n        MathInline,\n        MathBlock,\n        FontSize,\n        TextTransform,\n        LineHeight,\n        ParagraphSpacing,\n        Indent,\n        PageBreak,\n        Footnote,\n        PasteHandler,\n        AdvancedTypography,\n        ParagraphSystem,\n        StylesEngine,\n        PageLayout.configure(this._pageLayout),\n        Section,\n        Header,\n        Footer,\n        PageNumber,\n        TableOfContents,\n        Citation,\n        Bibliography,\n        SlashCommands.configure({ commands: options.slashCommands ?? defaultSlashCommands }),\n        FormatPainter,\n        TrackChanges.configure({ author: options.trackAuthor || 'Author' }),\n        TrackInsert,\n        TrackDelete,\n        LeaderMark,\n        FindReplace,\n        WordShortcuts,\n        TextBox,\n        Title,\n        Subtitle,\n        Pagination,\n        ...(options.dragHandles !== false ? [DragHandle] : []),\n      ],\n      content: initial,\n      onUpdate: ({ editor }) => {\n        options.onUpdate?.(editor.getJSON(), editor);\n        if (options.onWordCount) options.onWordCount(this.getWordCount());\n      },\n      onSelectionUpdate: ({ editor }) => options.onSelectionChange?.(editor),\n    });\n\n    this.commands = new CommandManager(this.editor);\n    this.exporter = new ExportEngine(this._styleManager);\n    this.printer = new PrintEngine();\n\n    (this.editor as any).options.parent = this;\n    this.applyPageLayoutToDOM(options.element);\n    this.syncPaginationLayout();\n  }\n\n  /** Push the current page-content height (in CSS pixels) into the Pagination\n   *  extension so the on-screen page boundary indicators reflect the layout. */\n  private syncPaginationLayout(): void {\n    const layoutPx = pageContentHeightPx(this._pageLayout);\n    const storage: any = (this.editor.storage as any).pagination;\n    if (storage) storage.contentHeightPx = layoutPx;\n    // Force a re-paint of the boundaries.\n    try {\n      const view = this.editor.view;\n      view.dispatch(view.state.tr.setMeta({ key: 'rkPagination' } as any, true));\n    } catch { /* noop */ }\n  }\n\n  // ---- Core API ----\n  public getHTML(): string { return this.editor.getHTML(); }\n  public getJSON(): any { return this.editor.getJSON(); }\n  public getText(): string { return this.editor.state.doc.textContent; }\n  public isEmpty(): boolean { return this.editor.isEmpty; }\n  public isEditable(): boolean { return this.editor.isEditable; }\n\n  public setDocument(content: string | any): void {\n    const validated = typeof content === 'object' ? DocumentValidator.validate(content) : content;\n    this.editor.commands.setContent(validated);\n  }\n\n  public clear(): void { this.editor.commands.clearContent(true); }\n  public focus(pos: 'start' | 'end' | 'all' | number = 'end'): void { this.editor.commands.focus(pos as any); }\n  public blur(): void { this.editor.commands.blur(); }\n  public destroy(): void { this.editor.destroy(); }\n\n  /** Toggle the editor between editable and read-only mode. */\n  public setEditable(editable: boolean): void {\n    this.editor.setEditable(editable);\n  }\n\n  // ---- Format proxy (legacy compatibility) ----\n  public get format() { return this.commands; }\n\n  // ---- Export API ----\n  public async exportDocx(filename = 'document.docx') {\n    return this.exporter.exportToDocx(this.getJSON(), { filename, pageLayout: this._pageLayout });\n  }\n\n  public async exportMarkdown(filename = 'document.md'): Promise<void> {\n    const md = await this.importer.exportMarkdown(this.getHTML());\n    this.importer.downloadMarkdown(md, filename);\n  }\n\n  public exportHtml(filename = 'document.html'): void {\n    const html = `<!doctype html>\n<html lang=\"en\">\n<head><meta charset=\"utf-8\"><title>Document</title></head>\n<body>${this.getHTML()}</body>\n</html>`;\n    const blob = new Blob([html], { type: 'text/html;charset=utf-8' });\n    const url = URL.createObjectURL(blob);\n    const a = document.createElement('a');\n    a.href = url;\n    a.download = filename;\n    a.click();\n    URL.revokeObjectURL(url);\n  }\n\n  public exportJson(filename = 'document.json'): void {\n    const blob = new Blob([JSON.stringify(this.getJSON(), null, 2)], { type: 'application/json' });\n    const url = URL.createObjectURL(blob);\n    const a = document.createElement('a');\n    a.href = url;\n    a.download = filename;\n    a.click();\n    URL.revokeObjectURL(url);\n  }\n\n  public async export(format: ExportFormat | 'markdown' | 'json', options: ExportOptions = {}) {\n    switch (format) {\n      case 'docx': return this.exportDocx(options.filename);\n      case 'pdf': return this.printPdf(options as any);\n      case 'html': return this.exportHtml(options.filename);\n      case 'markdown': return this.exportMarkdown(options.filename);\n      case 'json': return this.exportJson(options.filename);\n      default: console.warn(`Unsupported export format: ${format}`);\n    }\n  }\n\n  // ---- Print / PDF ----\n  /**\n   * Print only the editor content in an isolated iframe with A4 portrait\n   * defaults. Use the browser's \"Save as PDF\" option to export PDF.\n   */\n  public printPdf(options: PrintOptions = {}): void {\n    const html = this.getPrintableHTML();\n    this.printer.print(html, {\n      pageLayout: this._pageLayout,\n      title: 'Document',\n      ...options,\n    });\n  }\n\n  /**\n   * Build print-ready HTML by cloning the live editor DOM. This preserves\n   * NodeView-rendered content (Table of Contents, image resize wrappers,\n   * text boxes) that `editor.getHTML()` cannot serialize, then strips\n   * editor-only chrome (drag handles, resize handles, pagination spacers,\n   * contenteditable attrs).\n   */\n  public getPrintableHTML(): string {\n    const editorEl = this.editor.options.element as HTMLElement | undefined;\n    const proseMirror = editorEl?.querySelector('.ProseMirror') as HTMLElement | null;\n    if (!proseMirror) return this.getHTML();\n\n    const clone = proseMirror.cloneNode(true) as HTMLElement;\n\n    const dropSelectors = [\n      '.rk-page-spacer',\n      '.rk-resize-handle',\n      '.rk-textbox-handle',\n      '.rk-textbox-drag',\n      '.rk-drag-handle',\n      '.rk-toc-refresh',\n      '.ProseMirror-widget',\n      '.ProseMirror-gapcursor',\n      '.ProseMirror-separator',\n    ];\n    clone.querySelectorAll(dropSelectors.join(',')).forEach(el => el.remove());\n\n    clone.querySelectorAll('[contenteditable]').forEach(el => el.removeAttribute('contenteditable'));\n    clone.querySelectorAll('.ProseMirror-selectednode').forEach(el => el.classList.remove('ProseMirror-selectednode'));\n\n    return clone.innerHTML;\n  }\n\n  // ---- Import API ----\n  public async importDocx(file: File): Promise<void> {\n    const html = await this.importer.importDocx(file);\n    this.setDocument(html);\n  }\n\n  public async importMarkdown(text: string): Promise<void> {\n    const html = await this.importer.importMarkdown(text);\n    this.setDocument(html);\n  }\n\n  public async importFromFile(file: File): Promise<void> {\n    const name = file.name.toLowerCase();\n    if (name.endsWith('.docx')) return this.importDocx(file);\n    if (name.endsWith('.md') || name.endsWith('.markdown')) {\n      const text = await file.text();\n      return this.importMarkdown(text);\n    }\n    if (name.endsWith('.html') || name.endsWith('.htm')) {\n      const html = await file.text();\n      this.setDocument(html);\n      return;\n    }\n    if (name.endsWith('.json')) {\n      const text = await file.text();\n      this.setDocument(JSON.parse(text));\n      return;\n    }\n    if (name.endsWith('.txt')) {\n      const text = await file.text();\n      const html = text.split(/\\r?\\n/).map(l => `<p>${escapeHtml(l) || '<br>'}</p>`).join('');\n      this.setDocument(html);\n      return;\n    }\n    throw new Error(`Unsupported file format: ${file.name}`);\n  }\n\n  // ---- Document Tools ----\n  public getTableOfContents(): { level: number; text: string; id: string }[] {\n    const headings: { level: number; text: string; id: string }[] = [];\n    this.editor.state.doc.descendants((node) => {\n      if (node.type.name === 'heading') {\n        const text = node.textContent;\n        const id = slugify(text);\n        headings.push({ level: node.attrs.level, text, id });\n      }\n    });\n    return headings;\n  }\n\n  public getWordCount(): WordCountStats {\n    // `doc.textContent` concatenates with no block separators, so adjacent\n    // blocks ('apple', 'ball') would be counted as one word. Use textBetween\n    // with a newline separator to get correct word boundaries across blocks.\n    const doc = this.editor.state.doc;\n    const text = doc.textBetween(0, doc.content.size, '\\n', ' ');\n    const trimmed = text.trim();\n    const words = trimmed ? trimmed.split(/[\\s ]+/).filter(Boolean).length : 0;\n    const characters = text.length;\n    const charactersNoSpaces = text.replace(/\\s/g, '').length;\n    let paragraphs = 0;\n    doc.descendants(node => {\n      if (node.type.name === 'paragraph' && node.textContent.length) paragraphs++;\n    });\n    const sentences = trimmed\n      ? (trimmed.match(/[^.!?\\n]+[.!?]+/g) || [trimmed]).length\n      : 0;\n    const pages = Math.max(1, Math.ceil(words / 250));\n    const readingTimeMinutes = Math.max(1, Math.ceil(words / 200));\n    return { words, characters, charactersNoSpaces, paragraphs, sentences, pages, readingTimeMinutes };\n  }\n\n  // ---- Track Changes API ----\n  public toggleTrackChanges(): void {\n    (this.editor as any).chain().toggleTrackChanges().run();\n  }\n\n  public isTrackingChanges(): boolean {\n    return (this.editor.storage.trackChanges as any)?.enabled ?? false;\n  }\n\n  // ---- Find & Replace ----\n  public find(query: string, options: { caseSensitive?: boolean; regex?: boolean } = {}): number {\n    return (this.editor.commands as any).findText(query, options);\n  }\n\n  public replace(query: string, replacement: string, all = false, options: { caseSensitive?: boolean; regex?: boolean } = {}): number {\n    return (this.editor.commands as any)[all ? 'replaceAllText' : 'replaceText'](query, replacement, options);\n  }\n\n  public clearSearch(): void {\n    (this.editor.commands as any).clearSearch();\n  }\n\n  // ---- Pagination ----\n  /** Current measured page count from the Pagination extension. */\n  public getPageCount(): number {\n    return (this.editor.storage as any)?.pagination?.pageCount || 1;\n  }\n\n  /** Inside-page area in CSS pixels (page height minus top/bottom margins). */\n  public getPageContentHeightPx(): number {\n    return pageContentHeightPx(this._pageLayout);\n  }\n\n  // ---- Page Layout ----\n  public getPageLayout(): PageLayoutOptions { return { ...this._pageLayout }; }\n\n  public setPageLayout(layout: Partial<PageLayoutOptions>): void {\n    this._pageLayout = { ...this._pageLayout, ...layout };\n    if (layout.margins) this._pageLayout.margins = { ...this._pageLayout.margins, ...layout.margins };\n    this.applyPageLayoutToDOM(this.editor.options.element as HTMLElement);\n    this.syncPaginationLayout();\n  }\n\n  private applyPageLayoutToDOM(host: HTMLElement) {\n    const { width, height } = resolvePageDimensions(this._pageLayout);\n    const contentPx = pageContentHeightPx(this._pageLayout);\n    const editorEl = host.querySelector('.ProseMirror') as HTMLElement | null;\n    if (!editorEl) return;\n    editorEl.style.setProperty('--rk-page-width', width);\n    editorEl.style.setProperty('--rk-page-height', height);\n    editorEl.style.setProperty('--rk-page-content-height', `${contentPx}px`);\n    editorEl.style.setProperty('--rk-page-margin-top', this._pageLayout.margins.top);\n    editorEl.style.setProperty('--rk-page-margin-bottom', this._pageLayout.margins.bottom);\n    editorEl.style.setProperty('--rk-page-margin-left', this._pageLayout.margins.left);\n    editorEl.style.setProperty('--rk-page-margin-right', this._pageLayout.margins.right);\n    editorEl.dataset.pageOrientation = this._pageLayout.orientation;\n  }\n\n  // ---- Zoom ----\n  public getZoom(): number { return this._zoom; }\n\n  public setZoom(zoom: number): void {\n    const z = Math.min(3, Math.max(0.25, zoom));\n    this._zoom = z;\n    const editorEl = this.editor.options.element as HTMLElement;\n    const surface = editorEl.querySelector('.ProseMirror') as HTMLElement | null;\n    if (surface) {\n      surface.style.transform = `scale(${z})`;\n      surface.style.transformOrigin = 'top center';\n    }\n  }\n\n  // ---- Auto-save ----\n  public enableAutoSave(key = 'rk-editor-content', debounceMs = 500): () => void {\n    let timer: ReturnType<typeof setTimeout> | null = null;\n    const handler = () => {\n      if (timer) clearTimeout(timer);\n      timer = setTimeout(() => {\n        try {\n          localStorage.setItem(key, JSON.stringify(this.getJSON()));\n        } catch (e) {\n          console.warn('[WordEditor] Auto-save failed', e);\n        }\n      }, debounceMs);\n    };\n    this.editor.on('update', handler);\n    return () => this.editor.off('update', handler);\n  }\n\n  public loadAutoSave(key = 'rk-editor-content'): boolean {\n    const saved = localStorage.getItem(key);\n    if (!saved) return false;\n    try {\n      this.setDocument(JSON.parse(saved));\n      return true;\n    } catch (e) {\n      console.error('Failed to load autosave:', e);\n      return false;\n    }\n  }\n\n  public clearAutoSave(key = 'rk-editor-content'): void {\n    localStorage.removeItem(key);\n  }\n\n  // ---- Instance access ----\n  public get instance(): Editor { return this.editor; }\n  public get styleManager(): StyleManager { return this._styleManager; }\n}\n\nfunction escapeHtml(s: string): string {\n  return s.replace(/[&<>\"']/g, c => ({ '&': '&amp;', '<': '&lt;', '>': '&gt;', '\"': '&quot;', \"'\": '&#39;' }[c]!));\n}\n\nfunction slugify(s: string): string {\n  return s.toLowerCase().trim().replace(/\\s+/g, '-').replace(/[^a-z0-9-]/g, '').replace(/-+/g, '-');\n}\n\nfunction resolvePageDimensions(layout: PageLayoutOptions): { width: string; height: string } {\n  const portraitSizes: Record<string, [string, string]> = {\n    A4: ['210mm', '297mm'],\n    A3: ['297mm', '420mm'],\n    A5: ['148mm', '210mm'],\n    Letter: ['8.5in', '11in'],\n    Legal: ['8.5in', '14in'],\n    Tabloid: ['11in', '17in'],\n  };\n  const [w, h] = portraitSizes[layout.pageSize] || portraitSizes.A4;\n  if (layout.orientation === 'landscape') return { width: h, height: w };\n  return { width: w, height: h };\n}\n\n/** Return the editable content area height (page height minus top/bottom margins) in CSS pixels. */\nfunction pageContentHeightPx(layout: PageLayoutOptions): number {\n  const { height } = resolvePageDimensions(layout);\n  const totalPx = cssLengthToPx(height);\n  const topPx = cssLengthToPx(layout.margins.top);\n  const botPx = cssLengthToPx(layout.margins.bottom);\n  return Math.max(200, Math.round(totalPx - topPx - botPx));\n}\n\nfunction cssLengthToPx(value: string): number {\n  if (!value) return 0;\n  const s = String(value).trim();\n  const num = parseFloat(s);\n  if (isNaN(num)) return 0;\n  if (s.endsWith('in')) return num * 96;\n  if (s.endsWith('cm')) return num * 37.795;\n  if (s.endsWith('mm')) return num * 3.7795;\n  if (s.endsWith('pt')) return num * 1.333;\n  if (s.endsWith('pc')) return num * 16;\n  if (s.endsWith('px')) return num;\n  return num;\n}\n"],"names":["Link","Mark","HTMLAttributes","mergeAttributes","attributes","chain","FontSize","Extension","element","fontSize","TextTransform","textTransform","LineHeight","lineHeight","commands","type","ParagraphSpacing","spacing","Indent","t","currentIndent","PageBreak","Node","Footnote","content","PasteHandler","Plugin","PluginKey","view","event","html","doc","walker","node","el","AdvancedTypography","letterSpacing","wordSpacing","ParagraphSystem","padding","attrs","StyleManager","__publicField","style","name","resolved","currentParent","parentStyle","StylesEngine","resolvedAttributes","chainExec","level","DEFAULT_PAGE_LAYOUT","PageLayout","options","editor","parent","Section","Header","Footer","PageNumber","TableStyles","width","MultilevelList","listStyle","state","dispatch","selection","tr","found","pos","startNumber","Caption","ImageResize","height","float","MathInline","latex","MathBlock","TOC_TYPE","TableOfContents","a","changed","minLevel","maxLevel","$from","d","n","getPos","root","render","items","collectHeadings","header","escapeHtml","e","empty","list","item","li","link","text","leader","page","dom","updated","charCount","CHARS_PER_PAGE","slug","s","c","Citation","key","label","Bibliography","DEFAULT_COMMANDS","SlashCommands","extension","_view","_prevState","textBefore","query","cmd","commandTitle","from","start","ImageUpload","file","src","reader","input","files","imageFiles","f","handled","FormatPainter","to","marks","seen","range","mark","nodeType","nodeAttrs","fmt","targetType","markType","ext","_event","DragHandle","draggedNode","handleEl","currentPos","editorView","hide","onMouseMove","blockDepth","blockNode","rect","editorRect","_slice","moved","coords","dropPos","targetPos","insertAt","TrackChanges","changeId","change","transactions","oldState","newState","trackInsertType","trackDeleteType","origTr","step","_index","map","TrackInsert","TrackDelete","LeaderMark","KEY","buildRegex","opts","pattern","flags","findMatches","results","regex","match","decorationsFor","current","decos","r","i","Decoration","DecorationSet","FindReplace","replacement","target","oldSet","WordShortcuts","heading","TextBox","w","h","x","y","applyTransform","dragHandle","handlePositions","startX","startY","startW","startH","startNX","startNY","onMove","m","dx","dy","h2","nx","ny","onUp","pos2","dragging","dStartX","dStartY","dStartNX","dStartNY","contentDOM","Pagination","computePageBoundaries","rafId","lastRun","lastWidth","MIN_INTERVAL","recompute","force","now","obs","entries","next","onWindowResize","newView","pageHeight","defaultA4ContentPx","proseMirror","pageIndex","pageStartY","containerRect","totalContentHeight","offset","top","bottom","pageEnd","remaining","makeSpacer","fromHardBreak","Title","Subtitle","DocumentValidator","json","nodes","index","CommandManager","font","size","color","alignment","value","alt","href","q","title","filename","fn","saveAs","fileSaver","TWIPS_PER_INCH","TWIPS_PER_CM","TWIPS_PER_MM","TWIPS_PER_PT","DOCX_PAGE_SIZES","HEADING_MAP","HeadingLevel","ExportEngine","_styleManager","blob","sectionChildren","pageProps","sectionPropertiesFromLayout","Document","Packer","out","Paragraph","TextRun","BorderStyle","ref","AlignmentType","children","applyParagraphStyling","clamp","child","inlines","showLeader","showPageNumbers","indent","isTopLevel","runs","ShadingType","mapAlignment","data","fetchImageData","dim","parseImageSize","imageRun","ImageRun","childList","nested","marker","rows","row","TableRow","TableCell","Table","WidthType","cells","cell","isHeader","childContent","fill","bg","colorToHex","VerticalAlign","inline","ExternalHyperlink","formatToRun","UnderlineType","hex","parseFontSize","decimal","_","LevelFormat","bullet","b","nepali","before","parseSpacingTwips","after","line","left","parseIndentTwips","firstLine","align","num","parts","g","lo","hi","layout","orientation","PageOrientation","sizeKey","dims","margins","mime","bin","bytes","mimeToDocxType","res","buf","guessMimeFromUrl","parseDimensionPx","visit","textOf","v","ImportEngine","mammoth","arrayBuffer","result","marked","mod","TurndownService","service","gfm","markdown","url","DEFAULT_PRINT_CSS","PrintEngine","mergePageLayout","pageSize","printPageSize","margin","iframe","docHtml","escape","cleanup","trigger","waitForImages","images","img","resolve","orient","base","createImageResizeView","wrapper","NodeSelection","handle","aspectRatio","lockAspect","newWidth","newHeight","onMouseUp","updatedNode","WordEditor","initial","Editor","StarterKit","Placeholder","Underline","TextStyle","FontFamily","Color","Highlight","Subscript","Superscript","TextAlign","TableHeader","TaskList","TaskItem","Image","props","defaultSlashCommands","layoutPx","pageContentHeightPx","storage","validated","editable","md","format","clone","dropSelectors","l","headings","id","slugify","trimmed","words","characters","charactersNoSpaces","paragraphs","sentences","pages","readingTimeMinutes","all","host","resolvePageDimensions","contentPx","editorEl","zoom","z","surface","debounceMs","timer","handler","saved","portraitSizes","totalPx","cssLengthToPx","topPx","botPx"],"mappings":"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"}