authorly-editor 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.cjs.js","sources":["../src/utils/helpers.ts","../src/core/block-registry.ts","../src/blocks/paragraph.ts","../src/blocks/heading.ts","../src/blocks/list.ts","../src/blocks/quote.ts","../src/blocks/code.ts","../src/blocks/image.ts","../src/blocks/video.ts","../src/blocks/divider.ts","../src/blocks/callout.ts","../src/blocks/accordion.ts","../src/blocks/table.ts","../src/blocks/index.ts","../src/paste/sanitize.ts","../src/drag/drag-handle.ts","../src/core/selection.ts","../node_modules/lucide-react/dist/esm/defaultAttributes.js","../node_modules/lucide-react/dist/esm/createLucideIcon.js","../node_modules/lucide-react/dist/esm/icons/alert-circle.js","../node_modules/lucide-react/dist/esm/icons/alert-triangle.js","../node_modules/lucide-react/dist/esm/icons/align-center.js","../node_modules/lucide-react/dist/esm/icons/align-justify.js","../node_modules/lucide-react/dist/esm/icons/align-left.js","../node_modules/lucide-react/dist/esm/icons/align-right.js","../node_modules/lucide-react/dist/esm/icons/bold.js","../node_modules/lucide-react/dist/esm/icons/check-circle.js","../node_modules/lucide-react/dist/esm/icons/check-square.js","../node_modules/lucide-react/dist/esm/icons/check.js","../node_modules/lucide-react/dist/esm/icons/chevron-down.js","../node_modules/lucide-react/dist/esm/icons/chevron-up.js","../node_modules/lucide-react/dist/esm/icons/clipboard-paste.js","../node_modules/lucide-react/dist/esm/icons/code.js","../node_modules/lucide-react/dist/esm/icons/columns.js","../node_modules/lucide-react/dist/esm/icons/copy.js","../node_modules/lucide-react/dist/esm/icons/download.js","../node_modules/lucide-react/dist/esm/icons/eraser.js","../node_modules/lucide-react/dist/esm/icons/external-link.js","../node_modules/lucide-react/dist/esm/icons/file-code.js","../node_modules/lucide-react/dist/esm/icons/file-text.js","../node_modules/lucide-react/dist/esm/icons/file.js","../node_modules/lucide-react/dist/esm/icons/grip-vertical.js","../node_modules/lucide-react/dist/esm/icons/heading-1.js","../node_modules/lucide-react/dist/esm/icons/heading-2.js","../node_modules/lucide-react/dist/esm/icons/heading-3.js","../node_modules/lucide-react/dist/esm/icons/heading-4.js","../node_modules/lucide-react/dist/esm/icons/heading-5.js","../node_modules/lucide-react/dist/esm/icons/heading-6.js","../node_modules/lucide-react/dist/esm/icons/highlighter.js","../node_modules/lucide-react/dist/esm/icons/image.js","../node_modules/lucide-react/dist/esm/icons/indent.js","../node_modules/lucide-react/dist/esm/icons/info.js","../node_modules/lucide-react/dist/esm/icons/italic.js","../node_modules/lucide-react/dist/esm/icons/link-2-off.js","../node_modules/lucide-react/dist/esm/icons/link.js","../node_modules/lucide-react/dist/esm/icons/list-ordered.js","../node_modules/lucide-react/dist/esm/icons/list.js","../node_modules/lucide-react/dist/esm/icons/maximize-2.js","../node_modules/lucide-react/dist/esm/icons/minus.js","../node_modules/lucide-react/dist/esm/icons/moon.js","../node_modules/lucide-react/dist/esm/icons/more-horizontal.js","../node_modules/lucide-react/dist/esm/icons/move-down.js","../node_modules/lucide-react/dist/esm/icons/move-up.js","../node_modules/lucide-react/dist/esm/icons/outdent.js","../node_modules/lucide-react/dist/esm/icons/palette.js","../node_modules/lucide-react/dist/esm/icons/plus.js","../node_modules/lucide-react/dist/esm/icons/quote.js","../node_modules/lucide-react/dist/esm/icons/redo.js","../node_modules/lucide-react/dist/esm/icons/rotate-ccw.js","../node_modules/lucide-react/dist/esm/icons/rows.js","../node_modules/lucide-react/dist/esm/icons/scissors.js","../node_modules/lucide-react/dist/esm/icons/search.js","../node_modules/lucide-react/dist/esm/icons/settings.js","../node_modules/lucide-react/dist/esm/icons/strikethrough.js","../node_modules/lucide-react/dist/esm/icons/sun.js","../node_modules/lucide-react/dist/esm/icons/table.js","../node_modules/lucide-react/dist/esm/icons/trash-2.js","../node_modules/lucide-react/dist/esm/icons/type.js","../node_modules/lucide-react/dist/esm/icons/underline.js","../node_modules/lucide-react/dist/esm/icons/undo.js","../node_modules/lucide-react/dist/esm/icons/upload.js","../node_modules/lucide-react/dist/esm/icons/video.js","../node_modules/lucide-react/dist/esm/icons/x-circle.js","../node_modules/lucide-react/dist/esm/icons/x.js","../src/core/commands.ts","../src/components/Toolbar.tsx","../src/components/BlockMenu.tsx","../src/components/Editor.tsx","../src/components/Renderer.tsx","../src/components/TableOfContents.tsx","../src/components/BlockWrapper.tsx","../src/icons/index.tsx"],"sourcesContent":["/**\r\n * Utility Functions for Content Blocks Editor\r\n */\r\n\r\n/**\r\n * Generate a unique ID\r\n */\r\nexport function generateId(): string {\r\n return `cb-${Date.now().toString(36)}-${Math.random().toString(36).substring(2, 9)}`;\r\n}\r\n\r\n/**\r\n * Deep clone an object\r\n */\r\nexport function deepClone<T>(obj: T): T {\r\n if (obj === null || typeof obj !== 'object') {\r\n return obj;\r\n }\r\n if (Array.isArray(obj)) {\r\n return obj.map(item => deepClone(item)) as T;\r\n }\r\n const cloned = {} as T;\r\n for (const key in obj) {\r\n if (Object.prototype.hasOwnProperty.call(obj, key)) {\r\n cloned[key] = deepClone(obj[key]);\r\n }\r\n }\r\n return cloned;\r\n}\r\n\r\n/**\r\n * Debounce a function\r\n */\r\nexport function debounce<T extends (...args: unknown[]) => void>(\r\n fn: T,\r\n delay: number\r\n): (...args: Parameters<T>) => void {\r\n let timeoutId: ReturnType<typeof setTimeout>;\r\n return function (...args: Parameters<T>) {\r\n clearTimeout(timeoutId);\r\n timeoutId = setTimeout(() => fn(...args), delay);\r\n };\r\n}\r\n\r\n/**\r\n * Throttle a function\r\n */\r\nexport function throttle<T extends (...args: unknown[]) => void>(\r\n fn: T,\r\n limit: number\r\n): (...args: Parameters<T>) => void {\r\n let inThrottle = false;\r\n return function (...args: Parameters<T>) {\r\n if (!inThrottle) {\r\n fn(...args);\r\n inThrottle = true;\r\n setTimeout(() => (inThrottle = false), limit);\r\n }\r\n };\r\n}\r\n\r\n/**\r\n * Check if element is a block element\r\n */\r\nexport function isBlockElement(element: Element): boolean {\r\n return element.hasAttribute('data-block-id');\r\n}\r\n\r\n/**\r\n * Get the block element from a child element\r\n */\r\nexport function getBlockFromChild(element: Node | null): HTMLElement | null {\r\n if (!element) return null;\r\n \r\n let current: Node | null = element;\r\n while (current) {\r\n if (current instanceof HTMLElement && current.hasAttribute('data-block-id')) {\r\n return current;\r\n }\r\n current = current.parentNode;\r\n }\r\n return null;\r\n}\r\n\r\n/**\r\n * Get all text content from an element\r\n */\r\nexport function getTextContent(element: HTMLElement): string {\r\n return element.textContent || '';\r\n}\r\n\r\n/**\r\n * Count words in text\r\n */\r\nexport function countWords(text: string): number {\r\n return text\r\n .trim()\r\n .split(/\\s+/)\r\n .filter(word => word.length > 0).length;\r\n}\r\n\r\n/**\r\n * Count characters in text\r\n */\r\nexport function countCharacters(text: string, includeSpaces = true): number {\r\n return includeSpaces ? text.length : text.replace(/\\s/g, '').length;\r\n}\r\n\r\n/**\r\n * Check if selection is collapsed (cursor with no selection)\r\n */\r\nexport function isSelectionCollapsed(): boolean {\r\n const selection = window.getSelection();\r\n return selection ? selection.isCollapsed : true;\r\n}\r\n\r\n/**\r\n * Get current selection range\r\n */\r\nexport function getSelectionRange(): Range | null {\r\n const selection = window.getSelection();\r\n if (selection && selection.rangeCount > 0) {\r\n return selection.getRangeAt(0);\r\n }\r\n return null;\r\n}\r\n\r\n/**\r\n * Set selection range\r\n */\r\nexport function setSelectionRange(range: Range): void {\r\n const selection = window.getSelection();\r\n if (selection) {\r\n selection.removeAllRanges();\r\n selection.addRange(range);\r\n }\r\n}\r\n\r\n/**\r\n * Save current selection\r\n */\r\nexport function saveSelection(): Range | null {\r\n return getSelectionRange()?.cloneRange() || null;\r\n}\r\n\r\n/**\r\n * Restore selection from saved range\r\n */\r\nexport function restoreSelection(range: Range | null): void {\r\n if (range) {\r\n setSelectionRange(range);\r\n }\r\n}\r\n\r\n/**\r\n * Place cursor at end of element\r\n */\r\nexport function placeCursorAtEnd(element: HTMLElement): void {\r\n const range = document.createRange();\r\n const selection = window.getSelection();\r\n \r\n range.selectNodeContents(element);\r\n range.collapse(false);\r\n \r\n if (selection) {\r\n selection.removeAllRanges();\r\n selection.addRange(range);\r\n }\r\n}\r\n\r\n/**\r\n * Place cursor at start of element\r\n */\r\nexport function placeCursorAtStart(element: HTMLElement): void {\r\n const range = document.createRange();\r\n const selection = window.getSelection();\r\n \r\n range.selectNodeContents(element);\r\n range.collapse(true);\r\n \r\n if (selection) {\r\n selection.removeAllRanges();\r\n selection.addRange(range);\r\n }\r\n}\r\n\r\n/**\r\n * Check if element is empty (only whitespace)\r\n */\r\nexport function isElementEmpty(element: HTMLElement): boolean {\r\n const text = element.textContent || '';\r\n return text.trim().length === 0 && !element.querySelector('img, video, iframe');\r\n}\r\n\r\n/**\r\n * Strip HTML tags and get clean text\r\n */\r\nexport function stripHtml(html: string): string {\r\n const temp = document.createElement('div');\r\n temp.innerHTML = html;\r\n return temp.textContent || temp.innerText || '';\r\n}\r\n\r\n/**\r\n * Escape HTML special characters\r\n */\r\nexport function escapeHtml(text: string): string {\r\n const div = document.createElement('div');\r\n div.textContent = text;\r\n return div.innerHTML;\r\n}\r\n\r\n/**\r\n * Parse HTML string to element\r\n */\r\nexport function parseHtml(html: string): DocumentFragment {\r\n const template = document.createElement('template');\r\n template.innerHTML = html.trim();\r\n return template.content;\r\n}\r\n\r\n/**\r\n * Serialize element to HTML string\r\n */\r\nexport function serializeElement(element: HTMLElement): string {\r\n return element.outerHTML;\r\n}\r\n\r\n/**\r\n * Get element index among siblings\r\n */\r\nexport function getElementIndex(element: HTMLElement): number {\r\n const parent = element.parentElement;\r\n if (!parent) return -1;\r\n return Array.from(parent.children).indexOf(element);\r\n}\r\n\r\n/**\r\n * Insert element after reference element\r\n */\r\nexport function insertAfter(newElement: HTMLElement, referenceElement: HTMLElement): void {\r\n const parent = referenceElement.parentElement;\r\n if (parent) {\r\n parent.insertBefore(newElement, referenceElement.nextSibling);\r\n }\r\n}\r\n\r\n/**\r\n * Insert element before reference element\r\n */\r\nexport function insertBefore(newElement: HTMLElement, referenceElement: HTMLElement): void {\r\n const parent = referenceElement.parentElement;\r\n if (parent) {\r\n parent.insertBefore(newElement, referenceElement);\r\n }\r\n}\r\n\r\n/**\r\n * Swap two elements\r\n */\r\nexport function swapElements(el1: HTMLElement, el2: HTMLElement): void {\r\n const parent1 = el1.parentNode;\r\n const sibling1 = el1.nextSibling === el2 ? el1 : el1.nextSibling;\r\n \r\n el2.parentNode?.insertBefore(el1, el2);\r\n parent1?.insertBefore(el2, sibling1);\r\n}\r\n\r\n/**\r\n * Check if key combo matches\r\n */\r\nexport function matchesKeyCombo(event: KeyboardEvent, combo: string): boolean {\r\n const parts = combo.toLowerCase().split('+');\r\n const key = parts.pop();\r\n \r\n const modifiers = {\r\n ctrl: parts.includes('ctrl') || parts.includes('cmd'),\r\n shift: parts.includes('shift'),\r\n alt: parts.includes('alt'),\r\n };\r\n \r\n const ctrlOrCmd = event.ctrlKey || event.metaKey;\r\n \r\n return (\r\n event.key.toLowerCase() === key &&\r\n ctrlOrCmd === modifiers.ctrl &&\r\n event.shiftKey === modifiers.shift &&\r\n event.altKey === modifiers.alt\r\n );\r\n}\r\n\r\n/**\r\n * Create element with attributes\r\n */\r\nexport function createElement<K extends keyof HTMLElementTagNameMap>(\r\n tag: K,\r\n attributes?: Record<string, string>,\r\n children?: (Node | string)[]\r\n): HTMLElementTagNameMap[K] {\r\n const element = document.createElement(tag);\r\n \r\n if (attributes) {\r\n for (const [key, value] of Object.entries(attributes)) {\r\n element.setAttribute(key, value);\r\n }\r\n }\r\n \r\n if (children) {\r\n for (const child of children) {\r\n if (typeof child === 'string') {\r\n element.appendChild(document.createTextNode(child));\r\n } else {\r\n element.appendChild(child);\r\n }\r\n }\r\n }\r\n \r\n return element;\r\n}\r\n\r\n/**\r\n * Check if device is mobile\r\n */\r\nexport function isMobile(): boolean {\r\n return /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(\r\n navigator.userAgent\r\n );\r\n}\r\n\r\n/**\r\n * Check if device is touch enabled\r\n */\r\nexport function isTouchDevice(): boolean {\r\n return 'ontouchstart' in window || navigator.maxTouchPoints > 0;\r\n}\r\n\r\n/**\r\n * Get computed style value\r\n */\r\nexport function getComputedStyleValue(\r\n element: HTMLElement,\r\n property: string\r\n): string {\r\n return window.getComputedStyle(element).getPropertyValue(property);\r\n}\r\n\r\n/**\r\n * RequestAnimationFrame wrapper\r\n */\r\nexport function nextFrame(callback: () => void): number {\r\n return requestAnimationFrame(callback);\r\n}\r\n\r\n/**\r\n * Cancel animation frame\r\n */\r\nexport function cancelFrame(id: number): void {\r\n cancelAnimationFrame(id);\r\n}\r\n\r\n/**\r\n * Local storage helpers\r\n */\r\nexport const storage = {\r\n get<T>(key: string, defaultValue: T): T {\r\n try {\r\n const item = localStorage.getItem(key);\r\n return item ? JSON.parse(item) : defaultValue;\r\n } catch {\r\n return defaultValue;\r\n }\r\n },\r\n set<T>(key: string, value: T): void {\r\n try {\r\n localStorage.setItem(key, JSON.stringify(value));\r\n } catch {\r\n // Storage full or unavailable\r\n }\r\n },\r\n remove(key: string): void {\r\n try {\r\n localStorage.removeItem(key);\r\n } catch {\r\n // Storage unavailable\r\n }\r\n },\r\n};\r\n\r\n/**\r\n * Simple event emitter\r\n */\r\nexport class EventEmitter<T extends Record<string, unknown>> {\r\n private listeners: Map<keyof T, Set<(data: unknown) => void>> = new Map();\r\n\r\n on<K extends keyof T>(event: K, callback: (data: T[K]) => void): () => void {\r\n if (!this.listeners.has(event)) {\r\n this.listeners.set(event, new Set());\r\n }\r\n this.listeners.get(event)!.add(callback as (data: unknown) => void);\r\n \r\n return () => this.off(event, callback);\r\n }\r\n\r\n off<K extends keyof T>(event: K, callback: (data: T[K]) => void): void {\r\n this.listeners.get(event)?.delete(callback as (data: unknown) => void);\r\n }\r\n\r\n emit<K extends keyof T>(event: K, data: T[K]): void {\r\n this.listeners.get(event)?.forEach(callback => callback(data));\r\n }\r\n\r\n removeAllListeners(): void {\r\n this.listeners.clear();\r\n }\r\n}\r\n","/**\r\n * Block Registry - Manages all block definitions\r\n */\r\n\r\nimport type { BlockDefinition, BlockType, BlockData } from './types';\r\nimport { generateId } from '../utils/helpers';\r\n\r\nclass BlockRegistry {\r\n private blocks: Map<BlockType, BlockDefinition> = new Map();\r\n private defaultBlock: BlockType = 'paragraph';\r\n\r\n /**\r\n * Register a block definition\r\n */\r\n register(definition: BlockDefinition): void {\r\n this.blocks.set(definition.name, definition);\r\n }\r\n\r\n /**\r\n * Unregister a block\r\n */\r\n unregister(name: BlockType): void {\r\n this.blocks.delete(name);\r\n }\r\n\r\n /**\r\n * Get a block definition\r\n */\r\n get(name: BlockType): BlockDefinition | undefined {\r\n return this.blocks.get(name);\r\n }\r\n\r\n /**\r\n * Check if a block is registered\r\n */\r\n has(name: BlockType): boolean {\r\n return this.blocks.has(name);\r\n }\r\n\r\n /**\r\n * Get all registered blocks\r\n */\r\n getAll(): BlockDefinition[] {\r\n return Array.from(this.blocks.values());\r\n }\r\n\r\n /**\r\n * Get all block names\r\n */\r\n getNames(): BlockType[] {\r\n return Array.from(this.blocks.keys());\r\n }\r\n\r\n /**\r\n * Set the default block type\r\n */\r\n setDefaultBlock(name: BlockType): void {\r\n if (this.has(name)) {\r\n this.defaultBlock = name;\r\n }\r\n }\r\n\r\n /**\r\n * Get the default block type\r\n */\r\n getDefaultBlock(): BlockType {\r\n return this.defaultBlock;\r\n }\r\n\r\n /**\r\n * Create a block element\r\n */\r\n createBlock(type: BlockType, data?: Partial<BlockData>): HTMLElement | null {\r\n const definition = this.get(type);\r\n if (!definition) {\r\n console.warn(`Block type \"${type}\" is not registered`);\r\n return null;\r\n }\r\n\r\n const blockData = {\r\n id: generateId(),\r\n type,\r\n ...data,\r\n } as BlockData;\r\n\r\n const element = definition.create(blockData);\r\n element.setAttribute('data-block-id', blockData.id);\r\n element.setAttribute('data-block-type', type);\r\n\r\n return element;\r\n }\r\n\r\n /**\r\n * Get block type from element\r\n */\r\n getBlockType(element: HTMLElement): BlockType | null {\r\n return element.getAttribute('data-block-type') as BlockType | null;\r\n }\r\n\r\n /**\r\n * Get block data from element\r\n */\r\n getBlockData(element: HTMLElement): BlockData | null {\r\n const type = this.getBlockType(element);\r\n if (!type) return null;\r\n\r\n const definition = this.get(type);\r\n if (!definition) return null;\r\n\r\n return definition.getData(element);\r\n }\r\n\r\n /**\r\n * Update a block element\r\n */\r\n updateBlock(element: HTMLElement, data: Partial<BlockData>): void {\r\n const type = this.getBlockType(element);\r\n if (!type) return;\r\n\r\n const definition = this.get(type);\r\n if (!definition) return;\r\n\r\n definition.update(element, data);\r\n }\r\n\r\n /**\r\n * Transform a block to a different type\r\n */\r\n transformBlock(element: HTMLElement, newType: BlockType): HTMLElement | null {\r\n const currentType = this.getBlockType(element);\r\n if (!currentType || currentType === newType) return element;\r\n\r\n const currentDefinition = this.get(currentType);\r\n const newDefinition = this.get(newType);\r\n \r\n if (!currentDefinition || !newDefinition) return null;\r\n\r\n // Get content from current block\r\n const content = element.innerHTML;\r\n const id = element.getAttribute('data-block-id') || generateId();\r\n\r\n // Create new block\r\n const newElement = this.createBlock(newType, { id } as Partial<BlockData>);\r\n if (!newElement) return null;\r\n\r\n // Transfer content if the new block is editable\r\n if (newDefinition.editable) {\r\n const editableChild = newElement.querySelector('[contenteditable=\"true\"]') || newElement;\r\n if (editableChild instanceof HTMLElement) {\r\n editableChild.innerHTML = content;\r\n }\r\n }\r\n\r\n return newElement;\r\n }\r\n}\r\n\r\n// Singleton instance\r\nexport const blockRegistry = new BlockRegistry();\r\n\r\n// Export class for testing\r\nexport { BlockRegistry };\r\n","/**\r\n * Paragraph Block\r\n */\r\n\r\nimport type { BlockDefinition, ParagraphData } from '../core/types';\r\nimport { generateId } from '../utils/helpers';\r\n\r\nexport const paragraphBlock: BlockDefinition = {\r\n name: 'paragraph',\r\n tag: 'p',\r\n editable: true,\r\n allowedChildren: ['text', 'inline'],\r\n className: 'cb-paragraph',\r\n icon: 'paragraph',\r\n label: 'Paragraph',\r\n shortcut: 'Ctrl+0',\r\n\r\n create(data?: ParagraphData): HTMLElement {\r\n const p = document.createElement('p');\r\n p.className = 'cb-paragraph';\r\n p.setAttribute('contenteditable', 'true');\r\n p.setAttribute('data-block-id', data?.id || generateId());\r\n p.setAttribute('data-block-type', 'paragraph');\r\n \r\n if (data?.content) {\r\n p.innerHTML = data.content;\r\n }\r\n \r\n if (data?.align) {\r\n p.style.textAlign = data.align;\r\n }\r\n \r\n if (data?.className) {\r\n p.className = `cb-paragraph ${data.className}`;\r\n }\r\n\r\n // Placeholder\r\n if (!data?.content) {\r\n p.setAttribute('data-placeholder', 'Type something...');\r\n }\r\n\r\n return p;\r\n },\r\n\r\n getData(element: HTMLElement): ParagraphData {\r\n return {\r\n id: element.getAttribute('data-block-id') || generateId(),\r\n type: 'paragraph',\r\n content: element.innerHTML,\r\n align: element.style.textAlign as ParagraphData['align'],\r\n className: element.className,\r\n };\r\n },\r\n\r\n update(element: HTMLElement, data: Partial<ParagraphData>): void {\r\n if (data.content !== undefined) {\r\n element.innerHTML = data.content;\r\n }\r\n if (data.align) {\r\n element.style.textAlign = data.align;\r\n }\r\n if (data.className) {\r\n element.className = `cb-paragraph ${data.className}`;\r\n }\r\n },\r\n};\r\n","/**\r\n * Heading Block (H1-H6)\r\n */\r\n\r\nimport type { BlockDefinition, HeadingData, HeadingLevel } from '../core/types';\r\nimport { generateId } from '../utils/helpers';\r\n\r\nfunction createHeadingBlock(defaultLevel: HeadingLevel): BlockDefinition {\r\n return {\r\n name: 'heading',\r\n tag: `h${defaultLevel}`,\r\n editable: true,\r\n allowedChildren: ['text', 'inline'],\r\n className: `cb-heading cb-h${defaultLevel}`,\r\n icon: `heading${defaultLevel}`,\r\n label: defaultLevel === 1 ? 'Title' : `Heading ${defaultLevel}`,\r\n shortcut: `Ctrl+${defaultLevel}`,\r\n\r\n create(data?: HeadingData): HTMLElement {\r\n // Use level from data if provided, otherwise use default\r\n const level = data?.level || defaultLevel;\r\n const tag = `h${level}` as const;\r\n \r\n const heading = document.createElement(tag);\r\n heading.className = `cb-heading cb-h${level}`;\r\n heading.setAttribute('contenteditable', 'true');\r\n heading.setAttribute('data-block-id', data?.id || generateId());\r\n heading.setAttribute('data-block-type', 'heading');\r\n heading.setAttribute('data-heading-level', String(level));\r\n \r\n if (data?.content) {\r\n heading.innerHTML = data.content;\r\n }\r\n \r\n if (data?.align) {\r\n heading.style.textAlign = data.align;\r\n }\r\n\r\n if (!data?.content) {\r\n heading.setAttribute('data-placeholder', level === 1 ? 'Title' : `Heading ${level}`);\r\n }\r\n\r\n return heading;\r\n },\r\n\r\n getData(element: HTMLElement): HeadingData {\r\n const levelAttr = element.getAttribute('data-heading-level');\r\n return {\r\n id: element.getAttribute('data-block-id') || generateId(),\r\n type: 'heading',\r\n level: (levelAttr ? parseInt(levelAttr, 10) : defaultLevel) as HeadingLevel,\r\n content: element.innerHTML,\r\n align: element.style.textAlign as HeadingData['align'],\r\n };\r\n },\r\n\r\n update(element: HTMLElement, data: Partial<HeadingData>): void {\r\n if (data.content !== undefined) {\r\n element.innerHTML = data.content;\r\n }\r\n if (data.align) {\r\n element.style.textAlign = data.align;\r\n }\r\n if (data.level && data.level !== defaultLevel) {\r\n // Need to transform to different heading level\r\n element.setAttribute('data-heading-level', String(data.level));\r\n }\r\n },\r\n };\r\n}\r\n\r\n// Export individual heading levels\r\nexport const heading1Block = createHeadingBlock(1);\r\nexport const heading2Block = createHeadingBlock(2);\r\nexport const heading3Block = createHeadingBlock(3);\r\nexport const heading4Block = createHeadingBlock(4);\r\nexport const heading5Block = createHeadingBlock(5);\r\nexport const heading6Block = createHeadingBlock(6);\r\n\r\n// Factory function for creating heading blocks\r\nexport function createHeading(level: HeadingLevel, data?: Partial<HeadingData>): HTMLElement {\r\n const block = createHeadingBlock(level);\r\n return block.create({ ...data, level, type: 'heading' } as HeadingData);\r\n}\r\n","/**\r\n * List Blocks (Bullet, Numbered, Checklist)\r\n */\r\n\r\nimport type { BlockDefinition, ListData, ListItem, BlockType } from '../core/types';\r\nimport { generateId } from '../utils/helpers';\r\n\r\ntype ListType = 'bulletList' | 'numberedList' | 'checkList';\r\n\r\nfunction createListItemElement(item: ListItem, type: ListType): HTMLLIElement {\r\n const li = document.createElement('li');\r\n li.className = 'cb-list-item';\r\n li.setAttribute('data-item-id', item.id);\r\n\r\n if (type === 'checkList') {\r\n // Create checkbox wrapper\r\n const wrapper = document.createElement('div');\r\n wrapper.className = 'cb-checklist-wrapper';\r\n\r\n const checkbox = document.createElement('input');\r\n checkbox.type = 'checkbox';\r\n checkbox.className = 'cb-checkbox';\r\n checkbox.checked = item.checked || false;\r\n checkbox.setAttribute('tabindex', '-1');\r\n\r\n const content = document.createElement('span');\r\n content.className = 'cb-checklist-content';\r\n content.setAttribute('contenteditable', 'true');\r\n content.innerHTML = item.content;\r\n\r\n wrapper.appendChild(checkbox);\r\n wrapper.appendChild(content);\r\n li.appendChild(wrapper);\r\n\r\n if (item.checked) {\r\n li.classList.add('cb-checked');\r\n }\r\n } else {\r\n li.setAttribute('contenteditable', 'true');\r\n li.innerHTML = item.content;\r\n }\r\n\r\n // Handle nested items\r\n if (item.children && item.children.length > 0) {\r\n const nestedList = document.createElement(type === 'numberedList' ? 'ol' : 'ul');\r\n nestedList.className = `cb-nested-list cb-${type}`;\r\n item.children.forEach(child => {\r\n nestedList.appendChild(createListItemElement(child, type));\r\n });\r\n li.appendChild(nestedList);\r\n }\r\n\r\n return li;\r\n}\r\n\r\nfunction parseListItems(listElement: HTMLElement, type: ListType): ListItem[] {\r\n const items: ListItem[] = [];\r\n \r\n listElement.querySelectorAll(':scope > li').forEach(li => {\r\n const item: ListItem = {\r\n id: li.getAttribute('data-item-id') || generateId(),\r\n content: '',\r\n checked: false,\r\n children: [],\r\n };\r\n\r\n if (type === 'checkList') {\r\n const checkbox = li.querySelector('.cb-checkbox') as HTMLInputElement;\r\n const content = li.querySelector('.cb-checklist-content');\r\n item.checked = checkbox?.checked || false;\r\n item.content = content?.innerHTML || '';\r\n } else {\r\n // Get direct text content, excluding nested lists\r\n const clone = li.cloneNode(true) as HTMLElement;\r\n const nestedList = clone.querySelector('ul, ol');\r\n if (nestedList) nestedList.remove();\r\n item.content = clone.innerHTML;\r\n }\r\n\r\n // Parse nested list\r\n const nestedList = li.querySelector(':scope > ul, :scope > ol');\r\n if (nestedList) {\r\n item.children = parseListItems(nestedList as HTMLElement, type);\r\n }\r\n\r\n items.push(item);\r\n });\r\n\r\n return items;\r\n}\r\n\r\nfunction createListBlock(type: ListType): BlockDefinition {\r\n const tag = type === 'numberedList' ? 'ol' : 'ul';\r\n const name = type as BlockType;\r\n \r\n return {\r\n name,\r\n tag,\r\n editable: true,\r\n allowedChildren: ['text', 'inline', 'block'],\r\n className: `cb-list cb-${type}`,\r\n icon: type === 'bulletList' ? 'list' : type === 'numberedList' ? 'listOrdered' : 'checkList',\r\n label: type === 'bulletList' ? 'Bullet List' : type === 'numberedList' ? 'Numbered List' : 'Checklist',\r\n shortcut: type === 'bulletList' ? 'Ctrl+Shift+8' : type === 'numberedList' ? 'Ctrl+Shift+7' : undefined,\r\n\r\n create(data?: ListData): HTMLElement {\r\n const list = document.createElement(tag);\r\n list.className = `cb-list cb-${type}`;\r\n list.setAttribute('data-block-id', data?.id || generateId());\r\n list.setAttribute('data-block-type', type);\r\n\r\n if (data?.items && data.items.length > 0) {\r\n data.items.forEach(item => {\r\n list.appendChild(createListItemElement(item, type));\r\n });\r\n } else {\r\n // Create default empty item\r\n const defaultItem: ListItem = {\r\n id: generateId(),\r\n content: '',\r\n checked: false,\r\n };\r\n list.appendChild(createListItemElement(defaultItem, type));\r\n }\r\n\r\n return list;\r\n },\r\n\r\n getData(element: HTMLElement): ListData {\r\n return {\r\n id: element.getAttribute('data-block-id') || generateId(),\r\n type,\r\n items: parseListItems(element, type),\r\n };\r\n },\r\n\r\n update(element: HTMLElement, data: Partial<ListData>): void {\r\n if (data.items) {\r\n element.innerHTML = '';\r\n data.items.forEach(item => {\r\n element.appendChild(createListItemElement(item, type));\r\n });\r\n }\r\n },\r\n };\r\n}\r\n\r\n// Export list blocks\r\nexport const bulletListBlock = createListBlock('bulletList');\r\nexport const numberedListBlock = createListBlock('numberedList');\r\nexport const checkListBlock = createListBlock('checkList');\r\n\r\n/**\r\n * Add item to list\r\n */\r\nexport function addListItem(\r\n listElement: HTMLElement,\r\n afterItemId?: string,\r\n content = ''\r\n): ListItem {\r\n const type = listElement.getAttribute('data-block-type') as ListType;\r\n const item: ListItem = {\r\n id: generateId(),\r\n content,\r\n checked: false,\r\n };\r\n\r\n const li = createListItemElement(item, type);\r\n\r\n if (afterItemId) {\r\n const afterLi = listElement.querySelector(`[data-item-id=\"${afterItemId}\"]`);\r\n if (afterLi && afterLi.parentElement === listElement) {\r\n afterLi.after(li);\r\n } else {\r\n listElement.appendChild(li);\r\n }\r\n } else {\r\n listElement.appendChild(li);\r\n }\r\n\r\n // Focus the new item\r\n const editable = type === 'checkList' \r\n ? li.querySelector('.cb-checklist-content')\r\n : li;\r\n if (editable instanceof HTMLElement) {\r\n editable.focus();\r\n }\r\n\r\n return item;\r\n}\r\n\r\n/**\r\n * Remove item from list\r\n */\r\nexport function removeListItem(listElement: HTMLElement, itemId: string): boolean {\r\n const li = listElement.querySelector(`[data-item-id=\"${itemId}\"]`);\r\n if (!li) return false;\r\n\r\n const items = listElement.querySelectorAll(':scope > li');\r\n if (items.length <= 1) {\r\n // Don't remove last item, just clear it\r\n const content = li.querySelector('.cb-checklist-content') || li;\r\n if (content instanceof HTMLElement) {\r\n content.innerHTML = '';\r\n }\r\n return false;\r\n }\r\n\r\n li.remove();\r\n return true;\r\n}\r\n\r\n/**\r\n * Toggle checkbox in checklist\r\n */\r\nexport function toggleChecklistItem(li: HTMLElement): boolean {\r\n const checkbox = li.querySelector('.cb-checkbox') as HTMLInputElement;\r\n if (!checkbox) return false;\r\n\r\n checkbox.checked = !checkbox.checked;\r\n li.classList.toggle('cb-checked', checkbox.checked);\r\n return checkbox.checked;\r\n}\r\n\r\n/**\r\n * Indent list item (create nested list)\r\n */\r\nexport function indentListItem(li: HTMLElement): boolean {\r\n const prevLi = li.previousElementSibling as HTMLElement;\r\n if (!prevLi) return false;\r\n\r\n const listElement = li.parentElement;\r\n if (!listElement) return false;\r\n\r\n const type = listElement.getAttribute('data-block-type') as ListType;\r\n const tag = type === 'numberedList' ? 'ol' : 'ul';\r\n\r\n // Check if prev item already has a nested list\r\n let nestedList = prevLi.querySelector(`:scope > ${tag}`) as HTMLElement;\r\n if (!nestedList) {\r\n nestedList = document.createElement(tag);\r\n nestedList.className = `cb-nested-list cb-${type}`;\r\n prevLi.appendChild(nestedList);\r\n }\r\n\r\n nestedList.appendChild(li);\r\n return true;\r\n}\r\n\r\n/**\r\n * Outdent list item (move to parent list)\r\n */\r\nexport function outdentListItem(li: HTMLElement): boolean {\r\n const parentList = li.parentElement;\r\n if (!parentList || !parentList.classList.contains('cb-nested-list')) {\r\n return false;\r\n }\r\n\r\n const parentLi = parentList.parentElement;\r\n if (!parentLi) return false;\r\n\r\n const grandparentList = parentLi.parentElement;\r\n if (!grandparentList) return false;\r\n\r\n // Move li after its parent li\r\n grandparentList.insertBefore(li, parentLi.nextSibling);\r\n\r\n // Remove empty nested list\r\n if (parentList.children.length === 0) {\r\n parentList.remove();\r\n }\r\n\r\n return true;\r\n}\r\n","/**\r\n * Quote Block (Blockquote)\r\n */\r\n\r\nimport type { BlockDefinition, QuoteData } from '../core/types';\r\nimport { generateId } from '../utils/helpers';\r\n\r\nexport const quoteBlock: BlockDefinition = {\r\n name: 'quote',\r\n tag: 'blockquote',\r\n editable: true,\r\n allowedChildren: ['text', 'inline'],\r\n className: 'cb-quote',\r\n icon: 'quote',\r\n label: 'Quote',\r\n shortcut: 'Ctrl+Shift+.',\r\n\r\n create(data?: QuoteData): HTMLElement {\r\n const blockquote = document.createElement('blockquote');\r\n blockquote.className = 'cb-quote';\r\n blockquote.setAttribute('data-block-id', data?.id || generateId());\r\n blockquote.setAttribute('data-block-type', 'quote');\r\n\r\n // Main content\r\n const content = document.createElement('p');\r\n content.className = 'cb-quote-content';\r\n content.setAttribute('contenteditable', 'true');\r\n if (data?.content) {\r\n content.innerHTML = data.content;\r\n } else {\r\n content.setAttribute('data-placeholder', 'Type a quote...');\r\n }\r\n blockquote.appendChild(content);\r\n\r\n // Citation (optional)\r\n if (data?.citation) {\r\n const cite = document.createElement('cite');\r\n cite.className = 'cb-quote-citation';\r\n cite.setAttribute('contenteditable', 'true');\r\n cite.textContent = data.citation;\r\n blockquote.appendChild(cite);\r\n }\r\n\r\n return blockquote;\r\n },\r\n\r\n getData(element: HTMLElement): QuoteData {\r\n const content = element.querySelector('.cb-quote-content');\r\n const citation = element.querySelector('.cb-quote-citation');\r\n \r\n return {\r\n id: element.getAttribute('data-block-id') || generateId(),\r\n type: 'quote',\r\n content: content?.innerHTML || element.innerHTML,\r\n citation: citation?.textContent || undefined,\r\n };\r\n },\r\n\r\n update(element: HTMLElement, data: Partial<QuoteData>): void {\r\n if (data.content !== undefined) {\r\n const content = element.querySelector('.cb-quote-content');\r\n if (content) {\r\n content.innerHTML = data.content;\r\n }\r\n }\r\n if (data.citation !== undefined) {\r\n let citation = element.querySelector('.cb-quote-citation');\r\n if (data.citation) {\r\n if (!citation) {\r\n citation = document.createElement('cite');\r\n citation.className = 'cb-quote-citation';\r\n citation.setAttribute('contenteditable', 'true');\r\n element.appendChild(citation);\r\n }\r\n citation.textContent = data.citation;\r\n } else if (citation) {\r\n citation.remove();\r\n }\r\n }\r\n },\r\n};\r\n\r\n/**\r\n * Add citation to quote\r\n */\r\nexport function addCitation(blockquote: HTMLElement, text: string): void {\r\n let citation = blockquote.querySelector('.cb-quote-citation');\r\n if (!citation) {\r\n citation = document.createElement('cite');\r\n citation.className = 'cb-quote-citation';\r\n citation.setAttribute('contenteditable', 'true');\r\n blockquote.appendChild(citation);\r\n }\r\n citation.textContent = text;\r\n}\r\n\r\n/**\r\n * Remove citation from quote\r\n */\r\nexport function removeCitation(blockquote: HTMLElement): void {\r\n const citation = blockquote.querySelector('.cb-quote-citation');\r\n if (citation) {\r\n citation.remove();\r\n }\r\n}\r\n","/**\r\n * Code Block (Pre/Code for multi-line code)\r\n */\r\n\r\nimport type { BlockDefinition, CodeData } from '../core/types';\r\nimport { generateId } from '../utils/helpers';\r\n\r\n// Common programming languages for syntax highlighting\r\nexport const LANGUAGES = [\r\n { value: 'plaintext', label: 'Plain Text' },\r\n { value: 'javascript', label: 'JavaScript' },\r\n { value: 'typescript', label: 'TypeScript' },\r\n { value: 'python', label: 'Python' },\r\n { value: 'java', label: 'Java' },\r\n { value: 'csharp', label: 'C#' },\r\n { value: 'cpp', label: 'C++' },\r\n { value: 'go', label: 'Go' },\r\n { value: 'rust', label: 'Rust' },\r\n { value: 'php', label: 'PHP' },\r\n { value: 'ruby', label: 'Ruby' },\r\n { value: 'swift', label: 'Swift' },\r\n { value: 'kotlin', label: 'Kotlin' },\r\n { value: 'html', label: 'HTML' },\r\n { value: 'css', label: 'CSS' },\r\n { value: 'scss', label: 'SCSS' },\r\n { value: 'json', label: 'JSON' },\r\n { value: 'yaml', label: 'YAML' },\r\n { value: 'xml', label: 'XML' },\r\n { value: 'markdown', label: 'Markdown' },\r\n { value: 'sql', label: 'SQL' },\r\n { value: 'bash', label: 'Bash' },\r\n { value: 'shell', label: 'Shell' },\r\n { value: 'dockerfile', label: 'Dockerfile' },\r\n] as const;\r\n\r\nexport const codeBlock: BlockDefinition = {\r\n name: 'code',\r\n tag: 'pre',\r\n editable: true,\r\n allowedChildren: ['text'],\r\n className: 'cb-code-block',\r\n icon: 'code',\r\n label: 'Code Block',\r\n shortcut: 'Ctrl+Shift+C',\r\n\r\n create(data?: CodeData): HTMLElement {\r\n const wrapper = document.createElement('div');\r\n wrapper.className = 'cb-code-wrapper';\r\n wrapper.setAttribute('data-block-id', data?.id || generateId());\r\n wrapper.setAttribute('data-block-type', 'code');\r\n\r\n // Language selector bar\r\n const toolbar = document.createElement('div');\r\n toolbar.className = 'cb-code-toolbar';\r\n\r\n const langSelect = document.createElement('select');\r\n langSelect.className = 'cb-code-language';\r\n langSelect.setAttribute('tabindex', '-1');\r\n \r\n LANGUAGES.forEach(lang => {\r\n const option = document.createElement('option');\r\n option.value = lang.value;\r\n option.textContent = lang.label;\r\n if (data?.language === lang.value) {\r\n option.selected = true;\r\n }\r\n langSelect.appendChild(option);\r\n });\r\n\r\n // Copy button\r\n const copyBtn = document.createElement('button');\r\n copyBtn.type = 'button';\r\n copyBtn.className = 'cb-code-copy';\r\n copyBtn.setAttribute('tabindex', '-1');\r\n copyBtn.innerHTML = '<span class=\"cb-copy-text\">Copy</span>';\r\n copyBtn.onclick = () => {\r\n const code = wrapper.querySelector('code');\r\n if (code) {\r\n navigator.clipboard.writeText(code.textContent || '');\r\n copyBtn.innerHTML = '<span class=\"cb-copy-text\">Copied!</span>';\r\n setTimeout(() => {\r\n copyBtn.innerHTML = '<span class=\"cb-copy-text\">Copy</span>';\r\n }, 2000);\r\n }\r\n };\r\n\r\n toolbar.appendChild(langSelect);\r\n toolbar.appendChild(copyBtn);\r\n\r\n // Code container\r\n const pre = document.createElement('pre');\r\n pre.className = 'cb-code-block';\r\n\r\n const code = document.createElement('code');\r\n code.className = `cb-code language-${data?.language || 'plaintext'}`;\r\n code.setAttribute('contenteditable', 'true');\r\n code.setAttribute('spellcheck', 'false');\r\n code.setAttribute('data-placeholder', 'Write your code here...');\r\n \r\n if (data?.content) {\r\n code.textContent = data.content;\r\n }\r\n\r\n // Update language class when selector changes\r\n langSelect.onchange = () => {\r\n code.className = `cb-code language-${langSelect.value}`;\r\n wrapper.setAttribute('data-language', langSelect.value);\r\n };\r\n\r\n pre.appendChild(code);\r\n wrapper.appendChild(toolbar);\r\n wrapper.appendChild(pre);\r\n\r\n if (data?.language) {\r\n wrapper.setAttribute('data-language', data.language);\r\n }\r\n\r\n return wrapper;\r\n },\r\n\r\n getData(element: HTMLElement): CodeData {\r\n const code = element.querySelector('code');\r\n const langSelect = element.querySelector('.cb-code-language') as HTMLSelectElement;\r\n \r\n return {\r\n id: element.getAttribute('data-block-id') || generateId(),\r\n type: 'code',\r\n content: code?.textContent || '',\r\n language: langSelect?.value || element.getAttribute('data-language') || 'plaintext',\r\n };\r\n },\r\n\r\n update(element: HTMLElement, data: Partial<CodeData>): void {\r\n if (data.content !== undefined) {\r\n const code = element.querySelector('code');\r\n if (code) {\r\n code.textContent = data.content;\r\n }\r\n }\r\n if (data.language) {\r\n const code = element.querySelector('code');\r\n const langSelect = element.querySelector('.cb-code-language') as HTMLSelectElement;\r\n if (code) {\r\n code.className = `cb-code language-${data.language}`;\r\n }\r\n if (langSelect) {\r\n langSelect.value = data.language;\r\n }\r\n element.setAttribute('data-language', data.language);\r\n }\r\n },\r\n};\r\n\r\n/**\r\n * Set language for code block\r\n */\r\nexport function setLanguage(codeWrapper: HTMLElement, language: string): void {\r\n const code = codeWrapper.querySelector('code');\r\n const langSelect = codeWrapper.querySelector('.cb-code-language') as HTMLSelectElement;\r\n \r\n if (code) {\r\n code.className = `cb-code language-${language}`;\r\n }\r\n if (langSelect) {\r\n langSelect.value = language;\r\n }\r\n codeWrapper.setAttribute('data-language', language);\r\n}\r\n\r\n/**\r\n * Get code content\r\n */\r\nexport function getCode(codeWrapper: HTMLElement): string {\r\n const code = codeWrapper.querySelector('code');\r\n return code?.textContent || '';\r\n}\r\n","/**\r\n * Image Block\r\n */\r\n\r\nimport type { BlockDefinition, ImageData } from '../core/types';\r\nimport { generateId } from '../utils/helpers';\r\n\r\n/**\r\n * Add resize handles to a resizable wrapper element\r\n */\r\nfunction addResizeHandles(wrapper: HTMLElement): void {\r\n const handles = ['se', 'sw', 'ne', 'nw', 'e', 'w'];\r\n handles.forEach(pos => {\r\n const handle = document.createElement('div');\r\n handle.className = `cb-image-resize-handle handle-${pos}`;\r\n handle.setAttribute('data-handle', pos);\r\n wrapper.appendChild(handle);\r\n });\r\n}\r\n\r\nexport const imageBlock: BlockDefinition = {\r\n name: 'image',\r\n tag: 'figure',\r\n editable: false,\r\n allowedChildren: [],\r\n className: 'cb-image',\r\n icon: 'image',\r\n label: 'Image',\r\n\r\n create(data?: ImageData): HTMLElement {\r\n const figure = document.createElement('figure');\r\n figure.className = 'cb-image';\r\n figure.setAttribute('data-block-id', data?.id || generateId());\r\n figure.setAttribute('data-block-type', 'image');\r\n\r\n // Image container\r\n const imgContainer = document.createElement('div');\r\n imgContainer.className = 'cb-image-container';\r\n\r\n if (data?.src) {\r\n // Create resizable wrapper\r\n const resizableWrapper = document.createElement('div');\r\n resizableWrapper.className = 'cb-image-resizable';\r\n \r\n const img = document.createElement('img');\r\n img.className = 'cb-image-element';\r\n img.src = data.src;\r\n img.alt = data.alt || '';\r\n \r\n if (data.width) {\r\n img.style.width = typeof data.width === 'number' ? `${data.width}px` : data.width;\r\n }\r\n if (data.height) {\r\n img.style.height = typeof data.height === 'number' ? `${data.height}px` : data.height;\r\n }\r\n\r\n resizableWrapper.appendChild(img);\r\n \r\n // Add resize handles\r\n addResizeHandles(resizableWrapper);\r\n \r\n imgContainer.appendChild(resizableWrapper);\r\n } else {\r\n // Placeholder for upload - premium design\r\n const placeholder = document.createElement('div');\r\n placeholder.className = 'cb-image-placeholder';\r\n placeholder.innerHTML = `\r\n <div class=\"cb-image-placeholder-content\">\r\n <svg width=\"56\" height=\"56\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.5\">\r\n <rect x=\"3\" y=\"3\" width=\"18\" height=\"18\" rx=\"2\" ry=\"2\"/>\r\n <circle cx=\"9\" cy=\"9\" r=\"2\"/>\r\n <path d=\"m21 15-3.086-3.086a2 2 0 0 0-2.828 0L6 21\"/>\r\n </svg>\r\n <span>Drop an image here, or click to upload</span>\r\n <span class=\"cb-image-placeholder-hint\">Supports JPG, PNG, GIF, WebP up to 10MB</span>\r\n <input type=\"file\" accept=\"image/*\" class=\"cb-image-input\" />\r\n </div>\r\n <div class=\"cb-image-url-wrapper\">\r\n <input type=\"text\" class=\"cb-image-url-input\" placeholder=\"Paste image URL and press Enter\" />\r\n </div>\r\n `;\r\n imgContainer.appendChild(placeholder);\r\n }\r\n\r\n figure.appendChild(imgContainer);\r\n\r\n // Alignment controls\r\n if (data?.src) {\r\n const controls = document.createElement('div');\r\n controls.className = 'cb-image-controls';\r\n controls.innerHTML = `\r\n <button type=\"button\" class=\"cb-image-align\" data-align=\"left\" title=\"Align left\">\r\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\">\r\n <line x1=\"17\" x2=\"3\" y1=\"10\" y2=\"10\"/><line x1=\"21\" x2=\"3\" y1=\"6\" y2=\"6\"/><line x1=\"21\" x2=\"3\" y1=\"14\" y2=\"14\"/><line x1=\"17\" x2=\"3\" y1=\"18\" y2=\"18\"/>\r\n </svg>\r\n </button>\r\n <button type=\"button\" class=\"cb-image-align\" data-align=\"center\" title=\"Align center\">\r\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\">\r\n <line x1=\"18\" x2=\"6\" y1=\"10\" y2=\"10\"/><line x1=\"21\" x2=\"3\" y1=\"6\" y2=\"6\"/><line x1=\"21\" x2=\"3\" y1=\"14\" y2=\"14\"/><line x1=\"18\" x2=\"6\" y1=\"18\" y2=\"18\"/>\r\n </svg>\r\n </button>\r\n <button type=\"button\" class=\"cb-image-align\" data-align=\"right\" title=\"Align right\">\r\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\">\r\n <line x1=\"21\" x2=\"7\" y1=\"10\" y2=\"10\"/><line x1=\"21\" x2=\"3\" y1=\"6\" y2=\"6\"/><line x1=\"21\" x2=\"3\" y1=\"14\" y2=\"14\"/><line x1=\"21\" x2=\"7\" y1=\"18\" y2=\"18\"/>\r\n </svg>\r\n </button>\r\n <span class=\"cb-image-controls-divider\"></span>\r\n <button type=\"button\" class=\"cb-image-crop\" data-action=\"crop\" title=\"Crop image\">\r\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\">\r\n <path d=\"M6 2v14a2 2 0 0 0 2 2h14\"/>\r\n <path d=\"M18 22V8a2 2 0 0 0-2-2H2\"/>\r\n </svg>\r\n </button>\r\n `;\r\n figure.appendChild(controls);\r\n }\r\n\r\n // Caption\r\n const caption = document.createElement('figcaption');\r\n caption.className = 'cb-image-caption';\r\n caption.setAttribute('contenteditable', 'true');\r\n caption.setAttribute('data-placeholder', 'Add a caption...');\r\n if (data?.caption) {\r\n caption.textContent = data.caption;\r\n }\r\n figure.appendChild(caption);\r\n\r\n // Set alignment\r\n if (data?.align) {\r\n figure.setAttribute('data-align', data.align);\r\n }\r\n\r\n return figure;\r\n },\r\n\r\n getData(element: HTMLElement): ImageData {\r\n const img = element.querySelector('img');\r\n const caption = element.querySelector('figcaption');\r\n \r\n return {\r\n id: element.getAttribute('data-block-id') || generateId(),\r\n type: 'image',\r\n src: img?.src || '',\r\n alt: img?.alt || '',\r\n caption: caption?.textContent || undefined,\r\n width: img?.style.width || undefined,\r\n height: img?.style.height || undefined,\r\n align: element.getAttribute('data-align') as ImageData['align'] || undefined,\r\n };\r\n },\r\n\r\n update(element: HTMLElement, data: Partial<ImageData>): void {\r\n const img = element.querySelector('img');\r\n const caption = element.querySelector('figcaption');\r\n\r\n if (img) {\r\n if (data.src) img.src = data.src;\r\n if (data.alt !== undefined) img.alt = data.alt;\r\n if (data.width) img.style.width = typeof data.width === 'number' ? `${data.width}px` : data.width;\r\n if (data.height) img.style.height = typeof data.height === 'number' ? `${data.height}px` : data.height;\r\n }\r\n\r\n if (caption && data.caption !== undefined) {\r\n caption.textContent = data.caption;\r\n }\r\n\r\n if (data.align) {\r\n element.setAttribute('data-align', data.align);\r\n }\r\n },\r\n};\r\n\r\n/**\r\n * Set image source\r\n */\r\nexport function setImageSrc(figure: HTMLElement, src: string, alt = ''): void {\r\n let img = figure.querySelector('img');\r\n const container = figure.querySelector('.cb-image-container');\r\n \r\n if (!img && container) {\r\n // Remove placeholder\r\n const placeholder = container.querySelector('.cb-image-placeholder');\r\n if (placeholder) placeholder.remove();\r\n\r\n // Create resizable wrapper\r\n const resizableWrapper = document.createElement('div');\r\n resizableWrapper.className = 'cb-image-resizable';\r\n \r\n // Create image\r\n img = document.createElement('img');\r\n img.className = 'cb-image-element';\r\n resizableWrapper.appendChild(img);\r\n \r\n // Add resize handles\r\n addResizeHandles(resizableWrapper);\r\n \r\n container.appendChild(resizableWrapper);\r\n }\r\n\r\n if (img) {\r\n img.src = src;\r\n img.alt = alt;\r\n }\r\n}\r\n\r\n/**\r\n * Set image alignment\r\n */\r\nexport function setImageAlign(figure: HTMLElement, align: 'left' | 'center' | 'right'): void {\r\n figure.setAttribute('data-align', align);\r\n}\r\n\r\n/**\r\n * Create image from file\r\n */\r\nexport function createImageFromFile(file: File): Promise<string> {\r\n return new Promise((resolve, reject) => {\r\n if (!file.type.startsWith('image/')) {\r\n reject(new Error('File is not an image'));\r\n return;\r\n }\r\n\r\n const reader = new FileReader();\r\n reader.onload = () => resolve(reader.result as string);\r\n reader.onerror = () => reject(reader.error);\r\n reader.readAsDataURL(file);\r\n });\r\n}\r\n\r\n/**\r\n * Crop image using canvas\r\n */\r\nexport function cropImage(\r\n imageSrc: string,\r\n cropArea: { x: number; y: number; width: number; height: number },\r\n originalWidth: number,\r\n originalHeight: number\r\n): Promise<string> {\r\n return new Promise((resolve, reject) => {\r\n const img = new Image();\r\n img.crossOrigin = 'anonymous';\r\n \r\n img.onload = () => {\r\n const canvas = document.createElement('canvas');\r\n const ctx = canvas.getContext('2d');\r\n \r\n if (!ctx) {\r\n reject(new Error('Could not get canvas context'));\r\n return;\r\n }\r\n \r\n // Calculate actual pixel coordinates from percentage-based crop area\r\n const scaleX = img.naturalWidth / originalWidth;\r\n const scaleY = img.naturalHeight / originalHeight;\r\n \r\n const sx = cropArea.x * scaleX;\r\n const sy = cropArea.y * scaleY;\r\n const sw = cropArea.width * scaleX;\r\n const sh = cropArea.height * scaleY;\r\n \r\n canvas.width = sw;\r\n canvas.height = sh;\r\n \r\n ctx.drawImage(img, sx, sy, sw, sh, 0, 0, sw, sh);\r\n \r\n resolve(canvas.toDataURL('image/png'));\r\n };\r\n \r\n img.onerror = () => reject(new Error('Failed to load image'));\r\n img.src = imageSrc;\r\n });\r\n}\r\n\r\n/**\r\n * Create crop modal HTML\r\n */\r\nexport function createCropModal(imageSrc: string, onSave: (croppedSrc: string) => void, onCancel: () => void): HTMLElement {\r\n const modal = document.createElement('div');\r\n modal.className = 'cb-crop-modal';\r\n modal.innerHTML = `\r\n <div class=\"cb-crop-modal-backdrop\"></div>\r\n <div class=\"cb-crop-modal-content\">\r\n <div class=\"cb-crop-modal-header\">\r\n <h3>Crop Image</h3>\r\n <button type=\"button\" class=\"cb-crop-modal-close\" title=\"Close\">\r\n <svg width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\">\r\n <line x1=\"18\" y1=\"6\" x2=\"6\" y2=\"18\"/><line x1=\"6\" y1=\"6\" x2=\"18\" y2=\"18\"/>\r\n </svg>\r\n </button>\r\n </div>\r\n <div class=\"cb-crop-modal-body\">\r\n <div class=\"cb-crop-container\">\r\n <div class=\"cb-crop-image-wrapper\">\r\n <img src=\"${imageSrc}\" class=\"cb-crop-image\" alt=\"Crop preview\" />\r\n <div class=\"cb-crop-overlay\">\r\n <div class=\"cb-crop-area\">\r\n <div class=\"cb-crop-handle cb-crop-handle-nw\" data-handle=\"nw\"></div>\r\n <div class=\"cb-crop-handle cb-crop-handle-ne\" data-handle=\"ne\"></div>\r\n <div class=\"cb-crop-handle cb-crop-handle-sw\" data-handle=\"sw\"></div>\r\n <div class=\"cb-crop-handle cb-crop-handle-se\" data-handle=\"se\"></div>\r\n <div class=\"cb-crop-handle cb-crop-handle-n\" data-handle=\"n\"></div>\r\n <div class=\"cb-crop-handle cb-crop-handle-e\" data-handle=\"e\"></div>\r\n <div class=\"cb-crop-handle cb-crop-handle-s\" data-handle=\"s\"></div>\r\n <div class=\"cb-crop-handle cb-crop-handle-w\" data-handle=\"w\"></div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n <div class=\"cb-crop-aspect-ratios\">\r\n <button type=\"button\" class=\"cb-crop-aspect-btn active\" data-aspect=\"free\">Free</button>\r\n <button type=\"button\" class=\"cb-crop-aspect-btn\" data-aspect=\"1:1\">1:1</button>\r\n <button type=\"button\" class=\"cb-crop-aspect-btn\" data-aspect=\"4:3\">4:3</button>\r\n <button type=\"button\" class=\"cb-crop-aspect-btn\" data-aspect=\"16:9\">16:9</button>\r\n </div>\r\n </div>\r\n <div class=\"cb-crop-modal-footer\">\r\n <button type=\"button\" class=\"cb-crop-cancel-btn\">Cancel</button>\r\n <button type=\"button\" class=\"cb-crop-save-btn\">Apply Crop</button>\r\n </div>\r\n </div>\r\n `;\r\n \r\n // State\r\n let cropArea = { x: 50, y: 50, width: 200, height: 200 };\r\n let aspectRatio: number | null = null;\r\n let isDragging = false;\r\n let isResizing = false;\r\n let activeHandle: string | null = null;\r\n let startX = 0;\r\n let startY = 0;\r\n let startCrop = { ...cropArea };\r\n let imageWidth = 0;\r\n let imageHeight = 0;\r\n let isClosing = false; // Prevent double-close\r\n \r\n const imageWrapper = modal.querySelector('.cb-crop-image-wrapper') as HTMLElement;\r\n const cropImg = modal.querySelector('.cb-crop-image') as HTMLImageElement;\r\n const cropAreaEl = modal.querySelector('.cb-crop-area') as HTMLElement;\r\n \r\n const MIN_SIZE = 30;\r\n \r\n // Initialize crop area after image loads\r\n cropImg.onload = () => {\r\n // Get actual displayed dimensions\r\n imageWidth = cropImg.offsetWidth;\r\n imageHeight = cropImg.offsetHeight;\r\n \r\n // Set wrapper size to match image exactly\r\n imageWrapper.style.width = `${imageWidth}px`;\r\n imageWrapper.style.height = `${imageHeight}px`;\r\n \r\n // Center crop area at 80% of image\r\n const sizeW = imageWidth * 0.8;\r\n const sizeH = imageHeight * 0.8;\r\n cropArea = {\r\n x: (imageWidth - sizeW) / 2,\r\n y: (imageHeight - sizeH) / 2,\r\n width: sizeW,\r\n height: sizeH\r\n };\r\n updateCropAreaUI();\r\n };\r\n \r\n const updateCropAreaUI = () => {\r\n cropAreaEl.style.left = `${cropArea.x}px`;\r\n cropAreaEl.style.top = `${cropArea.y}px`;\r\n cropAreaEl.style.width = `${cropArea.width}px`;\r\n cropAreaEl.style.height = `${cropArea.height}px`;\r\n };\r\n \r\n const constrainCropArea = (area: typeof cropArea): typeof cropArea => {\r\n // Constrain position\r\n let x = Math.max(0, area.x);\r\n let y = Math.max(0, area.y);\r\n \r\n // Constrain size\r\n let width = Math.max(MIN_SIZE, area.width);\r\n let height = Math.max(MIN_SIZE, area.height);\r\n \r\n // Make sure it doesn't exceed image bounds\r\n if (x + width > imageWidth) {\r\n if (width > imageWidth) {\r\n width = imageWidth;\r\n x = 0;\r\n } else {\r\n x = imageWidth - width;\r\n }\r\n }\r\n \r\n if (y + height > imageHeight) {\r\n if (height > imageHeight) {\r\n height = imageHeight;\r\n y = 0;\r\n } else {\r\n y = imageHeight - height;\r\n }\r\n }\r\n \r\n return { x, y, width, height };\r\n };\r\n \r\n // Handle drag on crop area\r\n const handleCropMouseDown = (e: MouseEvent) => {\r\n if ((e.target as HTMLElement).classList.contains('cb-crop-handle')) return;\r\n \r\n isDragging = true;\r\n startX = e.clientX;\r\n startY = e.clientY;\r\n startCrop = { ...cropArea };\r\n e.preventDefault();\r\n };\r\n \r\n cropAreaEl.addEventListener('mousedown', handleCropMouseDown);\r\n \r\n // Handle resize handles\r\n const handleHandleMouseDown = (e: MouseEvent) => {\r\n const handle = e.currentTarget as HTMLElement;\r\n isResizing = true;\r\n activeHandle = handle.dataset.handle || null;\r\n startX = e.clientX;\r\n startY = e.clientY;\r\n startCrop = { ...cropArea };\r\n e.preventDefault();\r\n e.stopPropagation();\r\n };\r\n \r\n modal.querySelectorAll('.cb-crop-handle').forEach(handle => {\r\n handle.addEventListener('mousedown', handleHandleMouseDown as EventListener);\r\n });\r\n \r\n const handleMouseMove = (e: MouseEvent) => {\r\n if (!isDragging && !isResizing) return;\r\n \r\n const dx = e.clientX - startX;\r\n const dy = e.clientY - startY;\r\n \r\n if (isDragging) {\r\n cropArea = constrainCropArea({\r\n x: startCrop.x + dx,\r\n y: startCrop.y + dy,\r\n width: startCrop.width,\r\n height: startCrop.height\r\n });\r\n updateCropAreaUI();\r\n } else if (isResizing && activeHandle) {\r\n let newX = startCrop.x;\r\n let newY = startCrop.y;\r\n let newWidth = startCrop.width;\r\n let newHeight = startCrop.height;\r\n \r\n // Handle different resize directions\r\n if (activeHandle.includes('e')) {\r\n newWidth = startCrop.width + dx;\r\n }\r\n if (activeHandle.includes('w')) {\r\n const maxDx = startCrop.width - MIN_SIZE;\r\n const constrainedDx = Math.min(dx, maxDx);\r\n newX = startCrop.x + constrainedDx;\r\n newWidth = startCrop.width - constrainedDx;\r\n // Don't let it go past left edge\r\n if (newX < 0) {\r\n newWidth = newWidth + newX;\r\n newX = 0;\r\n }\r\n }\r\n if (activeHandle.includes('s')) {\r\n newHeight = startCrop.height + dy;\r\n }\r\n if (activeHandle.includes('n')) {\r\n const maxDy = startCrop.height - MIN_SIZE;\r\n const constrainedDy = Math.min(dy, maxDy);\r\n newY = startCrop.y + constrainedDy;\r\n newHeight = startCrop.height - constrainedDy;\r\n // Don't let it go past top edge\r\n if (newY < 0) {\r\n newHeight = newHeight + newY;\r\n newY = 0;\r\n }\r\n }\r\n \r\n // Apply aspect ratio constraint\r\n if (aspectRatio !== null) {\r\n if (activeHandle === 'e' || activeHandle === 'w') {\r\n newHeight = newWidth / aspectRatio;\r\n } else if (activeHandle === 'n' || activeHandle === 's') {\r\n newWidth = newHeight * aspectRatio;\r\n } else {\r\n // Corner handles - use the larger dimension\r\n const ratioFromWidth = newWidth / aspectRatio;\r\n const ratioFromHeight = newHeight * aspectRatio;\r\n if (Math.abs(newWidth - ratioFromHeight) < Math.abs(newHeight - ratioFromWidth)) {\r\n newWidth = ratioFromHeight;\r\n } else {\r\n newHeight = ratioFromWidth;\r\n }\r\n }\r\n }\r\n \r\n // Constrain to bounds\r\n newWidth = Math.max(MIN_SIZE, Math.min(newWidth, imageWidth - newX));\r\n newHeight = Math.max(MIN_SIZE, Math.min(newHeight, imageHeight - newY));\r\n \r\n // Reapply aspect ratio after constraining\r\n if (aspectRatio !== null) {\r\n const currentRatio = newWidth / newHeight;\r\n if (currentRatio > aspectRatio) {\r\n newWidth = newHeight * aspectRatio;\r\n } else {\r\n newHeight = newWidth / aspectRatio;\r\n }\r\n }\r\n \r\n cropArea = { x: newX, y: newY, width: newWidth, height: newHeight };\r\n updateCropAreaUI();\r\n }\r\n };\r\n \r\n const handleMouseUp = () => {\r\n isDragging = false;\r\n isResizing = false;\r\n activeHandle = null;\r\n };\r\n \r\n // Handle escape key\r\n const handleKeyDown = (e: KeyboardEvent) => {\r\n if (e.key === 'Escape') {\r\n e.preventDefault();\r\n closeModal();\r\n onCancel();\r\n }\r\n };\r\n \r\n document.addEventListener('mousemove', handleMouseMove);\r\n document.addEventListener('mouseup', handleMouseUp);\r\n document.addEventListener('keydown', handleKeyDown);\r\n \r\n // Cleanup function - removes all event listeners\r\n const cleanup = () => {\r\n document.removeEventListener('mousemove', handleMouseMove);\r\n document.removeEventListener('mouseup', handleMouseUp);\r\n document.removeEventListener('keydown', handleKeyDown);\r\n };\r\n \r\n // Close and cleanup - with guard against double-close\r\n const closeModal = () => {\r\n if (isClosing) return;\r\n isClosing = true;\r\n cleanup();\r\n if (modal.parentNode) {\r\n modal.parentNode.removeChild(modal);\r\n }\r\n };\r\n \r\n // Aspect ratio buttons\r\n modal.querySelectorAll('.cb-crop-aspect-btn').forEach(btn => {\r\n btn.addEventListener('click', (e) => {\r\n e.preventDefault();\r\n e.stopPropagation();\r\n \r\n modal.querySelectorAll('.cb-crop-aspect-btn').forEach(b => b.classList.remove('active'));\r\n btn.classList.add('active');\r\n \r\n const aspect = (btn as HTMLElement).dataset.aspect;\r\n if (aspect === 'free') {\r\n aspectRatio = null;\r\n } else if (aspect) {\r\n const [w, h] = aspect.split(':').map(Number);\r\n aspectRatio = w / h;\r\n \r\n // Apply to current crop area, centered\r\n const centerX = cropArea.x + cropArea.width / 2;\r\n const centerY = cropArea.y + cropArea.height / 2;\r\n \r\n // Calculate new dimensions that fit within current area\r\n let newWidth = cropArea.width;\r\n let newHeight = newWidth / aspectRatio;\r\n \r\n // If too tall, constrain by height\r\n if (newHeight > cropArea.height) {\r\n newHeight = cropArea.height;\r\n newWidth = newHeight * aspectRatio;\r\n }\r\n \r\n // Make sure it fits in the image\r\n if (newWidth > imageWidth) {\r\n newWidth = imageWidth;\r\n newHeight = newWidth / aspectRatio;\r\n }\r\n if (newHeight > imageHeight) {\r\n newHeight = imageHeight;\r\n newWidth = newHeight * aspectRatio;\r\n }\r\n \r\n // Center the new crop area\r\n let newX = centerX - newWidth / 2;\r\n let newY = centerY - newHeight / 2;\r\n \r\n // Constrain position\r\n newX = Math.max(0, Math.min(newX, imageWidth - newWidth));\r\n newY = Math.max(0, Math.min(newY, imageHeight - newHeight));\r\n \r\n cropArea = { x: newX, y: newY, width: newWidth, height: newHeight };\r\n updateCropAreaUI();\r\n }\r\n });\r\n });\r\n \r\n // Close button\r\n modal.querySelector('.cb-crop-modal-close')?.addEventListener('click', (e) => {\r\n e.preventDefault();\r\n e.stopPropagation();\r\n closeModal();\r\n onCancel();\r\n });\r\n \r\n // Backdrop click\r\n modal.querySelector('.cb-crop-modal-backdrop')?.addEventListener('click', (e) => {\r\n e.preventDefault();\r\n e.stopPropagation();\r\n closeModal();\r\n onCancel();\r\n });\r\n \r\n // Cancel button\r\n modal.querySelector('.cb-crop-cancel-btn')?.addEventListener('click', (e) => {\r\n e.preventDefault();\r\n e.stopPropagation();\r\n closeModal();\r\n onCancel();\r\n });\r\n \r\n // Save button\r\n modal.querySelector('.cb-crop-save-btn')?.addEventListener('click', async (e) => {\r\n e.preventDefault();\r\n e.stopPropagation();\r\n \r\n if (isClosing) return;\r\n \r\n try {\r\n const croppedSrc = await cropImage(\r\n cropImg.src,\r\n cropArea,\r\n imageWidth,\r\n imageHeight\r\n );\r\n closeModal();\r\n onSave(croppedSrc);\r\n } catch (err) {\r\n console.error('Failed to crop image:', err);\r\n }\r\n });\r\n \r\n // Prevent clicks inside modal content from bubbling\r\n modal.querySelector('.cb-crop-modal-content')?.addEventListener('click', (e) => {\r\n e.stopPropagation();\r\n });\r\n \r\n return modal;\r\n}\r\n","/**\r\n * Video Block\r\n */\r\n\r\nimport type { BlockDefinition, VideoData } from '../core/types';\r\nimport { generateId } from '../utils/helpers';\r\n\r\n// Common video platforms\r\nconst VIDEO_PATTERNS = {\r\n youtube: /(?:youtube\\.com\\/(?:watch\\?v=|embed\\/)|youtu\\.be\\/)([a-zA-Z0-9_-]{11})/,\r\n vimeo: /vimeo\\.com\\/(?:video\\/)?(\\d+)/,\r\n dailymotion: /dailymotion\\.com\\/(?:video|embed\\/video)\\/([a-zA-Z0-9]+)/,\r\n};\r\n\r\nexport const videoBlock: BlockDefinition = {\r\n name: 'video',\r\n tag: 'figure',\r\n editable: false,\r\n allowedChildren: [],\r\n className: 'cb-video',\r\n icon: 'video',\r\n label: 'Video',\r\n\r\n create(data?: VideoData): HTMLElement {\r\n const figure = document.createElement('figure');\r\n figure.className = 'cb-video';\r\n figure.setAttribute('data-block-id', data?.id || generateId());\r\n figure.setAttribute('data-block-type', 'video');\r\n\r\n const container = document.createElement('div');\r\n container.className = 'cb-video-container';\r\n\r\n if (data?.src) {\r\n const embedUrl = getEmbedUrl(data.src);\r\n \r\n if (embedUrl) {\r\n // External embed (YouTube, Vimeo, etc.)\r\n const iframe = document.createElement('iframe');\r\n iframe.className = 'cb-video-iframe';\r\n iframe.src = embedUrl;\r\n iframe.setAttribute('frameborder', '0');\r\n iframe.setAttribute('allowfullscreen', 'true');\r\n iframe.setAttribute('allow', 'accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture');\r\n \r\n if (data.width) {\r\n iframe.style.width = typeof data.width === 'number' ? `${data.width}px` : data.width;\r\n }\r\n if (data.height) {\r\n iframe.style.height = typeof data.height === 'number' ? `${data.height}px` : data.height;\r\n }\r\n\r\n container.appendChild(iframe);\r\n } else {\r\n // Direct video file\r\n const video = document.createElement('video');\r\n video.className = 'cb-video-element';\r\n video.src = data.src;\r\n video.controls = true;\r\n \r\n if (data.poster) {\r\n video.poster = data.poster;\r\n }\r\n if (data.width) {\r\n video.style.width = typeof data.width === 'number' ? `${data.width}px` : data.width;\r\n }\r\n if (data.height) {\r\n video.style.height = typeof data.height === 'number' ? `${data.height}px` : data.height;\r\n }\r\n\r\n container.appendChild(video);\r\n }\r\n } else {\r\n // Premium placeholder\r\n const placeholder = document.createElement('div');\r\n placeholder.className = 'cb-video-placeholder';\r\n placeholder.innerHTML = `\r\n <div class=\"cb-video-placeholder-content\">\r\n <svg width=\"56\" height=\"56\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.5\">\r\n <path d=\"m22 8-6 4 6 4V8Z\"/>\r\n <rect width=\"14\" height=\"12\" x=\"2\" y=\"6\" rx=\"2\" ry=\"2\"/>\r\n </svg>\r\n <span>Embed a video from YouTube, Vimeo, or upload</span>\r\n <span class=\"cb-video-placeholder-hint\">Paste a URL below and press Enter</span>\r\n <input type=\"text\" class=\"cb-video-url-input\" placeholder=\"https://youtube.com/watch?v=... or vimeo.com/...\" />\r\n </div>\r\n `;\r\n container.appendChild(placeholder);\r\n }\r\n\r\n figure.appendChild(container);\r\n\r\n // Caption\r\n const caption = document.createElement('figcaption');\r\n caption.className = 'cb-video-caption';\r\n caption.setAttribute('contenteditable', 'true');\r\n caption.setAttribute('data-placeholder', 'Add a caption...');\r\n if (data?.caption) {\r\n caption.textContent = data.caption;\r\n }\r\n figure.appendChild(caption);\r\n\r\n return figure;\r\n },\r\n\r\n getData(element: HTMLElement): VideoData {\r\n const iframe = element.querySelector('iframe');\r\n const video = element.querySelector('video');\r\n const caption = element.querySelector('figcaption');\r\n \r\n return {\r\n id: element.getAttribute('data-block-id') || generateId(),\r\n type: 'video',\r\n src: iframe?.src || video?.src || '',\r\n poster: video?.poster || undefined,\r\n caption: caption?.textContent || undefined,\r\n width: iframe?.style.width || video?.style.width || undefined,\r\n height: iframe?.style.height || video?.style.height || undefined,\r\n };\r\n },\r\n\r\n update(element: HTMLElement, data: Partial<VideoData>): void {\r\n if (data.src) {\r\n const container = element.querySelector('.cb-video-container');\r\n if (container) {\r\n container.innerHTML = '';\r\n \r\n const embedUrl = getEmbedUrl(data.src);\r\n \r\n if (embedUrl) {\r\n const iframe = document.createElement('iframe');\r\n iframe.className = 'cb-video-iframe';\r\n iframe.src = embedUrl;\r\n iframe.setAttribute('frameborder', '0');\r\n iframe.setAttribute('allowfullscreen', 'true');\r\n container.appendChild(iframe);\r\n } else {\r\n const video = document.createElement('video');\r\n video.className = 'cb-video-element';\r\n video.src = data.src;\r\n video.controls = true;\r\n if (data.poster) video.poster = data.poster;\r\n container.appendChild(video);\r\n }\r\n }\r\n }\r\n\r\n if (data.caption !== undefined) {\r\n const caption = element.querySelector('figcaption');\r\n if (caption) caption.textContent = data.caption;\r\n }\r\n },\r\n};\r\n\r\n/**\r\n * Get embed URL for common video platforms\r\n */\r\nexport function getEmbedUrl(url: string): string | null {\r\n // YouTube\r\n const ytMatch = url.match(VIDEO_PATTERNS.youtube);\r\n if (ytMatch) {\r\n return `https://www.youtube.com/embed/${ytMatch[1]}`;\r\n }\r\n\r\n // Vimeo\r\n const vimeoMatch = url.match(VIDEO_PATTERNS.vimeo);\r\n if (vimeoMatch) {\r\n return `https://player.vimeo.com/video/${vimeoMatch[1]}`;\r\n }\r\n\r\n // Dailymotion\r\n const dmMatch = url.match(VIDEO_PATTERNS.dailymotion);\r\n if (dmMatch) {\r\n return `https://www.dailymotion.com/embed/video/${dmMatch[1]}`;\r\n }\r\n\r\n // Check if it's already an embed URL\r\n if (url.includes('youtube.com/embed/') || \r\n url.includes('player.vimeo.com/') ||\r\n url.includes('dailymotion.com/embed/')) {\r\n return url;\r\n }\r\n\r\n return null;\r\n}\r\n\r\n/**\r\n * Set video source\r\n */\r\nexport function setVideoSrc(figure: HTMLElement, src: string): void {\r\n const container = figure.querySelector('.cb-video-container');\r\n if (!container) return;\r\n\r\n // Clear existing content\r\n container.innerHTML = '';\r\n\r\n const embedUrl = getEmbedUrl(src);\r\n \r\n if (embedUrl) {\r\n const iframe = document.createElement('iframe');\r\n iframe.className = 'cb-video-iframe';\r\n iframe.src = embedUrl;\r\n iframe.setAttribute('frameborder', '0');\r\n iframe.setAttribute('allowfullscreen', 'true');\r\n iframe.setAttribute('allow', 'accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture');\r\n container.appendChild(iframe);\r\n } else if (src) {\r\n const video = document.createElement('video');\r\n video.className = 'cb-video-element';\r\n video.src = src;\r\n video.controls = true;\r\n container.appendChild(video);\r\n }\r\n}\r\n","/**\r\n * Divider Block (Horizontal Rule)\r\n */\r\n\r\nimport type { BlockDefinition, DividerData } from '../core/types';\r\nimport { generateId } from '../utils/helpers';\r\n\r\nexport const dividerBlock: BlockDefinition = {\r\n name: 'divider',\r\n tag: 'hr',\r\n editable: false,\r\n allowedChildren: [],\r\n className: 'cb-divider',\r\n icon: 'minus',\r\n label: 'Divider',\r\n shortcut: 'Ctrl+Shift+-',\r\n\r\n create(data?: DividerData): HTMLElement {\r\n const wrapper = document.createElement('div');\r\n wrapper.className = 'cb-divider-wrapper';\r\n wrapper.setAttribute('data-block-id', data?.id || generateId());\r\n wrapper.setAttribute('data-block-type', 'divider');\r\n wrapper.setAttribute('contenteditable', 'false');\r\n\r\n const hr = document.createElement('hr');\r\n hr.className = 'cb-divider';\r\n \r\n if (data?.style) {\r\n hr.setAttribute('data-style', data.style);\r\n wrapper.setAttribute('data-divider-style', data.style);\r\n }\r\n\r\n wrapper.appendChild(hr);\r\n return wrapper;\r\n },\r\n\r\n getData(element: HTMLElement): DividerData {\r\n const hr = element.querySelector('hr');\r\n return {\r\n id: element.getAttribute('data-block-id') || generateId(),\r\n type: 'divider',\r\n style: (hr?.getAttribute('data-style') || element.getAttribute('data-divider-style') || 'solid') as DividerData['style'],\r\n };\r\n },\r\n\r\n update(element: HTMLElement, data: Partial<DividerData>): void {\r\n if (data.style) {\r\n const hr = element.querySelector('hr');\r\n if (hr) {\r\n hr.setAttribute('data-style', data.style);\r\n }\r\n element.setAttribute('data-divider-style', data.style);\r\n }\r\n },\r\n};\r\n\r\n/**\r\n * Set divider style\r\n */\r\nexport function setDividerStyle(wrapper: HTMLElement, style: 'solid' | 'dashed' | 'dotted'): void {\r\n const hr = wrapper.querySelector('hr');\r\n if (hr) {\r\n hr.setAttribute('data-style', style);\r\n }\r\n wrapper.setAttribute('data-divider-style', style);\r\n}\r\n","/**\r\n * Callout Block (Info/Warning/Error/Success boxes)\r\n */\r\n\r\nimport type { BlockDefinition, CalloutData, CalloutType } from '../core/types';\r\nimport { generateId } from '../utils/helpers';\r\n\r\nconst CALLOUT_ICONS: Record<CalloutType, string> = {\r\n info: '<svg width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"><circle cx=\"12\" cy=\"12\" r=\"10\"/><path d=\"M12 16v-4\"/><path d=\"M12 8h.01\"/></svg>',\r\n warning: '<svg width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"><path d=\"m21.73 18-8-14a2 2 0 0 0-3.48 0l-8 14A2 2 0 0 0 4 21h16a2 2 0 0 0 1.73-3Z\"/><path d=\"M12 9v4\"/><path d=\"M12 17h.01\"/></svg>',\r\n error: '<svg width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"><circle cx=\"12\" cy=\"12\" r=\"10\"/><path d=\"m15 9-6 6\"/><path d=\"m9 9 6 6\"/></svg>',\r\n success: '<svg width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"><circle cx=\"12\" cy=\"12\" r=\"10\"/><path d=\"m9 12 2 2 4-4\"/></svg>',\r\n note: '<svg width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"><path d=\"M14.5 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7.5L14.5 2z\"/><polyline points=\"14 2 14 8 20 8\"/><line x1=\"16\" x2=\"8\" y1=\"13\" y2=\"13\"/><line x1=\"16\" x2=\"8\" y1=\"17\" y2=\"17\"/><line x1=\"10\" x2=\"8\" y1=\"9\" y2=\"9\"/></svg>',\r\n};\r\n\r\nexport const calloutBlock: BlockDefinition = {\r\n name: 'callout',\r\n tag: 'aside',\r\n editable: true,\r\n allowedChildren: ['text', 'inline'],\r\n className: 'cb-callout',\r\n icon: 'alertCircle',\r\n label: 'Callout',\r\n\r\n create(data?: CalloutData): HTMLElement {\r\n const calloutType = data?.calloutType || 'info';\r\n \r\n const aside = document.createElement('aside');\r\n aside.className = `cb-callout cb-callout-${calloutType}`;\r\n aside.setAttribute('data-block-id', data?.id || generateId());\r\n aside.setAttribute('data-block-type', 'callout');\r\n aside.setAttribute('data-callout-type', calloutType);\r\n\r\n // Icon\r\n const iconWrapper = document.createElement('div');\r\n iconWrapper.className = 'cb-callout-icon';\r\n iconWrapper.innerHTML = CALLOUT_ICONS[calloutType];\r\n aside.appendChild(iconWrapper);\r\n\r\n // Content wrapper\r\n const contentWrapper = document.createElement('div');\r\n contentWrapper.className = 'cb-callout-content';\r\n\r\n // Title (optional)\r\n if (data?.title) {\r\n const title = document.createElement('div');\r\n title.className = 'cb-callout-title';\r\n title.setAttribute('contenteditable', 'true');\r\n title.textContent = data.title;\r\n contentWrapper.appendChild(title);\r\n }\r\n\r\n // Body\r\n const body = document.createElement('div');\r\n body.className = 'cb-callout-body';\r\n body.setAttribute('contenteditable', 'true');\r\n body.setAttribute('data-placeholder', 'Type callout content...');\r\n if (data?.content) {\r\n body.innerHTML = data.content;\r\n }\r\n contentWrapper.appendChild(body);\r\n\r\n aside.appendChild(contentWrapper);\r\n\r\n // Type selector (hidden by default, shown on focus)\r\n const typeSelector = document.createElement('div');\r\n typeSelector.className = 'cb-callout-type-selector';\r\n typeSelector.innerHTML = `\r\n <button type=\"button\" data-type=\"info\" title=\"Info\" class=\"${calloutType === 'info' ? 'active' : ''}\">\r\n ${CALLOUT_ICONS.info}\r\n </button>\r\n <button type=\"button\" data-type=\"success\" title=\"Success\" class=\"${calloutType === 'success' ? 'active' : ''}\">\r\n ${CALLOUT_ICONS.success}\r\n </button>\r\n <button type=\"button\" data-type=\"warning\" title=\"Warning\" class=\"${calloutType === 'warning' ? 'active' : ''}\">\r\n ${CALLOUT_ICONS.warning}\r\n </button>\r\n <button type=\"button\" data-type=\"error\" title=\"Error\" class=\"${calloutType === 'error' ? 'active' : ''}\">\r\n ${CALLOUT_ICONS.error}\r\n </button>\r\n <button type=\"button\" data-type=\"note\" title=\"Note\" class=\"${calloutType === 'note' ? 'active' : ''}\">\r\n ${CALLOUT_ICONS.note}\r\n </button>\r\n `;\r\n aside.appendChild(typeSelector);\r\n\r\n return aside;\r\n },\r\n\r\n getData(element: HTMLElement): CalloutData {\r\n const title = element.querySelector('.cb-callout-title');\r\n const body = element.querySelector('.cb-callout-body');\r\n \r\n return {\r\n id: element.getAttribute('data-block-id') || generateId(),\r\n type: 'callout',\r\n calloutType: (element.getAttribute('data-callout-type') || 'info') as CalloutType,\r\n title: title?.textContent || undefined,\r\n content: body?.innerHTML || '',\r\n };\r\n },\r\n\r\n update(element: HTMLElement, data: Partial<CalloutData>): void {\r\n if (data.calloutType) {\r\n setCalloutType(element, data.calloutType);\r\n }\r\n if (data.title !== undefined) {\r\n let title = element.querySelector('.cb-callout-title');\r\n if (data.title) {\r\n if (!title) {\r\n title = document.createElement('div');\r\n title.className = 'cb-callout-title';\r\n title.setAttribute('contenteditable', 'true');\r\n const content = element.querySelector('.cb-callout-content');\r\n const body = element.querySelector('.cb-callout-body');\r\n if (content && body) {\r\n content.insertBefore(title, body);\r\n }\r\n }\r\n title.textContent = data.title;\r\n } else if (title) {\r\n title.remove();\r\n }\r\n }\r\n if (data.content !== undefined) {\r\n const body = element.querySelector('.cb-callout-body');\r\n if (body) {\r\n body.innerHTML = data.content;\r\n }\r\n }\r\n },\r\n};\r\n\r\n/**\r\n * Set callout type\r\n */\r\nexport function setCalloutType(element: HTMLElement, type: CalloutType): void {\r\n // Update class\r\n element.className = `cb-callout cb-callout-${type}`;\r\n element.setAttribute('data-callout-type', type);\r\n\r\n // Update icon\r\n const icon = element.querySelector('.cb-callout-icon');\r\n if (icon) {\r\n icon.innerHTML = CALLOUT_ICONS[type];\r\n }\r\n\r\n // Update type selector\r\n const selector = element.querySelector('.cb-callout-type-selector');\r\n if (selector) {\r\n selector.querySelectorAll('button').forEach(btn => {\r\n btn.classList.toggle('active', btn.getAttribute('data-type') === type);\r\n });\r\n }\r\n}\r\n\r\n/**\r\n * Add title to callout\r\n */\r\nexport function addCalloutTitle(element: HTMLElement, text: string): void {\r\n let title = element.querySelector('.cb-callout-title');\r\n if (!title) {\r\n title = document.createElement('div');\r\n title.className = 'cb-callout-title';\r\n title.setAttribute('contenteditable', 'true');\r\n const content = element.querySelector('.cb-callout-content');\r\n const body = element.querySelector('.cb-callout-body');\r\n if (content && body) {\r\n content.insertBefore(title, body);\r\n }\r\n }\r\n title.textContent = text;\r\n}\r\n","/**\r\n * Accordion Block (Collapsible content)\r\n */\r\n\r\nimport type { BlockDefinition, AccordionData } from '../core/types';\r\nimport { generateId } from '../utils/helpers';\r\n\r\nexport const accordionBlock: BlockDefinition = {\r\n name: 'accordion',\r\n tag: 'details',\r\n editable: true,\r\n allowedChildren: ['text', 'inline', 'block'],\r\n className: 'cb-accordion',\r\n icon: 'chevronDown',\r\n label: 'Accordion',\r\n\r\n create(data?: AccordionData): HTMLElement {\r\n const details = document.createElement('details');\r\n details.className = 'cb-accordion';\r\n details.setAttribute('data-block-id', data?.id || generateId());\r\n details.setAttribute('data-block-type', 'accordion');\r\n \r\n if (data?.open) {\r\n details.open = true;\r\n }\r\n\r\n // Summary (title)\r\n const summary = document.createElement('summary');\r\n summary.className = 'cb-accordion-title';\r\n \r\n const titleText = document.createElement('span');\r\n titleText.className = 'cb-accordion-title-text';\r\n titleText.setAttribute('contenteditable', 'true');\r\n titleText.setAttribute('data-placeholder', 'Accordion title...');\r\n if (data?.title) {\r\n titleText.textContent = data.title;\r\n }\r\n \r\n const chevron = document.createElement('span');\r\n chevron.className = 'cb-accordion-chevron';\r\n chevron.innerHTML = `\r\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\">\r\n <path d=\"m6 9 6 6 6-6\"/>\r\n </svg>\r\n `;\r\n \r\n summary.appendChild(titleText);\r\n summary.appendChild(chevron);\r\n details.appendChild(summary);\r\n\r\n // Content\r\n const content = document.createElement('div');\r\n content.className = 'cb-accordion-content';\r\n content.setAttribute('contenteditable', 'true');\r\n content.setAttribute('data-placeholder', 'Accordion content...');\r\n if (data?.content) {\r\n content.innerHTML = data.content;\r\n }\r\n details.appendChild(content);\r\n\r\n return details;\r\n },\r\n\r\n getData(element: HTMLElement): AccordionData {\r\n const details = element as HTMLDetailsElement;\r\n const title = element.querySelector('.cb-accordion-title-text');\r\n const content = element.querySelector('.cb-accordion-content');\r\n \r\n return {\r\n id: element.getAttribute('data-block-id') || generateId(),\r\n type: 'accordion',\r\n title: title?.textContent || '',\r\n content: content?.innerHTML || '',\r\n open: details.open,\r\n };\r\n },\r\n\r\n update(element: HTMLElement, data: Partial<AccordionData>): void {\r\n const details = element as HTMLDetailsElement;\r\n \r\n if (data.title !== undefined) {\r\n const title = element.querySelector('.cb-accordion-title-text');\r\n if (title) title.textContent = data.title;\r\n }\r\n if (data.content !== undefined) {\r\n const content = element.querySelector('.cb-accordion-content');\r\n if (content) content.innerHTML = data.content;\r\n }\r\n if (data.open !== undefined) {\r\n details.open = data.open;\r\n }\r\n },\r\n};\r\n\r\n/**\r\n * Toggle accordion open/closed\r\n */\r\nexport function toggleAccordion(element: HTMLElement): boolean {\r\n const details = element as HTMLDetailsElement;\r\n details.open = !details.open;\r\n return details.open;\r\n}\r\n\r\n/**\r\n * Set accordion open state\r\n */\r\nexport function setAccordionOpen(element: HTMLElement, open: boolean): void {\r\n const details = element as HTMLDetailsElement;\r\n details.open = open;\r\n}\r\n","/**\r\n * Table Block\r\n */\r\n\r\nimport type { BlockDefinition, TableData, TableRow, TableCell } from '../core/types';\r\nimport { generateId } from '../utils/helpers';\r\n\r\nexport const tableBlock: BlockDefinition = {\r\n name: 'table',\r\n tag: 'table',\r\n editable: true,\r\n allowedChildren: ['text', 'inline'],\r\n className: 'cb-table',\r\n icon: 'table',\r\n label: 'Table',\r\n\r\n create(data?: TableData): HTMLElement {\r\n const wrapper = document.createElement('div');\r\n wrapper.className = 'cb-table-wrapper';\r\n wrapper.setAttribute('data-block-id', data?.id || generateId());\r\n wrapper.setAttribute('data-block-type', 'table');\r\n\r\n const table = document.createElement('table');\r\n table.className = 'cb-table';\r\n\r\n // Default: 3x3 table if no data\r\n const rows = data?.rows || [\r\n { cells: [{ content: '' }, { content: '' }, { content: '' }] },\r\n { cells: [{ content: '' }, { content: '' }, { content: '' }] },\r\n { cells: [{ content: '' }, { content: '' }, { content: '' }] },\r\n ];\r\n\r\n const hasHeader = data?.hasHeader ?? true;\r\n\r\n rows.forEach((row, rowIndex) => {\r\n const tr = document.createElement('tr');\r\n tr.className = 'cb-table-row';\r\n\r\n row.cells.forEach(cell => {\r\n const cellTag = hasHeader && rowIndex === 0 ? 'th' : 'td';\r\n const td = document.createElement(cellTag);\r\n td.className = 'cb-table-cell';\r\n td.setAttribute('contenteditable', 'true');\r\n td.innerHTML = cell.content || '';\r\n \r\n if (cell.align) {\r\n td.style.textAlign = cell.align;\r\n }\r\n if (cell.colSpan && cell.colSpan > 1) {\r\n td.colSpan = cell.colSpan;\r\n }\r\n if (cell.rowSpan && cell.rowSpan > 1) {\r\n td.rowSpan = cell.rowSpan;\r\n }\r\n\r\n tr.appendChild(td);\r\n });\r\n\r\n table.appendChild(tr);\r\n });\r\n\r\n wrapper.appendChild(table);\r\n\r\n // Table controls\r\n const controls = document.createElement('div');\r\n controls.className = 'cb-table-controls';\r\n controls.innerHTML = `\r\n <button type=\"button\" class=\"cb-table-btn\" data-action=\"addRow\" title=\"Add row\">\r\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\">\r\n <path d=\"M12 5v14\"/><path d=\"M5 12h14\"/>\r\n </svg>\r\n Row\r\n </button>\r\n <button type=\"button\" class=\"cb-table-btn\" data-action=\"addCol\" title=\"Add column\">\r\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\">\r\n <path d=\"M12 5v14\"/><path d=\"M5 12h14\"/>\r\n </svg>\r\n Column\r\n </button>\r\n <button type=\"button\" class=\"cb-table-btn cb-table-btn-danger\" data-action=\"deleteRow\" title=\"Delete row\">\r\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\">\r\n <path d=\"M5 12h14\"/>\r\n </svg>\r\n Row\r\n </button>\r\n <button type=\"button\" class=\"cb-table-btn cb-table-btn-danger\" data-action=\"deleteCol\" title=\"Delete column\">\r\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\">\r\n <path d=\"M5 12h14\"/>\r\n </svg>\r\n Column\r\n </button>\r\n `;\r\n wrapper.appendChild(controls);\r\n\r\n return wrapper;\r\n },\r\n\r\n getData(element: HTMLElement): TableData {\r\n const table = element.querySelector('table');\r\n const rows: TableRow[] = [];\r\n let hasHeader = false;\r\n\r\n table?.querySelectorAll('tr').forEach((tr, rowIndex) => {\r\n const cells: TableCell[] = [];\r\n \r\n tr.querySelectorAll('th, td').forEach(cell => {\r\n if (cell.tagName === 'TH') hasHeader = true;\r\n \r\n cells.push({\r\n content: cell.innerHTML,\r\n align: (cell as HTMLTableCellElement).style.textAlign as TableCell['align'] || undefined,\r\n colSpan: (cell as HTMLTableCellElement).colSpan > 1 ? (cell as HTMLTableCellElement).colSpan : undefined,\r\n rowSpan: (cell as HTMLTableCellElement).rowSpan > 1 ? (cell as HTMLTableCellElement).rowSpan : undefined,\r\n });\r\n });\r\n\r\n rows.push({ cells });\r\n });\r\n\r\n return {\r\n id: element.getAttribute('data-block-id') || generateId(),\r\n type: 'table',\r\n rows,\r\n hasHeader,\r\n };\r\n },\r\n\r\n update(element: HTMLElement, data: Partial<TableData>): void {\r\n if (data.rows) {\r\n const table = element.querySelector('table');\r\n if (table) {\r\n table.innerHTML = '';\r\n \r\n data.rows.forEach((row, rowIndex) => {\r\n const tr = document.createElement('tr');\r\n tr.className = 'cb-table-row';\r\n\r\n row.cells.forEach(cell => {\r\n const cellTag = data.hasHeader && rowIndex === 0 ? 'th' : 'td';\r\n const td = document.createElement(cellTag);\r\n td.className = 'cb-table-cell';\r\n td.setAttribute('contenteditable', 'true');\r\n td.innerHTML = cell.content || '';\r\n \r\n if (cell.align) td.style.textAlign = cell.align;\r\n if (cell.colSpan) td.colSpan = cell.colSpan;\r\n if (cell.rowSpan) td.rowSpan = cell.rowSpan;\r\n\r\n tr.appendChild(td);\r\n });\r\n\r\n table.appendChild(tr);\r\n });\r\n }\r\n }\r\n },\r\n};\r\n\r\n/**\r\n * Add row to table\r\n */\r\nexport function addTableRow(wrapper: HTMLElement, afterIndex?: number): void {\r\n const table = wrapper.querySelector('table');\r\n if (!table) return;\r\n\r\n const rows = table.querySelectorAll('tr');\r\n const colCount = rows[0]?.querySelectorAll('th, td').length || 3;\r\n\r\n const tr = document.createElement('tr');\r\n tr.className = 'cb-table-row';\r\n\r\n for (let i = 0; i < colCount; i++) {\r\n const td = document.createElement('td');\r\n td.className = 'cb-table-cell';\r\n td.setAttribute('contenteditable', 'true');\r\n tr.appendChild(td);\r\n }\r\n\r\n if (afterIndex !== undefined && rows[afterIndex]) {\r\n rows[afterIndex].after(tr);\r\n } else {\r\n table.appendChild(tr);\r\n }\r\n}\r\n\r\n/**\r\n * Add column to table\r\n */\r\nexport function addTableColumn(wrapper: HTMLElement, afterIndex?: number): void {\r\n const table = wrapper.querySelector('table');\r\n if (!table) return;\r\n\r\n table.querySelectorAll('tr').forEach((tr, rowIndex) => {\r\n const cells = tr.querySelectorAll('th, td');\r\n const isHeader = rowIndex === 0 && cells[0]?.tagName === 'TH';\r\n \r\n const cell = document.createElement(isHeader ? 'th' : 'td');\r\n cell.className = 'cb-table-cell';\r\n cell.setAttribute('contenteditable', 'true');\r\n\r\n if (afterIndex !== undefined && cells[afterIndex]) {\r\n cells[afterIndex].after(cell);\r\n } else {\r\n tr.appendChild(cell);\r\n }\r\n });\r\n}\r\n\r\n/**\r\n * Delete row from table\r\n */\r\nexport function deleteTableRow(wrapper: HTMLElement, index: number): boolean {\r\n const table = wrapper.querySelector('table');\r\n if (!table) return false;\r\n\r\n const rows = table.querySelectorAll('tr');\r\n if (rows.length <= 1) return false; // Keep at least one row\r\n\r\n rows[index]?.remove();\r\n return true;\r\n}\r\n\r\n/**\r\n * Delete column from table\r\n */\r\nexport function deleteTableColumn(wrapper: HTMLElement, index: number): boolean {\r\n const table = wrapper.querySelector('table');\r\n if (!table) return false;\r\n\r\n const rows = table.querySelectorAll('tr');\r\n const colCount = rows[0]?.querySelectorAll('th, td').length || 0;\r\n if (colCount <= 1) return false; // Keep at least one column\r\n\r\n rows.forEach(tr => {\r\n const cells = tr.querySelectorAll('th, td');\r\n cells[index]?.remove();\r\n });\r\n\r\n return true;\r\n}\r\n\r\n/**\r\n * Set cell alignment\r\n */\r\nexport function setCellAlignment(\r\n cell: HTMLTableCellElement,\r\n align: 'left' | 'center' | 'right'\r\n): void {\r\n cell.style.textAlign = align;\r\n}\r\n\r\n/**\r\n * Get currently focused cell\r\n */\r\nexport function getFocusedCell(wrapper: HTMLElement): HTMLTableCellElement | null {\r\n const activeElement = document.activeElement;\r\n if (activeElement && wrapper.contains(activeElement)) {\r\n const cell = activeElement.closest('td, th');\r\n return cell as HTMLTableCellElement | null;\r\n }\r\n return null;\r\n}\r\n\r\n/**\r\n * Get cell position (row, col)\r\n */\r\nexport function getCellPosition(cell: HTMLTableCellElement): { row: number; col: number } | null {\r\n const tr = cell.parentElement as HTMLTableRowElement;\r\n if (!tr) return null;\r\n\r\n const table = tr.closest('table');\r\n if (!table) return null;\r\n\r\n const rows = Array.from(table.querySelectorAll('tr'));\r\n const row = rows.indexOf(tr);\r\n\r\n const cells = Array.from(tr.querySelectorAll('th, td'));\r\n const col = cells.indexOf(cell);\r\n\r\n return { row, col };\r\n}\r\n","/**\r\n * Blocks Index - Export all block definitions\r\n */\r\n\r\n// Block definitions\r\nexport { paragraphBlock } from './paragraph';\r\nexport {\r\n heading1Block,\r\n heading2Block,\r\n heading3Block,\r\n heading4Block,\r\n heading5Block,\r\n heading6Block,\r\n createHeading,\r\n} from './heading';\r\nexport {\r\n bulletListBlock,\r\n numberedListBlock,\r\n checkListBlock,\r\n addListItem,\r\n removeListItem,\r\n toggleChecklistItem,\r\n indentListItem,\r\n outdentListItem,\r\n} from './list';\r\nexport { quoteBlock, addCitation, removeCitation } from './quote';\r\nexport { codeBlock, setLanguage, getCode, LANGUAGES } from './code';\r\nexport {\r\n imageBlock,\r\n setImageSrc,\r\n setImageAlign,\r\n createImageFromFile,\r\n} from './image';\r\nexport { videoBlock, setVideoSrc, getEmbedUrl } from './video';\r\nexport { dividerBlock, setDividerStyle } from './divider';\r\nexport { calloutBlock, setCalloutType, addCalloutTitle } from './callout';\r\nexport { accordionBlock, toggleAccordion, setAccordionOpen } from './accordion';\r\nexport {\r\n tableBlock,\r\n addTableRow,\r\n addTableColumn,\r\n deleteTableRow,\r\n deleteTableColumn,\r\n setCellAlignment,\r\n getFocusedCell,\r\n getCellPosition,\r\n} from './table';\r\n\r\n// Import all blocks for registration\r\nimport { paragraphBlock } from './paragraph';\r\nimport {\r\n heading1Block,\r\n heading2Block,\r\n heading3Block,\r\n heading4Block,\r\n heading5Block,\r\n heading6Block,\r\n} from './heading';\r\nimport { bulletListBlock, numberedListBlock, checkListBlock } from './list';\r\nimport { quoteBlock } from './quote';\r\nimport { codeBlock } from './code';\r\nimport { imageBlock } from './image';\r\nimport { videoBlock } from './video';\r\nimport { dividerBlock } from './divider';\r\nimport { calloutBlock } from './callout';\r\nimport { accordionBlock } from './accordion';\r\nimport { tableBlock } from './table';\r\n\r\nimport type { BlockDefinition } from '../core/types';\r\n\r\n/**\r\n * All built-in block definitions\r\n */\r\nexport const allBlocks: BlockDefinition[] = [\r\n paragraphBlock,\r\n heading1Block,\r\n heading2Block,\r\n heading3Block,\r\n heading4Block,\r\n heading5Block,\r\n heading6Block,\r\n bulletListBlock,\r\n numberedListBlock,\r\n checkListBlock,\r\n quoteBlock,\r\n codeBlock,\r\n imageBlock,\r\n videoBlock,\r\n dividerBlock,\r\n calloutBlock,\r\n accordionBlock,\r\n tableBlock,\r\n];\r\n\r\n/**\r\n * Default blocks for minimal editor\r\n */\r\nexport const defaultBlocks: BlockDefinition[] = [\r\n paragraphBlock,\r\n heading1Block,\r\n heading2Block,\r\n heading3Block,\r\n bulletListBlock,\r\n numberedListBlock,\r\n quoteBlock,\r\n codeBlock,\r\n imageBlock,\r\n dividerBlock,\r\n];\r\n\r\n/**\r\n * Block map by name\r\n */\r\nexport const blockMap = new Map<string, BlockDefinition>(\r\n allBlocks.map(block => [block.name, block])\r\n);\r\n\r\n/**\r\n * Get block definition by name\r\n */\r\nexport function getBlockDefinition(name: string): BlockDefinition | undefined {\r\n return blockMap.get(name);\r\n}\r\n","/**\r\n * Paste Sanitization - Clean and normalize pasted content\r\n * This is CRITICAL for maintaining clean HTML output\r\n */\r\n\r\n// Allowed tags that will be preserved\r\nconst ALLOWED_TAGS = new Set([\r\n // Block elements\r\n 'p', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6',\r\n 'ul', 'ol', 'li',\r\n 'blockquote', 'pre', 'code',\r\n 'hr', 'br',\r\n 'table', 'thead', 'tbody', 'tr', 'th', 'td',\r\n 'figure', 'figcaption',\r\n 'details', 'summary',\r\n // Inline elements\r\n 'strong', 'b', 'em', 'i', 'u', 's', 'del',\r\n 'a', 'span', 'mark', 'sub', 'sup',\r\n 'img', 'video', 'audio', 'iframe',\r\n]);\r\n\r\n// Tags that should be converted to other tags\r\nconst TAG_CONVERSIONS: Record<string, string> = {\r\n 'b': 'strong',\r\n 'i': 'em',\r\n 'strike': 's',\r\n 'del': 's',\r\n 'div': 'p', // Convert divs to paragraphs\r\n};\r\n\r\n// Allowed attributes per tag\r\nconst ALLOWED_ATTRIBUTES: Record<string, Set<string>> = {\r\n '*': new Set(['class', 'id']),\r\n 'a': new Set(['href', 'target', 'rel', 'title']),\r\n 'img': new Set(['src', 'alt', 'title', 'width', 'height']),\r\n 'video': new Set(['src', 'poster', 'controls', 'width', 'height']),\r\n 'audio': new Set(['src', 'controls']),\r\n 'iframe': new Set(['src', 'width', 'height', 'frameborder', 'allowfullscreen']),\r\n 'td': new Set(['colspan', 'rowspan']),\r\n 'th': new Set(['colspan', 'rowspan', 'scope']),\r\n 'ol': new Set(['start', 'type']),\r\n 'pre': new Set(['data-language']),\r\n 'code': new Set(['data-language']),\r\n 'span': new Set(['style']), // Allow limited inline styles\r\n};\r\n\r\n// Dangerous attributes that should always be removed\r\nconst DANGEROUS_ATTRIBUTES = new Set([\r\n 'onclick', 'onmouseover', 'onmouseout', 'onmousedown', 'onmouseup',\r\n 'onkeydown', 'onkeyup', 'onkeypress', 'onload', 'onerror', 'onsubmit',\r\n 'onfocus', 'onblur', 'onchange', 'oninput', 'onscroll', 'onresize',\r\n]);\r\n\r\n// Allowed CSS properties for inline styles\r\nconst ALLOWED_CSS_PROPERTIES = new Set([\r\n 'color', 'background-color', 'font-weight', 'font-style',\r\n 'text-decoration', 'text-align', 'vertical-align',\r\n]);\r\n\r\nexport interface SanitizeOptions {\r\n /** Allow iframes (for embeds) */\r\n allowIframes?: boolean;\r\n /** Allow tables */\r\n allowTables?: boolean;\r\n /** Allow images */\r\n allowImages?: boolean;\r\n /** Allow videos */\r\n allowVideos?: boolean;\r\n /** Additional allowed tags */\r\n additionalTags?: string[];\r\n /** Strip all styles */\r\n stripStyles?: boolean;\r\n /** Strip all classes */\r\n stripClasses?: boolean;\r\n /** Class prefix to keep (remove others) */\r\n keepClassPrefix?: string;\r\n /** Maximum nesting depth */\r\n maxDepth?: number;\r\n}\r\n\r\nconst DEFAULT_OPTIONS: SanitizeOptions = {\r\n allowIframes: true,\r\n allowTables: true,\r\n allowImages: true,\r\n allowVideos: true,\r\n additionalTags: [],\r\n stripStyles: false,\r\n stripClasses: false,\r\n keepClassPrefix: 'cb-',\r\n maxDepth: 10,\r\n};\r\n\r\n/**\r\n * Sanitize HTML string\r\n */\r\nexport function sanitizeHtml(html: string, options: SanitizeOptions = {}): string {\r\n const opts = { ...DEFAULT_OPTIONS, ...options };\r\n \r\n // Create a temporary container\r\n const container = document.createElement('div');\r\n container.innerHTML = html;\r\n\r\n // Process the DOM tree\r\n sanitizeNode(container, opts, 0);\r\n\r\n return container.innerHTML;\r\n}\r\n\r\n/**\r\n * Sanitize a DOM node recursively\r\n */\r\nfunction sanitizeNode(\r\n node: Node,\r\n options: SanitizeOptions,\r\n depth: number\r\n): void {\r\n if (depth > (options.maxDepth || 10)) {\r\n // Too deep, remove everything\r\n node.textContent = node.textContent;\r\n return;\r\n }\r\n\r\n const nodesToRemove: Node[] = [];\r\n const nodesToReplace: Array<{ old: Node; new: Node }> = [];\r\n\r\n // Process child nodes\r\n node.childNodes.forEach(child => {\r\n if (child.nodeType === Node.TEXT_NODE) {\r\n // Keep text nodes\r\n return;\r\n }\r\n\r\n if (child.nodeType === Node.COMMENT_NODE) {\r\n // Remove comments\r\n nodesToRemove.push(child);\r\n return;\r\n }\r\n\r\n if (child.nodeType !== Node.ELEMENT_NODE) {\r\n // Remove other node types\r\n nodesToRemove.push(child);\r\n return;\r\n }\r\n\r\n const element = child as HTMLElement;\r\n const tagName = element.tagName.toLowerCase();\r\n\r\n // Check if tag should be converted\r\n const convertedTag = TAG_CONVERSIONS[tagName];\r\n if (convertedTag) {\r\n const newElement = document.createElement(convertedTag);\r\n newElement.innerHTML = element.innerHTML;\r\n copyAllowedAttributes(element, newElement, options);\r\n nodesToReplace.push({ old: element, new: newElement });\r\n sanitizeNode(newElement, options, depth + 1);\r\n return;\r\n }\r\n\r\n // Check if tag is allowed\r\n const allowedTags = new Set([\r\n ...ALLOWED_TAGS,\r\n ...(options.additionalTags || []),\r\n ]);\r\n\r\n // Handle special cases\r\n if (tagName === 'iframe' && !options.allowIframes) {\r\n nodesToRemove.push(element);\r\n return;\r\n }\r\n if (tagName === 'table' && !options.allowTables) {\r\n // Convert table to plain text\r\n const text = document.createTextNode(element.textContent || '');\r\n nodesToReplace.push({ old: element, new: text });\r\n return;\r\n }\r\n if (tagName === 'img' && !options.allowImages) {\r\n nodesToRemove.push(element);\r\n return;\r\n }\r\n if ((tagName === 'video' || tagName === 'audio') && !options.allowVideos) {\r\n nodesToRemove.push(element);\r\n return;\r\n }\r\n\r\n if (!allowedTags.has(tagName)) {\r\n // Tag not allowed - unwrap (keep contents) or remove\r\n if (element.childNodes.length > 0) {\r\n // Unwrap: replace with children\r\n const fragment = document.createDocumentFragment();\r\n while (element.firstChild) {\r\n fragment.appendChild(element.firstChild);\r\n }\r\n nodesToReplace.push({ old: element, new: fragment });\r\n } else {\r\n nodesToRemove.push(element);\r\n }\r\n return;\r\n }\r\n\r\n // Sanitize attributes\r\n sanitizeAttributes(element, tagName, options);\r\n\r\n // Recurse into children\r\n sanitizeNode(element, options, depth + 1);\r\n });\r\n\r\n // Apply removals\r\n nodesToRemove.forEach(n => n.parentNode?.removeChild(n));\r\n\r\n // Apply replacements\r\n nodesToReplace.forEach(({ old, new: newNode }) => {\r\n old.parentNode?.replaceChild(newNode, old);\r\n });\r\n}\r\n\r\n/**\r\n * Sanitize element attributes\r\n */\r\nfunction sanitizeAttributes(\r\n element: HTMLElement,\r\n tagName: string,\r\n options: SanitizeOptions\r\n): void {\r\n const allowedGlobal = ALLOWED_ATTRIBUTES['*'] || new Set();\r\n const allowedForTag = ALLOWED_ATTRIBUTES[tagName] || new Set();\r\n const allowed = new Set([...allowedGlobal, ...allowedForTag]);\r\n\r\n // Get all attributes\r\n const attributes = Array.from(element.attributes);\r\n\r\n attributes.forEach(attr => {\r\n const name = attr.name.toLowerCase();\r\n\r\n // Always remove dangerous attributes\r\n if (DANGEROUS_ATTRIBUTES.has(name) || name.startsWith('on')) {\r\n element.removeAttribute(attr.name);\r\n return;\r\n }\r\n\r\n // Remove data-* attributes except specific ones\r\n if (name.startsWith('data-') && name !== 'data-language') {\r\n element.removeAttribute(attr.name);\r\n return;\r\n }\r\n\r\n // Handle class attribute\r\n if (name === 'class') {\r\n if (options.stripClasses) {\r\n element.removeAttribute('class');\r\n } else if (options.keepClassPrefix) {\r\n const classes = attr.value.split(/\\s+/);\r\n const kept = classes.filter(\r\n c => c.startsWith(options.keepClassPrefix!) || c.startsWith('cb-')\r\n );\r\n if (kept.length > 0) {\r\n element.className = kept.join(' ');\r\n } else {\r\n element.removeAttribute('class');\r\n }\r\n }\r\n return;\r\n }\r\n\r\n // Handle style attribute\r\n if (name === 'style') {\r\n if (options.stripStyles) {\r\n element.removeAttribute('style');\r\n } else {\r\n sanitizeStyles(element);\r\n }\r\n return;\r\n }\r\n\r\n // Remove if not in allowed list\r\n if (!allowed.has(name)) {\r\n element.removeAttribute(attr.name);\r\n return;\r\n }\r\n\r\n // Sanitize URLs\r\n if (name === 'href' || name === 'src') {\r\n const value = attr.value.trim().toLowerCase();\r\n if (\r\n value.startsWith('javascript:') ||\r\n value.startsWith('vbscript:') ||\r\n value.startsWith('data:text/html')\r\n ) {\r\n element.removeAttribute(attr.name);\r\n }\r\n }\r\n });\r\n}\r\n\r\n/**\r\n * Sanitize inline styles\r\n */\r\nfunction sanitizeStyles(element: HTMLElement): void {\r\n const style = element.style;\r\n const cssText = element.getAttribute('style') || '';\r\n \r\n // Parse and filter CSS properties\r\n const newStyles: string[] = [];\r\n \r\n cssText.split(';').forEach(declaration => {\r\n const [property, value] = declaration.split(':').map(s => s.trim());\r\n if (property && value && ALLOWED_CSS_PROPERTIES.has(property.toLowerCase())) {\r\n // Basic value sanitization (no url(), expression(), etc.)\r\n const lowerValue = value.toLowerCase();\r\n if (\r\n !lowerValue.includes('url(') &&\r\n !lowerValue.includes('expression(') &&\r\n !lowerValue.includes('javascript:')\r\n ) {\r\n newStyles.push(`${property}: ${value}`);\r\n }\r\n }\r\n });\r\n\r\n if (newStyles.length > 0) {\r\n element.setAttribute('style', newStyles.join('; '));\r\n } else {\r\n element.removeAttribute('style');\r\n }\r\n}\r\n\r\n/**\r\n * Copy allowed attributes from one element to another\r\n */\r\nfunction copyAllowedAttributes(\r\n source: HTMLElement,\r\n target: HTMLElement,\r\n options: SanitizeOptions\r\n): void {\r\n const tagName = target.tagName.toLowerCase();\r\n const allowedGlobal = ALLOWED_ATTRIBUTES['*'] || new Set();\r\n const allowedForTag = ALLOWED_ATTRIBUTES[tagName] || new Set();\r\n const allowed = new Set([...allowedGlobal, ...allowedForTag]);\r\n\r\n Array.from(source.attributes).forEach(attr => {\r\n const name = attr.name.toLowerCase();\r\n if (allowed.has(name) && !DANGEROUS_ATTRIBUTES.has(name)) {\r\n target.setAttribute(attr.name, attr.value);\r\n }\r\n });\r\n}\r\n\r\n/**\r\n * Sanitize pasted content from DataTransfer\r\n */\r\nexport function sanitizePaste(\r\n dataTransfer: DataTransfer,\r\n options: SanitizeOptions = {}\r\n): string {\r\n // Try HTML first\r\n let html = dataTransfer.getData('text/html');\r\n \r\n if (html) {\r\n // Remove Word/Google Docs specific junk\r\n html = cleanOfficeContent(html);\r\n return sanitizeHtml(html, options);\r\n }\r\n\r\n // Fall back to plain text\r\n const text = dataTransfer.getData('text/plain');\r\n if (text) {\r\n return convertPlainTextToHtml(text);\r\n }\r\n\r\n return '';\r\n}\r\n\r\n/**\r\n * Clean Microsoft Word and Google Docs content\r\n */\r\nfunction cleanOfficeContent(html: string): string {\r\n // Remove Word-specific tags and namespaces\r\n html = html.replace(/<\\/?o:[^>]*>/gi, '');\r\n html = html.replace(/<\\/?w:[^>]*>/gi, '');\r\n html = html.replace(/<\\/?m:[^>]*>/gi, '');\r\n html = html.replace(/<\\/?st1:[^>]*>/gi, '');\r\n \r\n // Remove Office namespace declarations\r\n html = html.replace(/\\s*xmlns:[a-z]+=\"[^\"]*\"/gi, '');\r\n \r\n // Remove mso- styles\r\n html = html.replace(/mso-[^;:\"']+:[^;:\"']+;?/gi, '');\r\n \r\n // Remove class=\"Mso*\"\r\n html = html.replace(/class=\"?Mso[^\">\\s]*/gi, '');\r\n \r\n // Remove empty spans\r\n html = html.replace(/<span[^>]*>\\s*<\\/span>/gi, '');\r\n \r\n // Remove Google Docs specific IDs\r\n html = html.replace(/id=\"docs-internal-guid-[^\"]*\"/gi, '');\r\n \r\n // Clean up extra whitespace\r\n html = html.replace(/\\s{2,}/g, ' ');\r\n \r\n return html;\r\n}\r\n\r\n/**\r\n * Convert plain text to HTML paragraphs\r\n */\r\nexport function convertPlainTextToHtml(text: string): string {\r\n if (!text) return '';\r\n\r\n // Split by double newlines (paragraphs)\r\n const paragraphs = text.split(/\\n\\n+/);\r\n\r\n return paragraphs\r\n .map(p => {\r\n // Convert single newlines to <br>\r\n const content = p\r\n .trim()\r\n .replace(/\\n/g, '<br>')\r\n .replace(/\\t/g, '&nbsp;&nbsp;&nbsp;&nbsp;');\r\n \r\n return content ? `<p>${content}</p>` : '';\r\n })\r\n .filter(Boolean)\r\n .join('');\r\n}\r\n\r\n/**\r\n * Normalize HTML structure\r\n */\r\nexport function normalizeHtml(html: string): string {\r\n const container = document.createElement('div');\r\n container.innerHTML = html;\r\n\r\n // Ensure all text content is wrapped in blocks\r\n const fragment = document.createDocumentFragment();\r\n let currentParagraph: HTMLParagraphElement | null = null;\r\n\r\n container.childNodes.forEach(node => {\r\n if (node.nodeType === Node.TEXT_NODE) {\r\n const text = node.textContent?.trim();\r\n if (text) {\r\n if (!currentParagraph) {\r\n currentParagraph = document.createElement('p');\r\n }\r\n currentParagraph.appendChild(document.createTextNode(text));\r\n }\r\n } else if (node.nodeType === Node.ELEMENT_NODE) {\r\n const element = node as HTMLElement;\r\n const isBlock = isBlockElement(element.tagName);\r\n \r\n if (isBlock) {\r\n if (currentParagraph) {\r\n fragment.appendChild(currentParagraph);\r\n currentParagraph = null;\r\n }\r\n fragment.appendChild(node.cloneNode(true));\r\n } else {\r\n if (!currentParagraph) {\r\n currentParagraph = document.createElement('p');\r\n }\r\n currentParagraph.appendChild(node.cloneNode(true));\r\n }\r\n }\r\n });\r\n\r\n if (currentParagraph) {\r\n fragment.appendChild(currentParagraph);\r\n }\r\n\r\n const result = document.createElement('div');\r\n result.appendChild(fragment);\r\n return result.innerHTML;\r\n}\r\n\r\n/**\r\n * Check if tag is a block-level element\r\n */\r\nfunction isBlockElement(tagName: string): boolean {\r\n const blockTags = new Set([\r\n 'P', 'H1', 'H2', 'H3', 'H4', 'H5', 'H6',\r\n 'UL', 'OL', 'LI', 'BLOCKQUOTE', 'PRE',\r\n 'TABLE', 'HR', 'DIV', 'FIGURE', 'DETAILS',\r\n ]);\r\n return blockTags.has(tagName.toUpperCase());\r\n}\r\n","/**\r\n * Drag & Drop - Block reordering functionality\r\n */\r\n\r\nimport { getBlockFromChild } from '../utils/helpers';\r\n\r\nexport interface DragState {\r\n isDragging: boolean;\r\n draggedElement: HTMLElement | null;\r\n placeholder: HTMLElement | null;\r\n startY: number;\r\n currentY: number;\r\n scrollInterval: number | null;\r\n}\r\n\r\nexport interface DragDropOptions {\r\n container: HTMLElement;\r\n handleSelector?: string;\r\n onDragStart?: (element: HTMLElement) => void;\r\n onDragMove?: (element: HTMLElement, targetElement: HTMLElement | null, position: 'before' | 'after') => void;\r\n onDragEnd?: (element: HTMLElement, newIndex: number) => void;\r\n onDragCancel?: () => void;\r\n}\r\n\r\nconst SCROLL_THRESHOLD = 50;\r\nconst SCROLL_SPEED = 10;\r\n\r\n/**\r\n * Initialize drag and drop for blocks\r\n */\r\nexport function initDragDrop(options: DragDropOptions) {\r\n const { container, handleSelector = '[data-drag-handle]' } = options;\r\n \r\n let state: DragState = {\r\n isDragging: false,\r\n draggedElement: null,\r\n placeholder: null,\r\n startY: 0,\r\n currentY: 0,\r\n scrollInterval: null,\r\n };\r\n\r\n // Create placeholder element\r\n function createPlaceholder(): HTMLElement {\r\n const placeholder = document.createElement('div');\r\n placeholder.className = 'cb-drag-placeholder';\r\n placeholder.style.cssText = `\r\n height: 4px;\r\n background: var(--cb-primary, #3b82f6);\r\n border-radius: 2px;\r\n margin: 4px 0;\r\n transition: opacity 0.2s;\r\n `;\r\n return placeholder;\r\n }\r\n\r\n // Get all blocks\r\n function getBlocks(): HTMLElement[] {\r\n return Array.from(container.querySelectorAll('[data-block-id]')) as HTMLElement[];\r\n }\r\n\r\n // Find drop target\r\n function findDropTarget(y: number): { element: HTMLElement | null; position: 'before' | 'after' } {\r\n const blocks = getBlocks().filter(b => b !== state.draggedElement);\r\n \r\n for (const block of blocks) {\r\n const rect = block.getBoundingClientRect();\r\n const midY = rect.top + rect.height / 2;\r\n \r\n if (y < midY) {\r\n return { element: block, position: 'before' };\r\n }\r\n }\r\n\r\n const lastBlock = blocks[blocks.length - 1];\r\n return { element: lastBlock || null, position: 'after' };\r\n }\r\n\r\n // Update placeholder position\r\n function updatePlaceholder(target: HTMLElement | null, position: 'before' | 'after') {\r\n if (!state.placeholder || !target) return;\r\n\r\n if (position === 'before') {\r\n target.parentNode?.insertBefore(state.placeholder, target);\r\n } else {\r\n target.parentNode?.insertBefore(state.placeholder, target.nextSibling);\r\n }\r\n }\r\n\r\n // Auto scroll when near edges\r\n function handleAutoScroll(clientY: number) {\r\n const containerRect = container.getBoundingClientRect();\r\n \r\n if (state.scrollInterval) {\r\n clearInterval(state.scrollInterval);\r\n state.scrollInterval = null;\r\n }\r\n\r\n if (clientY < containerRect.top + SCROLL_THRESHOLD) {\r\n // Scroll up\r\n state.scrollInterval = window.setInterval(() => {\r\n container.scrollTop -= SCROLL_SPEED;\r\n }, 16);\r\n } else if (clientY > containerRect.bottom - SCROLL_THRESHOLD) {\r\n // Scroll down\r\n state.scrollInterval = window.setInterval(() => {\r\n container.scrollTop += SCROLL_SPEED;\r\n }, 16);\r\n }\r\n }\r\n\r\n // Handle drag start\r\n function handleDragStart(e: MouseEvent | TouchEvent) {\r\n const target = e.target as HTMLElement;\r\n const handle = target.closest(handleSelector);\r\n \r\n if (!handle) return;\r\n\r\n const block = getBlockFromChild(handle);\r\n if (!block) return;\r\n\r\n e.preventDefault();\r\n \r\n const clientY = 'touches' in e ? e.touches[0].clientY : e.clientY;\r\n\r\n state = {\r\n ...state,\r\n isDragging: true,\r\n draggedElement: block,\r\n placeholder: createPlaceholder(),\r\n startY: clientY,\r\n currentY: clientY,\r\n };\r\n\r\n // Style dragged element\r\n block.style.opacity = '0.5';\r\n block.style.pointerEvents = 'none';\r\n \r\n // Add placeholder\r\n block.parentNode?.insertBefore(state.placeholder!, block.nextSibling);\r\n \r\n // Add document listeners\r\n document.addEventListener('mousemove', handleDragMove);\r\n document.addEventListener('mouseup', handleDragEnd);\r\n document.addEventListener('touchmove', handleDragMove, { passive: false });\r\n document.addEventListener('touchend', handleDragEnd);\r\n\r\n options.onDragStart?.(block);\r\n }\r\n\r\n // Handle drag move\r\n function handleDragMove(e: MouseEvent | TouchEvent) {\r\n if (!state.isDragging || !state.draggedElement) return;\r\n\r\n e.preventDefault();\r\n \r\n const clientY = 'touches' in e ? e.touches[0].clientY : e.clientY;\r\n state.currentY = clientY;\r\n\r\n // Auto scroll\r\n handleAutoScroll(clientY);\r\n\r\n // Find and update drop target\r\n const { element, position } = findDropTarget(clientY);\r\n updatePlaceholder(element, position);\r\n\r\n options.onDragMove?.(state.draggedElement, element, position);\r\n }\r\n\r\n // Handle drag end\r\n function handleDragEnd(e: MouseEvent | TouchEvent) {\r\n if (!state.isDragging || !state.draggedElement) {\r\n cleanup();\r\n return;\r\n }\r\n\r\n const { element, position } = findDropTarget(state.currentY);\r\n\r\n // Move element to new position\r\n if (element && state.placeholder?.parentNode) {\r\n state.placeholder.parentNode.insertBefore(\r\n state.draggedElement,\r\n state.placeholder\r\n );\r\n }\r\n\r\n // Calculate new index\r\n const blocks = getBlocks();\r\n const newIndex = blocks.indexOf(state.draggedElement);\r\n\r\n // Reset styles\r\n state.draggedElement.style.opacity = '';\r\n state.draggedElement.style.pointerEvents = '';\r\n\r\n options.onDragEnd?.(state.draggedElement, newIndex);\r\n\r\n cleanup();\r\n }\r\n\r\n // Cleanup\r\n function cleanup() {\r\n // Remove placeholder\r\n state.placeholder?.remove();\r\n \r\n // Clear scroll interval\r\n if (state.scrollInterval) {\r\n clearInterval(state.scrollInterval);\r\n }\r\n\r\n // Remove listeners\r\n document.removeEventListener('mousemove', handleDragMove);\r\n document.removeEventListener('mouseup', handleDragEnd);\r\n document.removeEventListener('touchmove', handleDragMove);\r\n document.removeEventListener('touchend', handleDragEnd);\r\n\r\n // Reset state\r\n state = {\r\n isDragging: false,\r\n draggedElement: null,\r\n placeholder: null,\r\n startY: 0,\r\n currentY: 0,\r\n scrollInterval: null,\r\n };\r\n }\r\n\r\n // Add container listeners\r\n container.addEventListener('mousedown', handleDragStart);\r\n container.addEventListener('touchstart', handleDragStart, { passive: false });\r\n\r\n // Return cleanup function\r\n return () => {\r\n container.removeEventListener('mousedown', handleDragStart);\r\n container.removeEventListener('touchstart', handleDragStart);\r\n cleanup();\r\n };\r\n}\r\n\r\n/**\r\n * Create a drag handle element\r\n */\r\nexport function createDragHandle(): HTMLElement {\r\n const handle = document.createElement('button');\r\n handle.type = 'button';\r\n handle.className = 'cb-drag-handle';\r\n handle.setAttribute('data-drag-handle', 'true');\r\n handle.setAttribute('tabindex', '-1');\r\n handle.setAttribute('aria-label', 'Drag to reorder');\r\n handle.innerHTML = `\r\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"currentColor\">\r\n <circle cx=\"5\" cy=\"3\" r=\"1.5\"/>\r\n <circle cx=\"11\" cy=\"3\" r=\"1.5\"/>\r\n <circle cx=\"5\" cy=\"8\" r=\"1.5\"/>\r\n <circle cx=\"11\" cy=\"8\" r=\"1.5\"/>\r\n <circle cx=\"5\" cy=\"13\" r=\"1.5\"/>\r\n <circle cx=\"11\" cy=\"13\" r=\"1.5\"/>\r\n </svg>\r\n `;\r\n return handle;\r\n}\r\n\r\n/**\r\n * Check if drag and drop is supported\r\n */\r\nexport function isDragDropSupported(): boolean {\r\n return 'draggable' in document.createElement('div');\r\n}\r\n","/**\r\n * Selection Utilities - DOM-based selection handling\r\n */\r\n\r\nimport { getBlockFromChild } from '../utils/helpers';\r\n\r\nexport interface SelectionState {\r\n range: Range | null;\r\n anchorNode: Node | null;\r\n focusNode: Node | null;\r\n anchorOffset: number;\r\n focusOffset: number;\r\n isCollapsed: boolean;\r\n block: HTMLElement | null;\r\n}\r\n\r\n/**\r\n * Get current selection state\r\n */\r\nexport function getSelectionState(): SelectionState {\r\n const selection = window.getSelection();\r\n \r\n if (!selection || selection.rangeCount === 0) {\r\n return {\r\n range: null,\r\n anchorNode: null,\r\n focusNode: null,\r\n anchorOffset: 0,\r\n focusOffset: 0,\r\n isCollapsed: true,\r\n block: null,\r\n };\r\n }\r\n\r\n const range = selection.getRangeAt(0);\r\n const block = getBlockFromChild(range.commonAncestorContainer);\r\n\r\n return {\r\n range: range.cloneRange(),\r\n anchorNode: selection.anchorNode,\r\n focusNode: selection.focusNode,\r\n anchorOffset: selection.anchorOffset,\r\n focusOffset: selection.focusOffset,\r\n isCollapsed: selection.isCollapsed,\r\n block,\r\n };\r\n}\r\n\r\n/**\r\n * Save selection state\r\n */\r\nexport function saveSelection(): SelectionState {\r\n return getSelectionState();\r\n}\r\n\r\n/**\r\n * Restore selection from state\r\n */\r\nexport function restoreSelection(state: SelectionState): boolean {\r\n if (!state.range) return false;\r\n\r\n try {\r\n const selection = window.getSelection();\r\n if (selection) {\r\n selection.removeAllRanges();\r\n selection.addRange(state.range);\r\n return true;\r\n }\r\n } catch {\r\n // Range might be invalid\r\n }\r\n return false;\r\n}\r\n\r\n/**\r\n * Get selected text\r\n */\r\nexport function getSelectedText(): string {\r\n const selection = window.getSelection();\r\n return selection?.toString() || '';\r\n}\r\n\r\n/**\r\n * Get selected HTML\r\n */\r\nexport function getSelectedHtml(): string {\r\n const selection = window.getSelection();\r\n if (!selection || selection.rangeCount === 0) return '';\r\n\r\n const range = selection.getRangeAt(0);\r\n const container = document.createElement('div');\r\n container.appendChild(range.cloneContents());\r\n return container.innerHTML;\r\n}\r\n\r\n/**\r\n * Check if selection is within element\r\n */\r\nexport function isSelectionInElement(element: HTMLElement): boolean {\r\n const selection = window.getSelection();\r\n if (!selection || selection.rangeCount === 0) return false;\r\n\r\n const range = selection.getRangeAt(0);\r\n return element.contains(range.commonAncestorContainer);\r\n}\r\n\r\n/**\r\n * Check if selection spans multiple blocks\r\n */\r\nexport function isMultiBlockSelection(container: HTMLElement): boolean {\r\n const selection = window.getSelection();\r\n if (!selection || selection.rangeCount === 0 || selection.isCollapsed) {\r\n return false;\r\n }\r\n\r\n const range = selection.getRangeAt(0);\r\n const startBlock = getBlockFromChild(range.startContainer);\r\n const endBlock = getBlockFromChild(range.endContainer);\r\n\r\n return startBlock !== endBlock;\r\n}\r\n\r\n/**\r\n * Select all content in element\r\n */\r\nexport function selectAllInElement(element: HTMLElement): void {\r\n const range = document.createRange();\r\n range.selectNodeContents(element);\r\n\r\n const selection = window.getSelection();\r\n if (selection) {\r\n selection.removeAllRanges();\r\n selection.addRange(range);\r\n }\r\n}\r\n\r\n/**\r\n * Collapse selection to start\r\n */\r\nexport function collapseToStart(): void {\r\n const selection = window.getSelection();\r\n if (selection && !selection.isCollapsed) {\r\n selection.collapseToStart();\r\n }\r\n}\r\n\r\n/**\r\n * Collapse selection to end\r\n */\r\nexport function collapseToEnd(): void {\r\n const selection = window.getSelection();\r\n if (selection && !selection.isCollapsed) {\r\n selection.collapseToEnd();\r\n }\r\n}\r\n\r\n/**\r\n * Set cursor position at offset in element\r\n */\r\nexport function setCursorPosition(\r\n element: HTMLElement,\r\n offset: number\r\n): boolean {\r\n const walker = document.createTreeWalker(\r\n element,\r\n NodeFilter.SHOW_TEXT,\r\n null\r\n );\r\n\r\n let currentOffset = 0;\r\n let node: Node | null;\r\n\r\n while ((node = walker.nextNode())) {\r\n const nodeLength = node.textContent?.length || 0;\r\n \r\n if (currentOffset + nodeLength >= offset) {\r\n const range = document.createRange();\r\n range.setStart(node, offset - currentOffset);\r\n range.collapse(true);\r\n\r\n const selection = window.getSelection();\r\n if (selection) {\r\n selection.removeAllRanges();\r\n selection.addRange(range);\r\n return true;\r\n }\r\n }\r\n currentOffset += nodeLength;\r\n }\r\n\r\n return false;\r\n}\r\n\r\n/**\r\n * Get cursor offset in element\r\n */\r\nexport function getCursorOffset(element: HTMLElement): number {\r\n const selection = window.getSelection();\r\n if (!selection || selection.rangeCount === 0) return 0;\r\n\r\n const range = selection.getRangeAt(0);\r\n const preCaretRange = range.cloneRange();\r\n preCaretRange.selectNodeContents(element);\r\n preCaretRange.setEnd(range.startContainer, range.startOffset);\r\n\r\n return preCaretRange.toString().length;\r\n}\r\n\r\n/**\r\n * Check if cursor is at start of element\r\n */\r\nexport function isCursorAtStart(element: HTMLElement): boolean {\r\n const selection = window.getSelection();\r\n if (!selection || selection.rangeCount === 0) return false;\r\n\r\n const range = selection.getRangeAt(0);\r\n if (!range.collapsed) return false;\r\n\r\n // Check if at very start\r\n const preCaretRange = range.cloneRange();\r\n preCaretRange.selectNodeContents(element);\r\n preCaretRange.setEnd(range.startContainer, range.startOffset);\r\n\r\n return preCaretRange.toString().length === 0;\r\n}\r\n\r\n/**\r\n * Check if cursor is at end of element\r\n */\r\nexport function isCursorAtEnd(element: HTMLElement): boolean {\r\n const selection = window.getSelection();\r\n if (!selection || selection.rangeCount === 0) return false;\r\n\r\n const range = selection.getRangeAt(0);\r\n if (!range.collapsed) return false;\r\n\r\n // Check if at very end\r\n const postCaretRange = range.cloneRange();\r\n postCaretRange.selectNodeContents(element);\r\n postCaretRange.setStart(range.endContainer, range.endOffset);\r\n\r\n return postCaretRange.toString().length === 0;\r\n}\r\n\r\n/**\r\n * Move cursor to start of element\r\n */\r\nexport function moveCursorToStart(element: HTMLElement): void {\r\n const range = document.createRange();\r\n const selection = window.getSelection();\r\n\r\n // Find first text node or use element itself\r\n const walker = document.createTreeWalker(\r\n element,\r\n NodeFilter.SHOW_TEXT,\r\n null\r\n );\r\n const firstTextNode = walker.nextNode();\r\n\r\n if (firstTextNode) {\r\n range.setStart(firstTextNode, 0);\r\n } else {\r\n range.setStart(element, 0);\r\n }\r\n range.collapse(true);\r\n\r\n if (selection) {\r\n selection.removeAllRanges();\r\n selection.addRange(range);\r\n }\r\n}\r\n\r\n/**\r\n * Move cursor to end of element\r\n */\r\nexport function moveCursorToEnd(element: HTMLElement): void {\r\n const range = document.createRange();\r\n const selection = window.getSelection();\r\n\r\n range.selectNodeContents(element);\r\n range.collapse(false);\r\n\r\n if (selection) {\r\n selection.removeAllRanges();\r\n selection.addRange(range);\r\n }\r\n}\r\n\r\n/**\r\n * Wrap selection with element\r\n */\r\nexport function wrapSelection(tagName: string, attributes?: Record<string, string>): HTMLElement | null {\r\n const selection = window.getSelection();\r\n if (!selection || selection.rangeCount === 0 || selection.isCollapsed) {\r\n return null;\r\n }\r\n\r\n const range = selection.getRangeAt(0);\r\n const wrapper = document.createElement(tagName);\r\n\r\n if (attributes) {\r\n for (const [key, value] of Object.entries(attributes)) {\r\n wrapper.setAttribute(key, value);\r\n }\r\n }\r\n\r\n try {\r\n range.surroundContents(wrapper);\r\n return wrapper;\r\n } catch {\r\n // Cannot wrap - selection spans multiple elements\r\n // Extract contents and wrap them\r\n const contents = range.extractContents();\r\n wrapper.appendChild(contents);\r\n range.insertNode(wrapper);\r\n return wrapper;\r\n }\r\n}\r\n\r\n/**\r\n * Unwrap element (replace with its contents)\r\n */\r\nexport function unwrapElement(element: HTMLElement): void {\r\n const parent = element.parentNode;\r\n if (!parent) return;\r\n\r\n while (element.firstChild) {\r\n parent.insertBefore(element.firstChild, element);\r\n }\r\n parent.removeChild(element);\r\n}\r\n\r\n/**\r\n * Find all elements of type within selection\r\n */\r\nexport function findElementsInSelection(\r\n tagName: string,\r\n container: HTMLElement\r\n): HTMLElement[] {\r\n const selection = window.getSelection();\r\n if (!selection || selection.rangeCount === 0) return [];\r\n\r\n const range = selection.getRangeAt(0);\r\n const elements: HTMLElement[] = [];\r\n\r\n const walker = document.createTreeWalker(\r\n container,\r\n NodeFilter.SHOW_ELEMENT,\r\n {\r\n acceptNode: (node) => {\r\n if (node instanceof HTMLElement && node.tagName.toLowerCase() === tagName.toLowerCase()) {\r\n return NodeFilter.FILTER_ACCEPT;\r\n }\r\n return NodeFilter.FILTER_SKIP;\r\n },\r\n }\r\n );\r\n\r\n let node: Node | null;\r\n while ((node = walker.nextNode())) {\r\n if (node instanceof HTMLElement && range.intersectsNode(node)) {\r\n elements.push(node);\r\n }\r\n }\r\n\r\n return elements;\r\n}\r\n","/**\n * @license lucide-react v0.294.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nvar defaultAttributes = {\n xmlns: \"http://www.w3.org/2000/svg\",\n width: 24,\n height: 24,\n viewBox: \"0 0 24 24\",\n fill: \"none\",\n stroke: \"currentColor\",\n strokeWidth: 2,\n strokeLinecap: \"round\",\n strokeLinejoin: \"round\"\n};\n\nexport { defaultAttributes as default };\n//# sourceMappingURL=defaultAttributes.js.map\n","/**\n * @license lucide-react v0.294.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport { forwardRef, createElement } from 'react';\nimport defaultAttributes from './defaultAttributes.js';\n\nconst toKebabCase = (string) => string.replace(/([a-z0-9])([A-Z])/g, \"$1-$2\").toLowerCase().trim();\nconst createLucideIcon = (iconName, iconNode) => {\n const Component = forwardRef(\n ({ color = \"currentColor\", size = 24, strokeWidth = 2, absoluteStrokeWidth, className = \"\", children, ...rest }, ref) => createElement(\n \"svg\",\n {\n ref,\n ...defaultAttributes,\n width: size,\n height: size,\n stroke: color,\n strokeWidth: absoluteStrokeWidth ? Number(strokeWidth) * 24 / Number(size) : strokeWidth,\n className: [\"lucide\", `lucide-${toKebabCase(iconName)}`, className].join(\" \"),\n ...rest\n },\n [\n ...iconNode.map(([tag, attrs]) => createElement(tag, attrs)),\n ...Array.isArray(children) ? children : [children]\n ]\n )\n );\n Component.displayName = `${iconName}`;\n return Component;\n};\n\nexport { createLucideIcon as default, toKebabCase };\n//# sourceMappingURL=createLucideIcon.js.map\n","/**\n * @license lucide-react v0.294.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst AlertCircle = createLucideIcon(\"AlertCircle\", [\n [\"circle\", { cx: \"12\", cy: \"12\", r: \"10\", key: \"1mglay\" }],\n [\"line\", { x1: \"12\", x2: \"12\", y1: \"8\", y2: \"12\", key: \"1pkeuh\" }],\n [\"line\", { x1: \"12\", x2: \"12.01\", y1: \"16\", y2: \"16\", key: \"4dfq90\" }]\n]);\n\nexport { AlertCircle as default };\n//# sourceMappingURL=alert-circle.js.map\n","/**\n * @license lucide-react v0.294.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst AlertTriangle = createLucideIcon(\"AlertTriangle\", [\n [\n \"path\",\n {\n d: \"m21.73 18-8-14a2 2 0 0 0-3.48 0l-8 14A2 2 0 0 0 4 21h16a2 2 0 0 0 1.73-3Z\",\n key: \"c3ski4\"\n }\n ],\n [\"path\", { d: \"M12 9v4\", key: \"juzpu7\" }],\n [\"path\", { d: \"M12 17h.01\", key: \"p32p05\" }]\n]);\n\nexport { AlertTriangle as default };\n//# sourceMappingURL=alert-triangle.js.map\n","/**\n * @license lucide-react v0.294.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst AlignCenter = createLucideIcon(\"AlignCenter\", [\n [\"line\", { x1: \"21\", x2: \"3\", y1: \"6\", y2: \"6\", key: \"1fp77t\" }],\n [\"line\", { x1: \"17\", x2: \"7\", y1: \"12\", y2: \"12\", key: \"rsh8ii\" }],\n [\"line\", { x1: \"19\", x2: \"5\", y1: \"18\", y2: \"18\", key: \"1t0tuv\" }]\n]);\n\nexport { AlignCenter as default };\n//# sourceMappingURL=align-center.js.map\n","/**\n * @license lucide-react v0.294.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst AlignJustify = createLucideIcon(\"AlignJustify\", [\n [\"line\", { x1: \"3\", x2: \"21\", y1: \"6\", y2: \"6\", key: \"4m8b97\" }],\n [\"line\", { x1: \"3\", x2: \"21\", y1: \"12\", y2: \"12\", key: \"10d38w\" }],\n [\"line\", { x1: \"3\", x2: \"21\", y1: \"18\", y2: \"18\", key: \"kwyyxn\" }]\n]);\n\nexport { AlignJustify as default };\n//# sourceMappingURL=align-justify.js.map\n","/**\n * @license lucide-react v0.294.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst AlignLeft = createLucideIcon(\"AlignLeft\", [\n [\"line\", { x1: \"21\", x2: \"3\", y1: \"6\", y2: \"6\", key: \"1fp77t\" }],\n [\"line\", { x1: \"15\", x2: \"3\", y1: \"12\", y2: \"12\", key: \"v6grx8\" }],\n [\"line\", { x1: \"17\", x2: \"3\", y1: \"18\", y2: \"18\", key: \"1awlsn\" }]\n]);\n\nexport { AlignLeft as default };\n//# sourceMappingURL=align-left.js.map\n","/**\n * @license lucide-react v0.294.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst AlignRight = createLucideIcon(\"AlignRight\", [\n [\"line\", { x1: \"21\", x2: \"3\", y1: \"6\", y2: \"6\", key: \"1fp77t\" }],\n [\"line\", { x1: \"21\", x2: \"9\", y1: \"12\", y2: \"12\", key: \"1uyos4\" }],\n [\"line\", { x1: \"21\", x2: \"7\", y1: \"18\", y2: \"18\", key: \"1g9eri\" }]\n]);\n\nexport { AlignRight as default };\n//# sourceMappingURL=align-right.js.map\n","/**\n * @license lucide-react v0.294.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst Bold = createLucideIcon(\"Bold\", [\n [\"path\", { d: \"M14 12a4 4 0 0 0 0-8H6v8\", key: \"v2sylx\" }],\n [\"path\", { d: \"M15 20a4 4 0 0 0 0-8H6v8Z\", key: \"1ef5ya\" }]\n]);\n\nexport { Bold as default };\n//# sourceMappingURL=bold.js.map\n","/**\n * @license lucide-react v0.294.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst CheckCircle = createLucideIcon(\"CheckCircle\", [\n [\"path\", { d: \"M22 11.08V12a10 10 0 1 1-5.93-9.14\", key: \"g774vq\" }],\n [\"path\", { d: \"m9 11 3 3L22 4\", key: \"1pflzl\" }]\n]);\n\nexport { CheckCircle as default };\n//# sourceMappingURL=check-circle.js.map\n","/**\n * @license lucide-react v0.294.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst CheckSquare = createLucideIcon(\"CheckSquare\", [\n [\"path\", { d: \"m9 11 3 3L22 4\", key: \"1pflzl\" }],\n [\"path\", { d: \"M21 12v7a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h11\", key: \"1jnkn4\" }]\n]);\n\nexport { CheckSquare as default };\n//# sourceMappingURL=check-square.js.map\n","/**\n * @license lucide-react v0.294.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst Check = createLucideIcon(\"Check\", [[\"path\", { d: \"M20 6 9 17l-5-5\", key: \"1gmf2c\" }]]);\n\nexport { Check as default };\n//# sourceMappingURL=check.js.map\n","/**\n * @license lucide-react v0.294.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst ChevronDown = createLucideIcon(\"ChevronDown\", [\n [\"path\", { d: \"m6 9 6 6 6-6\", key: \"qrunsl\" }]\n]);\n\nexport { ChevronDown as default };\n//# sourceMappingURL=chevron-down.js.map\n","/**\n * @license lucide-react v0.294.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst ChevronUp = createLucideIcon(\"ChevronUp\", [[\"path\", { d: \"m18 15-6-6-6 6\", key: \"153udz\" }]]);\n\nexport { ChevronUp as default };\n//# sourceMappingURL=chevron-up.js.map\n","/**\n * @license lucide-react v0.294.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst ClipboardPaste = createLucideIcon(\"ClipboardPaste\", [\n [\n \"path\",\n { d: \"M15 2H9a1 1 0 0 0-1 1v2c0 .6.4 1 1 1h6c.6 0 1-.4 1-1V3c0-.6-.4-1-1-1Z\", key: \"1pp7kr\" }\n ],\n [\n \"path\",\n {\n d: \"M8 4H6a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2M16 4h2a2 2 0 0 1 2 2v2M11 14h10\",\n key: \"2ik1ml\"\n }\n ],\n [\"path\", { d: \"m17 10 4 4-4 4\", key: \"vp2hj1\" }]\n]);\n\nexport { ClipboardPaste as default };\n//# sourceMappingURL=clipboard-paste.js.map\n","/**\n * @license lucide-react v0.294.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst Code = createLucideIcon(\"Code\", [\n [\"polyline\", { points: \"16 18 22 12 16 6\", key: \"z7tu5w\" }],\n [\"polyline\", { points: \"8 6 2 12 8 18\", key: \"1eg1df\" }]\n]);\n\nexport { Code as default };\n//# sourceMappingURL=code.js.map\n","/**\n * @license lucide-react v0.294.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst Columns = createLucideIcon(\"Columns\", [\n [\"rect\", { width: \"18\", height: \"18\", x: \"3\", y: \"3\", rx: \"2\", ry: \"2\", key: \"1m3agn\" }],\n [\"line\", { x1: \"12\", x2: \"12\", y1: \"3\", y2: \"21\", key: \"1efggb\" }]\n]);\n\nexport { Columns as default };\n//# sourceMappingURL=columns.js.map\n","/**\n * @license lucide-react v0.294.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst Copy = createLucideIcon(\"Copy\", [\n [\"rect\", { width: \"14\", height: \"14\", x: \"8\", y: \"8\", rx: \"2\", ry: \"2\", key: \"17jyea\" }],\n [\"path\", { d: \"M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2\", key: \"zix9uf\" }]\n]);\n\nexport { Copy as default };\n//# sourceMappingURL=copy.js.map\n","/**\n * @license lucide-react v0.294.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst Download = createLucideIcon(\"Download\", [\n [\"path\", { d: \"M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4\", key: \"ih7n3h\" }],\n [\"polyline\", { points: \"7 10 12 15 17 10\", key: \"2ggqvy\" }],\n [\"line\", { x1: \"12\", x2: \"12\", y1: \"15\", y2: \"3\", key: \"1vk2je\" }]\n]);\n\nexport { Download as default };\n//# sourceMappingURL=download.js.map\n","/**\n * @license lucide-react v0.294.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst Eraser = createLucideIcon(\"Eraser\", [\n [\n \"path\",\n {\n d: \"m7 21-4.3-4.3c-1-1-1-2.5 0-3.4l9.6-9.6c1-1 2.5-1 3.4 0l5.6 5.6c1 1 1 2.5 0 3.4L13 21\",\n key: \"182aya\"\n }\n ],\n [\"path\", { d: \"M22 21H7\", key: \"t4ddhn\" }],\n [\"path\", { d: \"m5 11 9 9\", key: \"1mo9qw\" }]\n]);\n\nexport { Eraser as default };\n//# sourceMappingURL=eraser.js.map\n","/**\n * @license lucide-react v0.294.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst ExternalLink = createLucideIcon(\"ExternalLink\", [\n [\"path\", { d: \"M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6\", key: \"a6xqqp\" }],\n [\"polyline\", { points: \"15 3 21 3 21 9\", key: \"mznyad\" }],\n [\"line\", { x1: \"10\", x2: \"21\", y1: \"14\", y2: \"3\", key: \"18c3s4\" }]\n]);\n\nexport { ExternalLink as default };\n//# sourceMappingURL=external-link.js.map\n","/**\n * @license lucide-react v0.294.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst FileCode = createLucideIcon(\"FileCode\", [\n [\n \"path\",\n { d: \"M14.5 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7.5L14.5 2z\", key: \"1nnpy2\" }\n ],\n [\"polyline\", { points: \"14 2 14 8 20 8\", key: \"1ew0cm\" }],\n [\"path\", { d: \"m10 13-2 2 2 2\", key: \"17smn8\" }],\n [\"path\", { d: \"m14 17 2-2-2-2\", key: \"14mezr\" }]\n]);\n\nexport { FileCode as default };\n//# sourceMappingURL=file-code.js.map\n","/**\n * @license lucide-react v0.294.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst FileText = createLucideIcon(\"FileText\", [\n [\n \"path\",\n { d: \"M14.5 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7.5L14.5 2z\", key: \"1nnpy2\" }\n ],\n [\"polyline\", { points: \"14 2 14 8 20 8\", key: \"1ew0cm\" }],\n [\"line\", { x1: \"16\", x2: \"8\", y1: \"13\", y2: \"13\", key: \"14keom\" }],\n [\"line\", { x1: \"16\", x2: \"8\", y1: \"17\", y2: \"17\", key: \"17nazh\" }],\n [\"line\", { x1: \"10\", x2: \"8\", y1: \"9\", y2: \"9\", key: \"1a5vjj\" }]\n]);\n\nexport { FileText as default };\n//# sourceMappingURL=file-text.js.map\n","/**\n * @license lucide-react v0.294.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst File = createLucideIcon(\"File\", [\n [\n \"path\",\n { d: \"M14.5 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7.5L14.5 2z\", key: \"1nnpy2\" }\n ],\n [\"polyline\", { points: \"14 2 14 8 20 8\", key: \"1ew0cm\" }]\n]);\n\nexport { File as default };\n//# sourceMappingURL=file.js.map\n","/**\n * @license lucide-react v0.294.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst GripVertical = createLucideIcon(\"GripVertical\", [\n [\"circle\", { cx: \"9\", cy: \"12\", r: \"1\", key: \"1vctgf\" }],\n [\"circle\", { cx: \"9\", cy: \"5\", r: \"1\", key: \"hp0tcf\" }],\n [\"circle\", { cx: \"9\", cy: \"19\", r: \"1\", key: \"fkjjf6\" }],\n [\"circle\", { cx: \"15\", cy: \"12\", r: \"1\", key: \"1tmaij\" }],\n [\"circle\", { cx: \"15\", cy: \"5\", r: \"1\", key: \"19l28e\" }],\n [\"circle\", { cx: \"15\", cy: \"19\", r: \"1\", key: \"f4zoj3\" }]\n]);\n\nexport { GripVertical as default };\n//# sourceMappingURL=grip-vertical.js.map\n","/**\n * @license lucide-react v0.294.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst Heading1 = createLucideIcon(\"Heading1\", [\n [\"path\", { d: \"M4 12h8\", key: \"17cfdx\" }],\n [\"path\", { d: \"M4 18V6\", key: \"1rz3zl\" }],\n [\"path\", { d: \"M12 18V6\", key: \"zqpxq5\" }],\n [\"path\", { d: \"m17 12 3-2v8\", key: \"1hhhft\" }]\n]);\n\nexport { Heading1 as default };\n//# sourceMappingURL=heading-1.js.map\n","/**\n * @license lucide-react v0.294.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst Heading2 = createLucideIcon(\"Heading2\", [\n [\"path\", { d: \"M4 12h8\", key: \"17cfdx\" }],\n [\"path\", { d: \"M4 18V6\", key: \"1rz3zl\" }],\n [\"path\", { d: \"M12 18V6\", key: \"zqpxq5\" }],\n [\"path\", { d: \"M21 18h-4c0-4 4-3 4-6 0-1.5-2-2.5-4-1\", key: \"9jr5yi\" }]\n]);\n\nexport { Heading2 as default };\n//# sourceMappingURL=heading-2.js.map\n","/**\n * @license lucide-react v0.294.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst Heading3 = createLucideIcon(\"Heading3\", [\n [\"path\", { d: \"M4 12h8\", key: \"17cfdx\" }],\n [\"path\", { d: \"M4 18V6\", key: \"1rz3zl\" }],\n [\"path\", { d: \"M12 18V6\", key: \"zqpxq5\" }],\n [\"path\", { d: \"M17.5 10.5c1.7-1 3.5 0 3.5 1.5a2 2 0 0 1-2 2\", key: \"68ncm8\" }],\n [\"path\", { d: \"M17 17.5c2 1.5 4 .3 4-1.5a2 2 0 0 0-2-2\", key: \"1ejuhz\" }]\n]);\n\nexport { Heading3 as default };\n//# sourceMappingURL=heading-3.js.map\n","/**\n * @license lucide-react v0.294.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst Heading4 = createLucideIcon(\"Heading4\", [\n [\"path\", { d: \"M4 12h8\", key: \"17cfdx\" }],\n [\"path\", { d: \"M4 18V6\", key: \"1rz3zl\" }],\n [\"path\", { d: \"M12 18V6\", key: \"zqpxq5\" }],\n [\"path\", { d: \"M17 10v4h4\", key: \"13sv97\" }],\n [\"path\", { d: \"M21 10v8\", key: \"1kdml4\" }]\n]);\n\nexport { Heading4 as default };\n//# sourceMappingURL=heading-4.js.map\n","/**\n * @license lucide-react v0.294.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst Heading5 = createLucideIcon(\"Heading5\", [\n [\"path\", { d: \"M4 12h8\", key: \"17cfdx\" }],\n [\"path\", { d: \"M4 18V6\", key: \"1rz3zl\" }],\n [\"path\", { d: \"M12 18V6\", key: \"zqpxq5\" }],\n [\"path\", { d: \"M17 13v-3h4\", key: \"1nvgqp\" }],\n [\n \"path\",\n { d: \"M17 17.7c.4.2.8.3 1.3.3 1.5 0 2.7-1.1 2.7-2.5S19.8 13 18.3 13H17\", key: \"2nebdn\" }\n ]\n]);\n\nexport { Heading5 as default };\n//# sourceMappingURL=heading-5.js.map\n","/**\n * @license lucide-react v0.294.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst Heading6 = createLucideIcon(\"Heading6\", [\n [\"path\", { d: \"M4 12h8\", key: \"17cfdx\" }],\n [\"path\", { d: \"M4 18V6\", key: \"1rz3zl\" }],\n [\"path\", { d: \"M12 18V6\", key: \"zqpxq5\" }],\n [\"circle\", { cx: \"19\", cy: \"16\", r: \"2\", key: \"15mx69\" }],\n [\"path\", { d: \"M20 10c-2 2-3 3.5-3 6\", key: \"f35dl0\" }]\n]);\n\nexport { Heading6 as default };\n//# sourceMappingURL=heading-6.js.map\n","/**\n * @license lucide-react v0.294.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst Highlighter = createLucideIcon(\"Highlighter\", [\n [\"path\", { d: \"m9 11-6 6v3h9l3-3\", key: \"1a3l36\" }],\n [\"path\", { d: \"m22 12-4.6 4.6a2 2 0 0 1-2.8 0l-5.2-5.2a2 2 0 0 1 0-2.8L14 4\", key: \"14a9rk\" }]\n]);\n\nexport { Highlighter as default };\n//# sourceMappingURL=highlighter.js.map\n","/**\n * @license lucide-react v0.294.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst Image = createLucideIcon(\"Image\", [\n [\"rect\", { width: \"18\", height: \"18\", x: \"3\", y: \"3\", rx: \"2\", ry: \"2\", key: \"1m3agn\" }],\n [\"circle\", { cx: \"9\", cy: \"9\", r: \"2\", key: \"af1f0g\" }],\n [\"path\", { d: \"m21 15-3.086-3.086a2 2 0 0 0-2.828 0L6 21\", key: \"1xmnt7\" }]\n]);\n\nexport { Image as default };\n//# sourceMappingURL=image.js.map\n","/**\n * @license lucide-react v0.294.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst Indent = createLucideIcon(\"Indent\", [\n [\"polyline\", { points: \"3 8 7 12 3 16\", key: \"f3rxhf\" }],\n [\"line\", { x1: \"21\", x2: \"11\", y1: \"12\", y2: \"12\", key: \"1fxxak\" }],\n [\"line\", { x1: \"21\", x2: \"11\", y1: \"6\", y2: \"6\", key: \"asgu94\" }],\n [\"line\", { x1: \"21\", x2: \"11\", y1: \"18\", y2: \"18\", key: \"13dsj7\" }]\n]);\n\nexport { Indent as default };\n//# sourceMappingURL=indent.js.map\n","/**\n * @license lucide-react v0.294.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst Info = createLucideIcon(\"Info\", [\n [\"circle\", { cx: \"12\", cy: \"12\", r: \"10\", key: \"1mglay\" }],\n [\"path\", { d: \"M12 16v-4\", key: \"1dtifu\" }],\n [\"path\", { d: \"M12 8h.01\", key: \"e9boi3\" }]\n]);\n\nexport { Info as default };\n//# sourceMappingURL=info.js.map\n","/**\n * @license lucide-react v0.294.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst Italic = createLucideIcon(\"Italic\", [\n [\"line\", { x1: \"19\", x2: \"10\", y1: \"4\", y2: \"4\", key: \"15jd3p\" }],\n [\"line\", { x1: \"14\", x2: \"5\", y1: \"20\", y2: \"20\", key: \"bu0au3\" }],\n [\"line\", { x1: \"15\", x2: \"9\", y1: \"4\", y2: \"20\", key: \"uljnxc\" }]\n]);\n\nexport { Italic as default };\n//# sourceMappingURL=italic.js.map\n","/**\n * @license lucide-react v0.294.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst Link2Off = createLucideIcon(\"Link2Off\", [\n [\"path\", { d: \"M9 17H7A5 5 0 0 1 7 7\", key: \"10o201\" }],\n [\"path\", { d: \"M15 7h2a5 5 0 0 1 4 8\", key: \"1d3206\" }],\n [\"line\", { x1: \"8\", x2: \"12\", y1: \"12\", y2: \"12\", key: \"rvw6j4\" }],\n [\"line\", { x1: \"2\", x2: \"22\", y1: \"2\", y2: \"22\", key: \"a6p6uj\" }]\n]);\n\nexport { Link2Off as default };\n//# sourceMappingURL=link-2-off.js.map\n","/**\n * @license lucide-react v0.294.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst Link = createLucideIcon(\"Link\", [\n [\"path\", { d: \"M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71\", key: \"1cjeqo\" }],\n [\"path\", { d: \"M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71\", key: \"19qd67\" }]\n]);\n\nexport { Link as default };\n//# sourceMappingURL=link.js.map\n","/**\n * @license lucide-react v0.294.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst ListOrdered = createLucideIcon(\"ListOrdered\", [\n [\"line\", { x1: \"10\", x2: \"21\", y1: \"6\", y2: \"6\", key: \"76qw6h\" }],\n [\"line\", { x1: \"10\", x2: \"21\", y1: \"12\", y2: \"12\", key: \"16nom4\" }],\n [\"line\", { x1: \"10\", x2: \"21\", y1: \"18\", y2: \"18\", key: \"u3jurt\" }],\n [\"path\", { d: \"M4 6h1v4\", key: \"cnovpq\" }],\n [\"path\", { d: \"M4 10h2\", key: \"16xx2s\" }],\n [\"path\", { d: \"M6 18H4c0-1 2-2 2-3s-1-1.5-2-1\", key: \"m9a95d\" }]\n]);\n\nexport { ListOrdered as default };\n//# sourceMappingURL=list-ordered.js.map\n","/**\n * @license lucide-react v0.294.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst List = createLucideIcon(\"List\", [\n [\"line\", { x1: \"8\", x2: \"21\", y1: \"6\", y2: \"6\", key: \"7ey8pc\" }],\n [\"line\", { x1: \"8\", x2: \"21\", y1: \"12\", y2: \"12\", key: \"rjfblc\" }],\n [\"line\", { x1: \"8\", x2: \"21\", y1: \"18\", y2: \"18\", key: \"c3b1m8\" }],\n [\"line\", { x1: \"3\", x2: \"3.01\", y1: \"6\", y2: \"6\", key: \"1g7gq3\" }],\n [\"line\", { x1: \"3\", x2: \"3.01\", y1: \"12\", y2: \"12\", key: \"1pjlvk\" }],\n [\"line\", { x1: \"3\", x2: \"3.01\", y1: \"18\", y2: \"18\", key: \"28t2mc\" }]\n]);\n\nexport { List as default };\n//# sourceMappingURL=list.js.map\n","/**\n * @license lucide-react v0.294.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst Maximize2 = createLucideIcon(\"Maximize2\", [\n [\"polyline\", { points: \"15 3 21 3 21 9\", key: \"mznyad\" }],\n [\"polyline\", { points: \"9 21 3 21 3 15\", key: \"1avn1i\" }],\n [\"line\", { x1: \"21\", x2: \"14\", y1: \"3\", y2: \"10\", key: \"ota7mn\" }],\n [\"line\", { x1: \"3\", x2: \"10\", y1: \"21\", y2: \"14\", key: \"1atl0r\" }]\n]);\n\nexport { Maximize2 as default };\n//# sourceMappingURL=maximize-2.js.map\n","/**\n * @license lucide-react v0.294.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst Minus = createLucideIcon(\"Minus\", [[\"path\", { d: \"M5 12h14\", key: \"1ays0h\" }]]);\n\nexport { Minus as default };\n//# sourceMappingURL=minus.js.map\n","/**\n * @license lucide-react v0.294.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst Moon = createLucideIcon(\"Moon\", [\n [\"path\", { d: \"M12 3a6 6 0 0 0 9 9 9 9 0 1 1-9-9Z\", key: \"a7tn18\" }]\n]);\n\nexport { Moon as default };\n//# sourceMappingURL=moon.js.map\n","/**\n * @license lucide-react v0.294.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst MoreHorizontal = createLucideIcon(\"MoreHorizontal\", [\n [\"circle\", { cx: \"12\", cy: \"12\", r: \"1\", key: \"41hilf\" }],\n [\"circle\", { cx: \"19\", cy: \"12\", r: \"1\", key: \"1wjl8i\" }],\n [\"circle\", { cx: \"5\", cy: \"12\", r: \"1\", key: \"1pcz8c\" }]\n]);\n\nexport { MoreHorizontal as default };\n//# sourceMappingURL=more-horizontal.js.map\n","/**\n * @license lucide-react v0.294.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst MoveDown = createLucideIcon(\"MoveDown\", [\n [\"path\", { d: \"M8 18L12 22L16 18\", key: \"cskvfv\" }],\n [\"path\", { d: \"M12 2V22\", key: \"r89rzk\" }]\n]);\n\nexport { MoveDown as default };\n//# sourceMappingURL=move-down.js.map\n","/**\n * @license lucide-react v0.294.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst MoveUp = createLucideIcon(\"MoveUp\", [\n [\"path\", { d: \"M8 6L12 2L16 6\", key: \"1yvkyx\" }],\n [\"path\", { d: \"M12 2V22\", key: \"r89rzk\" }]\n]);\n\nexport { MoveUp as default };\n//# sourceMappingURL=move-up.js.map\n","/**\n * @license lucide-react v0.294.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst Outdent = createLucideIcon(\"Outdent\", [\n [\"polyline\", { points: \"7 8 3 12 7 16\", key: \"2j60jr\" }],\n [\"line\", { x1: \"21\", x2: \"11\", y1: \"12\", y2: \"12\", key: \"1fxxak\" }],\n [\"line\", { x1: \"21\", x2: \"11\", y1: \"6\", y2: \"6\", key: \"asgu94\" }],\n [\"line\", { x1: \"21\", x2: \"11\", y1: \"18\", y2: \"18\", key: \"13dsj7\" }]\n]);\n\nexport { Outdent as default };\n//# sourceMappingURL=outdent.js.map\n","/**\n * @license lucide-react v0.294.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst Palette = createLucideIcon(\"Palette\", [\n [\"circle\", { cx: \"13.5\", cy: \"6.5\", r: \".5\", key: \"1xcu5\" }],\n [\"circle\", { cx: \"17.5\", cy: \"10.5\", r: \".5\", key: \"736e4u\" }],\n [\"circle\", { cx: \"8.5\", cy: \"7.5\", r: \".5\", key: \"clrty\" }],\n [\"circle\", { cx: \"6.5\", cy: \"12.5\", r: \".5\", key: \"1s4xz9\" }],\n [\n \"path\",\n {\n d: \"M12 2C6.5 2 2 6.5 2 12s4.5 10 10 10c.926 0 1.648-.746 1.648-1.688 0-.437-.18-.835-.437-1.125-.29-.289-.438-.652-.438-1.125a1.64 1.64 0 0 1 1.668-1.668h1.996c3.051 0 5.555-2.503 5.555-5.554C21.965 6.012 17.461 2 12 2z\",\n key: \"12rzf8\"\n }\n ]\n]);\n\nexport { Palette as default };\n//# sourceMappingURL=palette.js.map\n","/**\n * @license lucide-react v0.294.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst Plus = createLucideIcon(\"Plus\", [\n [\"path\", { d: \"M5 12h14\", key: \"1ays0h\" }],\n [\"path\", { d: \"M12 5v14\", key: \"s699le\" }]\n]);\n\nexport { Plus as default };\n//# sourceMappingURL=plus.js.map\n","/**\n * @license lucide-react v0.294.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst Quote = createLucideIcon(\"Quote\", [\n [\n \"path\",\n {\n d: \"M3 21c3 0 7-1 7-8V5c0-1.25-.756-2.017-2-2H4c-1.25 0-2 .75-2 1.972V11c0 1.25.75 2 2 2 1 0 1 0 1 1v1c0 1-1 2-2 2s-1 .008-1 1.031V20c0 1 0 1 1 1z\",\n key: \"4rm80e\"\n }\n ],\n [\n \"path\",\n {\n d: \"M15 21c3 0 7-1 7-8V5c0-1.25-.757-2.017-2-2h-4c-1.25 0-2 .75-2 1.972V11c0 1.25.75 2 2 2h.75c0 2.25.25 4-2.75 4v3c0 1 0 1 1 1z\",\n key: \"10za9r\"\n }\n ]\n]);\n\nexport { Quote as default };\n//# sourceMappingURL=quote.js.map\n","/**\n * @license lucide-react v0.294.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst Redo = createLucideIcon(\"Redo\", [\n [\"path\", { d: \"M21 7v6h-6\", key: \"3ptur4\" }],\n [\"path\", { d: \"M3 17a9 9 0 0 1 9-9 9 9 0 0 1 6 2.3l3 2.7\", key: \"1kgawr\" }]\n]);\n\nexport { Redo as default };\n//# sourceMappingURL=redo.js.map\n","/**\n * @license lucide-react v0.294.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst RotateCcw = createLucideIcon(\"RotateCcw\", [\n [\"path\", { d: \"M3 12a9 9 0 1 0 9-9 9.75 9.75 0 0 0-6.74 2.74L3 8\", key: \"1357e3\" }],\n [\"path\", { d: \"M3 3v5h5\", key: \"1xhq8a\" }]\n]);\n\nexport { RotateCcw as default };\n//# sourceMappingURL=rotate-ccw.js.map\n","/**\n * @license lucide-react v0.294.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst Rows = createLucideIcon(\"Rows\", [\n [\"rect\", { width: \"18\", height: \"18\", x: \"3\", y: \"3\", rx: \"2\", ry: \"2\", key: \"1m3agn\" }],\n [\"line\", { x1: \"3\", x2: \"21\", y1: \"12\", y2: \"12\", key: \"10d38w\" }]\n]);\n\nexport { Rows as default };\n//# sourceMappingURL=rows.js.map\n","/**\n * @license lucide-react v0.294.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst Scissors = createLucideIcon(\"Scissors\", [\n [\"circle\", { cx: \"6\", cy: \"6\", r: \"3\", key: \"1lh9wr\" }],\n [\"path\", { d: \"M8.12 8.12 12 12\", key: \"1alkpv\" }],\n [\"path\", { d: \"M20 4 8.12 15.88\", key: \"xgtan2\" }],\n [\"circle\", { cx: \"6\", cy: \"18\", r: \"3\", key: \"fqmcym\" }],\n [\"path\", { d: \"M14.8 14.8 20 20\", key: \"ptml3r\" }]\n]);\n\nexport { Scissors as default };\n//# sourceMappingURL=scissors.js.map\n","/**\n * @license lucide-react v0.294.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst Search = createLucideIcon(\"Search\", [\n [\"circle\", { cx: \"11\", cy: \"11\", r: \"8\", key: \"4ej97u\" }],\n [\"path\", { d: \"m21 21-4.3-4.3\", key: \"1qie3q\" }]\n]);\n\nexport { Search as default };\n//# sourceMappingURL=search.js.map\n","/**\n * @license lucide-react v0.294.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst Settings = createLucideIcon(\"Settings\", [\n [\n \"path\",\n {\n d: \"M12.22 2h-.44a2 2 0 0 0-2 2v.18a2 2 0 0 1-1 1.73l-.43.25a2 2 0 0 1-2 0l-.15-.08a2 2 0 0 0-2.73.73l-.22.38a2 2 0 0 0 .73 2.73l.15.1a2 2 0 0 1 1 1.72v.51a2 2 0 0 1-1 1.74l-.15.09a2 2 0 0 0-.73 2.73l.22.38a2 2 0 0 0 2.73.73l.15-.08a2 2 0 0 1 2 0l.43.25a2 2 0 0 1 1 1.73V20a2 2 0 0 0 2 2h.44a2 2 0 0 0 2-2v-.18a2 2 0 0 1 1-1.73l.43-.25a2 2 0 0 1 2 0l.15.08a2 2 0 0 0 2.73-.73l.22-.39a2 2 0 0 0-.73-2.73l-.15-.08a2 2 0 0 1-1-1.74v-.5a2 2 0 0 1 1-1.74l.15-.09a2 2 0 0 0 .73-2.73l-.22-.38a2 2 0 0 0-2.73-.73l-.15.08a2 2 0 0 1-2 0l-.43-.25a2 2 0 0 1-1-1.73V4a2 2 0 0 0-2-2z\",\n key: \"1qme2f\"\n }\n ],\n [\"circle\", { cx: \"12\", cy: \"12\", r: \"3\", key: \"1v7zrd\" }]\n]);\n\nexport { Settings as default };\n//# sourceMappingURL=settings.js.map\n","/**\n * @license lucide-react v0.294.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst Strikethrough = createLucideIcon(\"Strikethrough\", [\n [\"path\", { d: \"M16 4H9a3 3 0 0 0-2.83 4\", key: \"43sutm\" }],\n [\"path\", { d: \"M14 12a4 4 0 0 1 0 8H6\", key: \"nlfj13\" }],\n [\"line\", { x1: \"4\", x2: \"20\", y1: \"12\", y2: \"12\", key: \"1e0a9i\" }]\n]);\n\nexport { Strikethrough as default };\n//# sourceMappingURL=strikethrough.js.map\n","/**\n * @license lucide-react v0.294.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst Sun = createLucideIcon(\"Sun\", [\n [\"circle\", { cx: \"12\", cy: \"12\", r: \"4\", key: \"4exip2\" }],\n [\"path\", { d: \"M12 2v2\", key: \"tus03m\" }],\n [\"path\", { d: \"M12 20v2\", key: \"1lh1kg\" }],\n [\"path\", { d: \"m4.93 4.93 1.41 1.41\", key: \"149t6j\" }],\n [\"path\", { d: \"m17.66 17.66 1.41 1.41\", key: \"ptbguv\" }],\n [\"path\", { d: \"M2 12h2\", key: \"1t8f8n\" }],\n [\"path\", { d: \"M20 12h2\", key: \"1q8mjw\" }],\n [\"path\", { d: \"m6.34 17.66-1.41 1.41\", key: \"1m8zz5\" }],\n [\"path\", { d: \"m19.07 4.93-1.41 1.41\", key: \"1shlcs\" }]\n]);\n\nexport { Sun as default };\n//# sourceMappingURL=sun.js.map\n","/**\n * @license lucide-react v0.294.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst Table = createLucideIcon(\"Table\", [\n [\"path\", { d: \"M12 3v18\", key: \"108xh3\" }],\n [\"rect\", { width: \"18\", height: \"18\", x: \"3\", y: \"3\", rx: \"2\", key: \"afitv7\" }],\n [\"path\", { d: \"M3 9h18\", key: \"1pudct\" }],\n [\"path\", { d: \"M3 15h18\", key: \"5xshup\" }]\n]);\n\nexport { Table as default };\n//# sourceMappingURL=table.js.map\n","/**\n * @license lucide-react v0.294.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst Trash2 = createLucideIcon(\"Trash2\", [\n [\"path\", { d: \"M3 6h18\", key: \"d0wm0j\" }],\n [\"path\", { d: \"M19 6v14c0 1-1 2-2 2H7c-1 0-2-1-2-2V6\", key: \"4alrt4\" }],\n [\"path\", { d: \"M8 6V4c0-1 1-2 2-2h4c1 0 2 1 2 2v2\", key: \"v07s0e\" }],\n [\"line\", { x1: \"10\", x2: \"10\", y1: \"11\", y2: \"17\", key: \"1uufr5\" }],\n [\"line\", { x1: \"14\", x2: \"14\", y1: \"11\", y2: \"17\", key: \"xtxkd\" }]\n]);\n\nexport { Trash2 as default };\n//# sourceMappingURL=trash-2.js.map\n","/**\n * @license lucide-react v0.294.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst Type = createLucideIcon(\"Type\", [\n [\"polyline\", { points: \"4 7 4 4 20 4 20 7\", key: \"1nosan\" }],\n [\"line\", { x1: \"9\", x2: \"15\", y1: \"20\", y2: \"20\", key: \"swin9y\" }],\n [\"line\", { x1: \"12\", x2: \"12\", y1: \"4\", y2: \"20\", key: \"1tx1rr\" }]\n]);\n\nexport { Type as default };\n//# sourceMappingURL=type.js.map\n","/**\n * @license lucide-react v0.294.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst Underline = createLucideIcon(\"Underline\", [\n [\"path\", { d: \"M6 4v6a6 6 0 0 0 12 0V4\", key: \"9kb039\" }],\n [\"line\", { x1: \"4\", x2: \"20\", y1: \"20\", y2: \"20\", key: \"nun2al\" }]\n]);\n\nexport { Underline as default };\n//# sourceMappingURL=underline.js.map\n","/**\n * @license lucide-react v0.294.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst Undo = createLucideIcon(\"Undo\", [\n [\"path\", { d: \"M3 7v6h6\", key: \"1v2h90\" }],\n [\"path\", { d: \"M21 17a9 9 0 0 0-9-9 9 9 0 0 0-6 2.3L3 13\", key: \"1r6uu6\" }]\n]);\n\nexport { Undo as default };\n//# sourceMappingURL=undo.js.map\n","/**\n * @license lucide-react v0.294.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst Upload = createLucideIcon(\"Upload\", [\n [\"path\", { d: \"M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4\", key: \"ih7n3h\" }],\n [\"polyline\", { points: \"17 8 12 3 7 8\", key: \"t8dd8p\" }],\n [\"line\", { x1: \"12\", x2: \"12\", y1: \"3\", y2: \"15\", key: \"widbto\" }]\n]);\n\nexport { Upload as default };\n//# sourceMappingURL=upload.js.map\n","/**\n * @license lucide-react v0.294.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst Video = createLucideIcon(\"Video\", [\n [\"path\", { d: \"m22 8-6 4 6 4V8Z\", key: \"50v9me\" }],\n [\"rect\", { width: \"14\", height: \"12\", x: \"2\", y: \"6\", rx: \"2\", ry: \"2\", key: \"1rqjg6\" }]\n]);\n\nexport { Video as default };\n//# sourceMappingURL=video.js.map\n","/**\n * @license lucide-react v0.294.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst XCircle = createLucideIcon(\"XCircle\", [\n [\"circle\", { cx: \"12\", cy: \"12\", r: \"10\", key: \"1mglay\" }],\n [\"path\", { d: \"m15 9-6 6\", key: \"1uzhvr\" }],\n [\"path\", { d: \"m9 9 6 6\", key: \"z0biqf\" }]\n]);\n\nexport { XCircle as default };\n//# sourceMappingURL=x-circle.js.map\n","/**\n * @license lucide-react v0.294.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst X = createLucideIcon(\"X\", [\n [\"path\", { d: \"M18 6 6 18\", key: \"1bl5f8\" }],\n [\"path\", { d: \"m6 6 12 12\", key: \"d8bk6v\" }]\n]);\n\nexport { X as default };\n//# sourceMappingURL=x.js.map\n","/**\r\n * Commands - DOM-based editing commands\r\n */\r\n\r\nimport type { EditorInstance, InlineFormat, BlockType } from './types';\r\nimport { blockRegistry } from './block-registry';\r\nimport {\r\n getSelectionState,\r\n wrapSelection,\r\n unwrapElement,\r\n findElementsInSelection,\r\n moveCursorToEnd,\r\n moveCursorToStart,\r\n} from './selection';\r\nimport { getBlockFromChild, insertAfter, insertBefore } from '../utils/helpers';\r\n\r\n// Inline format tag mappings\r\nconst FORMAT_TAGS: Record<InlineFormat, string> = {\r\n bold: 'strong',\r\n italic: 'em',\r\n underline: 'u',\r\n strikethrough: 's',\r\n code: 'code',\r\n link: 'a',\r\n textColor: 'span',\r\n highlight: 'mark',\r\n};\r\n\r\n/**\r\n * Check if a format is active at current selection\r\n */\r\nexport function isFormatActive(format: InlineFormat, container: HTMLElement): boolean {\r\n const selection = window.getSelection();\r\n if (!selection || selection.rangeCount === 0) return false;\r\n\r\n const range = selection.getRangeAt(0);\r\n let node: Node | null = range.commonAncestorContainer;\r\n\r\n // Walk up to find format tag\r\n const tag = FORMAT_TAGS[format].toUpperCase();\r\n while (node && node !== container) {\r\n if (node instanceof HTMLElement && node.tagName === tag) {\r\n return true;\r\n }\r\n node = node.parentNode;\r\n }\r\n\r\n return false;\r\n}\r\n\r\n/**\r\n * Toggle inline format\r\n */\r\nexport function toggleFormat(\r\n format: InlineFormat,\r\n container: HTMLElement,\r\n attributes?: Record<string, string>\r\n): void {\r\n const selection = window.getSelection();\r\n if (!selection || selection.rangeCount === 0) return;\r\n\r\n const tag = FORMAT_TAGS[format];\r\n const isActive = isFormatActive(format, container);\r\n\r\n if (selection.isCollapsed) {\r\n // No selection - just return, can't format nothing\r\n return;\r\n }\r\n\r\n if (isActive) {\r\n // Remove format\r\n const elements = findElementsInSelection(tag, container);\r\n elements.forEach(el => unwrapElement(el));\r\n } else {\r\n // Apply format\r\n wrapSelection(tag, attributes);\r\n }\r\n}\r\n\r\n/**\r\n * Apply bold format\r\n */\r\nexport function toggleBold(container: HTMLElement): void {\r\n // Try execCommand first (better cross-browser support)\r\n document.execCommand('bold', false);\r\n}\r\n\r\n/**\r\n * Apply italic format\r\n */\r\nexport function toggleItalic(container: HTMLElement): void {\r\n document.execCommand('italic', false);\r\n}\r\n\r\n/**\r\n * Apply underline format\r\n */\r\nexport function toggleUnderline(container: HTMLElement): void {\r\n document.execCommand('underline', false);\r\n}\r\n\r\n/**\r\n * Apply strikethrough format\r\n */\r\nexport function toggleStrikethrough(container: HTMLElement): void {\r\n document.execCommand('strikeThrough', false);\r\n}\r\n\r\n/**\r\n * Apply inline code format\r\n */\r\nexport function toggleInlineCode(container: HTMLElement): void {\r\n toggleFormat('code', container);\r\n}\r\n\r\n/**\r\n * Insert or edit link\r\n */\r\nexport function insertLink(container: HTMLElement, url: string, text?: string): void {\r\n const selection = window.getSelection();\r\n if (!selection) return;\r\n\r\n if (selection.isCollapsed && text) {\r\n // No selection, insert link with text\r\n const link = document.createElement('a');\r\n link.href = url;\r\n link.textContent = text;\r\n \r\n const range = selection.getRangeAt(0);\r\n range.insertNode(link);\r\n \r\n // Move cursor after link\r\n const newRange = document.createRange();\r\n newRange.setStartAfter(link);\r\n newRange.collapse(true);\r\n selection.removeAllRanges();\r\n selection.addRange(newRange);\r\n } else {\r\n // Wrap selection in link\r\n document.execCommand('createLink', false, url);\r\n }\r\n}\r\n\r\n/**\r\n * Remove link\r\n */\r\nexport function removeLink(container: HTMLElement): void {\r\n document.execCommand('unlink', false);\r\n}\r\n\r\n/**\r\n * Set text color\r\n */\r\nexport function setTextColor(container: HTMLElement, color: string): void {\r\n document.execCommand('foreColor', false, color);\r\n}\r\n\r\n/**\r\n * Set background/highlight color\r\n */\r\nexport function setHighlightColor(container: HTMLElement, color: string): void {\r\n document.execCommand('hiliteColor', false, color);\r\n}\r\n\r\n/**\r\n * Set text alignment\r\n */\r\nexport function setAlignment(\r\n element: HTMLElement,\r\n align: 'left' | 'center' | 'right' | 'justify'\r\n): void {\r\n element.style.textAlign = align;\r\n}\r\n\r\n/**\r\n * Clear all formatting\r\n */\r\nexport function clearFormatting(container: HTMLElement): void {\r\n document.execCommand('removeFormat', false);\r\n}\r\n\r\n/**\r\n * Insert a new block\r\n */\r\nexport function insertBlock(\r\n container: HTMLElement,\r\n type: BlockType,\r\n position?: 'before' | 'after',\r\n referenceBlock?: HTMLElement\r\n): HTMLElement | null {\r\n const block = blockRegistry.createBlock(type);\r\n if (!block) return null;\r\n\r\n if (referenceBlock) {\r\n if (position === 'before') {\r\n insertBefore(block, referenceBlock);\r\n } else {\r\n insertAfter(block, referenceBlock);\r\n }\r\n } else {\r\n container.appendChild(block);\r\n }\r\n\r\n // Focus the new block\r\n const editableChild = block.querySelector('[contenteditable=\"true\"]') || \r\n (block.hasAttribute('contenteditable') ? block : null);\r\n \r\n if (editableChild instanceof HTMLElement) {\r\n editableChild.focus();\r\n moveCursorToStart(editableChild);\r\n }\r\n\r\n return block;\r\n}\r\n\r\n/**\r\n * Delete a block\r\n */\r\nexport function deleteBlock(block: HTMLElement, container: HTMLElement): HTMLElement | null {\r\n const blocks = Array.from(container.querySelectorAll('[data-block-id]'));\r\n const index = blocks.indexOf(block);\r\n \r\n // Find block to focus after deletion\r\n const prevBlock = blocks[index - 1] as HTMLElement | undefined;\r\n const nextBlock = blocks[index + 1] as HTMLElement | undefined;\r\n \r\n // Remove the block\r\n block.remove();\r\n\r\n // Focus adjacent block\r\n const targetBlock = nextBlock || prevBlock;\r\n if (targetBlock) {\r\n const editableChild = targetBlock.querySelector('[contenteditable=\"true\"]') || \r\n (targetBlock.hasAttribute('contenteditable') ? targetBlock : null);\r\n \r\n if (editableChild instanceof HTMLElement) {\r\n editableChild.focus();\r\n if (!nextBlock) {\r\n moveCursorToEnd(editableChild);\r\n } else {\r\n moveCursorToStart(editableChild);\r\n }\r\n }\r\n }\r\n\r\n // If no blocks left, create a default block\r\n if (blocks.length <= 1) {\r\n const defaultBlock = blockRegistry.createBlock(blockRegistry.getDefaultBlock());\r\n if (defaultBlock) {\r\n container.appendChild(defaultBlock);\r\n return defaultBlock;\r\n }\r\n }\r\n\r\n return targetBlock || null;\r\n}\r\n\r\n/**\r\n * Move block up\r\n */\r\nexport function moveBlockUp(block: HTMLElement, container: HTMLElement): boolean {\r\n const prevSibling = block.previousElementSibling;\r\n if (prevSibling && prevSibling instanceof HTMLElement) {\r\n container.insertBefore(block, prevSibling);\r\n return true;\r\n }\r\n return false;\r\n}\r\n\r\n/**\r\n * Move block down\r\n */\r\nexport function moveBlockDown(block: HTMLElement, container: HTMLElement): boolean {\r\n const nextSibling = block.nextElementSibling;\r\n if (nextSibling && nextSibling instanceof HTMLElement) {\r\n container.insertBefore(nextSibling, block);\r\n return true;\r\n }\r\n return false;\r\n}\r\n\r\n/**\r\n * Duplicate a block\r\n */\r\nexport function duplicateBlock(block: HTMLElement): HTMLElement {\r\n const clone = block.cloneNode(true) as HTMLElement;\r\n \r\n // Generate new ID\r\n const newId = `cb-${Date.now().toString(36)}-${Math.random().toString(36).substring(2, 9)}`;\r\n clone.setAttribute('data-block-id', newId);\r\n \r\n insertAfter(clone, block);\r\n return clone;\r\n}\r\n\r\n/**\r\n * Transform block to different type\r\n */\r\nexport function transformBlock(\r\n block: HTMLElement,\r\n newType: BlockType,\r\n container: HTMLElement\r\n): HTMLElement | null {\r\n const newBlock = blockRegistry.transformBlock(block, newType);\r\n if (!newBlock) return null;\r\n\r\n // Replace old block with new one\r\n block.parentNode?.replaceChild(newBlock, block);\r\n\r\n // Focus new block\r\n const editableChild = newBlock.querySelector('[contenteditable=\"true\"]') || \r\n (newBlock.hasAttribute('contenteditable') ? newBlock : null);\r\n \r\n if (editableChild instanceof HTMLElement) {\r\n editableChild.focus();\r\n }\r\n\r\n return newBlock;\r\n}\r\n\r\n/**\r\n * Merge two blocks\r\n */\r\nexport function mergeBlocks(\r\n sourceBlock: HTMLElement,\r\n targetBlock: HTMLElement\r\n): void {\r\n const sourceContent = sourceBlock.innerHTML;\r\n \r\n // Append content to target\r\n const targetEditable = targetBlock.querySelector('[contenteditable=\"true\"]') || targetBlock;\r\n if (targetEditable instanceof HTMLElement) {\r\n targetEditable.innerHTML += sourceContent;\r\n moveCursorToEnd(targetEditable);\r\n }\r\n\r\n // Remove source block\r\n sourceBlock.remove();\r\n}\r\n\r\n/**\r\n * Split block at cursor position\r\n */\r\nexport function splitBlock(\r\n block: HTMLElement,\r\n container: HTMLElement\r\n): HTMLElement | null {\r\n const selection = window.getSelection();\r\n if (!selection || selection.rangeCount === 0) return null;\r\n\r\n const range = selection.getRangeAt(0);\r\n \r\n // Create range for content after cursor\r\n const afterRange = document.createRange();\r\n afterRange.setStart(range.endContainer, range.endOffset);\r\n afterRange.setEndAfter(block.lastChild || block);\r\n \r\n // Extract content after cursor\r\n const afterContent = afterRange.extractContents();\r\n \r\n // Create new block with after content\r\n const blockType = blockRegistry.getBlockType(block) || 'paragraph';\r\n const newBlock = blockRegistry.createBlock(blockType);\r\n \r\n if (!newBlock) return null;\r\n\r\n const newEditable = newBlock.querySelector('[contenteditable=\"true\"]') || newBlock;\r\n if (newEditable instanceof HTMLElement) {\r\n newEditable.appendChild(afterContent);\r\n }\r\n\r\n // Insert new block after current\r\n insertAfter(newBlock, block);\r\n\r\n // Focus new block\r\n if (newEditable instanceof HTMLElement) {\r\n newEditable.focus();\r\n moveCursorToStart(newEditable);\r\n }\r\n\r\n return newBlock;\r\n}\r\n\r\n/**\r\n * Indent block (for lists)\r\n */\r\nexport function indentBlock(block: HTMLElement): boolean {\r\n const blockType = blockRegistry.getBlockType(block);\r\n if (blockType !== 'bulletList' && blockType !== 'numberedList') {\r\n return false;\r\n }\r\n\r\n // Add margin or wrap in nested list\r\n const currentMargin = parseInt(block.style.marginLeft || '0', 10);\r\n block.style.marginLeft = `${currentMargin + 24}px`;\r\n return true;\r\n}\r\n\r\n/**\r\n * Outdent block (for lists)\r\n */\r\nexport function outdentBlock(block: HTMLElement): boolean {\r\n const blockType = blockRegistry.getBlockType(block);\r\n if (blockType !== 'bulletList' && blockType !== 'numberedList') {\r\n return false;\r\n }\r\n\r\n const currentMargin = parseInt(block.style.marginLeft || '0', 10);\r\n if (currentMargin > 0) {\r\n block.style.marginLeft = `${Math.max(0, currentMargin - 24)}px`;\r\n return true;\r\n }\r\n return false;\r\n}\r\n\r\n/**\r\n * Create command executor\r\n */\r\nexport function createCommandExecutor(editor: EditorInstance) {\r\n return {\r\n bold: () => toggleBold(editor.container),\r\n italic: () => toggleItalic(editor.container),\r\n underline: () => toggleUnderline(editor.container),\r\n strikethrough: () => toggleStrikethrough(editor.container),\r\n inlineCode: () => toggleInlineCode(editor.container),\r\n link: (url: string, text?: string) => insertLink(editor.container, url, text),\r\n unlink: () => removeLink(editor.container),\r\n textColor: (color: string) => setTextColor(editor.container, color),\r\n highlight: (color: string) => setHighlightColor(editor.container, color),\r\n clearFormat: () => clearFormatting(editor.container),\r\n alignLeft: (el: HTMLElement) => setAlignment(el, 'left'),\r\n alignCenter: (el: HTMLElement) => setAlignment(el, 'center'),\r\n alignRight: (el: HTMLElement) => setAlignment(el, 'right'),\r\n alignJustify: (el: HTMLElement) => setAlignment(el, 'justify'),\r\n insertBlock: (type: BlockType, pos?: 'before' | 'after', ref?: HTMLElement) =>\r\n insertBlock(editor.container, type, pos, ref),\r\n deleteBlock: (block: HTMLElement) => deleteBlock(block, editor.container),\r\n moveUp: (block: HTMLElement) => moveBlockUp(block, editor.container),\r\n moveDown: (block: HTMLElement) => moveBlockDown(block, editor.container),\r\n duplicate: (block: HTMLElement) => duplicateBlock(block),\r\n transform: (block: HTMLElement, type: BlockType) =>\r\n transformBlock(block, type, editor.container),\r\n merge: (source: HTMLElement, target: HTMLElement) => mergeBlocks(source, target),\r\n split: (block: HTMLElement) => splitBlock(block, editor.container),\r\n indent: (block: HTMLElement) => indentBlock(block),\r\n outdent: (block: HTMLElement) => outdentBlock(block),\r\n };\r\n}\r\n","/**\r\n * Toolbar Component - Professional with floating popovers\r\n */\r\n\r\nimport React, { useState, useCallback, useRef, useEffect } from 'react';\r\nimport type { ToolbarProps, InlineFormat, BlockType } from '../core/types';\r\nimport {\r\n Bold,\r\n Italic,\r\n Underline,\r\n Strikethrough,\r\n Code,\r\n Link,\r\n Highlighter,\r\n AlignLeft,\r\n AlignCenter,\r\n AlignRight,\r\n AlignJustify,\r\n Undo,\r\n Redo,\r\n List,\r\n ListOrdered,\r\n CheckSquare,\r\n Quote,\r\n Heading1,\r\n Heading2,\r\n Heading3,\r\n Image,\r\n Video,\r\n Minus,\r\n Table,\r\n Eraser,\r\n Download,\r\n FileCode,\r\n ChevronDown,\r\n AlertCircle,\r\n Palette,\r\n X,\r\n type LucideIcon,\r\n} from 'lucide-react';\r\nimport {\r\n toggleBold,\r\n toggleItalic,\r\n toggleUnderline,\r\n toggleStrikethrough,\r\n toggleInlineCode,\r\n insertLink,\r\n setHighlightColor,\r\n setTextColor,\r\n clearFormatting,\r\n setAlignment,\r\n} from '../core/commands';\r\nimport { isFormatActive } from '../core/commands';\r\nimport { getBlockFromChild } from '../utils/helpers';\r\n\r\ninterface ToolbarButton {\r\n icon: LucideIcon;\r\n label: string;\r\n action: (e: React.MouseEvent) => void;\r\n isActive?: () => boolean;\r\n shortcut?: string;\r\n}\r\n\r\ninterface ToolbarGroup {\r\n name: string;\r\n buttons: ToolbarButton[];\r\n}\r\n\r\ntype PopoverType = 'link' | 'highlight' | 'textColor' | null;\r\n\r\nexport const Toolbar: React.FC<ToolbarProps> = ({\r\n editor,\r\n className = '',\r\n darkMode = false,\r\n}) => {\r\n const [activePopover, setActivePopover] = useState<PopoverType>(null);\r\n const [popoverPosition, setPopoverPosition] = useState({ x: 0, y: 0 });\r\n const [linkUrl, setLinkUrl] = useState('');\r\n const [linkText, setLinkText] = useState('');\r\n const [formatState, setFormatState] = useState({\r\n bold: false,\r\n italic: false,\r\n underline: false,\r\n strikethrough: false,\r\n });\r\n const toolbarRef = useRef<HTMLDivElement>(null);\r\n const popoverRef = useRef<HTMLDivElement>(null);\r\n\r\n // Update format state on selection change (debounced to avoid flicker)\r\n useEffect(() => {\r\n const updateFormatState = () => {\r\n // Only update if selection is within the editor\r\n const selection = window.getSelection();\r\n if (!selection || !selection.rangeCount) return;\r\n \r\n const range = selection.getRangeAt(0);\r\n const container = editor?.container;\r\n if (!container || !container.contains(range.commonAncestorContainer)) return;\r\n \r\n setFormatState({\r\n bold: document.queryCommandState('bold'),\r\n italic: document.queryCommandState('italic'),\r\n underline: document.queryCommandState('underline'),\r\n strikethrough: document.queryCommandState('strikeThrough'),\r\n });\r\n };\r\n\r\n document.addEventListener('selectionchange', updateFormatState);\r\n return () => document.removeEventListener('selectionchange', updateFormatState);\r\n }, [editor]);\r\n\r\n // Text colors\r\n const textColors = [\r\n { color: '#000000', label: 'Black' },\r\n { color: '#374151', label: 'Gray' },\r\n { color: '#dc2626', label: 'Red' },\r\n { color: '#ea580c', label: 'Orange' },\r\n { color: '#ca8a04', label: 'Yellow' },\r\n { color: '#16a34a', label: 'Green' },\r\n { color: '#0891b2', label: 'Cyan' },\r\n { color: '#2563eb', label: 'Blue' },\r\n { color: '#7c3aed', label: 'Purple' },\r\n { color: '#db2777', label: 'Pink' },\r\n ];\r\n\r\n // Highlight colors \r\n const highlightColors = [\r\n { color: '#fef08a', label: 'Yellow' },\r\n { color: '#bbf7d0', label: 'Green' },\r\n { color: '#bfdbfe', label: 'Blue' },\r\n { color: '#fecaca', label: 'Red' },\r\n { color: '#e9d5ff', label: 'Purple' },\r\n { color: '#fed7aa', label: 'Orange' },\r\n { color: '#99f6e4', label: 'Teal' },\r\n { color: '#fce7f3', label: 'Pink' },\r\n { color: '#e5e7eb', label: 'Gray' },\r\n { color: 'transparent', label: 'None' },\r\n ];\r\n\r\n // Close popover when clicking outside\r\n useEffect(() => {\r\n const handleClickOutside = (e: MouseEvent) => {\r\n if (popoverRef.current && !popoverRef.current.contains(e.target as Node) &&\r\n !toolbarRef.current?.contains(e.target as Node)) {\r\n setActivePopover(null);\r\n }\r\n };\r\n\r\n document.addEventListener('mousedown', handleClickOutside);\r\n return () => document.removeEventListener('mousedown', handleClickOutside);\r\n }, []);\r\n\r\n // Open popover at button position\r\n const openPopover = useCallback((type: PopoverType, e: React.MouseEvent) => {\r\n if (activePopover === type) {\r\n setActivePopover(null);\r\n return;\r\n }\r\n \r\n const button = e.currentTarget as HTMLElement;\r\n const rect = button.getBoundingClientRect();\r\n const toolbarRect = toolbarRef.current?.getBoundingClientRect();\r\n \r\n setPopoverPosition({\r\n x: rect.left - (toolbarRect?.left || 0),\r\n y: rect.bottom - (toolbarRect?.top || 0) + 8,\r\n });\r\n setActivePopover(type);\r\n setLinkUrl('');\r\n setLinkText('');\r\n }, [activePopover]);\r\n\r\n // Handle link insertion\r\n const handleInsertLink = useCallback(() => {\r\n if (linkUrl && editor?.container) {\r\n insertLink(editor.container, linkUrl, linkText || undefined);\r\n setActivePopover(null);\r\n setLinkUrl('');\r\n setLinkText('');\r\n }\r\n }, [linkUrl, linkText, editor]);\r\n\r\n // Handle text color\r\n const handleTextColor = useCallback((color: string) => {\r\n if (editor?.container) {\r\n setTextColor(editor.container, color);\r\n setActivePopover(null);\r\n }\r\n }, [editor]);\r\n\r\n // Handle highlight color\r\n const handleHighlight = useCallback((color: string) => {\r\n if (editor?.container) {\r\n if (color === 'transparent') {\r\n document.execCommand('removeFormat', false);\r\n } else {\r\n setHighlightColor(editor.container, color);\r\n }\r\n setActivePopover(null);\r\n }\r\n }, [editor]);\r\n\r\n // Handle export\r\n const handleExport = useCallback((format: 'html' | 'json') => {\r\n if (!editor) return;\r\n \r\n const html = editor.getHTML();\r\n let content: string;\r\n let filename: string;\r\n let type: string;\r\n\r\n if (format === 'html') {\r\n content = `<!DOCTYPE html>\r\n<html>\r\n<head>\r\n <meta charset=\"UTF-8\">\r\n <title>Document</title>\r\n <style>\r\n body { font-family: system-ui, sans-serif; max-width: 800px; margin: 0 auto; padding: 2rem; line-height: 1.6; }\r\n img { max-width: 100%; height: auto; }\r\n pre { background: #f3f4f6; padding: 1rem; border-radius: 0.5rem; overflow-x: auto; }\r\n code { font-family: monospace; }\r\n blockquote { border-left: 4px solid #3b82f6; margin: 1rem 0; padding: 0.5rem 1rem; background: #f8fafc; }\r\n table { border-collapse: collapse; width: 100%; }\r\n th, td { border: 1px solid #e5e7eb; padding: 0.5rem; text-align: left; }\r\n th { background: #f9fafb; font-weight: 600; }\r\n </style>\r\n</head>\r\n<body>\r\n${html}\r\n</body>\r\n</html>`;\r\n filename = 'document.html';\r\n type = 'text/html';\r\n } else {\r\n content = JSON.stringify({ content: html }, null, 2);\r\n filename = 'document.json';\r\n type = 'application/json';\r\n }\r\n\r\n const blob = new Blob([content], { type });\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 }, [editor]);\r\n\r\n if (!editor) return null;\r\n\r\n // Helper to transform or insert block\r\n const handleBlockAction = (type: BlockType, data?: Record<string, any>) => {\r\n const activeElement = document.activeElement;\r\n const block = activeElement?.closest('.cb-block');\r\n const blockId = block?.getAttribute('data-block-id');\r\n const currentType = block?.getAttribute('data-block-type');\r\n const editable = block?.querySelector('[contenteditable=\"true\"]');\r\n \r\n if (blockId && currentType === 'paragraph' && editable && !editable.textContent?.trim()) {\r\n editor.transformBlock(block as HTMLElement, type, data);\r\n } else {\r\n editor.insertBlock(type, data as any);\r\n }\r\n };\r\n\r\n const toolbarGroups: ToolbarGroup[] = [\r\n {\r\n name: 'history',\r\n buttons: [\r\n {\r\n icon: Undo,\r\n label: 'Undo',\r\n action: () => editor.undo(),\r\n shortcut: 'Ctrl+Z',\r\n },\r\n {\r\n icon: Redo,\r\n label: 'Redo',\r\n action: () => editor.redo(),\r\n shortcut: 'Ctrl+Y',\r\n },\r\n ],\r\n },\r\n {\r\n name: 'formatting',\r\n buttons: [\r\n {\r\n icon: Bold,\r\n label: 'Bold',\r\n action: () => toggleBold(editor.container),\r\n isActive: () => formatState.bold,\r\n shortcut: 'Ctrl+B',\r\n },\r\n {\r\n icon: Italic,\r\n label: 'Italic',\r\n action: () => toggleItalic(editor.container),\r\n isActive: () => formatState.italic,\r\n shortcut: 'Ctrl+I',\r\n },\r\n {\r\n icon: Underline,\r\n label: 'Underline',\r\n action: () => toggleUnderline(editor.container),\r\n isActive: () => formatState.underline,\r\n shortcut: 'Ctrl+U',\r\n },\r\n {\r\n icon: Strikethrough,\r\n label: 'Strikethrough',\r\n action: () => toggleStrikethrough(editor.container),\r\n isActive: () => formatState.strikethrough,\r\n },\r\n {\r\n icon: Code,\r\n label: 'Inline Code',\r\n action: () => toggleInlineCode(editor.container),\r\n },\r\n ],\r\n },\r\n {\r\n name: 'richtext',\r\n buttons: [\r\n {\r\n icon: Link,\r\n label: 'Insert Link',\r\n action: (e) => openPopover('link', e),\r\n },\r\n {\r\n icon: Highlighter,\r\n label: 'Highlight',\r\n action: (e) => openPopover('highlight', e),\r\n },\r\n {\r\n icon: Palette,\r\n label: 'Text Color',\r\n action: (e) => openPopover('textColor', e),\r\n },\r\n ],\r\n },\r\n {\r\n name: 'alignment',\r\n buttons: [\r\n {\r\n icon: AlignLeft,\r\n label: 'Align Left',\r\n action: () => {\r\n const block = getBlockFromChild(document.activeElement);\r\n if (block) setAlignment(block, 'left');\r\n },\r\n },\r\n {\r\n icon: AlignCenter,\r\n label: 'Align Center',\r\n action: () => {\r\n const block = getBlockFromChild(document.activeElement);\r\n if (block) setAlignment(block, 'center');\r\n },\r\n },\r\n {\r\n icon: AlignRight,\r\n label: 'Align Right',\r\n action: () => {\r\n const block = getBlockFromChild(document.activeElement);\r\n if (block) setAlignment(block, 'right');\r\n },\r\n },\r\n ],\r\n },\r\n {\r\n name: 'headings',\r\n buttons: [\r\n {\r\n icon: Heading1,\r\n label: 'Heading 1',\r\n action: () => handleBlockAction('heading', { level: 1 }),\r\n shortcut: 'Ctrl+1',\r\n },\r\n {\r\n icon: Heading2,\r\n label: 'Heading 2',\r\n action: () => handleBlockAction('heading', { level: 2 }),\r\n shortcut: 'Ctrl+2',\r\n },\r\n {\r\n icon: Heading3,\r\n label: 'Heading 3',\r\n action: () => handleBlockAction('heading', { level: 3 }),\r\n shortcut: 'Ctrl+3',\r\n },\r\n ],\r\n },\r\n {\r\n name: 'blocks',\r\n buttons: [\r\n {\r\n icon: List,\r\n label: 'Bullet List',\r\n action: () => handleBlockAction('bulletList'),\r\n },\r\n {\r\n icon: ListOrdered,\r\n label: 'Numbered List',\r\n action: () => handleBlockAction('numberedList'),\r\n },\r\n {\r\n icon: CheckSquare,\r\n label: 'Checklist',\r\n action: () => handleBlockAction('checkList'),\r\n },\r\n {\r\n icon: Quote,\r\n label: 'Quote',\r\n action: () => handleBlockAction('quote'),\r\n },\r\n {\r\n icon: FileCode,\r\n label: 'Code Block',\r\n action: () => handleBlockAction('code'),\r\n },\r\n ],\r\n },\r\n {\r\n name: 'media',\r\n buttons: [\r\n {\r\n icon: Image,\r\n label: 'Image',\r\n action: () => editor.insertBlock('image'),\r\n },\r\n {\r\n icon: Video,\r\n label: 'Video',\r\n action: () => editor.insertBlock('video'),\r\n },\r\n {\r\n icon: Table,\r\n label: 'Table',\r\n action: () => editor.insertBlock('table'),\r\n },\r\n {\r\n icon: AlertCircle,\r\n label: 'Callout',\r\n action: () => handleBlockAction('callout'),\r\n },\r\n {\r\n icon: Minus,\r\n label: 'Divider',\r\n action: () => editor.insertBlock('divider'),\r\n },\r\n ],\r\n },\r\n {\r\n name: 'utils',\r\n buttons: [\r\n {\r\n icon: Eraser,\r\n label: 'Clear Formatting',\r\n action: () => clearFormatting(editor.container),\r\n },\r\n {\r\n icon: Download,\r\n label: 'Export HTML',\r\n action: () => handleExport('html'),\r\n },\r\n ],\r\n },\r\n ];\r\n\r\n return (\r\n <div\r\n ref={toolbarRef}\r\n className={`cb-toolbar ${className} ${darkMode ? 'cb-toolbar-dark' : ''}`}\r\n role=\"toolbar\"\r\n aria-label=\"Editor formatting options\"\r\n onMouseDown={(e) => {\r\n // Only prevent default if not clicking inside a popover input\r\n if (!(e.target as HTMLElement).closest('.cb-popover')) {\r\n e.preventDefault();\r\n }\r\n }}\r\n >\r\n {toolbarGroups.map((group) => (\r\n <div key={group.name} className=\"cb-toolbar-group\" role=\"group\">\r\n {group.buttons.map((button) => (\r\n <button\r\n key={button.label}\r\n type=\"button\"\r\n className={`cb-toolbar-btn ${button.isActive?.() ? 'cb-toolbar-btn-active' : ''}`}\r\n onClick={button.action}\r\n title={`${button.label}${button.shortcut ? ` (${button.shortcut})` : ''}`}\r\n aria-label={button.label}\r\n aria-pressed={button.isActive?.()}\r\n >\r\n <button.icon size={18} />\r\n </button>\r\n ))}\r\n </div>\r\n ))}\r\n\r\n {/* Floating Popovers */}\r\n {activePopover && (\r\n <div\r\n ref={popoverRef}\r\n className=\"cb-popover\"\r\n style={{\r\n position: 'absolute',\r\n left: popoverPosition.x,\r\n top: popoverPosition.y,\r\n zIndex: 1000,\r\n }}\r\n >\r\n {/* Link Popover */}\r\n {activePopover === 'link' && (\r\n <div className=\"cb-popover-content cb-link-popover\">\r\n <div className=\"cb-popover-header\">\r\n <span>Insert Link</span>\r\n <button \r\n type=\"button\" \r\n className=\"cb-popover-close\"\r\n onClick={() => setActivePopover(null)}\r\n >\r\n <X size={14} />\r\n </button>\r\n </div>\r\n <div className=\"cb-popover-body\">\r\n <input\r\n type=\"url\"\r\n value={linkUrl}\r\n onChange={(e) => setLinkUrl(e.target.value)}\r\n placeholder=\"https://example.com\"\r\n className=\"cb-popover-input\"\r\n autoFocus\r\n onKeyDown={(e) => {\r\n if (e.key === 'Enter') handleInsertLink();\r\n if (e.key === 'Escape') setActivePopover(null);\r\n }}\r\n />\r\n <input\r\n type=\"text\"\r\n value={linkText}\r\n onChange={(e) => setLinkText(e.target.value)}\r\n placeholder=\"Link text (optional)\"\r\n className=\"cb-popover-input\"\r\n onKeyDown={(e) => {\r\n if (e.key === 'Enter') handleInsertLink();\r\n if (e.key === 'Escape') setActivePopover(null);\r\n }}\r\n />\r\n <button\r\n type=\"button\"\r\n className=\"cb-popover-btn-primary\"\r\n onClick={handleInsertLink}\r\n disabled={!linkUrl}\r\n >\r\n Insert Link\r\n </button>\r\n </div>\r\n </div>\r\n )}\r\n\r\n {/* Highlight Color Popover */}\r\n {activePopover === 'highlight' && (\r\n <div className=\"cb-popover-content cb-color-popover\">\r\n <div className=\"cb-popover-header\">\r\n <span>Highlight Color</span>\r\n <button \r\n type=\"button\" \r\n className=\"cb-popover-close\"\r\n onClick={() => setActivePopover(null)}\r\n >\r\n <X size={14} />\r\n </button>\r\n </div>\r\n <div className=\"cb-color-grid\">\r\n {highlightColors.map(({ color, label }) => (\r\n <button\r\n key={color}\r\n type=\"button\"\r\n className=\"cb-color-swatch\"\r\n style={{ \r\n backgroundColor: color === 'transparent' ? '#fff' : color,\r\n border: color === 'transparent' ? '2px dashed #ccc' : undefined,\r\n }}\r\n onClick={() => handleHighlight(color)}\r\n title={label}\r\n >\r\n {color === 'transparent' && <X size={12} />}\r\n </button>\r\n ))}\r\n </div>\r\n </div>\r\n )}\r\n\r\n {/* Text Color Popover */}\r\n {activePopover === 'textColor' && (\r\n <div className=\"cb-popover-content cb-color-popover\">\r\n <div className=\"cb-popover-header\">\r\n <span>Text Color</span>\r\n <button \r\n type=\"button\" \r\n className=\"cb-popover-close\"\r\n onClick={() => setActivePopover(null)}\r\n >\r\n <X size={14} />\r\n </button>\r\n </div>\r\n <div className=\"cb-color-grid\">\r\n {textColors.map(({ color, label }) => (\r\n <button\r\n key={color}\r\n type=\"button\"\r\n className=\"cb-color-swatch\"\r\n style={{ backgroundColor: color }}\r\n onClick={() => handleTextColor(color)}\r\n title={label}\r\n />\r\n ))}\r\n </div>\r\n </div>\r\n )}\r\n </div>\r\n )}\r\n </div>\r\n );\r\n};\r\n","/**\r\n * Block Menu Component - Slash command menu for inserting blocks\r\n */\r\n\r\nimport React, { useState, useEffect, useRef, useCallback } from 'react';\r\nimport type { BlockMenuProps, BlockType } from '../core/types';\r\nimport {\r\n Type,\r\n Heading1,\r\n Heading2,\r\n Heading3,\r\n List,\r\n ListOrdered,\r\n CheckSquare,\r\n Quote,\r\n Code,\r\n Image,\r\n Video,\r\n Minus,\r\n AlertCircle,\r\n ChevronDown,\r\n Table,\r\n type LucideIcon,\r\n} from 'lucide-react';\r\n\r\ninterface BlockMenuItem {\r\n type: BlockType;\r\n label: string;\r\n description: string;\r\n icon: LucideIcon;\r\n keywords: string[];\r\n data?: Record<string, any>; // Additional data to pass when creating block\r\n}\r\n\r\nconst BLOCK_MENU_ITEMS: BlockMenuItem[] = [\r\n {\r\n type: 'paragraph',\r\n label: 'Paragraph',\r\n description: 'Plain text paragraph',\r\n icon: Type,\r\n keywords: ['text', 'paragraph', 'p'],\r\n },\r\n {\r\n type: 'heading',\r\n label: 'Heading 1',\r\n description: 'Large section heading',\r\n icon: Heading1,\r\n keywords: ['h1', 'heading', 'title', 'header'],\r\n data: { level: 1 },\r\n },\r\n {\r\n type: 'heading',\r\n label: 'Heading 2',\r\n description: 'Medium section heading',\r\n icon: Heading2,\r\n keywords: ['h2', 'heading', 'subtitle'],\r\n data: { level: 2 },\r\n },\r\n {\r\n type: 'heading',\r\n label: 'Heading 3',\r\n description: 'Small section heading',\r\n icon: Heading3,\r\n keywords: ['h3', 'heading'],\r\n data: { level: 3 },\r\n },\r\n {\r\n type: 'bulletList',\r\n label: 'Bullet List',\r\n description: 'Create a bulleted list',\r\n icon: List,\r\n keywords: ['bullet', 'list', 'ul', 'unordered'],\r\n },\r\n {\r\n type: 'numberedList',\r\n label: 'Numbered List',\r\n description: 'Create a numbered list',\r\n icon: ListOrdered,\r\n keywords: ['number', 'list', 'ol', 'ordered'],\r\n },\r\n {\r\n type: 'checkList',\r\n label: 'Checklist',\r\n description: 'Track tasks with checkboxes',\r\n icon: CheckSquare,\r\n keywords: ['check', 'todo', 'task', 'checkbox'],\r\n },\r\n {\r\n type: 'quote',\r\n label: 'Quote',\r\n description: 'Capture a quote',\r\n icon: Quote,\r\n keywords: ['quote', 'blockquote', 'citation'],\r\n },\r\n {\r\n type: 'code',\r\n label: 'Code Block',\r\n description: 'Display code with syntax highlighting',\r\n icon: Code,\r\n keywords: ['code', 'pre', 'syntax', 'programming'],\r\n },\r\n {\r\n type: 'image',\r\n label: 'Image',\r\n description: 'Upload or embed an image',\r\n icon: Image,\r\n keywords: ['image', 'picture', 'photo', 'img'],\r\n },\r\n {\r\n type: 'video',\r\n label: 'Video',\r\n description: 'Embed a video from YouTube, Vimeo, etc.',\r\n icon: Video,\r\n keywords: ['video', 'youtube', 'vimeo', 'embed'],\r\n },\r\n {\r\n type: 'divider',\r\n label: 'Divider',\r\n description: 'Visual separator between sections',\r\n icon: Minus,\r\n keywords: ['divider', 'hr', 'line', 'separator'],\r\n },\r\n {\r\n type: 'callout',\r\n label: 'Callout',\r\n description: 'Highlight important information',\r\n icon: AlertCircle,\r\n keywords: ['callout', 'alert', 'info', 'warning', 'note'],\r\n },\r\n {\r\n type: 'accordion',\r\n label: 'Accordion',\r\n description: 'Collapsible content section',\r\n icon: ChevronDown,\r\n keywords: ['accordion', 'collapse', 'toggle', 'details'],\r\n },\r\n {\r\n type: 'table',\r\n label: 'Table',\r\n description: 'Add a table',\r\n icon: Table,\r\n keywords: ['table', 'grid', 'rows', 'columns'],\r\n },\r\n];\r\n\r\nexport const BlockMenu: React.FC<BlockMenuProps> = ({\r\n editor,\r\n position,\r\n onSelect,\r\n onClose,\r\n}) => {\r\n const [search, setSearch] = useState('');\r\n const [selectedIndex, setSelectedIndex] = useState(0);\r\n const menuRef = useRef<HTMLDivElement>(null);\r\n const inputRef = useRef<HTMLInputElement>(null);\r\n\r\n // Filter items based on search\r\n const filteredItems = BLOCK_MENU_ITEMS.filter((item) => {\r\n if (!search) return true;\r\n const searchLower = search.toLowerCase();\r\n return (\r\n item.label.toLowerCase().includes(searchLower) ||\r\n item.description.toLowerCase().includes(searchLower) ||\r\n item.keywords.some((k) => k.includes(searchLower))\r\n );\r\n });\r\n\r\n // Reset selection when filter changes\r\n useEffect(() => {\r\n setSelectedIndex(0);\r\n }, [search]);\r\n\r\n // Focus input on mount\r\n useEffect(() => {\r\n inputRef.current?.focus();\r\n }, []);\r\n\r\n // Handle click outside\r\n useEffect(() => {\r\n const handleClickOutside = (e: MouseEvent) => {\r\n if (menuRef.current && !menuRef.current.contains(e.target as Node)) {\r\n onClose();\r\n }\r\n };\r\n\r\n document.addEventListener('mousedown', handleClickOutside);\r\n return () => document.removeEventListener('mousedown', handleClickOutside);\r\n }, [onClose]);\r\n\r\n // Handle keyboard navigation\r\n const handleKeyDown = useCallback(\r\n (e: React.KeyboardEvent) => {\r\n switch (e.key) {\r\n case 'ArrowDown':\r\n e.preventDefault();\r\n setSelectedIndex((prev) =>\r\n prev < filteredItems.length - 1 ? prev + 1 : 0\r\n );\r\n break;\r\n case 'ArrowUp':\r\n e.preventDefault();\r\n setSelectedIndex((prev) =>\r\n prev > 0 ? prev - 1 : filteredItems.length - 1\r\n );\r\n break;\r\n case 'Enter':\r\n e.preventDefault();\r\n if (filteredItems[selectedIndex]) {\r\n const item = filteredItems[selectedIndex];\r\n onSelect(item.type, item.data);\r\n }\r\n break;\r\n case 'Escape':\r\n e.preventDefault();\r\n onClose();\r\n break;\r\n }\r\n },\r\n [filteredItems, selectedIndex, onSelect, onClose]\r\n );\r\n\r\n // Calculate position (ensure menu stays in viewport)\r\n const style: React.CSSProperties = {\r\n position: 'fixed',\r\n left: Math.min(position.x, window.innerWidth - 320),\r\n top: Math.min(position.y, window.innerHeight - 400),\r\n zIndex: 1000,\r\n };\r\n\r\n return (\r\n <div\r\n ref={menuRef}\r\n className=\"cb-block-menu\"\r\n style={style}\r\n role=\"listbox\"\r\n aria-label=\"Insert block\"\r\n >\r\n <div className=\"cb-block-menu-search\">\r\n <input\r\n ref={inputRef}\r\n type=\"text\"\r\n value={search}\r\n onChange={(e) => setSearch(e.target.value)}\r\n onKeyDown={handleKeyDown}\r\n placeholder=\"Search blocks...\"\r\n className=\"cb-block-menu-input\"\r\n aria-label=\"Search blocks\"\r\n />\r\n </div>\r\n\r\n <div className=\"cb-block-menu-list\">\r\n {filteredItems.length === 0 ? (\r\n <div className=\"cb-block-menu-empty\">No matching blocks</div>\r\n ) : (\r\n filteredItems.map((item, index) => (\r\n <button\r\n key={`${item.type}-${item.label}`}\r\n type=\"button\"\r\n className={`cb-block-menu-item ${\r\n index === selectedIndex ? 'cb-block-menu-item-selected' : ''\r\n }`}\r\n onClick={() => onSelect(item.type, item.data)}\r\n onMouseEnter={() => setSelectedIndex(index)}\r\n role=\"option\"\r\n aria-selected={index === selectedIndex}\r\n >\r\n <div className=\"cb-block-menu-item-icon\">\r\n <item.icon size={20} />\r\n </div>\r\n <div className=\"cb-block-menu-item-content\">\r\n <span className=\"cb-block-menu-item-label\">{item.label}</span>\r\n <span className=\"cb-block-menu-item-description\">\r\n {item.description}\r\n </span>\r\n </div>\r\n </button>\r\n ))\r\n )}\r\n </div>\r\n\r\n <div className=\"cb-block-menu-footer\">\r\n <span>↑↓ Navigate</span>\r\n <span>↵ Select</span>\r\n <span>Esc Close</span>\r\n </div>\r\n </div>\r\n );\r\n};\r\n","/**\r\n * ContentBlocksEditor - Main React Component\r\n * Complete rewrite with proper block handling\r\n */\r\n\r\nimport React, {\r\n useRef,\r\n useEffect,\r\n useState,\r\n useCallback,\r\n useImperativeHandle,\r\n forwardRef,\r\n useMemo,\r\n} from 'react';\r\nimport type {\r\n ContentBlocksEditorProps,\r\n EditorInstance,\r\n BlockType,\r\n BlockData,\r\n EditorState,\r\n InlineFormat,\r\n} from '../core/types';\r\nimport { blockRegistry } from '../core/block-registry';\r\nimport { allBlocks } from '../blocks';\r\nimport { sanitizePaste } from '../paste/sanitize';\r\nimport { initDragDrop, createDragHandle } from '../drag/drag-handle';\r\nimport {\r\n isCursorAtStart,\r\n isCursorAtEnd,\r\n moveCursorToEnd,\r\n moveCursorToStart,\r\n getSelectionState,\r\n} from '../core/selection';\r\nimport {\r\n generateId,\r\n debounce,\r\n countWords,\r\n countCharacters,\r\n getBlockFromChild,\r\n} from '../utils/helpers';\r\nimport { Toolbar } from './Toolbar';\r\nimport { BlockMenu } from './BlockMenu';\r\nimport { GripVertical, Plus, Trash2, ChevronUp, ChevronDown } from 'lucide-react';\r\nimport { addTableRow, addTableColumn, deleteTableRow, deleteTableColumn, getFocusedCell, getCellPosition } from '../blocks/table';\r\nimport { setImageSrc, createImageFromFile, setImageAlign, createCropModal } from '../blocks/image';\r\nimport { setVideoSrc } from '../blocks/video';\r\nimport { setCalloutType } from '../blocks/callout';\r\n\r\nexport interface EditorRef {\r\n getHTML: () => string;\r\n setHTML: (html: string) => void;\r\n getText: () => string;\r\n focus: () => void;\r\n blur: () => void;\r\n insertBlock: (type: BlockType, data?: Partial<BlockData>) => HTMLElement | null;\r\n getEditor: () => EditorInstance | null;\r\n}\r\n\r\nconst ContentBlocksEditorInner: React.ForwardRefRenderFunction<\r\n EditorRef,\r\n ContentBlocksEditorProps\r\n> = (props, ref) => {\r\n const {\r\n initialContent = '',\r\n blocks: enabledBlocks,\r\n placeholder = 'Type \"/\" for commands...',\r\n readOnly = false,\r\n classPrefix = 'cb',\r\n className = '',\r\n style,\r\n showToolbar = true,\r\n toolbarPosition = 'top',\r\n darkMode = false,\r\n autoFocus = false,\r\n spellCheck = true,\r\n onChange,\r\n onSave,\r\n onFocus,\r\n onBlur,\r\n onReady,\r\n } = props;\r\n\r\n const containerRef = useRef<HTMLDivElement>(null);\r\n const contentRef = useRef<HTMLDivElement>(null);\r\n const initialContentLoadedRef = useRef(false); // Track if initial content was loaded\r\n const undoStackRef = useRef<string[]>([]); // Ref for undo stack to avoid stale closures\r\n const redoStackRef = useRef<string[]>([]); // Ref for redo stack to avoid stale closures\r\n const [isMounted, setIsMounted] = useState(false); // Track mount state for toolbar\r\n const [activeBlockId, setActiveBlockId] = useState<string | null>(null);\r\n const [showBlockMenu, setShowBlockMenu] = useState(false);\r\n const [blockMenuPosition, setBlockMenuPosition] = useState({ x: 0, y: 0 });\r\n const [hoveredBlockId, setHoveredBlockId] = useState<string | null>(null);\r\n const [selectionVersion, setSelectionVersion] = useState(0); // Force toolbar update on selection change\r\n const [editorState, setEditorState] = useState<EditorState>({\r\n blocks: [],\r\n activeBlock: null,\r\n selection: null,\r\n undoStack: [],\r\n redoStack: [],\r\n wordCount: 0,\r\n charCount: 0,\r\n isDirty: false,\r\n });\r\n\r\n // Register all blocks on mount\r\n useEffect(() => {\r\n allBlocks.forEach(block => {\r\n blockRegistry.register(block);\r\n });\r\n }, []);\r\n\r\n // Set mounted state after initial render to enable toolbar\r\n useEffect(() => {\r\n setIsMounted(true);\r\n }, []);\r\n\r\n // Track selection changes to update toolbar active states\r\n useEffect(() => {\r\n const handleSelectionChange = () => {\r\n // Only update if selection is within our editor\r\n const selection = window.getSelection();\r\n if (selection && contentRef.current?.contains(selection.anchorNode)) {\r\n setSelectionVersion(v => v + 1);\r\n }\r\n };\r\n\r\n document.addEventListener('selectionchange', handleSelectionChange);\r\n return () => document.removeEventListener('selectionchange', handleSelectionChange);\r\n }, []);\r\n\r\n // Create a block element with controls\r\n const createBlockWithControls = useCallback((type: BlockType, data?: Partial<BlockData>): HTMLElement => {\r\n const blockId = data?.id || generateId();\r\n \r\n // Create wrapper\r\n const wrapper = document.createElement('div');\r\n wrapper.className = 'cb-block';\r\n wrapper.setAttribute('data-block-id', blockId);\r\n wrapper.setAttribute('data-block-type', type);\r\n\r\n // Create controls container\r\n const controls = document.createElement('div');\r\n controls.className = 'cb-block-controls';\r\n controls.innerHTML = `\r\n <button type=\"button\" class=\"cb-block-btn cb-block-add\" data-action=\"add\" title=\"Add block below\">\r\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\">\r\n <path d=\"M12 5v14M5 12h14\"/>\r\n </svg>\r\n </button>\r\n <button type=\"button\" class=\"cb-block-btn cb-block-drag\" data-drag-handle title=\"Drag to reorder\">\r\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"currentColor\">\r\n <circle cx=\"9\" cy=\"5\" r=\"1.5\"/><circle cx=\"15\" cy=\"5\" r=\"1.5\"/>\r\n <circle cx=\"9\" cy=\"12\" r=\"1.5\"/><circle cx=\"15\" cy=\"12\" r=\"1.5\"/>\r\n <circle cx=\"9\" cy=\"19\" r=\"1.5\"/><circle cx=\"15\" cy=\"19\" r=\"1.5\"/>\r\n </svg>\r\n </button>\r\n `;\r\n\r\n // Create actions container (right side)\r\n const actions = document.createElement('div');\r\n actions.className = 'cb-block-actions';\r\n actions.innerHTML = `\r\n <button type=\"button\" class=\"cb-block-btn\" data-action=\"moveup\" title=\"Move up\">\r\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\">\r\n <path d=\"m18 15-6-6-6 6\"/>\r\n </svg>\r\n </button>\r\n <button type=\"button\" class=\"cb-block-btn\" data-action=\"movedown\" title=\"Move down\">\r\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\">\r\n <path d=\"m6 9 6 6 6-6\"/>\r\n </svg>\r\n </button>\r\n <button type=\"button\" class=\"cb-block-btn cb-block-delete\" data-action=\"delete\" title=\"Delete block\">\r\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\">\r\n <path d=\"M3 6h18M19 6v14a2 2 0 01-2 2H7a2 2 0 01-2-2V6m3 0V4a2 2 0 012-2h4a2 2 0 012 2v2\"/>\r\n </svg>\r\n </button>\r\n `;\r\n\r\n // Create content wrapper\r\n const content = document.createElement('div');\r\n content.className = 'cb-block-content';\r\n\r\n // Create the actual block content\r\n const blockElement = blockRegistry.createBlock(type, { ...data, id: blockId } as BlockData);\r\n if (blockElement) {\r\n // Remove data attributes from inner element (they're on wrapper now)\r\n blockElement.removeAttribute('data-block-id');\r\n blockElement.removeAttribute('data-block-type');\r\n content.appendChild(blockElement);\r\n }\r\n\r\n wrapper.appendChild(controls);\r\n wrapper.appendChild(content);\r\n wrapper.appendChild(actions);\r\n\r\n return wrapper;\r\n }, []);\r\n\r\n // Initialize editor content (only on first mount, not on initialContent changes)\r\n useEffect(() => {\r\n if (!contentRef.current || initialContentLoadedRef.current) return;\r\n initialContentLoadedRef.current = true;\r\n \r\n contentRef.current.innerHTML = '';\r\n\r\n if (initialContent && initialContent.trim()) {\r\n // Parse HTML and create blocks\r\n const tempDiv = document.createElement('div');\r\n tempDiv.innerHTML = initialContent;\r\n\r\n Array.from(tempDiv.children).forEach(child => {\r\n if (child instanceof HTMLElement) {\r\n const blockType = detectBlockType(child);\r\n const blockData = extractBlockData(child, blockType);\r\n const block = createBlockWithControls(blockType, blockData);\r\n contentRef.current?.appendChild(block);\r\n }\r\n });\r\n }\r\n\r\n // Ensure at least one paragraph exists\r\n if (contentRef.current.children.length === 0) {\r\n const block = createBlockWithControls('paragraph');\r\n contentRef.current.appendChild(block);\r\n }\r\n\r\n updateState();\r\n \r\n // Initialize drag and drop\r\n if (!readOnly && contentRef.current) {\r\n initDragDrop({\r\n container: contentRef.current,\r\n handleSelector: '[data-drag-handle]',\r\n onDragEnd: () => {\r\n updateState();\r\n emitChange();\r\n },\r\n });\r\n }\r\n }, [readOnly]);\r\n\r\n // Auto focus\r\n useEffect(() => {\r\n if (autoFocus && contentRef.current) {\r\n setTimeout(() => {\r\n const firstEditable = contentRef.current?.querySelector('[contenteditable=\"true\"]');\r\n if (firstEditable instanceof HTMLElement) {\r\n firstEditable.focus();\r\n }\r\n }, 100);\r\n }\r\n }, [autoFocus]);\r\n\r\n // Detect block type from HTML element\r\n const detectBlockType = (element: HTMLElement): BlockType => {\r\n const tag = element.tagName.toLowerCase();\r\n const className = element.className || '';\r\n \r\n switch (tag) {\r\n case 'h1': return 'heading';\r\n case 'h2': return 'heading';\r\n case 'h3': return 'heading';\r\n case 'h4': return 'heading';\r\n case 'h5': return 'heading';\r\n case 'h6': return 'heading';\r\n case 'ul':\r\n if (className.includes('checklist') || element.querySelector('input[type=\"checkbox\"]')) {\r\n return 'checkList';\r\n }\r\n return 'bulletList';\r\n case 'ol': return 'numberedList';\r\n case 'blockquote': return 'quote';\r\n case 'pre': return 'code';\r\n case 'figure':\r\n if (element.querySelector('img')) return 'image';\r\n if (element.querySelector('video, iframe')) return 'video';\r\n return 'paragraph';\r\n case 'hr': return 'divider';\r\n case 'table': return 'table';\r\n case 'aside': return 'callout';\r\n case 'details': return 'accordion';\r\n case 'div':\r\n if (className.includes('code')) return 'code';\r\n if (className.includes('callout')) return 'callout';\r\n if (className.includes('divider')) return 'divider';\r\n if (className.includes('table')) return 'table';\r\n return 'paragraph';\r\n default:\r\n return 'paragraph';\r\n }\r\n };\r\n\r\n // Extract block data from HTML element\r\n const extractBlockData = (element: HTMLElement, type: BlockType): Partial<BlockData> => {\r\n const data: any = { type };\r\n \r\n switch (type) {\r\n case 'heading':\r\n const level = parseInt(element.tagName.charAt(1)) || 2;\r\n data.level = level;\r\n data.content = element.innerHTML;\r\n break;\r\n case 'paragraph':\r\n data.content = element.innerHTML;\r\n break;\r\n case 'bulletList':\r\n case 'numberedList':\r\n case 'checkList':\r\n const items: any[] = [];\r\n element.querySelectorAll(':scope > li').forEach(li => {\r\n items.push({\r\n id: generateId(),\r\n content: li.innerHTML,\r\n checked: li.querySelector('input[type=\"checkbox\"]')?.hasAttribute('checked'),\r\n });\r\n });\r\n data.items = items;\r\n break;\r\n case 'quote':\r\n data.content = element.innerHTML;\r\n break;\r\n case 'code':\r\n const code = element.querySelector('code') || element;\r\n data.content = code.textContent || '';\r\n data.language = element.getAttribute('data-language') || 'plaintext';\r\n break;\r\n case 'image':\r\n const img = element.querySelector('img');\r\n data.src = img?.src || '';\r\n data.alt = img?.alt || '';\r\n data.caption = element.querySelector('figcaption')?.textContent || '';\r\n break;\r\n case 'divider':\r\n data.style = 'solid';\r\n break;\r\n case 'callout':\r\n data.calloutType = element.getAttribute('data-callout-type') || 'info';\r\n data.content = element.querySelector('.cb-callout-body')?.innerHTML || element.innerHTML;\r\n break;\r\n case 'accordion':\r\n data.title = element.querySelector('summary')?.textContent || '';\r\n data.content = element.querySelector('.cb-accordion-content')?.innerHTML || '';\r\n data.open = (element as HTMLDetailsElement).open;\r\n break;\r\n case 'table':\r\n // Parse table structure\r\n const rows: any[] = [];\r\n element.querySelectorAll('tr').forEach(tr => {\r\n const cells: any[] = [];\r\n tr.querySelectorAll('th, td').forEach(cell => {\r\n cells.push({ content: cell.innerHTML });\r\n });\r\n rows.push({ cells });\r\n });\r\n data.rows = rows;\r\n break;\r\n }\r\n \r\n return data;\r\n };\r\n\r\n // Get clean HTML output (no editor artifacts)\r\n const getHTML = useCallback((): string => {\r\n if (!contentRef.current) return '';\r\n \r\n let html = '';\r\n \r\n contentRef.current.querySelectorAll('.cb-block').forEach(wrapper => {\r\n const type = wrapper.getAttribute('data-block-type') as BlockType;\r\n const content = wrapper.querySelector('.cb-block-content');\r\n \r\n if (!content) return;\r\n \r\n // Get the actual content element\r\n const blockElement = content.firstElementChild as HTMLElement;\r\n if (!blockElement) return;\r\n \r\n // Clone and clean\r\n const clone = blockElement.cloneNode(true) as HTMLElement;\r\n \r\n // Remove editor-specific attributes and elements\r\n clone.removeAttribute('data-placeholder');\r\n clone.removeAttribute('contenteditable');\r\n clone.querySelectorAll('[data-placeholder]').forEach(el => el.removeAttribute('data-placeholder'));\r\n clone.querySelectorAll('[contenteditable]').forEach(el => el.removeAttribute('contenteditable'));\r\n clone.querySelectorAll('.cb-code-toolbar, .cb-image-controls, .cb-table-controls, .cb-callout-type-selector').forEach(el => el.remove());\r\n \r\n // Special handling for different block types\r\n switch (type) {\r\n case 'code':\r\n const codeEl = clone.querySelector('code');\r\n const preEl = clone.querySelector('pre');\r\n if (codeEl && preEl) {\r\n const lang = clone.getAttribute('data-language') || 'plaintext';\r\n html += `<pre data-language=\"${lang}\"><code>${codeEl.textContent}</code></pre>\\n`;\r\n } else {\r\n html += clone.outerHTML + '\\n';\r\n }\r\n break;\r\n case 'divider':\r\n html += '<hr>\\n';\r\n break;\r\n default:\r\n html += clone.outerHTML + '\\n';\r\n }\r\n });\r\n \r\n return html.trim();\r\n }, []);\r\n\r\n // Set HTML content\r\n const setHTML = useCallback((html: string, restoreFocus: boolean = false): void => {\r\n if (!contentRef.current) return;\r\n contentRef.current.innerHTML = '';\r\n \r\n const tempDiv = document.createElement('div');\r\n tempDiv.innerHTML = html;\r\n\r\n Array.from(tempDiv.children).forEach(child => {\r\n if (child instanceof HTMLElement) {\r\n const blockType = detectBlockType(child);\r\n const blockData = extractBlockData(child, blockType);\r\n const block = createBlockWithControls(blockType, blockData);\r\n contentRef.current?.appendChild(block);\r\n }\r\n });\r\n\r\n if (contentRef.current.children.length === 0) {\r\n const block = createBlockWithControls('paragraph');\r\n contentRef.current.appendChild(block);\r\n }\r\n\r\n // Restore focus to first editable element if requested\r\n if (restoreFocus) {\r\n setTimeout(() => {\r\n const firstEditable = contentRef.current?.querySelector('[contenteditable=\"true\"]');\r\n if (firstEditable instanceof HTMLElement) {\r\n firstEditable.focus();\r\n }\r\n }, 0);\r\n }\r\n }, [createBlockWithControls]);\r\n\r\n const getText = useCallback((): string => {\r\n return contentRef.current?.textContent || '';\r\n }, []);\r\n\r\n const focus = useCallback((): void => {\r\n const firstEditable = contentRef.current?.querySelector('[contenteditable=\"true\"]');\r\n if (firstEditable instanceof HTMLElement) {\r\n firstEditable.focus();\r\n }\r\n }, []);\r\n\r\n const blur = useCallback((): void => {\r\n if (document.activeElement instanceof HTMLElement) {\r\n document.activeElement.blur();\r\n }\r\n }, []);\r\n\r\n const updateState = useCallback(() => {\r\n if (!contentRef.current) return;\r\n\r\n const text = contentRef.current.textContent || '';\r\n\r\n setEditorState(prev => ({\r\n ...prev,\r\n wordCount: countWords(text),\r\n charCount: countCharacters(text),\r\n }));\r\n }, []);\r\n\r\n const emitChange = useCallback(\r\n debounce(() => {\r\n if (onChange) {\r\n onChange(getHTML());\r\n }\r\n }, 300),\r\n [onChange, getHTML]\r\n );\r\n\r\n const saveToHistory = useCallback(() => {\r\n const currentHTML = getHTML();\r\n undoStackRef.current = [...undoStackRef.current.slice(-49), currentHTML];\r\n redoStackRef.current = [];\r\n setEditorState(prev => ({\r\n ...prev,\r\n undoStack: undoStackRef.current,\r\n redoStack: [],\r\n isDirty: true,\r\n }));\r\n }, [getHTML]);\r\n\r\n const handleUndo = useCallback(() => {\r\n if (undoStackRef.current.length === 0) return;\r\n\r\n const current = getHTML();\r\n const previous = undoStackRef.current[undoStackRef.current.length - 1];\r\n\r\n undoStackRef.current = undoStackRef.current.slice(0, -1);\r\n redoStackRef.current = [...redoStackRef.current, current];\r\n\r\n setEditorState(prev => ({\r\n ...prev,\r\n undoStack: undoStackRef.current,\r\n redoStack: redoStackRef.current,\r\n }));\r\n\r\n setHTML(previous, true); // true = restore focus\r\n }, [getHTML, setHTML]);\r\n\r\n const handleRedo = useCallback(() => {\r\n if (redoStackRef.current.length === 0) return;\r\n\r\n const current = getHTML();\r\n const next = redoStackRef.current[redoStackRef.current.length - 1];\r\n\r\n redoStackRef.current = redoStackRef.current.slice(0, -1);\r\n undoStackRef.current = [...undoStackRef.current, current];\r\n\r\n setEditorState(prev => ({\r\n ...prev,\r\n redoStack: redoStackRef.current,\r\n undoStack: undoStackRef.current,\r\n }));\r\n\r\n setHTML(next, true); // true = restore focus\r\n }, [getHTML, setHTML]);\r\n\r\n // Insert a new block\r\n const insertBlockAfter = useCallback((type: BlockType, afterBlockId?: string, data?: Partial<BlockData>): HTMLElement | null => {\r\n if (!contentRef.current) return null;\r\n \r\n saveToHistory();\r\n \r\n const newBlock = createBlockWithControls(type, data);\r\n \r\n if (afterBlockId) {\r\n const afterBlock = contentRef.current.querySelector(`[data-block-id=\"${afterBlockId}\"]`);\r\n if (afterBlock) {\r\n afterBlock.after(newBlock);\r\n } else {\r\n contentRef.current.appendChild(newBlock);\r\n }\r\n } else {\r\n contentRef.current.appendChild(newBlock);\r\n }\r\n \r\n // Focus the new block\r\n setTimeout(() => {\r\n // For code blocks, the contenteditable is nested deeper\r\n const codeEditable = newBlock.querySelector('.cb-code[contenteditable=\"true\"]');\r\n const editable = codeEditable || newBlock.querySelector('[contenteditable=\"true\"]');\r\n if (editable instanceof HTMLElement) {\r\n editable.focus();\r\n moveCursorToStart(editable);\r\n }\r\n }, 50);\r\n \r\n updateState();\r\n emitChange();\r\n \r\n return newBlock;\r\n }, [createBlockWithControls, saveToHistory, updateState, emitChange]);\r\n\r\n // Delete a block\r\n const deleteBlockById = useCallback((blockId: string): void => {\r\n if (!contentRef.current) return;\r\n \r\n const blocks = contentRef.current.querySelectorAll('.cb-block');\r\n if (blocks.length <= 1) {\r\n // Don't delete last block, just clear it\r\n const content = blocks[0]?.querySelector('[contenteditable=\"true\"]');\r\n if (content instanceof HTMLElement) {\r\n content.innerHTML = '';\r\n content.focus();\r\n }\r\n return;\r\n }\r\n \r\n saveToHistory();\r\n \r\n const block = contentRef.current.querySelector(`[data-block-id=\"${blockId}\"]`);\r\n if (!block) return;\r\n \r\n const prevBlock = block.previousElementSibling as HTMLElement;\r\n const nextBlock = block.nextElementSibling as HTMLElement;\r\n \r\n block.remove();\r\n \r\n // Focus adjacent block\r\n const targetBlock = nextBlock || prevBlock;\r\n if (targetBlock) {\r\n const editable = targetBlock.querySelector('[contenteditable=\"true\"]');\r\n if (editable instanceof HTMLElement) {\r\n editable.focus();\r\n if (!nextBlock) {\r\n moveCursorToEnd(editable);\r\n }\r\n }\r\n }\r\n \r\n updateState();\r\n emitChange();\r\n }, [saveToHistory, updateState, emitChange]);\r\n\r\n // Move block up/down\r\n const moveBlock = useCallback((blockId: string, direction: 'up' | 'down'): void => {\r\n if (!contentRef.current) return;\r\n \r\n const block = contentRef.current.querySelector(`[data-block-id=\"${blockId}\"]`);\r\n if (!block) return;\r\n \r\n saveToHistory();\r\n \r\n if (direction === 'up' && block.previousElementSibling) {\r\n block.previousElementSibling.before(block);\r\n } else if (direction === 'down' && block.nextElementSibling) {\r\n block.nextElementSibling.after(block);\r\n }\r\n \r\n updateState();\r\n emitChange();\r\n }, [saveToHistory, updateState, emitChange]);\r\n\r\n // Transform block to different type\r\n const transformBlockType = useCallback((blockId: string, newType: BlockType, data?: Record<string, any>): void => {\r\n if (!contentRef.current) return;\r\n \r\n const wrapper = contentRef.current.querySelector(`[data-block-id=\"${blockId}\"]`);\r\n if (!wrapper) return;\r\n \r\n const currentType = wrapper.getAttribute('data-block-type');\r\n if (currentType === newType && !data) return;\r\n \r\n saveToHistory();\r\n \r\n // Get current content\r\n const contentEl = wrapper.querySelector('[contenteditable=\"true\"]');\r\n const currentContent = contentEl?.innerHTML || '';\r\n \r\n // Create new block with same content where applicable\r\n const blockData = { content: currentContent, ...data } as any;\r\n const newBlock = createBlockWithControls(newType, blockData);\r\n \r\n // Replace old block\r\n wrapper.replaceWith(newBlock);\r\n \r\n // Focus new block\r\n setTimeout(() => {\r\n // For code blocks, the contenteditable is nested deeper\r\n const codeEditable = newBlock.querySelector('.cb-code[contenteditable=\"true\"]');\r\n const editable = codeEditable || newBlock.querySelector('[contenteditable=\"true\"]');\r\n if (editable instanceof HTMLElement) {\r\n editable.focus();\r\n moveCursorToStart(editable);\r\n }\r\n }, 50);\r\n \r\n updateState();\r\n emitChange();\r\n }, [createBlockWithControls, saveToHistory, updateState, emitChange]);\r\n\r\n // Store editorState in a ref to avoid re-creating instance on every state change\r\n const editorStateRef = useRef(editorState);\r\n editorStateRef.current = editorState;\r\n\r\n // Store activeBlockId in a ref to avoid re-creating instance\r\n const activeBlockIdRef = useRef(activeBlockId);\r\n activeBlockIdRef.current = activeBlockId;\r\n\r\n // Create stable editor instance that doesn't change on every keystroke\r\n const editorInstance = useMemo((): EditorInstance | null => {\r\n // Need isMounted to ensure refs are populated\r\n if (!isMounted || !containerRef.current || !contentRef.current) return null;\r\n\r\n return {\r\n container: contentRef.current,\r\n config: props,\r\n get state() { return editorStateRef.current; }, // Getter to always return current state\r\n getHTML,\r\n setHTML,\r\n getText,\r\n insertBlock: (type, data) => insertBlockAfter(type, activeBlockIdRef.current || undefined, data),\r\n deleteBlock: (block) => {\r\n const id = block.getAttribute('data-block-id');\r\n if (id) deleteBlockById(id);\r\n },\r\n moveBlock: (block, direction) => {\r\n const id = block.getAttribute('data-block-id');\r\n if (id) moveBlock(id, direction);\r\n },\r\n transformBlock: (block, newType, data) => {\r\n const id = block.getAttribute('data-block-id');\r\n if (id) transformBlockType(id, newType, data);\r\n return block;\r\n },\r\n toggleFormat: (format: InlineFormat) => {\r\n switch (format) {\r\n case 'bold': document.execCommand('bold'); break;\r\n case 'italic': document.execCommand('italic'); break;\r\n case 'underline': document.execCommand('underline'); break;\r\n case 'strikethrough': document.execCommand('strikeThrough'); break;\r\n }\r\n emitChange();\r\n },\r\n isFormatActive: (format: InlineFormat) => {\r\n switch (format) {\r\n case 'bold': return document.queryCommandState('bold');\r\n case 'italic': return document.queryCommandState('italic');\r\n case 'underline': return document.queryCommandState('underline');\r\n case 'strikethrough': return document.queryCommandState('strikeThrough');\r\n default: return false;\r\n }\r\n },\r\n selectionVersion, // Include to trigger toolbar re-render on selection change\r\n undo: handleUndo,\r\n redo: handleRedo,\r\n focus,\r\n blur,\r\n destroy: () => {},\r\n registerBlock: (def) => blockRegistry.register(def),\r\n registerCommand: () => {},\r\n executeCommand: () => {},\r\n };\r\n // Only recreate when truly necessary - not on editorState or activeBlockId changes\r\n // eslint-disable-next-line react-hooks/exhaustive-deps\r\n }, [isMounted, selectionVersion, props, getHTML, setHTML, getText, insertBlockAfter, deleteBlockById,\r\n moveBlock, transformBlockType, handleUndo, handleRedo, focus, blur, emitChange]);\r\n\r\n // Expose methods via ref\r\n useImperativeHandle(ref, () => ({\r\n getHTML,\r\n setHTML,\r\n getText,\r\n focus,\r\n blur,\r\n insertBlock: (type: BlockType, data?: Partial<BlockData>) =>\r\n insertBlockAfter(type, activeBlockIdRef.current || undefined, data),\r\n getEditor: () => editorInstance,\r\n }), [getHTML, setHTML, getText, focus, blur, insertBlockAfter, editorInstance]);\r\n\r\n // Notify ready\r\n useEffect(() => {\r\n if (onReady && editorInstance) {\r\n onReady(editorInstance);\r\n }\r\n }, [onReady, editorInstance]);\r\n\r\n // Handle image file upload\r\n const handleImageUpload = useCallback(async (e: Event) => {\r\n const input = e.target as HTMLInputElement;\r\n const file = input.files?.[0];\r\n if (!file) return;\r\n \r\n const figure = input.closest('figure.cb-image') as HTMLElement;\r\n if (!figure) return;\r\n \r\n saveToHistory();\r\n \r\n try {\r\n const dataUrl = await createImageFromFile(file);\r\n setImageSrc(figure, dataUrl, file.name);\r\n \r\n // Add alignment controls since we now have an image\r\n let controls = figure.querySelector('.cb-image-controls');\r\n if (!controls) {\r\n controls = document.createElement('div');\r\n controls.className = 'cb-image-controls';\r\n controls.innerHTML = `\r\n <button type=\"button\" class=\"cb-image-align\" data-align=\"left\" title=\"Align left\">\r\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\">\r\n <line x1=\"17\" x2=\"3\" y1=\"10\" y2=\"10\"/><line x1=\"21\" x2=\"3\" y1=\"6\" y2=\"6\"/><line x1=\"21\" x2=\"3\" y1=\"14\" y2=\"14\"/><line x1=\"17\" x2=\"3\" y1=\"18\" y2=\"18\"/>\r\n </svg>\r\n </button>\r\n <button type=\"button\" class=\"cb-image-align\" data-align=\"center\" title=\"Align center\">\r\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\">\r\n <line x1=\"18\" x2=\"6\" y1=\"10\" y2=\"10\"/><line x1=\"21\" x2=\"3\" y1=\"6\" y2=\"6\"/><line x1=\"21\" x2=\"3\" y1=\"14\" y2=\"14\"/><line x1=\"18\" x2=\"6\" y1=\"18\" y2=\"18\"/>\r\n </svg>\r\n </button>\r\n <button type=\"button\" class=\"cb-image-align\" data-align=\"right\" title=\"Align right\">\r\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\">\r\n <line x1=\"21\" x2=\"7\" y1=\"10\" y2=\"10\"/><line x1=\"21\" x2=\"3\" y1=\"6\" y2=\"6\"/><line x1=\"21\" x2=\"3\" y1=\"14\" y2=\"14\"/><line x1=\"21\" x2=\"7\" y1=\"18\" y2=\"18\"/>\r\n </svg>\r\n </button>\r\n <span class=\"cb-image-controls-divider\"></span>\r\n <button type=\"button\" class=\"cb-image-crop\" data-action=\"crop\" title=\"Crop image\">\r\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\">\r\n <path d=\"M6 2v14a2 2 0 0 0 2 2h14\"/><path d=\"M18 22V8a2 2 0 0 0-2-2H2\"/>\r\n </svg>\r\n </button>\r\n `;\r\n const caption = figure.querySelector('figcaption');\r\n if (caption) {\r\n figure.insertBefore(controls, caption);\r\n } else {\r\n figure.appendChild(controls);\r\n }\r\n }\r\n \r\n emitChange();\r\n } catch (err) {\r\n console.error('Failed to load image:', err);\r\n }\r\n }, [saveToHistory, emitChange]);\r\n\r\n // Set up image input listeners\r\n useEffect(() => {\r\n if (!contentRef.current) return;\r\n \r\n const handleImageInputChange = (e: Event) => {\r\n handleImageUpload(e);\r\n };\r\n \r\n const handleImageAlignClick = (e: MouseEvent) => {\r\n const button = (e.target as HTMLElement).closest('[data-align]') as HTMLElement;\r\n if (!button) return;\r\n \r\n const align = button.getAttribute('data-align') as 'left' | 'center' | 'right';\r\n const figure = button.closest('figure.cb-image') as HTMLElement;\r\n \r\n if (figure && align) {\r\n saveToHistory();\r\n setImageAlign(figure, align);\r\n emitChange();\r\n }\r\n };\r\n \r\n // Use event delegation for image inputs\r\n const container = contentRef.current;\r\n \r\n container.addEventListener('change', (e) => {\r\n if ((e.target as HTMLElement).matches('.cb-image-input')) {\r\n handleImageInputChange(e);\r\n }\r\n });\r\n \r\n container.addEventListener('click', (e) => {\r\n const target = e.target as HTMLElement;\r\n \r\n // Handle image alignment clicks\r\n if (target.closest('.cb-image-align')) {\r\n handleImageAlignClick(e as MouseEvent);\r\n }\r\n \r\n // Handle image crop button click\r\n if (target.closest('.cb-image-crop')) {\r\n e.preventDefault();\r\n e.stopPropagation();\r\n \r\n // Check if crop modal is already open\r\n if (document.querySelector('.cb-crop-modal')) {\r\n return;\r\n }\r\n \r\n const figure = target.closest('figure.cb-image') as HTMLElement;\r\n const img = figure?.querySelector('img') as HTMLImageElement;\r\n \r\n if (figure && img && img.src) {\r\n const modal = createCropModal(\r\n img.src,\r\n (croppedSrc) => {\r\n saveToHistory();\r\n img.src = croppedSrc;\r\n emitChange();\r\n },\r\n () => {} // onCancel - nothing needed\r\n );\r\n document.body.appendChild(modal);\r\n }\r\n }\r\n \r\n // Handle checkbox clicks in checklists\r\n if (target.classList.contains('cb-checkbox')) {\r\n const checkbox = target as HTMLInputElement;\r\n const li = checkbox.closest('.cb-list-item') as HTMLElement;\r\n if (li) {\r\n saveToHistory();\r\n // Toggle cb-checked class based on new checkbox state\r\n // Note: checkbox.checked is already updated by the browser at this point\r\n li.classList.toggle('cb-checked', checkbox.checked);\r\n emitChange();\r\n }\r\n }\r\n });\r\n \r\n // Handle video URL input\r\n container.addEventListener('keydown', (e) => {\r\n const target = e.target as HTMLElement;\r\n if (target.classList.contains('cb-video-url-input') && e.key === 'Enter') {\r\n e.preventDefault();\r\n const input = target as HTMLInputElement;\r\n const url = input.value.trim();\r\n if (url) {\r\n const figure = target.closest('figure.cb-video') as HTMLElement;\r\n if (figure) {\r\n saveToHistory();\r\n setVideoSrc(figure, url);\r\n emitChange();\r\n }\r\n }\r\n }\r\n \r\n // Handle image URL input\r\n if (target.classList.contains('cb-image-url-input') && e.key === 'Enter') {\r\n e.preventDefault();\r\n const input = target as HTMLInputElement;\r\n const url = input.value.trim();\r\n if (url) {\r\n const figure = target.closest('figure.cb-image') as HTMLElement;\r\n if (figure) {\r\n saveToHistory();\r\n setImageSrc(figure, url);\r\n \r\n // Add alignment controls\r\n let controls = figure.querySelector('.cb-image-controls');\r\n if (!controls) {\r\n controls = document.createElement('div');\r\n controls.className = 'cb-image-controls';\r\n controls.innerHTML = `\r\n <button type=\"button\" class=\"cb-image-align\" data-align=\"left\" title=\"Align left\">\r\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\">\r\n <line x1=\"17\" x2=\"3\" y1=\"10\" y2=\"10\"/><line x1=\"21\" x2=\"3\" y1=\"6\" y2=\"6\"/><line x1=\"21\" x2=\"3\" y1=\"14\" y2=\"14\"/><line x1=\"17\" x2=\"3\" y1=\"18\" y2=\"18\"/>\r\n </svg>\r\n </button>\r\n <button type=\"button\" class=\"cb-image-align\" data-align=\"center\" title=\"Align center\">\r\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\">\r\n <line x1=\"18\" x2=\"6\" y1=\"10\" y2=\"10\"/><line x1=\"21\" x2=\"3\" y1=\"6\" y2=\"6\"/><line x1=\"21\" x2=\"3\" y1=\"14\" y2=\"14\"/><line x1=\"18\" x2=\"6\" y1=\"18\" y2=\"18\"/>\r\n </svg>\r\n </button>\r\n <button type=\"button\" class=\"cb-image-align\" data-align=\"right\" title=\"Align right\">\r\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\">\r\n <line x1=\"21\" x2=\"7\" y1=\"10\" y2=\"10\"/><line x1=\"21\" x2=\"3\" y1=\"6\" y2=\"6\"/><line x1=\"21\" x2=\"3\" y1=\"14\" y2=\"14\"/><line x1=\"21\" x2=\"7\" y1=\"18\" y2=\"18\"/>\r\n </svg>\r\n </button>\r\n <span class=\"cb-image-controls-divider\"></span>\r\n <button type=\"button\" class=\"cb-image-crop\" data-action=\"crop\" title=\"Crop image\">\r\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\">\r\n <path d=\"M6 2v14a2 2 0 0 0 2 2h14\"/><path d=\"M18 22V8a2 2 0 0 0-2-2H2\"/>\r\n </svg>\r\n </button>\r\n `;\r\n const caption = figure.querySelector('figcaption');\r\n if (caption) {\r\n figure.insertBefore(controls, caption);\r\n } else {\r\n figure.appendChild(controls);\r\n }\r\n }\r\n \r\n emitChange();\r\n }\r\n }\r\n }\r\n });\r\n \r\n // Handle callout type selector clicks\r\n container.addEventListener('click', (e) => {\r\n const typeButton = (e.target as HTMLElement).closest('.cb-callout-type-selector button[data-type]') as HTMLElement;\r\n if (typeButton) {\r\n e.preventDefault();\r\n e.stopPropagation();\r\n const newType = typeButton.getAttribute('data-type') as 'info' | 'warning' | 'error' | 'success' | 'note';\r\n const callout = typeButton.closest('.cb-callout') as HTMLElement;\r\n if (callout && newType) {\r\n saveToHistory();\r\n setCalloutType(callout, newType);\r\n emitChange();\r\n }\r\n }\r\n });\r\n \r\n }, [handleImageUpload, saveToHistory, emitChange]);\r\n\r\n // Handle image resize\r\n useEffect(() => {\r\n if (!contentRef.current || readOnly) return;\r\n \r\n const container = contentRef.current;\r\n let isResizing = false;\r\n let startX = 0;\r\n let startWidth = 0;\r\n let currentImg: HTMLImageElement | null = null;\r\n let currentWrapper: HTMLElement | null = null;\r\n let handleType: string | null = null;\r\n \r\n const handleResizeStart = (e: MouseEvent) => {\r\n const handle = (e.target as HTMLElement).closest('.cb-image-resize-handle') as HTMLElement;\r\n if (!handle) return;\r\n \r\n e.preventDefault();\r\n e.stopPropagation();\r\n \r\n currentWrapper = handle.closest('.cb-image-resizable') as HTMLElement;\r\n currentImg = currentWrapper?.querySelector('img') as HTMLImageElement;\r\n handleType = handle.getAttribute('data-handle');\r\n \r\n if (!currentImg || !currentWrapper) return;\r\n \r\n isResizing = true;\r\n startX = e.clientX;\r\n startWidth = currentImg.offsetWidth;\r\n \r\n currentWrapper.classList.add('resizing');\r\n document.body.style.cursor = handle.style.cursor || 'se-resize';\r\n document.body.style.userSelect = 'none';\r\n \r\n saveToHistory();\r\n };\r\n \r\n const handleResizeMove = (e: MouseEvent) => {\r\n if (!isResizing || !currentImg || !handleType) return;\r\n \r\n e.preventDefault();\r\n \r\n const diff = e.clientX - startX;\r\n let newWidth: number;\r\n \r\n // Handle direction affects how we calculate width\r\n if (handleType === 'w' || handleType === 'sw' || handleType === 'nw') {\r\n newWidth = startWidth - diff;\r\n } else {\r\n newWidth = startWidth + diff;\r\n }\r\n \r\n // Constrain width between 50px and 100% of container\r\n const containerWidth = container.offsetWidth - 100; // Account for padding\r\n newWidth = Math.max(50, Math.min(newWidth, containerWidth));\r\n \r\n currentImg.style.width = `${newWidth}px`;\r\n currentImg.style.height = 'auto';\r\n };\r\n \r\n const handleResizeEnd = () => {\r\n if (!isResizing) return;\r\n \r\n isResizing = false;\r\n \r\n if (currentWrapper) {\r\n currentWrapper.classList.remove('resizing');\r\n }\r\n \r\n document.body.style.cursor = '';\r\n document.body.style.userSelect = '';\r\n \r\n currentImg = null;\r\n currentWrapper = null;\r\n handleType = null;\r\n \r\n emitChange();\r\n };\r\n \r\n container.addEventListener('mousedown', handleResizeStart);\r\n document.addEventListener('mousemove', handleResizeMove);\r\n document.addEventListener('mouseup', handleResizeEnd);\r\n \r\n return () => {\r\n container.removeEventListener('mousedown', handleResizeStart);\r\n document.removeEventListener('mousemove', handleResizeMove);\r\n document.removeEventListener('mouseup', handleResizeEnd);\r\n };\r\n }, [readOnly, saveToHistory, emitChange]);\r\n\r\n // Handle block control clicks\r\n const handleBlockControlClick = useCallback((e: React.MouseEvent) => {\r\n const target = e.target as HTMLElement;\r\n const button = target.closest('[data-action]') as HTMLElement;\r\n if (!button) return;\r\n \r\n const action = button.getAttribute('data-action');\r\n const block = button.closest('.cb-block') as HTMLElement;\r\n const blockId = block?.getAttribute('data-block-id');\r\n \r\n if (!blockId && !action?.startsWith('add') && !action?.startsWith('delete')) return;\r\n \r\n e.preventDefault();\r\n e.stopPropagation();\r\n \r\n switch (action) {\r\n case 'add':\r\n if (blockId) {\r\n // Insert a new paragraph block after current block\r\n saveToHistory();\r\n const newBlock = createBlockWithControls('paragraph');\r\n block.after(newBlock);\r\n \r\n // Focus the new block\r\n const newEditable = newBlock.querySelector('[contenteditable=\"true\"]') as HTMLElement;\r\n if (newEditable) {\r\n newEditable.focus();\r\n }\r\n \r\n // Get the new block's ID and open the menu\r\n const newBlockId = newBlock.getAttribute('data-block-id');\r\n if (newBlockId) {\r\n setActiveBlockId(newBlockId);\r\n setTimeout(() => {\r\n const rect = newBlock.getBoundingClientRect();\r\n setBlockMenuPosition({ x: rect.left, y: rect.bottom + 8 });\r\n setShowBlockMenu(true);\r\n }, 50);\r\n }\r\n \r\n updateState();\r\n emitChange();\r\n }\r\n break;\r\n case 'delete':\r\n if (blockId) deleteBlockById(blockId);\r\n break;\r\n case 'moveup':\r\n if (blockId) moveBlock(blockId, 'up');\r\n break;\r\n case 'movedown':\r\n if (blockId) moveBlock(blockId, 'down');\r\n break;\r\n // Table actions\r\n case 'addRow': {\r\n const tableWrapper = button.closest('.cb-table-wrapper') as HTMLElement;\r\n if (tableWrapper) {\r\n saveToHistory();\r\n addTableRow(tableWrapper);\r\n emitChange();\r\n }\r\n break;\r\n }\r\n case 'addCol': {\r\n const tableWrapper = button.closest('.cb-table-wrapper') as HTMLElement;\r\n if (tableWrapper) {\r\n saveToHistory();\r\n addTableColumn(tableWrapper);\r\n emitChange();\r\n }\r\n break;\r\n }\r\n case 'deleteRow': {\r\n const tableWrapper = button.closest('.cb-table-wrapper') as HTMLElement;\r\n if (tableWrapper) {\r\n const cell = getFocusedCell(tableWrapper);\r\n if (cell) {\r\n const pos = getCellPosition(cell);\r\n if (pos) {\r\n saveToHistory();\r\n deleteTableRow(tableWrapper, pos.row);\r\n emitChange();\r\n }\r\n } else {\r\n // Delete last row if no cell is focused\r\n const table = tableWrapper.querySelector('table');\r\n const rows = table?.querySelectorAll('tr');\r\n if (rows && rows.length > 1) {\r\n saveToHistory();\r\n deleteTableRow(tableWrapper, rows.length - 1);\r\n emitChange();\r\n }\r\n }\r\n }\r\n break;\r\n }\r\n case 'deleteCol': {\r\n const tableWrapper = button.closest('.cb-table-wrapper') as HTMLElement;\r\n if (tableWrapper) {\r\n const cell = getFocusedCell(tableWrapper);\r\n if (cell) {\r\n const pos = getCellPosition(cell);\r\n if (pos) {\r\n saveToHistory();\r\n deleteTableColumn(tableWrapper, pos.col);\r\n emitChange();\r\n }\r\n } else {\r\n // Delete last column if no cell is focused\r\n const table = tableWrapper.querySelector('table');\r\n const firstRow = table?.querySelector('tr');\r\n const cells = firstRow?.querySelectorAll('th, td');\r\n if (cells && cells.length > 1) {\r\n saveToHistory();\r\n deleteTableColumn(tableWrapper, cells.length - 1);\r\n emitChange();\r\n }\r\n }\r\n }\r\n break;\r\n }\r\n }\r\n }, [deleteBlockById, moveBlock, saveToHistory, emitChange]);\r\n\r\n // Handle keyboard events\r\n const handleKeyDown = useCallback((e: React.KeyboardEvent) => {\r\n if (readOnly) return;\r\n \r\n // Don't handle keys if block menu is open (let it handle its own keys)\r\n if (showBlockMenu) return;\r\n\r\n const target = e.target as HTMLElement;\r\n const block = target.closest('.cb-block') as HTMLElement;\r\n const blockId = block?.getAttribute('data-block-id');\r\n const blockType = block?.getAttribute('data-block-type') as BlockType;\r\n\r\n // Keyboard shortcuts\r\n if (e.ctrlKey || e.metaKey) {\r\n switch (e.key.toLowerCase()) {\r\n case 'b':\r\n e.preventDefault();\r\n document.execCommand('bold');\r\n emitChange();\r\n return;\r\n case 'i':\r\n e.preventDefault();\r\n document.execCommand('italic');\r\n emitChange();\r\n return;\r\n case 'u':\r\n e.preventDefault();\r\n document.execCommand('underline');\r\n emitChange();\r\n return;\r\n case 's':\r\n e.preventDefault();\r\n if (onSave) onSave(getHTML());\r\n return;\r\n case 'z':\r\n e.preventDefault();\r\n if (e.shiftKey) {\r\n handleRedo();\r\n } else {\r\n handleUndo();\r\n }\r\n return;\r\n case 'y':\r\n e.preventDefault();\r\n handleRedo();\r\n return;\r\n case '1':\r\n case '2':\r\n case '3':\r\n if (blockId) {\r\n e.preventDefault();\r\n // Transform to heading\r\n saveToHistory();\r\n const level = parseInt(e.key);\r\n const content = target.innerHTML;\r\n const wrapper = block;\r\n wrapper.setAttribute('data-block-type', 'heading');\r\n const contentDiv = wrapper.querySelector('.cb-block-content');\r\n if (contentDiv) {\r\n contentDiv.innerHTML = `<h${level} class=\"cb-heading cb-h${level}\" contenteditable=\"true\">${content}</h${level}>`;\r\n const newEl = contentDiv.querySelector('[contenteditable]') as HTMLElement;\r\n if (newEl) {\r\n newEl.focus();\r\n moveCursorToEnd(newEl);\r\n }\r\n }\r\n emitChange();\r\n }\r\n return;\r\n }\r\n }\r\n\r\n // Tab key in code blocks - insert indentation\r\n if (e.key === 'Tab' && blockType === 'code') {\r\n e.preventDefault();\r\n \r\n const selection = window.getSelection();\r\n const range = selection?.getRangeAt(0);\r\n \r\n if (range) {\r\n // Insert 2 spaces for indentation\r\n const indent = ' ';\r\n const textNode = document.createTextNode(indent);\r\n range.insertNode(textNode);\r\n range.setStartAfter(textNode);\r\n range.setEndAfter(textNode);\r\n selection?.removeAllRanges();\r\n selection?.addRange(range);\r\n emitChange();\r\n }\r\n return;\r\n }\r\n\r\n // Tab key in tables - navigate between cells\r\n if (e.key === 'Tab' && blockType === 'table') {\r\n e.preventDefault();\r\n \r\n const cell = target.closest('td, th') as HTMLTableCellElement;\r\n if (!cell) return;\r\n \r\n const tr = cell.parentElement as HTMLTableRowElement;\r\n const table = tr.closest('table');\r\n if (!tr || !table) return;\r\n \r\n const cells = Array.from(tr.querySelectorAll('th, td'));\r\n const currentIndex = cells.indexOf(cell);\r\n const rows = Array.from(table.querySelectorAll('tr'));\r\n const currentRowIndex = rows.indexOf(tr);\r\n \r\n let nextCell: HTMLTableCellElement | null = null;\r\n \r\n if (e.shiftKey) {\r\n // Move backward\r\n if (currentIndex > 0) {\r\n nextCell = cells[currentIndex - 1] as HTMLTableCellElement;\r\n } else if (currentRowIndex > 0) {\r\n const prevRow = rows[currentRowIndex - 1];\r\n const prevCells = prevRow.querySelectorAll('th, td');\r\n nextCell = prevCells[prevCells.length - 1] as HTMLTableCellElement;\r\n }\r\n } else {\r\n // Move forward\r\n if (currentIndex < cells.length - 1) {\r\n nextCell = cells[currentIndex + 1] as HTMLTableCellElement;\r\n } else if (currentRowIndex < rows.length - 1) {\r\n const nextRow = rows[currentRowIndex + 1];\r\n const nextCells = nextRow.querySelectorAll('th, td');\r\n nextCell = nextCells[0] as HTMLTableCellElement;\r\n } else {\r\n // At last cell - add new row\r\n const tableWrapper = target.closest('.cb-table-wrapper') as HTMLElement;\r\n if (tableWrapper) {\r\n saveToHistory();\r\n addTableRow(tableWrapper);\r\n const newRow = table.querySelector('tr:last-child');\r\n const newCells = newRow?.querySelectorAll('td');\r\n nextCell = newCells?.[0] as HTMLTableCellElement;\r\n emitChange();\r\n }\r\n }\r\n }\r\n \r\n if (nextCell) {\r\n nextCell.focus();\r\n // Select all content in the cell\r\n const range = document.createRange();\r\n range.selectNodeContents(nextCell);\r\n const selection = window.getSelection();\r\n selection?.removeAllRanges();\r\n selection?.addRange(range);\r\n }\r\n return;\r\n }\r\n\r\n // Enter key\r\n if (e.key === 'Enter' && !e.shiftKey) {\r\n // Don't split code blocks on enter\r\n if (blockType === 'code') return;\r\n \r\n // For lists, handle specially\r\n if (blockType === 'bulletList' || blockType === 'numberedList' || blockType === 'checkList') {\r\n const li = target.closest('li');\r\n if (!li) return;\r\n \r\n // Get the editable content element\r\n const editableContent = blockType === 'checkList' \r\n ? li.querySelector('.cb-checklist-content') as HTMLElement\r\n : li;\r\n \r\n // Check if the list item is empty\r\n const content = editableContent?.textContent?.trim() || '';\r\n \r\n if (content === '') {\r\n // Empty list item - exit list and create paragraph\r\n e.preventDefault();\r\n saveToHistory();\r\n \r\n const listElement = li.closest('ul, ol') as HTMLElement;\r\n const wrapper = block;\r\n \r\n // Check if this is a nested list\r\n const isNested = li.parentElement?.classList.contains('cb-nested-list');\r\n \r\n if (isNested) {\r\n // Outdent the item instead of exiting\r\n const parentList = li.parentElement as HTMLElement;\r\n const parentLi = parentList.parentElement as HTMLElement;\r\n const grandparentList = parentLi.parentElement as HTMLElement;\r\n \r\n if (grandparentList) {\r\n grandparentList.insertBefore(li, parentLi.nextSibling);\r\n if (parentList.children.length === 0) {\r\n parentList.remove();\r\n }\r\n // Focus the moved item\r\n const focusTarget = blockType === 'checkList' \r\n ? li.querySelector('.cb-checklist-content') as HTMLElement\r\n : li;\r\n if (focusTarget) {\r\n focusTarget.focus();\r\n }\r\n }\r\n } else {\r\n // Top-level empty item - check if it's the only item\r\n const items = listElement?.querySelectorAll(':scope > li');\r\n \r\n if (items && items.length === 1) {\r\n // Only one item, transform the entire block to paragraph\r\n if (blockId) {\r\n transformBlockType(blockId, 'paragraph');\r\n }\r\n } else {\r\n // Remove this item and create a paragraph after the list\r\n li.remove();\r\n insertBlockAfter('paragraph', blockId || undefined);\r\n }\r\n }\r\n \r\n emitChange();\r\n return;\r\n }\r\n \r\n // Non-empty item - create new list item\r\n e.preventDefault();\r\n saveToHistory();\r\n \r\n const selection = window.getSelection();\r\n const range = selection?.getRangeAt(0);\r\n \r\n // Get content after cursor\r\n let afterContent = '';\r\n if (range && editableContent) {\r\n const afterRange = document.createRange();\r\n afterRange.setStart(range.endContainer, range.endOffset);\r\n afterRange.setEndAfter(editableContent.lastChild || editableContent);\r\n const fragment = afterRange.extractContents();\r\n const temp = document.createElement('div');\r\n temp.appendChild(fragment);\r\n afterContent = temp.innerHTML;\r\n }\r\n \r\n // Create new list item\r\n const newLi = document.createElement('li');\r\n newLi.className = 'cb-list-item';\r\n newLi.setAttribute('data-item-id', generateId());\r\n \r\n if (blockType === 'checkList') {\r\n const wrapper = document.createElement('div');\r\n wrapper.className = 'cb-checklist-wrapper';\r\n \r\n const checkbox = document.createElement('input');\r\n checkbox.type = 'checkbox';\r\n checkbox.className = 'cb-checkbox';\r\n checkbox.setAttribute('tabindex', '-1');\r\n \r\n const contentSpan = document.createElement('span');\r\n contentSpan.className = 'cb-checklist-content';\r\n contentSpan.setAttribute('contenteditable', 'true');\r\n contentSpan.innerHTML = afterContent;\r\n \r\n wrapper.appendChild(checkbox);\r\n wrapper.appendChild(contentSpan);\r\n newLi.appendChild(wrapper);\r\n \r\n li.after(newLi);\r\n contentSpan.focus();\r\n moveCursorToStart(contentSpan);\r\n } else {\r\n newLi.setAttribute('contenteditable', 'true');\r\n newLi.innerHTML = afterContent;\r\n \r\n li.after(newLi);\r\n newLi.focus();\r\n moveCursorToStart(newLi);\r\n }\r\n \r\n emitChange();\r\n return;\r\n }\r\n \r\n e.preventDefault();\r\n saveToHistory();\r\n \r\n // Create new paragraph after current block\r\n insertBlockAfter('paragraph', blockId || undefined);\r\n return;\r\n }\r\n\r\n // Backspace at start\r\n if (e.key === 'Backspace' && isCursorAtStart(target)) {\r\n // Transform to paragraph or merge\r\n if (blockType && blockType !== 'paragraph' && blockType !== 'divider') {\r\n e.preventDefault();\r\n if (blockId) transformBlockType(blockId, 'paragraph');\r\n return;\r\n }\r\n \r\n // Merge with previous block\r\n const prevBlock = block?.previousElementSibling as HTMLElement;\r\n if (prevBlock && prevBlock.classList.contains('cb-block')) {\r\n const prevType = prevBlock.getAttribute('data-block-type');\r\n if (prevType !== 'divider' && prevType !== 'image' && prevType !== 'video') {\r\n e.preventDefault();\r\n saveToHistory();\r\n \r\n const prevEditable = prevBlock.querySelector('[contenteditable=\"true\"]') as HTMLElement;\r\n const currentContent = target.innerHTML;\r\n \r\n if (prevEditable && currentContent) {\r\n prevEditable.innerHTML += currentContent;\r\n }\r\n \r\n if (prevEditable) {\r\n moveCursorToEnd(prevEditable);\r\n prevEditable.focus();\r\n }\r\n \r\n if (blockId) deleteBlockById(blockId);\r\n }\r\n }\r\n return;\r\n }\r\n\r\n // Slash command\r\n if (e.key === '/' && isCursorAtStart(target) && target.textContent === '') {\r\n e.preventDefault();\r\n const rect = block.getBoundingClientRect();\r\n setBlockMenuPosition({ x: rect.left, y: rect.bottom + 8 });\r\n setShowBlockMenu(true);\r\n if (blockId) setActiveBlockId(blockId);\r\n return;\r\n }\r\n\r\n // Arrow navigation between blocks\r\n if (e.key === 'ArrowUp' && isCursorAtStart(target)) {\r\n const prevBlock = block?.previousElementSibling as HTMLElement;\r\n if (prevBlock && prevBlock.classList.contains('cb-block')) {\r\n e.preventDefault();\r\n const prevEditable = prevBlock.querySelector('[contenteditable=\"true\"]') as HTMLElement;\r\n if (prevEditable) {\r\n prevEditable.focus();\r\n moveCursorToEnd(prevEditable);\r\n }\r\n }\r\n return;\r\n }\r\n\r\n if (e.key === 'ArrowDown' && isCursorAtEnd(target)) {\r\n const nextBlock = block?.nextElementSibling as HTMLElement;\r\n if (nextBlock && nextBlock.classList.contains('cb-block')) {\r\n e.preventDefault();\r\n const nextEditable = nextBlock.querySelector('[contenteditable=\"true\"]') as HTMLElement;\r\n if (nextEditable) {\r\n nextEditable.focus();\r\n moveCursorToStart(nextEditable);\r\n }\r\n }\r\n return;\r\n }\r\n }, [\r\n readOnly, saveToHistory, insertBlockAfter, deleteBlockById, transformBlockType,\r\n handleUndo, handleRedo, onSave, getHTML, emitChange\r\n ]);\r\n\r\n // Handle input\r\n const handleInput = useCallback(() => {\r\n updateState();\r\n emitChange();\r\n }, [updateState, emitChange]);\r\n\r\n // Handle paste\r\n const handlePaste = useCallback((e: React.ClipboardEvent) => {\r\n if (readOnly) return;\r\n \r\n e.preventDefault();\r\n saveToHistory();\r\n \r\n const cleanHtml = sanitizePaste(e.clipboardData);\r\n document.execCommand('insertHTML', false, cleanHtml);\r\n \r\n updateState();\r\n emitChange();\r\n }, [readOnly, saveToHistory, updateState, emitChange]);\r\n\r\n // Handle focus\r\n const handleFocus = useCallback((e: React.FocusEvent) => {\r\n const block = (e.target as HTMLElement).closest('.cb-block') as HTMLElement;\r\n const blockId = block?.getAttribute('data-block-id');\r\n setActiveBlockId(blockId);\r\n if (onFocus) onFocus();\r\n }, [onFocus]);\r\n\r\n // Handle blur\r\n const handleBlur = useCallback((e: React.FocusEvent) => {\r\n if (containerRef.current?.contains(e.relatedTarget as Node)) {\r\n return;\r\n }\r\n setActiveBlockId(null);\r\n if (onBlur) onBlur();\r\n }, [onBlur]);\r\n\r\n // Handle block selection from menu\r\n const handleBlockMenuSelect = useCallback((type: BlockType, data?: Record<string, any>) => {\r\n setShowBlockMenu(false);\r\n \r\n if (activeBlockId) {\r\n // Check if current block is empty - if so, transform it\r\n const currentBlock = contentRef.current?.querySelector(`[data-block-id=\"${activeBlockId}\"]`);\r\n const editable = currentBlock?.querySelector('[contenteditable=\"true\"]');\r\n \r\n if (editable && editable.textContent?.trim() === '') {\r\n // For headings with level data, we need to handle specially\r\n if (type === 'heading' && data?.level) {\r\n transformBlockType(activeBlockId, type, data);\r\n } else {\r\n transformBlockType(activeBlockId, type);\r\n }\r\n } else {\r\n insertBlockAfter(type, activeBlockId, data);\r\n }\r\n } else {\r\n insertBlockAfter(type, undefined, data);\r\n }\r\n }, [activeBlockId, transformBlockType, insertBlockAfter]);\r\n\r\n // Mouse enter/leave for block hover\r\n const handleMouseEnter = useCallback((e: React.MouseEvent) => {\r\n const block = (e.target as HTMLElement).closest('.cb-block') as HTMLElement;\r\n const blockId = block?.getAttribute('data-block-id');\r\n setHoveredBlockId(blockId);\r\n }, []);\r\n\r\n const handleMouseLeave = useCallback(() => {\r\n setHoveredBlockId(null);\r\n }, []);\r\n\r\n const editorClasses = [\r\n `${classPrefix}-editor`,\r\n darkMode ? `${classPrefix}-dark` : `${classPrefix}-light`,\r\n readOnly ? `${classPrefix}-readonly` : '',\r\n className,\r\n ].filter(Boolean).join(' ');\r\n\r\n return (\r\n <div ref={containerRef} className={editorClasses} style={style} data-editor-root>\r\n {showToolbar && toolbarPosition === 'top' && editorInstance && (\r\n <Toolbar editor={editorInstance} darkMode={darkMode} />\r\n )}\r\n\r\n <div\r\n ref={contentRef}\r\n className={`${classPrefix}-content`}\r\n onClick={handleBlockControlClick}\r\n onKeyDown={handleKeyDown}\r\n onInput={handleInput}\r\n onPaste={handlePaste}\r\n onFocus={handleFocus}\r\n onBlur={handleBlur}\r\n onMouseOver={handleMouseEnter}\r\n onMouseOut={handleMouseLeave}\r\n data-placeholder={placeholder}\r\n spellCheck={spellCheck}\r\n role=\"textbox\"\r\n aria-multiline=\"true\"\r\n aria-label=\"Content editor\"\r\n />\r\n\r\n {showToolbar && toolbarPosition === 'bottom' && editorInstance && (\r\n <Toolbar editor={editorInstance} darkMode={darkMode} />\r\n )}\r\n\r\n {showBlockMenu && editorInstance && (\r\n <BlockMenu\r\n editor={editorInstance}\r\n position={blockMenuPosition}\r\n onSelect={handleBlockMenuSelect}\r\n onClose={() => setShowBlockMenu(false)}\r\n />\r\n )}\r\n\r\n <div className={`${classPrefix}-status`}>\r\n <span>{editorState.wordCount} words</span>\r\n <span>{editorState.charCount} characters</span>\r\n </div>\r\n </div>\r\n );\r\n};\r\n\r\nexport const ContentBlocksEditor = forwardRef(ContentBlocksEditorInner);\r\n","/**\r\n * ContentBlocksRenderer - Renders HTML content with all styles included\r\n * A self-contained component that displays editor output beautifully\r\n * No external CSS required - just import and use\r\n * \r\n * @example\r\n * ```tsx\r\n * import { ContentBlocksRenderer } from 'authorly';\r\n * \r\n * function BlogPost({ content }) {\r\n * return <ContentBlocksRenderer html={content} darkMode={false} />;\r\n * }\r\n * ```\r\n */\r\n\r\nimport React, { useMemo } from 'react';\r\n\r\nexport interface ContentBlocksRendererProps {\r\n /** HTML content to render */\r\n html: string;\r\n /** Enable dark mode */\r\n darkMode?: boolean;\r\n /** Custom class name */\r\n className?: string;\r\n /** Custom styles */\r\n style?: React.CSSProperties;\r\n /** Process code blocks with copy button */\r\n enableCodeCopy?: boolean;\r\n /** Process checklist items with strikethrough */\r\n enableChecklistStyles?: boolean;\r\n /** Add IDs to headings for navigation */\r\n enableHeadingIds?: boolean;\r\n /** Class prefix for custom styling */\r\n classPrefix?: string;\r\n}\r\n\r\n// Escape HTML for code display\r\nfunction escapeHtml(text: string): string {\r\n return text\r\n .replace(/&/g, '&amp;')\r\n .replace(/</g, '&lt;')\r\n .replace(/>/g, '&gt;')\r\n .replace(/\"/g, '&quot;')\r\n .replace(/'/g, '&#039;');\r\n}\r\n\r\n// Process HTML for rendering\r\nfunction processHtml(\r\n html: string, \r\n options: {\r\n enableCodeCopy: boolean;\r\n enableChecklistStyles: boolean;\r\n enableHeadingIds: boolean;\r\n }\r\n): string {\r\n if (!html) return '';\r\n \r\n const parser = new DOMParser();\r\n const doc = parser.parseFromString(html, 'text/html');\r\n \r\n // Add IDs to headings for navigation\r\n if (options.enableHeadingIds) {\r\n const headings = doc.querySelectorAll('h1, h2, h3, h4, h5, h6');\r\n headings.forEach((heading, index) => {\r\n if (!heading.id) {\r\n heading.id = `heading-${index}`;\r\n }\r\n });\r\n }\r\n \r\n // Enhance code blocks with wrapper and copy button\r\n if (options.enableCodeCopy) {\r\n const codeBlocks = doc.querySelectorAll('pre');\r\n codeBlocks.forEach((pre, index) => {\r\n // Skip if already processed\r\n if (pre.parentElement?.classList.contains('cbr-code-wrapper')) return;\r\n \r\n const code = pre.querySelector('code');\r\n const codeContent = code?.textContent || pre.textContent || '';\r\n \r\n const wrapper = doc.createElement('div');\r\n wrapper.className = 'cbr-code-wrapper';\r\n wrapper.innerHTML = `\r\n <div class=\"cbr-code-toolbar\">\r\n <span class=\"cbr-code-lang\">Code</span>\r\n <button class=\"cbr-code-copy\" data-code-index=\"${index}\" onclick=\"\r\n navigator.clipboard.writeText(this.closest('.cbr-code-wrapper').querySelector('code').textContent);\r\n this.textContent = 'Copied!';\r\n setTimeout(() => this.textContent = 'Copy', 2000);\r\n \">Copy</button>\r\n </div>\r\n <pre class=\"cbr-code-block\"><code>${escapeHtml(codeContent)}</code></pre>\r\n `;\r\n \r\n pre.replaceWith(wrapper);\r\n });\r\n }\r\n \r\n // Handle checklist items - add class for checked items\r\n if (options.enableChecklistStyles) {\r\n const checklistItems = doc.querySelectorAll('li');\r\n checklistItems.forEach((li) => {\r\n const checkbox = li.querySelector('input[type=\"checkbox\"]');\r\n if (checkbox && (checkbox as HTMLInputElement).checked) {\r\n li.classList.add('cbr-checked-item');\r\n }\r\n });\r\n }\r\n\r\n // Remove editor-only elements\r\n doc.querySelectorAll('.cb-image-controls, .cb-image-placeholder, .cb-video-placeholder, .cb-callout-type-selector, .cb-image-resize-handle').forEach(el => el.remove());\r\n \r\n return doc.body.innerHTML;\r\n}\r\n\r\n// Generate CSS styles based on dark mode\r\nfunction generateStyles(darkMode: boolean, classPrefix: string): string {\r\n const p = classPrefix;\r\n \r\n // Color variables\r\n const colors = darkMode ? {\r\n bg: '#1f2937',\r\n bgSecondary: '#111827',\r\n bgTertiary: '#374151',\r\n text: '#f9fafb',\r\n textSecondary: '#d1d5db',\r\n textMuted: '#9ca3af',\r\n border: '#374151',\r\n borderLight: '#4b5563',\r\n primary: '#3b82f6',\r\n link: '#60a5fa',\r\n code: '#f472b6',\r\n codeBg: 'rgba(255, 255, 255, 0.1)',\r\n quoteBg: 'rgba(59, 130, 246, 0.1)',\r\n calloutInfo: 'rgba(59, 130, 246, 0.1)',\r\n calloutInfoBorder: 'rgba(59, 130, 246, 0.3)',\r\n calloutSuccess: 'rgba(16, 185, 129, 0.1)',\r\n calloutSuccessBorder: 'rgba(16, 185, 129, 0.3)',\r\n calloutWarning: 'rgba(245, 158, 11, 0.1)',\r\n calloutWarningBorder: 'rgba(245, 158, 11, 0.3)',\r\n calloutError: 'rgba(239, 68, 68, 0.1)',\r\n calloutErrorBorder: 'rgba(239, 68, 68, 0.3)',\r\n tableBg: '#374151',\r\n } : {\r\n bg: '#ffffff',\r\n bgSecondary: '#f9fafb',\r\n bgTertiary: '#f3f4f6',\r\n text: '#111827',\r\n textSecondary: '#4b5563',\r\n textMuted: '#6b7280',\r\n border: '#e5e7eb',\r\n borderLight: '#d1d5db',\r\n primary: '#3b82f6',\r\n link: '#2563eb',\r\n code: '#d63384',\r\n codeBg: '#f3f4f6',\r\n quoteBg: '#eff6ff',\r\n calloutInfo: '#eff6ff',\r\n calloutInfoBorder: '#bfdbfe',\r\n calloutSuccess: '#f0fdf4',\r\n calloutSuccessBorder: '#bbf7d0',\r\n calloutWarning: '#fffbeb',\r\n calloutWarningBorder: '#fde68a',\r\n calloutError: '#fef2f2',\r\n calloutErrorBorder: '#fecaca',\r\n tableBg: '#f9fafb',\r\n };\r\n\r\n return `\r\n .${p} {\r\n font-family: system-ui, -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif;\r\n line-height: 1.7;\r\n color: ${colors.text};\r\n word-wrap: break-word;\r\n overflow-wrap: break-word;\r\n }\r\n\r\n /* Typography */\r\n .${p} h1 { font-size: 2.25rem; font-weight: 700; margin: 1.5rem 0 1rem; line-height: 1.2; }\r\n .${p} h2 { font-size: 1.75rem; font-weight: 600; margin: 1.25rem 0 0.75rem; line-height: 1.3; }\r\n .${p} h3 { font-size: 1.5rem; font-weight: 600; margin: 1rem 0 0.5rem; line-height: 1.4; }\r\n .${p} h4 { font-size: 1.25rem; font-weight: 600; margin: 1rem 0 0.5rem; }\r\n .${p} h5 { font-size: 1.125rem; font-weight: 600; margin: 0.75rem 0 0.5rem; }\r\n .${p} h6 { font-size: 1rem; font-weight: 600; margin: 0.75rem 0 0.5rem; }\r\n .${p} p { margin: 0.75rem 0; }\r\n \r\n /* Links */\r\n .${p} a { color: ${colors.link}; text-decoration: underline; }\r\n .${p} a:hover { color: ${colors.primary}; }\r\n\r\n /* Lists */\r\n .${p} ul, .${p} ol { margin: 0.75rem 0; padding-left: 1.5rem; }\r\n .${p} li { margin: 0.25rem 0; }\r\n .${p} li.cbr-checked-item { text-decoration: line-through; color: ${colors.textMuted}; }\r\n\r\n /* Checklist specific */\r\n .${p} ul:has(input[type=\"checkbox\"]) { list-style: none; padding-left: 0; }\r\n .${p} li:has(input[type=\"checkbox\"]) { display: flex; align-items: flex-start; gap: 0.5rem; }\r\n .${p} input[type=\"checkbox\"] { margin-top: 0.25rem; accent-color: ${colors.primary}; }\r\n\r\n /* Blockquote */\r\n .${p} blockquote {\r\n margin: 1rem 0;\r\n padding: 0.75rem 1rem;\r\n border-left: 4px solid ${colors.primary};\r\n background: ${colors.quoteBg};\r\n border-radius: 0 0.375rem 0.375rem 0;\r\n }\r\n .${p} blockquote p { margin: 0; font-style: italic; }\r\n\r\n /* Inline code */\r\n .${p} code:not(.cbr-code-block code) {\r\n padding: 0.2em 0.4em;\r\n font-size: 0.875em;\r\n font-family: 'SF Mono', Monaco, Consolas, monospace;\r\n background: ${colors.codeBg};\r\n border: 1px solid ${colors.border};\r\n border-radius: 0.25rem;\r\n color: ${colors.code};\r\n }\r\n\r\n /* Code block wrapper */\r\n .${p} .cbr-code-wrapper {\r\n margin: 1rem 0;\r\n border: 1px solid ${colors.border};\r\n border-radius: 0.5rem;\r\n overflow: hidden;\r\n }\r\n .${p} .cbr-code-toolbar {\r\n display: flex;\r\n align-items: center;\r\n justify-content: space-between;\r\n padding: 0.5rem 0.75rem;\r\n background: ${colors.bgTertiary};\r\n border-bottom: 1px solid ${colors.borderLight};\r\n }\r\n .${p} .cbr-code-lang {\r\n font-size: 0.75rem;\r\n color: ${colors.textMuted};\r\n font-weight: 500;\r\n }\r\n .${p} .cbr-code-copy {\r\n padding: 0.25rem 0.5rem;\r\n font-size: 0.75rem;\r\n background: transparent;\r\n border: none;\r\n border-radius: 0.25rem;\r\n color: ${colors.textMuted};\r\n cursor: pointer;\r\n transition: all 0.15s ease;\r\n }\r\n .${p} .cbr-code-copy:hover {\r\n background: ${colors.border};\r\n color: ${colors.text};\r\n }\r\n .${p} .cbr-code-block {\r\n margin: 0;\r\n padding: 1rem;\r\n background: ${colors.bgSecondary};\r\n overflow-x: auto;\r\n }\r\n .${p} .cbr-code-block code {\r\n font-family: 'SF Mono', Monaco, Consolas, monospace;\r\n font-size: 0.875rem;\r\n line-height: 1.6;\r\n color: ${colors.textSecondary};\r\n background: none !important;\r\n border: none !important;\r\n padding: 0 !important;\r\n }\r\n\r\n /* Images */\r\n .${p} img { max-width: 100%; height: auto; border-radius: 0.5rem; }\r\n .${p} figure { margin: 1rem 0; }\r\n .${p} figure[data-align=\"center\"] { text-align: center; }\r\n .${p} figure[data-align=\"center\"] img { display: inline-block; }\r\n .${p} figure[data-align=\"right\"] { text-align: right; }\r\n .${p} figure[data-align=\"right\"] img { display: inline-block; }\r\n .${p} figure[data-align=\"left\"] { text-align: left; }\r\n .${p} figcaption { \r\n font-size: 0.875rem; \r\n color: ${colors.textMuted}; \r\n margin-top: 0.5rem; \r\n }\r\n\r\n /* Video */\r\n .${p} .cb-video { margin: 1rem 0; }\r\n .${p} .cb-video iframe { max-width: 100%; border-radius: 0.5rem; }\r\n\r\n /* Tables */\r\n .${p} table {\r\n width: 100%;\r\n border-collapse: collapse;\r\n margin: 1rem 0;\r\n }\r\n .${p} th, .${p} td {\r\n border: 1px solid ${colors.border};\r\n padding: 0.5rem 0.75rem;\r\n text-align: left;\r\n }\r\n .${p} th {\r\n background: ${colors.tableBg};\r\n font-weight: 600;\r\n }\r\n\r\n /* Horizontal rule */\r\n .${p} hr {\r\n border: none;\r\n border-top: 1px solid ${colors.border};\r\n margin: 1.5rem 0;\r\n }\r\n\r\n /* Callouts */\r\n .${p} aside, .${p} .cb-callout {\r\n display: flex;\r\n gap: 0.75rem;\r\n margin: 1rem 0;\r\n padding: 1rem;\r\n border-radius: 0.5rem;\r\n border: 1px solid;\r\n }\r\n .${p} aside[data-callout-type=\"info\"], .${p} .cb-callout[data-callout-type=\"info\"] {\r\n background: ${colors.calloutInfo};\r\n border-color: ${colors.calloutInfoBorder};\r\n }\r\n .${p} aside[data-callout-type=\"success\"], .${p} .cb-callout[data-callout-type=\"success\"] {\r\n background: ${colors.calloutSuccess};\r\n border-color: ${colors.calloutSuccessBorder};\r\n }\r\n .${p} aside[data-callout-type=\"warning\"], .${p} .cb-callout[data-callout-type=\"warning\"] {\r\n background: ${colors.calloutWarning};\r\n border-color: ${colors.calloutWarningBorder};\r\n }\r\n .${p} aside[data-callout-type=\"error\"], .${p} .cb-callout[data-callout-type=\"error\"] {\r\n background: ${colors.calloutError};\r\n border-color: ${colors.calloutErrorBorder};\r\n }\r\n .${p} aside[data-callout-type=\"note\"], .${p} .cb-callout[data-callout-type=\"note\"] {\r\n background: ${colors.bgTertiary};\r\n border-color: ${colors.border};\r\n }\r\n .${p} .cb-callout-icon {\r\n flex-shrink: 0;\r\n width: 24px;\r\n height: 24px;\r\n }\r\n .${p} .cb-callout-content { flex: 1; }\r\n .${p} .cb-callout-content p { margin: 0; }\r\n\r\n /* Accordion */\r\n .${p} details {\r\n margin: 1rem 0;\r\n border: 1px solid ${colors.border};\r\n border-radius: 0.5rem;\r\n overflow: hidden;\r\n }\r\n .${p} summary {\r\n padding: 0.75rem 1rem;\r\n background: ${colors.bgSecondary};\r\n cursor: pointer;\r\n font-weight: 500;\r\n }\r\n .${p} summary:hover { background: ${colors.bgTertiary}; }\r\n .${p} details > div, .${p} details > p:not(:first-child) {\r\n padding: 1rem;\r\n }\r\n\r\n /* Text alignment */\r\n .${p} [style*=\"text-align: center\"], .${p} [data-align=\"center\"] { text-align: center; }\r\n .${p} [style*=\"text-align: right\"], .${p} [data-align=\"right\"] { text-align: right; }\r\n .${p} [style*=\"text-align: left\"], .${p} [data-align=\"left\"] { text-align: left; }\r\n .${p} [style*=\"text-align: justify\"], .${p} [data-align=\"justify\"] { text-align: justify; }\r\n `;\r\n}\r\n\r\n/**\r\n * ContentBlocksRenderer - Renders HTML content with beautiful styling\r\n * \r\n * @example\r\n * ```tsx\r\n * import { ContentBlocksRenderer } from 'authorly';\r\n * \r\n * function Preview({ html }) {\r\n * return <ContentBlocksRenderer html={html} darkMode={false} />;\r\n * }\r\n * ```\r\n */\r\nexport const ContentBlocksRenderer: React.FC<ContentBlocksRendererProps> = ({\r\n html,\r\n darkMode = false,\r\n className = '',\r\n style,\r\n enableCodeCopy = true,\r\n enableChecklistStyles = true,\r\n enableHeadingIds = true,\r\n classPrefix = 'cbr-content',\r\n}) => {\r\n // Process HTML\r\n const processedHtml = useMemo(() => {\r\n return processHtml(html, {\r\n enableCodeCopy,\r\n enableChecklistStyles,\r\n enableHeadingIds,\r\n });\r\n }, [html, enableCodeCopy, enableChecklistStyles, enableHeadingIds]);\r\n\r\n // Generate styles\r\n const styles = useMemo(() => {\r\n return generateStyles(darkMode, classPrefix);\r\n }, [darkMode, classPrefix]);\r\n\r\n if (!html) {\r\n return (\r\n <div className={`${classPrefix} ${className}`.trim()} style={style}>\r\n <style>{styles}</style>\r\n <p style={{ color: darkMode ? '#64748b' : '#9ca3af' }}>No content to display</p>\r\n </div>\r\n );\r\n }\r\n\r\n return (\r\n <div className={`${classPrefix} ${className}`.trim()} style={style}>\r\n <style>{styles}</style>\r\n <div dangerouslySetInnerHTML={{ __html: processedHtml }} />\r\n </div>\r\n );\r\n};\r\n\r\nexport default ContentBlocksRenderer;\r\n","/**\r\n * TableOfContents - Extracts headings from HTML and renders navigation\r\n * A self-contained component with all styles included\r\n */\r\n\r\nimport React, { useMemo, useCallback } from 'react';\r\n\r\nexport interface TocItem {\r\n id: string;\r\n text: string;\r\n level: number;\r\n children: TocItem[];\r\n}\r\n\r\nexport interface TableOfContentsProps {\r\n /** HTML content to extract headings from */\r\n html: string;\r\n /** Enable dark mode */\r\n darkMode?: boolean;\r\n /** Custom class name */\r\n className?: string;\r\n /** Custom styles */\r\n style?: React.CSSProperties;\r\n /** Title to display above the TOC */\r\n title?: string;\r\n /** Minimum heading level to include (1-6) */\r\n minLevel?: number;\r\n /** Maximum heading level to include (1-6) */\r\n maxLevel?: number;\r\n /** Callback when a heading is clicked */\r\n onNavigate?: (id: string, item: TocItem) => void;\r\n /** Whether to scroll smoothly to the heading */\r\n smoothScroll?: boolean;\r\n /** Element or selector to find headings in (for navigation) */\r\n targetContainer?: HTMLElement | string | null;\r\n /** Show as collapsible */\r\n collapsible?: boolean;\r\n /** Initial collapsed state */\r\n defaultCollapsed?: boolean;\r\n}\r\n\r\n// Parse headings from HTML and build nested TOC\r\nfunction parseHeadings(html: string, minLevel: number, maxLevel: number): TocItem[] {\r\n if (!html) return [];\r\n \r\n const parser = new DOMParser();\r\n const doc = parser.parseFromString(html, 'text/html');\r\n \r\n // Build selector for heading levels\r\n const selectors = [];\r\n for (let i = minLevel; i <= maxLevel; i++) {\r\n selectors.push(`h${i}`);\r\n }\r\n const headings = doc.querySelectorAll(selectors.join(', '));\r\n \r\n const items: TocItem[] = [];\r\n const stack: { level: number; item: TocItem }[] = [];\r\n \r\n headings.forEach((heading, index) => {\r\n const level = parseInt(heading.tagName.charAt(1));\r\n const text = heading.textContent?.trim() || '';\r\n if (!text) return;\r\n \r\n // Use existing ID or generate one\r\n const id = heading.id || `heading-${index}`;\r\n \r\n const item: TocItem = { id, text, level, children: [] };\r\n \r\n // Find parent for nesting\r\n while (stack.length > 0 && stack[stack.length - 1].level >= level) {\r\n stack.pop();\r\n }\r\n \r\n if (stack.length === 0) {\r\n items.push(item);\r\n } else {\r\n stack[stack.length - 1].item.children.push(item);\r\n }\r\n \r\n stack.push({ level, item });\r\n });\r\n \r\n return items;\r\n}\r\n\r\n// Generate CSS styles\r\nfunction generateStyles(darkMode: boolean): string {\r\n const colors = darkMode ? {\r\n bg: '#1e293b',\r\n bgHover: '#334155',\r\n text: '#94a3b8',\r\n textHover: '#f1f5f9',\r\n textActive: '#60a5fa',\r\n border: '#334155',\r\n title: '#64748b',\r\n } : {\r\n bg: '#ffffff',\r\n bgHover: '#f1f5f9',\r\n text: '#64748b',\r\n textHover: '#0f172a',\r\n textActive: '#3b82f6',\r\n border: '#e2e8f0',\r\n title: '#94a3b8',\r\n };\r\n\r\n return `\r\n .cbtoc {\r\n font-family: system-ui, -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif;\r\n }\r\n .cbtoc-title {\r\n margin: 0 0 0.75rem;\r\n font-size: 0.75rem;\r\n font-weight: 600;\r\n text-transform: uppercase;\r\n letter-spacing: 0.05em;\r\n color: ${colors.title};\r\n }\r\n .cbtoc-list {\r\n list-style: none;\r\n margin: 0;\r\n padding: 0;\r\n }\r\n .cbtoc-list-nested {\r\n padding-left: 0.75rem;\r\n }\r\n .cbtoc-item {\r\n margin: 0.125rem 0;\r\n }\r\n .cbtoc-link {\r\n display: block;\r\n padding: 0.25rem 0.5rem;\r\n font-size: 0.8125rem;\r\n color: ${colors.text};\r\n background: none;\r\n border: none;\r\n border-radius: 0.25rem;\r\n cursor: pointer;\r\n text-align: left;\r\n width: 100%;\r\n transition: all 0.15s ease;\r\n white-space: nowrap;\r\n overflow: hidden;\r\n text-overflow: ellipsis;\r\n }\r\n .cbtoc-link:hover {\r\n background: ${colors.bgHover};\r\n color: ${colors.textHover};\r\n }\r\n .cbtoc-link-h1 { font-weight: 600; font-size: 0.875rem; }\r\n .cbtoc-link-h2 { font-weight: 500; font-size: 0.8125rem; }\r\n .cbtoc-link-h3, .cbtoc-link-h4, .cbtoc-link-h5, .cbtoc-link-h6 { font-weight: 400; font-size: 0.75rem; }\r\n .cbtoc-empty {\r\n font-size: 0.75rem;\r\n color: ${colors.text};\r\n padding: 0.5rem;\r\n }\r\n .cbtoc-toggle {\r\n display: flex;\r\n align-items: center;\r\n justify-content: space-between;\r\n width: 100%;\r\n padding: 0.5rem 0.75rem;\r\n background: none;\r\n border: none;\r\n border-bottom: 1px solid ${colors.border};\r\n cursor: pointer;\r\n color: ${colors.title};\r\n }\r\n .cbtoc-toggle:hover {\r\n background: ${colors.bgHover};\r\n }\r\n .cbtoc-toggle-icon {\r\n transition: transform 0.2s ease;\r\n }\r\n .cbtoc-toggle-icon-collapsed {\r\n transform: rotate(-90deg);\r\n }\r\n .cbtoc-content {\r\n overflow: hidden;\r\n transition: max-height 0.3s ease;\r\n }\r\n .cbtoc-content-collapsed {\r\n max-height: 0;\r\n }\r\n .cbtoc-content-expanded {\r\n max-height: 2000px;\r\n }\r\n `;\r\n}\r\n\r\n// Recursive TOC list component\r\nconst TocList: React.FC<{\r\n items: TocItem[];\r\n depth: number;\r\n onNavigate: (id: string, item: TocItem) => void;\r\n}> = ({ items, depth, onNavigate }) => {\r\n if (items.length === 0) return null;\r\n\r\n return (\r\n <ul className={`cbtoc-list ${depth > 0 ? 'cbtoc-list-nested' : ''}`}>\r\n {items.map((item) => (\r\n <li key={item.id} className=\"cbtoc-item\">\r\n <button\r\n className={`cbtoc-link cbtoc-link-h${item.level}`}\r\n onClick={() => onNavigate(item.id, item)}\r\n title={item.text}\r\n >\r\n {item.text}\r\n </button>\r\n {item.children.length > 0 && (\r\n <TocList items={item.children} depth={depth + 1} onNavigate={onNavigate} />\r\n )}\r\n </li>\r\n ))}\r\n </ul>\r\n );\r\n};\r\n\r\n/**\r\n * TableOfContents - Generates navigation from HTML headings\r\n * \r\n * @example\r\n * ```tsx\r\n * import { TableOfContents } from 'authorly';\r\n * \r\n * function Sidebar({ html }) {\r\n * return (\r\n * <TableOfContents \r\n * html={html} \r\n * darkMode={false}\r\n * title=\"Contents\"\r\n * onNavigate={(id) => {\r\n * document.getElementById(id)?.scrollIntoView({ behavior: 'smooth' });\r\n * }}\r\n * />\r\n * );\r\n * }\r\n * ```\r\n */\r\nexport const TableOfContents: React.FC<TableOfContentsProps> = ({\r\n html,\r\n darkMode = false,\r\n className = '',\r\n style,\r\n title = 'Table of Contents',\r\n minLevel = 1,\r\n maxLevel = 6,\r\n onNavigate,\r\n smoothScroll = true,\r\n targetContainer = null,\r\n collapsible = false,\r\n defaultCollapsed = false,\r\n}) => {\r\n const [isCollapsed, setIsCollapsed] = React.useState(defaultCollapsed);\r\n\r\n // Parse headings\r\n const tocItems = useMemo(() => {\r\n return parseHeadings(html, minLevel, maxLevel);\r\n }, [html, minLevel, maxLevel]);\r\n\r\n // Generate styles\r\n const styles = useMemo(() => {\r\n return generateStyles(darkMode);\r\n }, [darkMode]);\r\n\r\n // Handle navigation\r\n const handleNavigate = useCallback((id: string, item: TocItem) => {\r\n // Call custom handler if provided\r\n if (onNavigate) {\r\n onNavigate(id, item);\r\n return;\r\n }\r\n\r\n // Default navigation behavior\r\n let element: HTMLElement | null = null;\r\n\r\n if (targetContainer) {\r\n const container = typeof targetContainer === 'string' \r\n ? document.querySelector(targetContainer) \r\n : targetContainer;\r\n element = container?.querySelector(`#${id}`) as HTMLElement;\r\n } else {\r\n element = document.getElementById(id);\r\n }\r\n\r\n if (element) {\r\n element.scrollIntoView({ \r\n behavior: smoothScroll ? 'smooth' : 'auto', \r\n block: 'start' \r\n });\r\n }\r\n }, [onNavigate, smoothScroll, targetContainer]);\r\n\r\n // Toggle collapsed state\r\n const toggleCollapsed = useCallback(() => {\r\n setIsCollapsed(prev => !prev);\r\n }, []);\r\n\r\n if (tocItems.length === 0) {\r\n return (\r\n <nav className={`cbtoc ${className}`.trim()} style={style}>\r\n <style>{styles}</style>\r\n {title && <h3 className=\"cbtoc-title\">{title}</h3>}\r\n <p className=\"cbtoc-empty\">No headings found</p>\r\n </nav>\r\n );\r\n }\r\n\r\n if (collapsible) {\r\n return (\r\n <nav className={`cbtoc ${className}`.trim()} style={style}>\r\n <style>{styles}</style>\r\n <button className=\"cbtoc-toggle\" onClick={toggleCollapsed}>\r\n <span className=\"cbtoc-title\" style={{ margin: 0 }}>{title}</span>\r\n <svg \r\n className={`cbtoc-toggle-icon ${isCollapsed ? 'cbtoc-toggle-icon-collapsed' : ''}`}\r\n width=\"16\" \r\n height=\"16\" \r\n viewBox=\"0 0 24 24\" \r\n fill=\"none\" \r\n stroke=\"currentColor\" \r\n strokeWidth=\"2\"\r\n >\r\n <polyline points=\"6 9 12 15 18 9\"></polyline>\r\n </svg>\r\n </button>\r\n <div className={`cbtoc-content ${isCollapsed ? 'cbtoc-content-collapsed' : 'cbtoc-content-expanded'}`}>\r\n <div style={{ padding: '0.5rem' }}>\r\n <TocList items={tocItems} depth={0} onNavigate={handleNavigate} />\r\n </div>\r\n </div>\r\n </nav>\r\n );\r\n }\r\n\r\n return (\r\n <nav className={`cbtoc ${className}`.trim()} style={style}>\r\n <style>{styles}</style>\r\n {title && <h3 className=\"cbtoc-title\">{title}</h3>}\r\n <TocList items={tocItems} depth={0} onNavigate={handleNavigate} />\r\n </nav>\r\n );\r\n};\r\n\r\nexport default TableOfContents;\r\n\r\n// Export utility functions for custom implementations\r\nexport { parseHeadings };\r\n","/**\r\n * Block Wrapper Component - Wraps each block with controls\r\n */\r\n\r\nimport React, { useState, useCallback } from 'react';\r\nimport {\r\n GripVertical,\r\n Plus,\r\n Trash2,\r\n Copy,\r\n MoveUp,\r\n MoveDown,\r\n MoreHorizontal,\r\n} from 'lucide-react';\r\nimport type { BlockType } from '../core/types';\r\n\r\ninterface BlockWrapperProps {\r\n children: React.ReactNode;\r\n blockId: string;\r\n blockType: BlockType;\r\n isActive?: boolean;\r\n onAddBlock?: (position: 'before' | 'after') => void;\r\n onDeleteBlock?: () => void;\r\n onDuplicateBlock?: () => void;\r\n onMoveUp?: () => void;\r\n onMoveDown?: () => void;\r\n onDragStart?: (e: React.DragEvent) => void;\r\n className?: string;\r\n}\r\n\r\nexport const BlockWrapper: React.FC<BlockWrapperProps> = ({\r\n children,\r\n blockId,\r\n blockType,\r\n isActive = false,\r\n onAddBlock,\r\n onDeleteBlock,\r\n onDuplicateBlock,\r\n onMoveUp,\r\n onMoveDown,\r\n onDragStart,\r\n className = '',\r\n}) => {\r\n const [showMenu, setShowMenu] = useState(false);\r\n\r\n const handleMenuToggle = useCallback((e: React.MouseEvent) => {\r\n e.preventDefault();\r\n e.stopPropagation();\r\n setShowMenu(!showMenu);\r\n }, [showMenu]);\r\n\r\n const handleAction = useCallback(\r\n (action?: () => void) => {\r\n return (e: React.MouseEvent) => {\r\n e.preventDefault();\r\n e.stopPropagation();\r\n setShowMenu(false);\r\n if (action) action();\r\n };\r\n },\r\n []\r\n );\r\n\r\n return (\r\n <div\r\n className={`cb-block-wrapper ${isActive ? 'cb-block-wrapper-active' : ''} ${className}`}\r\n data-block-wrapper={blockId}\r\n >\r\n {/* Left side controls */}\r\n <div className=\"cb-block-controls cb-block-controls-left\">\r\n {/* Add block button */}\r\n <button\r\n type=\"button\"\r\n className=\"cb-block-btn cb-block-add\"\r\n onClick={handleAction(() => onAddBlock?.('before'))}\r\n title=\"Add block above\"\r\n tabIndex={-1}\r\n >\r\n <Plus size={14} />\r\n </button>\r\n\r\n {/* Drag handle */}\r\n <button\r\n type=\"button\"\r\n className=\"cb-block-btn cb-block-drag\"\r\n data-drag-handle\r\n draggable\r\n onDragStart={onDragStart}\r\n title=\"Drag to reorder\"\r\n tabIndex={-1}\r\n >\r\n <GripVertical size={14} />\r\n </button>\r\n </div>\r\n\r\n {/* Block content */}\r\n <div className=\"cb-block-content\">{children}</div>\r\n\r\n {/* Right side controls (shown on hover/active) */}\r\n <div className=\"cb-block-controls cb-block-controls-right\">\r\n {/* More options */}\r\n <div className=\"cb-block-menu-container\">\r\n <button\r\n type=\"button\"\r\n className=\"cb-block-btn cb-block-more\"\r\n onClick={handleMenuToggle}\r\n title=\"More options\"\r\n tabIndex={-1}\r\n >\r\n <MoreHorizontal size={14} />\r\n </button>\r\n\r\n {showMenu && (\r\n <div className=\"cb-block-dropdown\">\r\n <button\r\n type=\"button\"\r\n className=\"cb-block-dropdown-item\"\r\n onClick={handleAction(onDuplicateBlock)}\r\n >\r\n <Copy size={14} />\r\n <span>Duplicate</span>\r\n </button>\r\n <button\r\n type=\"button\"\r\n className=\"cb-block-dropdown-item\"\r\n onClick={handleAction(onMoveUp)}\r\n >\r\n <MoveUp size={14} />\r\n <span>Move up</span>\r\n </button>\r\n <button\r\n type=\"button\"\r\n className=\"cb-block-dropdown-item\"\r\n onClick={handleAction(onMoveDown)}\r\n >\r\n <MoveDown size={14} />\r\n <span>Move down</span>\r\n </button>\r\n <div className=\"cb-block-dropdown-divider\" />\r\n <button\r\n type=\"button\"\r\n className=\"cb-block-dropdown-item cb-block-dropdown-item-danger\"\r\n onClick={handleAction(onDeleteBlock)}\r\n >\r\n <Trash2 size={14} />\r\n <span>Delete</span>\r\n </button>\r\n </div>\r\n )}\r\n </div>\r\n </div>\r\n </div>\r\n );\r\n};\r\n","/**\r\n * Icons - Using Lucide React\r\n */\r\n\r\nimport {\r\n Type,\r\n Heading1,\r\n Heading2,\r\n Heading3,\r\n Heading4,\r\n Heading5,\r\n Heading6,\r\n List,\r\n ListOrdered,\r\n CheckSquare,\r\n Quote,\r\n Code,\r\n Image,\r\n Video,\r\n Minus,\r\n AlertCircle,\r\n ChevronDown,\r\n Table,\r\n Bold,\r\n Italic,\r\n Underline,\r\n Strikethrough,\r\n Link,\r\n Link2Off,\r\n Highlighter,\r\n Palette,\r\n AlignLeft,\r\n AlignCenter,\r\n AlignRight,\r\n AlignJustify,\r\n Undo,\r\n Redo,\r\n Copy,\r\n Scissors,\r\n ClipboardPaste,\r\n Trash2,\r\n Plus,\r\n GripVertical,\r\n MoreHorizontal,\r\n ChevronUp,\r\n MoveUp,\r\n MoveDown,\r\n Maximize2,\r\n X,\r\n Check,\r\n Search,\r\n Settings,\r\n Sun,\r\n Moon,\r\n FileText,\r\n FileCode,\r\n Download,\r\n Upload,\r\n ExternalLink,\r\n Info,\r\n AlertTriangle,\r\n XCircle,\r\n CheckCircle,\r\n FileIcon,\r\n Indent,\r\n Outdent,\r\n RotateCcw,\r\n Columns,\r\n Rows,\r\n Eraser,\r\n type LucideIcon,\r\n} from 'lucide-react';\r\n\r\nexport type IconName =\r\n | 'paragraph'\r\n | 'heading1'\r\n | 'heading2'\r\n | 'heading3'\r\n | 'heading4'\r\n | 'heading5'\r\n | 'heading6'\r\n | 'list'\r\n | 'listOrdered'\r\n | 'checkList'\r\n | 'quote'\r\n | 'code'\r\n | 'image'\r\n | 'video'\r\n | 'divider'\r\n | 'callout'\r\n | 'accordion'\r\n | 'table'\r\n | 'bold'\r\n | 'italic'\r\n | 'underline'\r\n | 'strikethrough'\r\n | 'link'\r\n | 'unlink'\r\n | 'highlight'\r\n | 'textColor'\r\n | 'alignLeft'\r\n | 'alignCenter'\r\n | 'alignRight'\r\n | 'alignJustify'\r\n | 'undo'\r\n | 'redo'\r\n | 'copy'\r\n | 'cut'\r\n | 'paste'\r\n | 'delete'\r\n | 'plus'\r\n | 'drag'\r\n | 'more'\r\n | 'chevronUp'\r\n | 'chevronDown'\r\n | 'moveUp'\r\n | 'moveDown'\r\n | 'maximize'\r\n | 'close'\r\n | 'check'\r\n | 'search'\r\n | 'settings'\r\n | 'sun'\r\n | 'moon'\r\n | 'document'\r\n | 'codeFile'\r\n | 'download'\r\n | 'upload'\r\n | 'externalLink'\r\n | 'info'\r\n | 'warning'\r\n | 'error'\r\n | 'success'\r\n | 'file'\r\n | 'indent'\r\n | 'outdent'\r\n | 'clear'\r\n | 'columns'\r\n | 'rows'\r\n | 'eraser';\r\n\r\n/**\r\n * Icon map - maps icon names to Lucide components\r\n */\r\nexport const iconMap: Record<IconName, LucideIcon> = {\r\n paragraph: Type,\r\n heading1: Heading1,\r\n heading2: Heading2,\r\n heading3: Heading3,\r\n heading4: Heading4,\r\n heading5: Heading5,\r\n heading6: Heading6,\r\n list: List,\r\n listOrdered: ListOrdered,\r\n checkList: CheckSquare,\r\n quote: Quote,\r\n code: Code,\r\n image: Image,\r\n video: Video,\r\n divider: Minus,\r\n callout: AlertCircle,\r\n accordion: ChevronDown,\r\n table: Table,\r\n bold: Bold,\r\n italic: Italic,\r\n underline: Underline,\r\n strikethrough: Strikethrough,\r\n link: Link,\r\n unlink: Link2Off,\r\n highlight: Highlighter,\r\n textColor: Palette,\r\n alignLeft: AlignLeft,\r\n alignCenter: AlignCenter,\r\n alignRight: AlignRight,\r\n alignJustify: AlignJustify,\r\n undo: Undo,\r\n redo: Redo,\r\n copy: Copy,\r\n cut: Scissors,\r\n paste: ClipboardPaste,\r\n delete: Trash2,\r\n plus: Plus,\r\n drag: GripVertical,\r\n more: MoreHorizontal,\r\n chevronUp: ChevronUp,\r\n chevronDown: ChevronDown,\r\n moveUp: MoveUp,\r\n moveDown: MoveDown,\r\n maximize: Maximize2,\r\n close: X,\r\n check: Check,\r\n search: Search,\r\n settings: Settings,\r\n sun: Sun,\r\n moon: Moon,\r\n document: FileText,\r\n codeFile: FileCode,\r\n download: Download,\r\n upload: Upload,\r\n externalLink: ExternalLink,\r\n info: Info,\r\n warning: AlertTriangle,\r\n error: XCircle,\r\n success: CheckCircle,\r\n file: FileIcon,\r\n indent: Indent,\r\n outdent: Outdent,\r\n clear: RotateCcw,\r\n columns: Columns,\r\n rows: Rows,\r\n eraser: Eraser,\r\n};\r\n\r\n/**\r\n * Get icon component by name\r\n */\r\nexport function getIcon(name: IconName): LucideIcon {\r\n return iconMap[name] || Type;\r\n}\r\n\r\n// Re-export commonly used icons\r\nexport {\r\n Type,\r\n Heading1,\r\n Heading2,\r\n Heading3,\r\n Bold,\r\n Italic,\r\n Underline,\r\n Link,\r\n Code,\r\n List,\r\n ListOrdered,\r\n Quote,\r\n Image,\r\n Table,\r\n Minus,\r\n Plus,\r\n GripVertical,\r\n Undo,\r\n Redo,\r\n AlignLeft,\r\n AlignCenter,\r\n AlignRight,\r\n Trash2,\r\n Settings,\r\n Download,\r\n ChevronDown,\r\n X,\r\n Check,\r\n MoreHorizontal,\r\n};\r\n"],"names":["generateId","deepClone","obj","item","cloned","key","debounce","fn","delay","timeoutId","args","throttle","limit","inThrottle","isBlockElement","element","getBlockFromChild","current","getTextContent","countWords","text","word","countCharacters","includeSpaces","isSelectionCollapsed","selection","getSelectionRange","setSelectionRange","range","saveSelection","_a","restoreSelection","placeCursorAtEnd","placeCursorAtStart","isElementEmpty","stripHtml","html","temp","escapeHtml","div","parseHtml","template","serializeElement","getElementIndex","parent","insertAfter","newElement","referenceElement","insertBefore","swapElements","el1","el2","parent1","sibling1","matchesKeyCombo","event","combo","parts","modifiers","ctrlOrCmd","createElement","tag","attributes","children","value","child","isMobile","isTouchDevice","getComputedStyleValue","property","nextFrame","callback","cancelFrame","id","storage","defaultValue","EventEmitter","__publicField","data","BlockRegistry","definition","name","type","blockData","newType","currentType","currentDefinition","newDefinition","content","editableChild","blockRegistry","paragraphBlock","p","createHeadingBlock","defaultLevel","level","heading","levelAttr","heading1Block","heading2Block","heading3Block","heading4Block","heading5Block","heading6Block","createHeading","createListItemElement","li","wrapper","checkbox","nestedList","parseListItems","listElement","items","clone","createListBlock","list","defaultItem","bulletListBlock","numberedListBlock","checkListBlock","addListItem","afterItemId","afterLi","editable","removeListItem","itemId","toggleChecklistItem","indentListItem","prevLi","outdentListItem","parentList","parentLi","grandparentList","quoteBlock","blockquote","cite","citation","addCitation","removeCitation","LANGUAGES","codeBlock","toolbar","langSelect","lang","option","copyBtn","code","pre","setLanguage","codeWrapper","language","getCode","addResizeHandles","pos","handle","imageBlock","figure","imgContainer","resizableWrapper","img","placeholder","controls","caption","setImageSrc","src","alt","container","setImageAlign","align","createImageFromFile","file","resolve","reject","reader","cropImage","imageSrc","cropArea","originalWidth","originalHeight","canvas","ctx","scaleX","scaleY","sx","sy","sw","sh","createCropModal","onSave","onCancel","modal","aspectRatio","isDragging","isResizing","activeHandle","startX","startY","startCrop","imageWidth","imageHeight","isClosing","imageWrapper","cropImg","cropAreaEl","MIN_SIZE","sizeW","sizeH","updateCropAreaUI","constrainCropArea","area","x","y","width","height","handleCropMouseDown","e","handleHandleMouseDown","handleMouseMove","dx","dy","newX","newY","newWidth","newHeight","maxDx","constrainedDx","maxDy","constrainedDy","ratioFromWidth","ratioFromHeight","handleMouseUp","handleKeyDown","closeModal","cleanup","btn","b","aspect","w","h","centerX","centerY","_b","_c","_d","croppedSrc","err","_e","VIDEO_PATTERNS","videoBlock","embedUrl","getEmbedUrl","iframe","video","url","ytMatch","vimeoMatch","dmMatch","setVideoSrc","dividerBlock","hr","setDividerStyle","style","CALLOUT_ICONS","calloutBlock","calloutType","aside","iconWrapper","contentWrapper","title","body","typeSelector","setCalloutType","icon","selector","addCalloutTitle","accordionBlock","details","summary","titleText","chevron","toggleAccordion","setAccordionOpen","open","tableBlock","table","rows","hasHeader","row","rowIndex","tr","cell","cellTag","td","cells","addTableRow","afterIndex","colCount","i","addTableColumn","isHeader","deleteTableRow","index","deleteTableColumn","setCellAlignment","getFocusedCell","activeElement","getCellPosition","col","allBlocks","defaultBlocks","blockMap","block","getBlockDefinition","ALLOWED_TAGS","TAG_CONVERSIONS","ALLOWED_ATTRIBUTES","DANGEROUS_ATTRIBUTES","ALLOWED_CSS_PROPERTIES","DEFAULT_OPTIONS","sanitizeHtml","options","opts","sanitizeNode","node","depth","nodesToRemove","nodesToReplace","tagName","convertedTag","copyAllowedAttributes","allowedTags","fragment","sanitizeAttributes","n","old","newNode","allowedGlobal","allowedForTag","allowed","attr","kept","c","sanitizeStyles","cssText","newStyles","declaration","s","lowerValue","source","target","sanitizePaste","dataTransfer","cleanOfficeContent","convertPlainTextToHtml","normalizeHtml","currentParagraph","result","SCROLL_THRESHOLD","SCROLL_SPEED","initDragDrop","handleSelector","state","createPlaceholder","getBlocks","findDropTarget","blocks","rect","midY","updatePlaceholder","position","handleAutoScroll","clientY","containerRect","handleDragStart","handleDragMove","handleDragEnd","newIndex","createDragHandle","isDragDropSupported","getSelectionState","getSelectedText","getSelectedHtml","isSelectionInElement","isMultiBlockSelection","startBlock","endBlock","selectAllInElement","collapseToStart","collapseToEnd","setCursorPosition","offset","walker","currentOffset","nodeLength","getCursorOffset","preCaretRange","isCursorAtStart","isCursorAtEnd","postCaretRange","moveCursorToStart","firstTextNode","moveCursorToEnd","wrapSelection","contents","unwrapElement","findElementsInSelection","elements","defaultAttributes","toKebabCase","string","createLucideIcon","iconName","iconNode","Component","forwardRef","color","size","strokeWidth","absoluteStrokeWidth","className","rest","ref","attrs","AlertCircle","AlertTriangle","AlignCenter","AlignJustify","AlignLeft","AlignRight","Bold","CheckCircle","CheckSquare","Check","ChevronDown","ChevronUp","ClipboardPaste","Code","Columns","Copy","Download","Eraser","ExternalLink","FileCode","FileText","File","GripVertical","Heading1","Heading2","Heading3","Heading4","Heading5","Heading6","Highlighter","Image","Indent","Info","Italic","Link2Off","Link","ListOrdered","List","Maximize2","Minus","Moon","MoreHorizontal","MoveDown","MoveUp","Outdent","Palette","Plus","Quote","Redo","RotateCcw","Rows","Scissors","Search","Settings","Strikethrough","Sun","Table","Trash2","Type","Underline","Undo","Upload","Video","XCircle","X","FORMAT_TAGS","isFormatActive","format","toggleFormat","isActive","el","toggleBold","toggleItalic","toggleUnderline","toggleStrikethrough","toggleInlineCode","insertLink","link","newRange","removeLink","setTextColor","setHighlightColor","setAlignment","clearFormatting","insertBlock","referenceBlock","deleteBlock","prevBlock","nextBlock","targetBlock","defaultBlock","moveBlockUp","prevSibling","moveBlockDown","nextSibling","duplicateBlock","newId","transformBlock","newBlock","mergeBlocks","sourceBlock","sourceContent","targetEditable","splitBlock","afterRange","afterContent","blockType","newEditable","indentBlock","currentMargin","outdentBlock","createCommandExecutor","editor","Toolbar","darkMode","activePopover","setActivePopover","useState","popoverPosition","setPopoverPosition","linkUrl","setLinkUrl","linkText","setLinkText","formatState","setFormatState","toolbarRef","useRef","popoverRef","useEffect","updateFormatState","textColors","highlightColors","handleClickOutside","openPopover","useCallback","toolbarRect","handleInsertLink","handleTextColor","handleHighlight","handleExport","filename","blob","a","handleBlockAction","blockId","toolbarGroups","jsxs","group","jsx","button","label","BLOCK_MENU_ITEMS","BlockMenu","onSelect","onClose","search","setSearch","selectedIndex","setSelectedIndex","menuRef","inputRef","filteredItems","searchLower","k","prev","ContentBlocksEditorInner","props","initialContent","enabledBlocks","readOnly","classPrefix","showToolbar","toolbarPosition","autoFocus","spellCheck","onChange","onFocus","onBlur","onReady","containerRef","contentRef","initialContentLoadedRef","undoStackRef","redoStackRef","isMounted","setIsMounted","activeBlockId","setActiveBlockId","showBlockMenu","setShowBlockMenu","blockMenuPosition","setBlockMenuPosition","hoveredBlockId","setHoveredBlockId","selectionVersion","setSelectionVersion","editorState","setEditorState","handleSelectionChange","v","createBlockWithControls","actions","blockElement","tempDiv","detectBlockType","extractBlockData","updateState","emitChange","firstEditable","getHTML","codeEl","preEl","setHTML","restoreFocus","getText","focus","blur","saveToHistory","currentHTML","handleUndo","previous","handleRedo","next","insertBlockAfter","afterBlockId","afterBlock","deleteBlockById","moveBlock","direction","transformBlockType","contentEl","editorStateRef","activeBlockIdRef","editorInstance","useMemo","def","useImperativeHandle","handleImageUpload","input","dataUrl","handleImageInputChange","handleImageAlignClick","typeButton","callout","startWidth","currentImg","currentWrapper","handleType","handleResizeStart","handleResizeMove","diff","containerWidth","handleResizeEnd","handleBlockControlClick","action","newBlockId","tableWrapper","firstRow","contentDiv","newEl","textNode","currentIndex","currentRowIndex","nextCell","prevCells","newRow","newCells","editableContent","focusTarget","newLi","contentSpan","prevType","prevEditable","currentContent","nextEditable","handleInput","handlePaste","cleanHtml","handleFocus","handleBlur","handleBlockMenuSelect","currentBlock","handleMouseEnter","handleMouseLeave","editorClasses","ContentBlocksEditor","processHtml","doc","codeContent","generateStyles","colors","ContentBlocksRenderer","enableCodeCopy","enableChecklistStyles","enableHeadingIds","processedHtml","styles","parseHeadings","minLevel","maxLevel","selectors","headings","stack","TocList","onNavigate","TableOfContents","smoothScroll","targetContainer","collapsible","defaultCollapsed","isCollapsed","setIsCollapsed","React","tocItems","handleNavigate","toggleCollapsed","BlockWrapper","onAddBlock","onDeleteBlock","onDuplicateBlock","onMoveUp","onMoveDown","onDragStart","showMenu","setShowMenu","handleMenuToggle","handleAction","iconMap","FileIcon","getIcon"],"mappings":"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","x_google_ignoreList":[17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83]}