@smart-input/core 1.0.0 → 1.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/core.min.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"core.min.mjs","sources":["../src/state/state.ts","../src/state/useState.ts","../../../node_modules/.pnpm/@emotion+unitless@0.10.0/node_modules/@emotion/unitless/dist/emotion-unitless.esm.js","../../../node_modules/.pnpm/react-style-stringify@1.2.0/node_modules/react-style-stringify/dist/index.mjs","../src/types/block.ts","../src/utils/functions.ts","../src/hooks/useElementObserver.ts","../src/components/UnmanagedEditor/UnmanagedEditor.tsx","../src/hooks/useMutationObserver.ts","../../../node_modules/.pnpm/classnames@2.5.1/node_modules/classnames/index.js","../src/components/Editor/functions.ts","../src/components/Editor/Editor.tsx","../../../node_modules/.pnpm/zustand@5.0.2_@types+react@18.3.12_react@18.3.1/node_modules/zustand/esm/middleware.mjs","../src/state/utils.ts","../src/state/blocksStore.ts","../src/hooks/useChangeNotify.ts","../src/state/bufferStore.ts","../src/types/state/cursorPosition.ts","../src/state/cursorPosition.ts","../src/hooks/useCursorChangeNotify.ts","../src/state/apiStore.ts","../src/state/behaviourStore.ts","../src/state/keyHandlerStore.ts","../src/types/editorProps.ts","../src/state/dragHandlerStore.ts","../src/state/blockRerenderHandlerStore.ts","../src/state/StateProvider.tsx","../src/components/Api/functions.ts","../src/components/Api/Api.tsx","../src/components/SmartInput/SmartInput.tsx","../src/components/ErrorBoundary/ErrorBoundary.tsx","../src/utils/colours.ts","../src/utils/constants.ts","../src/utils/logger.ts"],"sourcesContent":["import React from 'react';\nimport { State } from '@atypes/state';\n\n// @ts-expect-error initialisation later\nexport const StateContext = React.createContext<State>();\n","import React, { useEffect } from 'react';\nimport { StoreApi, UseBoundStore, useStore } from 'zustand';\nimport { StateContext } from '@state/state';\n\nimport {\n BehaviourState,\n BlocksState,\n BufferState,\n CursorPositionState,\n State,\n} from '@atypes/state';\nimport { ApiState } from '@src/types/state/api';\nimport { KeyHandlerState } from '@src/types/state/keyHandler';\nimport { DragHandlerState } from '@src/types/state/dragHandler';\nimport { BlockRerenderHandlerState } from '@src/types/state/blockRerenderHandler';\n\nconst useState = <T extends object, U = unknown>(\n storeSelector: (state: State) => UseBoundStore<StoreApi<T>>,\n selector: (state: T) => U,\n) => {\n const store = storeSelector(React.useContext(StateContext));\n\n if (store === null) {\n throw new Error('useState must be used within StateProvider');\n }\n return useStore<UseBoundStore<StoreApi<T>>, U>(store, selector);\n};\n\nconst useTopLevelSubscribe = <T extends object, U = unknown>(\n store: UseBoundStore<StoreApi<T>>,\n selector: (state: T) => U,\n callback: (current: U, previous: U) => void,\n) => {\n useEffect(() => {\n // @ts-expect-error not a genuine error\n const unsubscribe = store.subscribe(selector, callback);\n return () => {\n unsubscribe();\n };\n }, [store, selector, callback]);\n};\n\nconst useSubscribe = <T extends object, U = unknown>(\n storeSelector: (state: State) => UseBoundStore<StoreApi<T>>,\n selector: (state: T) => U,\n callback: (current: U, previous: U) => void,\n) => {\n const store = storeSelector(React.useContext(StateContext));\n\n if (store === null) {\n throw new Error('useState must be used within StateProvider');\n }\n useEffect(() => {\n // @ts-expect-error not a genuine error\n const unsubscribe = store.subscribe(selector, callback);\n return () => {\n unsubscribe();\n };\n }, [store, selector, callback]);\n};\n\nconst useBlocks = <U = unknown>(selector: (state: BlocksState) => U) =>\n useState((s) => s.blocksStore, selector);\n\nconst useBuffer = <U = unknown>(selector: (state: BufferState) => U) =>\n useState((s) => s.bufferStore, selector);\n\nconst useCursorPosition = <U = unknown>(\n selector: (state: CursorPositionState) => U,\n) => useState((s) => s.cursorPositionStore, selector);\n\nconst useApi = <U = unknown>(selector: (state: ApiState) => U) =>\n useState((s) => s.apiStore, selector);\n\nconst useBehaviour = <U = unknown>(selector: (state: BehaviourState) => U) =>\n useState((s) => s.behaviourStore, selector);\n\nconst useKeyHandlers = <U = unknown>(selector: (state: KeyHandlerState) => U) =>\n useState((s) => s.keyHandlerStore, selector);\n\nconst useDragHandlers = <U = unknown>(\n selector: (state: DragHandlerState) => U,\n) => useState((s) => s.dragHandlerStore, selector);\n\nconst useBlockRerenderHandlers = <U = unknown>(\n selector: (state: BlockRerenderHandlerState) => U,\n) => useState((s) => s.blockRerenderHandlerStore, selector);\n\nconst useTopLevelBlocksSubscriber = <U = unknown>(\n store: UseBoundStore<StoreApi<BlocksState>>,\n selector: (state: BlocksState) => U,\n callback: (current: U, previous: U) => void,\n) => useTopLevelSubscribe(store, selector, callback);\n\nconst useBlocksSubscriber = <U = unknown>(\n selector: (state: BlocksState) => U,\n callback: (current: U, previous: U) => void,\n) => useSubscribe((s) => s.blocksStore, selector, callback);\n\nconst useTopLevelCursorPositionSubscriber = <U = unknown>(\n store: UseBoundStore<StoreApi<CursorPositionState>>,\n selector: (state: CursorPositionState) => U,\n callback: (current: U, previous: U) => void,\n) => useTopLevelSubscribe(store, selector, callback);\n\nconst useCursorPositionSubscriber = <U = unknown>(\n selector: (state: CursorPositionState) => U,\n callback: (current: U, previous: U) => void,\n) => useSubscribe((s) => s.cursorPositionStore, selector, callback);\n\nexport {\n useBlocks,\n useBuffer,\n useCursorPosition,\n useApi,\n useBehaviour,\n useKeyHandlers,\n useDragHandlers,\n useBlockRerenderHandlers,\n useBlocksSubscriber,\n useTopLevelBlocksSubscriber,\n useCursorPositionSubscriber,\n useTopLevelCursorPositionSubscriber,\n};\n","var unitlessKeys = {\n animationIterationCount: 1,\n aspectRatio: 1,\n borderImageOutset: 1,\n borderImageSlice: 1,\n borderImageWidth: 1,\n boxFlex: 1,\n boxFlexGroup: 1,\n boxOrdinalGroup: 1,\n columnCount: 1,\n columns: 1,\n flex: 1,\n flexGrow: 1,\n flexPositive: 1,\n flexShrink: 1,\n flexNegative: 1,\n flexOrder: 1,\n gridRow: 1,\n gridRowEnd: 1,\n gridRowSpan: 1,\n gridRowStart: 1,\n gridColumn: 1,\n gridColumnEnd: 1,\n gridColumnSpan: 1,\n gridColumnStart: 1,\n msGridRow: 1,\n msGridRowSpan: 1,\n msGridColumn: 1,\n msGridColumnSpan: 1,\n fontWeight: 1,\n lineHeight: 1,\n opacity: 1,\n order: 1,\n orphans: 1,\n scale: 1,\n tabSize: 1,\n widows: 1,\n zIndex: 1,\n zoom: 1,\n WebkitLineClamp: 1,\n // SVG-related properties\n fillOpacity: 1,\n floodOpacity: 1,\n stopOpacity: 1,\n strokeDasharray: 1,\n strokeDashoffset: 1,\n strokeMiterlimit: 1,\n strokeOpacity: 1,\n strokeWidth: 1\n};\n\nexport { unitlessKeys as default };\n","// src/helpers.ts\nimport unitless from \"@emotion/unitless\";\nvar DEFAULT_UNIT = \"px\";\nvar isCSSPropertyValue = (value) => typeof value === \"number\" || typeof value === \"string\";\nfunction camelToKebab(str) {\n return str.replace(/[A-Z]/g, (match) => `-${match.toLowerCase()}`);\n}\nfunction trimCssSelector(selector) {\n return selector.replace(/\\s*([+~>])\\s*/g, \"$1\").replace(/\\s{2,}/g, \" \").trim();\n}\nfunction applyCssUnits(property, value, unit = DEFAULT_UNIT) {\n if (typeof value !== \"string\" && typeof value !== \"number\") {\n throw new Error(\n \"Invalid input: value of 'cssProperties' must be string or number.\"\n );\n }\n const isUnitless = unitless[property] === 1;\n if (typeof value === \"string\" || value === 0 || isUnitless) {\n return `${value}`;\n }\n const resolvedUnit = (typeof unit === \"string\" ? unit : unit[property]) || DEFAULT_UNIT;\n return `${value}${resolvedUnit}`;\n}\n\n// src/stringifyStyleDeclaration.ts\nfunction stringifyStyleDeclaration(styleDeclaration, options) {\n if (typeof styleDeclaration !== \"object\" || styleDeclaration === null) {\n throw new TypeError(\n `[stringifyStyleDeclaration]: Expected 'styleDeclaration' to be a non-null object, but received ${styleDeclaration} (type:${typeof styleDeclaration}).`\n );\n }\n const importantSuffix = options?.important ? \"!important\" : \"\";\n return Object.entries(styleDeclaration).filter(([_, value]) => isCSSPropertyValue(value)).map(\n ([property, value]) => `${camelToKebab(property)}:${applyCssUnits(\n property,\n value,\n options?.unit\n )}${importantSuffix};`\n ).join(\"\");\n}\n\n// src/stringifyStyleRule.ts\nfunction stringifyStyleRule(styleRule, options) {\n if (typeof styleRule !== \"object\" || styleRule === null) {\n throw new TypeError(\n `[stringifyStyleRule]: Expected 'styleRule' to be a non-null object, but received ${styleRule} (type:${typeof styleRule}).`\n );\n }\n return Object.entries(styleRule).reduce((result, [selector, declaration]) => {\n if (Object.keys(declaration).length > 0) {\n result.push(\n `${trimCssSelector(selector)}{${stringifyStyleDeclaration(\n declaration,\n options\n )}}`\n );\n }\n return result;\n }, []).join(\"\");\n}\n\n// src/stringify-react-styles.ts\nfunction stringifyCSSProperties(cssProperties, optionsOrImportant = false) {\n if (typeof cssProperties !== \"object\" || cssProperties === null) {\n throw new TypeError(\n `[stringifyCSSProperties]: Expected 'cssProperties' to be a non-null object, but received ${cssProperties} (type:${typeof cssProperties}).`\n );\n }\n const options = typeof optionsOrImportant === \"boolean\" ? {\n important: optionsOrImportant\n } : optionsOrImportant;\n return stringifyStyleDeclaration(cssProperties, options);\n}\nfunction stringifyStyleMap(styleMap, optionsOrImportant = false) {\n if (typeof styleMap !== \"object\" || styleMap === null) {\n throw new TypeError(\n `[stringifyStyleMap]: Expected 'styleMap' to be a non-null object, but received ${styleMap} (type:${typeof styleMap}).`\n );\n }\n const options = typeof optionsOrImportant === \"boolean\" ? {\n important: optionsOrImportant\n } : optionsOrImportant;\n return stringifyStyleRule(styleMap, options);\n}\nexport {\n stringifyCSSProperties,\n stringifyStyleDeclaration,\n stringifyStyleMap,\n stringifyStyleRule\n};\n//# sourceMappingURL=index.mjs.map","import { CSSProperties } from 'react';\n\n/**\n * The type of block in the editor.\n */\nexport enum BlockType {\n /** Plain text block */\n Text = 'text',\n /** Styled block with custom styling and behavior */\n Styled = 'styled',\n /** Document/file attachment block */\n Document = 'document',\n /** Image block */\n Image = 'image',\n}\n\n/**\n * Represents a plain text block in the editor.\n */\nexport interface TextBlock {\n /** The block type identifier */\n type: BlockType.Text;\n /** The text content of the block */\n text: string;\n}\n\n/**\n * Represents a styled block in the editor with custom styling and behavior.\n * Styled blocks can have custom CSS styles, classes, and can be made uneditable or undeletable.\n */\nexport interface StyledBlock {\n /** The block type identifier */\n type: BlockType.Styled;\n /** Unique identifier for the block */\n id: string;\n /** The text content of the block */\n text: string;\n /** Custom CSS styles to apply to the block */\n style?: CSSProperties | undefined;\n /** CSS class name to apply to the block */\n className?: string;\n /** If true, the block's content cannot be edited */\n uneditable?: boolean | undefined;\n /** If true, the block cannot be deleted by the user */\n undeletable?: boolean | undefined;\n}\n\n/**\n * Represents a document/file attachment block in the editor.\n */\nexport interface DocumentBlock {\n /** The block type identifier */\n type: BlockType.Document;\n /** Unique identifier for the block */\n id: string;\n /** The name of the document file */\n name: string;\n /** The File object representing the document */\n file: File;\n /** The URL for accessing the document (e.g., blob URL) */\n url: string;\n /** The MIME content type of the document */\n contentType: string;\n /** If true, the block cannot be deleted by the user */\n undeletable?: boolean | undefined;\n}\n\n/**\n * Represents an image block in the editor.\n */\nexport interface ImageBlock {\n /** The block type identifier */\n type: BlockType.Image;\n /** Unique identifier for the block */\n id: string;\n /** The name of the image file */\n name: string;\n /** The File object representing the image */\n file: File;\n /** The URL for displaying the image (e.g., blob URL) */\n url: string;\n /** Alternative text for accessibility */\n alt?: string | undefined;\n /** The MIME content type of the image */\n contentType: string;\n /** If true, the block cannot be deleted by the user */\n undeletable?: boolean | undefined;\n}\n\n/**\n * A block can be any of the supported block types in the editor.\n */\nexport type Block = TextBlock | StyledBlock | DocumentBlock | ImageBlock;\n","import { Block, BlockType, StyledBlock } from '@atypes/block';\nimport { CommitItem } from '@src/types';\nimport { BlockIndex } from '@src/types/api';\n\nimport { stringifyCSSProperties } from 'react-style-stringify';\n\nconst convertBlocksToCommitItems = (blocks: Block[]): CommitItem[] => {\n const items: CommitItem[] = [];\n let currentText = '';\n\n blocks.forEach((block) => {\n if (block.type === BlockType.Text || block.type === BlockType.Styled) {\n // Accumulate text from text and styled blocks\n currentText += 'text' in block ? block.text : '';\n } else if (block.type === BlockType.Document) {\n // When we hit a document, push accumulated text first\n if (currentText) {\n items.push(currentText);\n currentText = '';\n }\n // Transform DocumentBlock to Document type\n items.push({\n type: 'document',\n name: block.name,\n file: block.file,\n url: block.url,\n contentType: block.contentType,\n });\n } else if (block.type === BlockType.Image) {\n // When we hit an image, push accumulated text first\n if (currentText) {\n items.push(currentText);\n currentText = '';\n }\n // Transform ImageBlock to Image type\n items.push({\n type: 'image',\n name: block.name,\n file: block.file,\n url: block.url,\n ...(block.alt !== undefined ? { alt: block.alt } : {}),\n contentType: block.contentType,\n });\n }\n });\n\n // Push any remaining text at the end\n if (currentText) {\n items.push(currentText);\n }\n\n return items;\n};\n\nconst getCursorPosition = (preElement: HTMLPreElement, selRange: Range) => {\n let charCount = 0;\n\n // Walk through only direct children and their direct text nodes\n for (let i = 0; i < preElement.childNodes.length; i++) {\n const node = preElement.childNodes[i];\n if (!node) continue;\n\n // Check if we've reached the selection container\n if (node === selRange.startContainer) {\n return charCount + selRange.startOffset;\n }\n\n // If the selection is inside this node, we need to check its direct children only\n if (node.contains(selRange.startContainer)) {\n // For elements, check their direct text children only\n if (node.nodeType === Node.ELEMENT_NODE) {\n for (let j = 0; j < node.childNodes.length; j++) {\n const childNode = node.childNodes[j];\n if (!childNode) continue;\n if (childNode === selRange.startContainer) {\n return charCount + selRange.startOffset;\n }\n if (childNode.nodeType === Node.TEXT_NODE) {\n if (childNode.contains(selRange.startContainer)) {\n return charCount + selRange.startOffset;\n }\n charCount += (childNode as Text).length;\n }\n }\n // If we didn't find it in direct children, just return current count\n return charCount;\n } else if (node.nodeType === Node.TEXT_NODE) {\n return charCount + selRange.startOffset;\n }\n }\n\n // Count characters in this top-level node\n if (node.nodeType === Node.TEXT_NODE) {\n charCount += (node as Text).length;\n } else if (node.nodeType === Node.ELEMENT_NODE) {\n const element = node as HTMLElement;\n // Count BR elements as single characters\n if (element.tagName === 'BR') {\n charCount += 1;\n } else {\n // Only count direct text node children of this element\n for (let j = 0; j < node.childNodes.length; j++) {\n const childNode = node.childNodes[j];\n if (!childNode) continue;\n if (childNode.nodeType === Node.TEXT_NODE) {\n charCount += (childNode as Text).length;\n } else if (childNode.nodeType === Node.ELEMENT_NODE) {\n const childElement = childNode as HTMLElement;\n if (childElement.tagName === 'BR') {\n charCount += 1;\n }\n }\n }\n }\n }\n }\n\n return charCount;\n};\n\nconst getPositionAndRect = (range: Range, pre: HTMLPreElement | null) => {\n const rect = range.getBoundingClientRect();\n const characterPosition = pre ? getCursorPosition(pre, range) : 0;\n\n return {\n characterPosition,\n rect: {\n left: rect.left,\n top: rect.top,\n right: rect.right,\n bottom: rect.bottom,\n },\n };\n};\n\n// Document icon as data URI (simple document/file icon)\nconst DOCUMENT_ICON =\n 'data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNDgiIGhlaWdodD0iNDgiIHZpZXdCb3g9IjAgMCA0OCA0OCIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48cmVjdCB3aWR0aD0iNDgiIGhlaWdodD0iNDgiIGZpbGw9IiNGNUY1RjUiLz48cGF0aCBkPSJNMTIgOEMxMiA2Ljg5NTQzIDEyLjg5NTQgNiAxNCA2SDI2TDM2IDE2VjQwQzM2IDQxLjEwNDYgMzUuMTA0NiA0MiAzNCA0MkgxNEMxMi44OTU0IDQyIDEyIDQxLjEwNDYgMTIgNDBWOFoiIGZpbGw9IiM0Mjg1RjQiLz48cGF0aCBkPSJNMjYgNlYxNEgyNlYxNkgzNkwyNiA2WiIgZmlsbD0iIzFBNzNFOCIvPjxwYXRoIGQ9Ik0xOCAyMkgzME0xOCAyNkgzME0xOCAzMEgyNiIgc3Ryb2tlPSJ3aGl0ZSIgc3Ryb2tlLXdpZHRoPSIyIiBzdHJva2UtbGluZWNhcD0icm91bmQiLz48L3N2Zz4=';\n\ninterface CreateElementOptions {\n imageWidth?: string;\n imageHeight?: string;\n documentWidth?: string;\n documentHeight?: string;\n onDeleteBlock?: (blockId: string) => void;\n}\n\nconst createElement = (block: Block, options?: CreateElementOptions): Node => {\n if (block.type === BlockType.Text) {\n return document.createTextNode(block.text);\n }\n if (block.type === BlockType.Document) {\n const container = document.createElement('span');\n container.id = block.id;\n container.style.cssText =\n 'position: relative; display: inline-block; vertical-align: middle; margin: 2px; cursor: pointer;';\n container.setAttribute('data-block-type', 'document');\n container.setAttribute('contenteditable', 'false');\n container.classList.add('media-block-container');\n\n // Open in new window on double click\n container.ondblclick = (e) => {\n e.preventDefault();\n e.stopPropagation();\n if (block.url) {\n window.open(block.url, '_blank');\n }\n };\n\n const img = document.createElement('img');\n img.src = DOCUMENT_ICON;\n img.alt = block.name;\n img.title = block.name;\n const width = options?.documentWidth || '32px';\n const height = options?.documentHeight || '32px';\n img.style.cssText = `width: ${width}; height: ${height}; display: block;`;\n img.setAttribute('contenteditable', 'false');\n\n const deleteBtn = document.createElement('button');\n deleteBtn.innerHTML = '×';\n deleteBtn.className = 'media-delete-btn';\n deleteBtn.setAttribute('contenteditable', 'false');\n deleteBtn.style.cssText =\n 'position: absolute; top: -8px; right: -8px; width: 20px; height: 20px; border-radius: 50%; background: #ff4444; color: white; border: 2px solid white; cursor: pointer; font-size: 16px; line-height: 16px; padding: 0; display: none; z-index: 10;';\n if (options?.onDeleteBlock) {\n deleteBtn.onclick = (e) => {\n e.preventDefault();\n e.stopPropagation();\n options.onDeleteBlock?.(block.id);\n };\n }\n\n container.appendChild(img);\n container.appendChild(deleteBtn);\n return container;\n }\n if (block.type === BlockType.Image) {\n const container = document.createElement('span');\n container.id = block.id;\n container.style.cssText =\n 'position: relative; display: inline-block; vertical-align: middle; margin: 2px; cursor: pointer;';\n container.setAttribute('data-block-type', 'image');\n container.setAttribute('contenteditable', 'false');\n container.classList.add('media-block-container');\n\n // Open in new window on double click\n container.ondblclick = (e) => {\n e.preventDefault();\n e.stopPropagation();\n if (block.url) {\n window.open(block.url, '_blank');\n }\n };\n\n const img = document.createElement('img');\n img.src = block.url;\n img.alt = block.alt || block.name;\n img.title = block.name;\n const width = options?.imageWidth || '32px';\n const height = options?.imageHeight || '32px';\n img.style.cssText = `max-width: ${width}; max-height: ${height}; display: block;`;\n img.setAttribute('contenteditable', 'false');\n\n const deleteBtn = document.createElement('button');\n deleteBtn.innerHTML = '×';\n deleteBtn.className = 'media-delete-btn';\n deleteBtn.setAttribute('contenteditable', 'false');\n deleteBtn.style.cssText =\n 'position: absolute; top: -8px; right: -8px; width: 20px; height: 20px; border-radius: 50%; background: #ff4444; color: white; border: 2px solid white; cursor: pointer; font-size: 16px; line-height: 16px; padding: 0; display: none; z-index: 10;';\n if (options?.onDeleteBlock) {\n deleteBtn.onclick = (e) => {\n e.preventDefault();\n e.stopPropagation();\n options.onDeleteBlock?.(block.id);\n };\n }\n\n container.appendChild(img);\n container.appendChild(deleteBtn);\n return container;\n }\n const element = document.createElement('span');\n element.id = block.id;\n element.textContent = block.text;\n if ('style' in block && block.style) {\n element.style.cssText = stringifyCSSProperties(block.style);\n }\n return element;\n};\n\nconst preContainsTextNode = (\n preElement: HTMLPreElement,\n text: string,\n start: number,\n): boolean => {\n for (let i = start; i < preElement.childNodes.length; i++) {\n const element = preElement.childNodes[i];\n if (!element) continue;\n if (element.nodeName === '#text' && element.textContent === text) {\n return true;\n }\n }\n return false;\n};\n\nconst preContainsNode = (\n preElement: HTMLPreElement,\n id: string,\n start: number,\n): boolean => {\n for (let i = start; i < preElement.childNodes.length; i++) {\n const element = preElement.childNodes[i];\n if (!element) continue;\n if ('id' in element && element.id === id) {\n return true;\n }\n }\n return false;\n};\n\nconst getSelectionRange = (preElement: HTMLPreElement) => {\n const selection = document.getSelection();\n if (!selection) return null;\n if (selection.anchorNode === preElement && preElement.lastChild) {\n const range = document.createRange();\n if (preElement.lastChild) {\n if (preElement.lastChild.nodeType === Node.ELEMENT_NODE) {\n range.setStartAfter(preElement.lastChild);\n } \n // If it's a text node, place cursor at the end of the text\n else if (preElement.lastChild.nodeType === Node.TEXT_NODE) {\n range.setStart(preElement.lastChild, (preElement.lastChild as Text).length);\n }\n range.collapse(true);\n return range;\n } \n }\n if (selection.rangeCount > 0) {\n return selection.getRangeAt(0);\n }\n return null;\n};\n\nconst replaceLineFeeds = (text: string) => {\n return text.replaceAll('\\r\\n', '\\n').replaceAll('\\r', '\\n');\n};\n\nconst getBlockAndOffset = (position: number, blocks: Block[]) => {\n let pos = Math.max(0, Math.floor(position));\n for (let i = 0; i < blocks.length; i++) {\n const b = blocks[i];\n if (!b) continue;\n if (b.type !== BlockType.Text && b.type !== BlockType.Styled) {\n continue;\n }\n const len = 'text' in b ? b.text?.length ?? 0 : 0;\n if (pos <= len) {\n return { index: i, offset: pos, block: b };\n }\n pos -= len;\n }\n // position beyond end -> return last block end (or empty)\n if (blocks.length === 0)\n return { index: 0, offset: 0, block: undefined as unknown as Block };\n const last = blocks[blocks.length - 1];\n if (!last) {\n return { index: 0, offset: 0, block: undefined as unknown as Block };\n }\n const lastLen =\n last.type === BlockType.Text\n ? 'text' in last\n ? last.text?.length ?? 0\n : 0\n : 'text' in last\n ? last.text?.length ?? 0\n : 0;\n return { index: blocks.length - 1, offset: lastLen, block: last };\n};\n\nconst insertCarridgeReturnInString = (text: string, offset: number) => {\n const start = offset > 0 ? text.substring(0, offset) : '';\n const end = offset < text.length ? text.substring(offset, text.length) : '';\n return start + '\\n' + end;\n};\n\nconst insertCarridgeReturn = (pre: HTMLPreElement, blocks: Block[]) => {\n const range = getSelectionRange(pre);\n const characterPosition = range ? getCursorPosition(pre, range) : 0;\n const { index, block, offset } = getBlockAndOffset(characterPosition, blocks);\n if (\n !block ||\n (block.type !== BlockType.Text && block.type !== BlockType.Styled)\n ) {\n return blocks;\n }\n const newBlock = {\n ...block,\n text: insertCarridgeReturnInString(block.text, offset),\n };\n setCursorPosition(pre, characterPosition + 1);\n return blocks.map((b, idx) => (idx === index ? newBlock : b));\n};\n\nconst isCarridgeReturn = (childNode: ChildNode) => {\n return (\n childNode.nodeName === 'DIV' &&\n childNode.childNodes.length > 0 &&\n childNode.firstChild?.nodeName === 'BR'\n );\n};\n\nconst setCursorPosition = (\n preElement: HTMLElement,\n characterPosition: number,\n) => {\n // set cursor position to characterPosition\n const newRange = document.createRange();\n const sel = window.getSelection();\n let charCount = 0;\n let foundStart = false;\n\n // Walk through only direct children and their direct text nodes\n for (let i = 0; i < preElement.childNodes.length; i++) {\n const node = preElement.childNodes[i];\n if (!node) continue;\n\n if (node.nodeType === Node.TEXT_NODE) {\n // Top-level text node\n const nodeLength = (node as Text).length;\n const nextCharCount = charCount + nodeLength;\n if (\n characterPosition === nextCharCount &&\n node.nextSibling &&\n 'contentEditable' in node.nextSibling &&\n node.nextSibling.contentEditable !== 'true'\n ) {\n foundStart = true;\n newRange.setStartAfter(node.nextSibling);\n break;\n }\n if (characterPosition <= nextCharCount) {\n foundStart = true;\n newRange.setStart(node, characterPosition - charCount);\n break;\n }\n charCount = nextCharCount;\n } else if (node.nodeType === Node.ELEMENT_NODE) {\n const element = node as HTMLElement;\n // Handle BR elements as single characters\n if (element.tagName === 'BR') {\n const nextCharCount = charCount + 1;\n if (characterPosition <= nextCharCount) {\n foundStart = true;\n newRange.setStart(node, 0);\n break;\n }\n charCount = nextCharCount;\n } else {\n // Only count direct text node children of this element\n for (let j = 0; j < node.childNodes.length; j++) {\n const childNode = node.childNodes[j];\n if (!childNode) continue;\n if (childNode.nodeType === Node.TEXT_NODE) {\n const nodeLength = (childNode as Text).length;\n const nextCharCount = charCount + nodeLength;\n if (characterPosition <= nextCharCount) {\n foundStart = true;\n newRange.setStart(childNode, characterPosition - charCount);\n break;\n }\n charCount = nextCharCount;\n } else if (childNode.nodeType === Node.ELEMENT_NODE) {\n const childElement = childNode as HTMLElement;\n if (childElement.tagName === 'BR') {\n const nextCharCount = charCount + 1;\n if (characterPosition <= nextCharCount) {\n foundStart = true;\n newRange.setStart(childNode, 0);\n break;\n }\n charCount = nextCharCount;\n }\n }\n }\n if (foundStart) {\n break;\n }\n }\n }\n }\n\n if (!foundStart && preElement.lastChild) {\n newRange.setStartAfter(preElement.lastChild);\n }\n newRange.collapse(true);\n if (sel) {\n sel.removeAllRanges();\n sel.addRange(newRange);\n }\n};\n\nconst removeMatchedText = (text: string, matchedText: string): string => {\n const regex = new RegExp(\n matchedText.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&'),\n 'i',\n );\n return text.replace(regex, '');\n};\n\nconst getBlockIndexAtPosition = (\n position: number,\n blocks: Block[],\n): { index: number; offset: number } | null => {\n let blockStart = 0;\n for (let i = 0; i < blocks.length; i++) {\n const block = blocks[i];\n if (!block) continue;\n const blockLength = 'text' in block ? block.text.length : 0;\n if (position >= blockStart && position < blockStart + blockLength) {\n return {\n index: i,\n offset: position - blockStart,\n };\n }\n blockStart += blockLength;\n }\n return null;\n};\n\nconst replaceTextAtPosition = (\n blocks: Block[],\n position: number,\n oldText: string,\n newText: string,\n) => {\n const currentBlocks = blocks ?? [];\n const pos = Math.max(0, position ?? 0);\n\n // Find the block that contains the position\n let blockIndex = -1;\n let blockStart = 0;\n for (let i = 0; i < currentBlocks.length; i++) {\n const block = currentBlocks[i];\n if (!block) continue;\n const blockLength = 'text' in block ? block.text.length : 0;\n if (pos >= blockStart && pos < blockStart + blockLength) {\n blockIndex = i;\n break;\n }\n blockStart += blockLength;\n }\n\n // If no block found or oldText is not in the block, return false\n if (blockIndex === -1) {\n return null;\n }\n\n const currentBlock = currentBlocks[blockIndex];\n if (!currentBlock || !('text' in currentBlock)) {\n return null; // Can't replace text in non-text blocks\n }\n\n const blockText = currentBlock.text;\n const blockPos = pos - blockStart; // position within the block\n\n // Check if oldText is completely within the block\n const oldTextIndex = blockText.indexOf(oldText, blockPos);\n if (oldTextIndex !== blockPos) {\n return null; // oldText not found at the correct position\n }\n\n const newBlockText =\n blockText.slice(0, oldTextIndex) +\n newText +\n blockText.slice(oldTextIndex + oldText.length);\n const newBlocks = [...currentBlocks];\n newBlocks[blockIndex] = {\n ...currentBlock,\n text: newBlockText,\n };\n return {\n newBlocks,\n newPosition: position + newText.length,\n };\n};\n\nconst insertStyledBlockAtPosition = (\n blocks: Block[],\n position: number,\n oldText: string,\n id: string,\n text: string,\n style: React.CSSProperties,\n) => {\n const currentBlocks = blocks ?? [];\n let blockIndex = -1;\n let blockStart = 0;\n\n // Find the block that contains the position\n for (let i = 0; i < currentBlocks.length; i++) {\n const block = currentBlocks[i];\n if (!block) continue;\n const blockLength = 'text' in block ? block.text.length : 0;\n if (position >= blockStart && position < blockStart + blockLength) {\n blockIndex = i;\n break;\n }\n blockStart += blockLength;\n }\n\n const newBlocks = [...currentBlocks];\n const posInBlock = position - blockStart;\n\n if (blockIndex === -1) {\n // Position is at the end or before any blocks\n newBlocks.push({\n id,\n type: BlockType.Styled,\n text: text,\n style: style,\n } as Block);\n } else {\n // Split the current block and insert the styled block\n const currentBlock = newBlocks[blockIndex];\n if (!currentBlock) {\n return { newBlocks: currentBlocks, newPosition: position };\n }\n\n // Only process blocks that have text\n if (!('text' in currentBlock)) {\n return { newBlocks: currentBlocks, newPosition: position };\n }\n\n const beforeText = currentBlock.text.slice(0, posInBlock);\n const afterText = currentBlock.text.slice(posInBlock + oldText.length);\n\n if (posInBlock > 0) {\n newBlocks[blockIndex] = { ...currentBlock, text: beforeText };\n } else {\n newBlocks.splice(blockIndex, 1);\n blockIndex -= 1;\n }\n newBlocks.splice(blockIndex + 1, 0, {\n id,\n type: BlockType.Styled,\n text: text,\n style: style,\n } as Block);\n\n if (afterText) {\n newBlocks.splice(blockIndex + 2, 0, { ...currentBlock, text: afterText });\n }\n }\n\n return {\n newBlocks,\n newPosition: position + text.length,\n };\n};\n\nconst transformToTextBlocks = (blocks: Block[], blockIndexes: BlockIndex[]) => {\n const currentBlocks = blocks ?? [];\n\n // Sort indices in descending order to safely remove blocks without affecting earlier indices\n const sortedIndices = blockIndexes\n .map((bi) => (typeof bi === 'number' ? bi : bi.idx))\n .sort((a, b) => b - a);\n\n const newBlocks = [...currentBlocks];\n\n for (const idx of sortedIndices) {\n if (idx < 0 || idx >= newBlocks.length) continue;\n\n const blockToTransform = newBlocks[idx];\n if (!blockToTransform) continue;\n\n // Skip blocks without text property\n if (!('text' in blockToTransform)) continue;\n\n const precedingBlock = idx > 0 ? newBlocks[idx - 1] : null;\n\n // If there's a preceding text block, merge with it\n if (precedingBlock && precedingBlock.type === BlockType.Text) {\n const mergedText = precedingBlock.text + blockToTransform.text;\n newBlocks[idx - 1] = { ...precedingBlock, text: mergedText };\n newBlocks.splice(idx, 1);\n } else {\n // Otherwise, convert to text block\n newBlocks[idx] = { ...blockToTransform, type: BlockType.Text };\n }\n }\n return {\n newBlocks,\n };\n};\n\nconst splitTextFromStyledBlock = (\n blocks: Block[],\n styled: StyledBlock,\n index: number,\n lookup: string,\n) => {\n const isAfter = styled.text.indexOf(lookup) === 0;\n const newText = styled.text.replace(lookup, '');\n const newBlocks: Block[] = [\n ...blocks.slice(0, index),\n ...(!isAfter\n ? [\n {\n type: BlockType.Text,\n text: newText,\n } as Block,\n ]\n : []),\n {\n ...styled,\n text: lookup,\n } as Block,\n ...(isAfter\n ? [\n {\n type: BlockType.Text,\n text: newText,\n } as Block,\n ]\n : []),\n ...blocks.slice(index + 1),\n ];\n return {\n newBlocks,\n };\n};\n\n/**\n * Generate a unique ID for blocks\n */\nconst generateId = (): string => {\n return `${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;\n};\n\n/**\n * Check if a file is an image\n */\nconst isImageFile = (file: File): boolean => {\n return file.type.startsWith('image/');\n};\n\n/**\n * Get caret range from point with cross-browser support\n */\nconst getCaretRangeFromPoint = (\n clientX: number,\n clientY: number,\n): Range | null => {\n if (document.caretRangeFromPoint) {\n return document.caretRangeFromPoint(clientX, clientY);\n } else if ((document as any).caretPositionFromPoint) {\n const position = (document as any).caretPositionFromPoint(clientX, clientY);\n if (position) {\n const range = document.createRange();\n range.setStart(position.offsetNode, position.offset);\n return range;\n }\n }\n return null;\n};\n\n/**\n * Check if a DataTransfer contains valid file content\n */\nconst hasValidContent = (dataTransfer: DataTransfer): boolean => {\n // During dragover, files array may be empty for security reasons\n // Check types or items instead\n if (dataTransfer.types && dataTransfer.types.includes('Files')) {\n return true;\n }\n // Fallback to checking files (available in drop event)\n return dataTransfer.files && dataTransfer.files.length > 0;\n};\n\n/**\n * Check if a block is draggable (Image, Document, or uneditable Styled blocks)\n */\nconst isDraggableBlock = (block: Block, blockId: string): boolean => {\n if (!('id' in block) || block.id !== blockId) return false;\n // Allow dragging of Image and Document blocks\n if (block.type === BlockType.Image || block.type === BlockType.Document)\n return true;\n // For Styled blocks, only allow dragging if they are uneditable\n if (block.type === BlockType.Styled) return block.uneditable === true;\n return false;\n};\n\nexport {\n convertBlocksToCommitItems,\n getCursorPosition,\n getPositionAndRect,\n setCursorPosition,\n preContainsTextNode,\n createElement,\n preContainsNode,\n getSelectionRange,\n replaceLineFeeds,\n insertCarridgeReturn,\n isCarridgeReturn,\n removeMatchedText,\n getBlockIndexAtPosition,\n replaceTextAtPosition,\n insertStyledBlockAtPosition,\n transformToTextBlocks,\n splitTextFromStyledBlock,\n generateId,\n isImageFile,\n getCaretRangeFromPoint,\n hasValidContent,\n isDraggableBlock,\n};\n","import { useEffect, useRef } from 'react';\n\n/**\n * Hook that observes an element for position and size changes.\n * Calls the provided callback when either the element's size changes\n * or its position changes (due to scrolling or layout shifts).\n *\n * @param element - The DOM element to observe\n * @param callback - Function to call when position or size changes\n *\n * @example\n * ```tsx\n * const preRef = useRef<HTMLPreElement>(null);\n *\n * useElementObserver(preRef.current, () => {\n * console.log('Element position or size changed');\n * updateCursorPosition();\n * });\n * ```\n */\nexport const useElementObserver = (\n element: HTMLElement | null,\n callback: () => void,\n) => {\n const lastPositionRef = useRef({ top: 0, left: 0 });\n const callbackRef = useRef(callback);\n\n // Keep callback ref up to date\n useEffect(() => {\n callbackRef.current = callback;\n }, [callback]);\n\n useEffect(() => {\n if (!element) return;\n\n let rafId: number | null = null;\n let isObserving = true;\n\n const triggerCallback = () => {\n callbackRef.current();\n };\n\n // Check for position changes using requestAnimationFrame\n const checkPosition = () => {\n if (!isObserving || !element) return;\n\n const rect = element.getBoundingClientRect();\n const currentPosition = { top: rect.top, left: rect.left };\n\n // Check if position has changed\n if (\n currentPosition.top !== lastPositionRef.current.top ||\n currentPosition.left !== lastPositionRef.current.left\n ) {\n lastPositionRef.current = currentPosition;\n triggerCallback();\n }\n\n rafId = requestAnimationFrame(checkPosition);\n };\n\n // Use ResizeObserver for size changes\n let resizeObserver: ResizeObserver | null = null;\n if (typeof ResizeObserver !== 'undefined') {\n resizeObserver = new ResizeObserver(triggerCallback);\n resizeObserver.observe(element);\n }\n\n // Use IntersectionObserver to detect position changes efficiently\n let intersectionObserver: IntersectionObserver | null = null;\n if (typeof IntersectionObserver !== 'undefined') {\n intersectionObserver = new IntersectionObserver(triggerCallback, {\n root: null, // viewport\n threshold: [0, 0.25, 0.5, 0.75, 1],\n });\n intersectionObserver.observe(element);\n }\n\n // Listen for scroll events on window and scrollable ancestors\n window.addEventListener('scroll', triggerCallback, true);\n window.addEventListener('resize', triggerCallback);\n\n // Start position checking as fallback\n rafId = requestAnimationFrame(checkPosition);\n\n return () => {\n isObserving = false;\n if (rafId !== null) {\n cancelAnimationFrame(rafId);\n }\n if (resizeObserver) {\n resizeObserver.disconnect();\n }\n if (intersectionObserver) {\n intersectionObserver.disconnect();\n }\n window.removeEventListener('scroll', triggerCallback, true);\n window.removeEventListener('resize', triggerCallback);\n };\n }, [element]);\n};\n","import React, {\n ClipboardEvent,\n forwardRef,\n KeyboardEvent,\n memo,\n useCallback,\n useRef,\n} from 'react';\nimport {\n useApi,\n useBehaviour,\n useCursorPosition,\n useDragHandlers,\n useKeyHandlers,\n} from '@state/useState';\nimport { getPositionAndRect, getSelectionRange } from '../../utils/functions';\nimport { useElementObserver } from '../../hooks/useElementObserver';\nimport styles from './UnmanagedEditor.module.less';\n\n/**\n * Props for the UnmanagedEditor component.\n */\ninterface UnmanagedEditorProps {\n /** Callback invoked when the editor content changes */\n onChange: (isReturn?: boolean) => void;\n /** Callback invoked when undo is triggered (Ctrl/Cmd+Z) */\n onUndo: () => void;\n /** Whether to allow line breaks (default: false) */\n enableLineBreaks?: boolean;\n /** Placeholder text shown when editor is empty */\n placeholder?: string;\n /** Custom CSS class name to apply to the editor area */\n className?: string | undefined;\n}\n\n/**\n * UnmanagedEditor provides the low-level contentEditable interface.\n * This component handles keyboard events, cursor tracking, and user interactions.\n * It's typically used internally by the Editor component rather than directly.\n *\n * @component\n * @internal\n */\nexport const UnmanagedEditor = memo(\n forwardRef<HTMLPreElement, UnmanagedEditorProps>((props, ref) => {\n const {\n onChange,\n onUndo,\n enableLineBreaks = false,\n placeholder = 'Start typing',\n className,\n } = props;\n const keyHandlers = useKeyHandlers((s) => s.keyHandlers);\n const { dragOverHandlers, dragLeaveHandlers, dropHandlers } =\n useDragHandlers((s) => s);\n const preRef = useRef<HTMLPreElement | null>(null);\n const { updatePosition } = useCursorPosition((s) => s);\n const { setElement } = useApi((s) => s);\n const selectionInProgress = useBehaviour((s) => s.selectionInProgress);\n\n const setRef = useCallback(\n (element: HTMLPreElement | null) => {\n if (!ref) return;\n if (typeof ref === 'function') {\n ref(element);\n } else {\n // Type assertion to allow assignment to current\n (ref as React.MutableRefObject<HTMLPreElement | null>).current =\n element;\n }\n preRef.current = element;\n setElement(preRef.current);\n },\n [ref, setElement],\n );\n\n const handleKeyDown = useCallback(\n (event: KeyboardEvent<HTMLPreElement>) => {\n if (keyHandlers.length > 0) {\n for (const handler of keyHandlers) {\n if (handler({ ...event })) {\n event.preventDefault();\n event.stopPropagation();\n break;\n }\n }\n }\n if (\n event.key === 'Enter' &&\n (selectionInProgress || !enableLineBreaks)\n ) {\n event.preventDefault();\n return;\n }\n if (event.key === 'z' && (event.ctrlKey || event.metaKey)) {\n onUndo();\n event.preventDefault();\n return;\n }\n },\n [onUndo, selectionInProgress, enableLineBreaks, keyHandlers],\n );\n\n const updateCursorPosition = useCallback(() => {\n if (!preRef.current) return;\n const range = getSelectionRange(preRef.current);\n if (range) {\n const { characterPosition, rect } = getPositionAndRect(\n range,\n preRef.current,\n );\n updatePosition(characterPosition, rect);\n }\n }, [updatePosition]);\n\n // Monitor pre element for position and size changes\n useElementObserver(preRef.current, updateCursorPosition);\n\n const handleKeyUp = useCallback(\n (event: KeyboardEvent) => {\n if (\n event.key === 'Enter' &&\n (selectionInProgress || !enableLineBreaks)\n ) {\n event.preventDefault();\n return;\n }\n updateCursorPosition();\n onChange(event.key === 'Enter');\n },\n [updateCursorPosition, onChange, enableLineBreaks, selectionInProgress],\n );\n\n const handleChange = useCallback(() => {\n updateCursorPosition();\n onChange();\n }, [updateCursorPosition, onChange]);\n\n const handleCopy = useCallback((event: ClipboardEvent<HTMLPreElement>) => {\n const selection = document.getSelection();\n if (selection && selection.rangeCount > 0) {\n const range = selection.getRangeAt(0);\n const fragment = range.cloneContents();\n const container = document.createElement('div');\n container.appendChild(fragment);\n const text = container.textContent ?? '';\n const html = container.innerHTML ?? '';\n event.clipboardData.setData('text/plain', text);\n event.clipboardData.setData('text/html', html);\n event.preventDefault();\n } else if (preRef.current) {\n const text = preRef.current.textContent ?? '';\n const html = preRef.current.innerHTML ?? text;\n event.clipboardData.setData('text/plain', text);\n event.clipboardData.setData('text/html', html);\n event.preventDefault();\n }\n }, []);\n\n const handlePaste = useCallback(\n (event: React.ClipboardEvent<HTMLPreElement>) => {\n const text = event.clipboardData.getData('text/plain');\n document.execCommand('insertText', false, text);\n event.preventDefault();\n },\n [],\n );\n\n const handleDragOver = useCallback(\n (event: React.DragEvent<HTMLPreElement>) => {\n for (let index = 0; index < dragOverHandlers.length; index++) {\n const handler = dragOverHandlers[index];\n if (handler && handler(event)) {\n event.preventDefault();\n break;\n }\n }\n },\n [dragOverHandlers],\n );\n\n const handleDragLeave = useCallback(\n (event: React.DragEvent<HTMLPreElement>) => {\n for (let index = 0; index < dragLeaveHandlers.length; index++) {\n const handler = dragLeaveHandlers[index];\n if (handler && handler(event)) {\n event.preventDefault();\n break;\n }\n }\n },\n [dragLeaveHandlers],\n );\n\n const handleDrop = useCallback(\n (event: React.DragEvent<HTMLPreElement>) => {\n for (let index = 0; index < dropHandlers.length; index++) {\n const handler = dropHandlers[index];\n if (handler && handler(event)) {\n event.preventDefault();\n break;\n }\n }\n },\n [dropHandlers],\n );\n\n return (\n <pre\n id=\"si-edit-element\"\n className={`${styles['editor']} ${className ?? ''}`}\n contentEditable={true}\n role=\"textbox\"\n tabIndex={0}\n aria-label={placeholder}\n aria-multiline={enableLineBreaks}\n ref={setRef}\n autoCapitalize=\"none\"\n autoCorrect=\"off\"\n spellCheck=\"false\"\n onChange={handleChange}\n onKeyDown={handleKeyDown}\n onKeyUp={handleKeyUp}\n onMouseUp={updateCursorPosition}\n onClick={updateCursorPosition}\n onCopy={handleCopy}\n onPaste={handlePaste}\n onDragOver={handleDragOver}\n onDragLeave={handleDragLeave}\n onDrop={handleDrop}\n data-placeholder={placeholder}\n />\n );\n }),\n);\n\nUnmanagedEditor.displayName = 'UnmanagedEditor';\n","import { useEffect } from 'react';\n\n/**\n * Hook that sets up a MutationObserver to watch for changes in the DOM tree.\n * Useful for reacting to dynamic DOM changes in the editor.\n *\n * @param targetNode - The DOM node to observe\n * @param callback - Function to call when mutations are observed\n * @param options - MutationObserver configuration options\n *\n * @example\n * ```tsx\n * const editorRef = useRef<HTMLDivElement>(null);\n *\n * useMutationObserver(\n * editorRef.current?.querySelector('pre'),\n * (mutations) => {\n * console.log('DOM changed:', mutations);\n * // Reattach event listeners or update state\n * },\n * { childList: true, subtree: true }\n * );\n * ```\n */\nexport const useMutationObserver = (\n targetNode: Node | null,\n callback: MutationCallback,\n options?: MutationObserverInit,\n) => {\n useEffect(() => {\n if (!targetNode) return;\n\n const observer = new MutationObserver(callback);\n\n observer.observe(targetNode, options);\n\n callback([], observer);\n return () => observer.disconnect();\n }, [options, targetNode, callback]);\n};\n","/*!\n\tCopyright (c) 2018 Jed Watson.\n\tLicensed under the MIT License (MIT), see\n\thttp://jedwatson.github.io/classnames\n*/\n/* global define */\n\n(function () {\n\t'use strict';\n\n\tvar hasOwn = {}.hasOwnProperty;\n\n\tfunction classNames () {\n\t\tvar classes = '';\n\n\t\tfor (var i = 0; i < arguments.length; i++) {\n\t\t\tvar arg = arguments[i];\n\t\t\tif (arg) {\n\t\t\t\tclasses = appendClass(classes, parseValue(arg));\n\t\t\t}\n\t\t}\n\n\t\treturn classes;\n\t}\n\n\tfunction parseValue (arg) {\n\t\tif (typeof arg === 'string' || typeof arg === 'number') {\n\t\t\treturn arg;\n\t\t}\n\n\t\tif (typeof arg !== 'object') {\n\t\t\treturn '';\n\t\t}\n\n\t\tif (Array.isArray(arg)) {\n\t\t\treturn classNames.apply(null, arg);\n\t\t}\n\n\t\tif (arg.toString !== Object.prototype.toString && !arg.toString.toString().includes('[native code]')) {\n\t\t\treturn arg.toString();\n\t\t}\n\n\t\tvar classes = '';\n\n\t\tfor (var key in arg) {\n\t\t\tif (hasOwn.call(arg, key) && arg[key]) {\n\t\t\t\tclasses = appendClass(classes, key);\n\t\t\t}\n\t\t}\n\n\t\treturn classes;\n\t}\n\n\tfunction appendClass (value, newClass) {\n\t\tif (!newClass) {\n\t\t\treturn value;\n\t\t}\n\t\n\t\tif (value) {\n\t\t\treturn value + ' ' + newClass;\n\t\t}\n\t\n\t\treturn value + newClass;\n\t}\n\n\tif (typeof module !== 'undefined' && module.exports) {\n\t\tclassNames.default = classNames;\n\t\tmodule.exports = classNames;\n\t} else if (typeof define === 'function' && typeof define.amd === 'object' && define.amd) {\n\t\t// register as 'classnames', consistent with npm package name\n\t\tdefine('classnames', [], function () {\n\t\t\treturn classNames;\n\t\t});\n\t} else {\n\t\twindow.classNames = classNames;\n\t}\n}());\n","import { Block, EditorProps } from '@src/types';\nimport { stringifyCSSProperties } from 'react-style-stringify';\n\nconst addBlockEventListeners = (\n element: HTMLElement,\n block: Block,\n options: EditorProps,\n) => {\n (window as any).lastAddBlockEventListeners = {\n blockId: 'id' in block ? block.id : 'no-id',\n optionsKeys: Object.keys(options),\n hasOnBlockClick: !!options.onBlockClick,\n };\n const {\n onBlockClick,\n onBlockDblClick,\n onBlockMouseUp,\n onBlockMouseDown,\n onBlockMouseEnter,\n onBlockMouseLeave,\n onBlockMouseOver,\n onBlockMouseMove,\n } = options;\n if (onBlockClick)\n element.onclick = (event: MouseEvent) => onBlockClick?.(block, event);\n if (onBlockDblClick)\n element.ondblclick = (event: MouseEvent) => onBlockDblClick?.(block, event);\n if (onBlockMouseUp)\n element.onmouseup = (event: MouseEvent) => onBlockMouseUp?.(block, event);\n if (onBlockMouseDown)\n element.onmousedown = (event: MouseEvent) =>\n onBlockMouseDown?.(block, event);\n if (onBlockMouseEnter)\n element.onmouseenter = (event: MouseEvent) =>\n onBlockMouseEnter?.(block, event);\n if (onBlockMouseLeave)\n element.onmouseleave = (event: MouseEvent) =>\n onBlockMouseLeave?.(block, event);\n if (onBlockMouseOver)\n element.onmouseover = (event: MouseEvent) =>\n onBlockMouseOver?.(block, event);\n if (onBlockMouseMove)\n element.onmousemove = (event: MouseEvent) =>\n onBlockMouseMove?.(block, event);\n};\n\nconst getElementText = (element: HTMLElement): string => {\n if (element.childElementCount === 0) {\n return element.textContent ?? '';\n }\n for (let index = 0; index < element.childNodes.length; index++) {\n const node = element.childNodes[index];\n if (node && node.nodeType === Node.TEXT_NODE) {\n return node.textContent ?? '';\n }\n }\n return '';\n};\n\nconst setElementText = (element: HTMLElement, text: string): void => {\n if (element.childElementCount === 0) {\n element.textContent = text;\n return;\n }\n for (let index = 0; index < element.childNodes.length; index++) {\n const node = element.childNodes[index];\n if (node && node.nodeType === Node.TEXT_NODE) {\n node.textContent = text;\n return;\n }\n }\n};\n\nconst areStylesDifferent = (\n blockStyle: React.CSSProperties,\n elementStyle: string,\n): boolean => {\n const blockCss = stringifyCSSProperties(blockStyle).replace(/\\s/g, '');\n const elementCss = elementStyle\n .replace(/\\s/g, '')\n .replace('cursor:grab;', '')\n .replace('-webkit-user-drag:element;', '');\n return blockCss !== elementCss;\n};\n\nexport {\n addBlockEventListeners,\n getElementText,\n setElementText,\n areStylesDifferent,\n};\n","import React, {\n FC,\n memo,\n useCallback,\n useEffect,\n useMemo,\n useRef,\n} from 'react';\nimport {\n useBlockRerenderHandlers,\n useBlocks,\n useBuffer,\n useCursorPosition,\n} from '@state/useState';\nimport { stringifyCSSProperties } from 'react-style-stringify';\nimport { UnmanagedEditor } from '@components/UnmanagedEditor';\nimport { Block, BlockType, StyledBlock } from '@atypes/block';\nimport { useMutationObserver } from '@hooks/useMutationObserver';\nimport {\n createElement,\n getCursorPosition,\n getSelectionRange,\n insertCarridgeReturn,\n isCarridgeReturn,\n preContainsNode,\n preContainsTextNode,\n replaceLineFeeds,\n setCursorPosition,\n} from '../../utils/functions';\nimport { EditorProps } from '@src/types';\nimport cx from 'classnames';\nimport {\n addBlockEventListeners,\n areStylesDifferent,\n getElementText,\n setElementText,\n} from './functions';\nimport style from './Editor.module.less';\n\n// Document icon as data URI (same as in functions.ts)\nconst DOCUMENT_ICON =\n 'data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNDgiIGhlaWdodD0iNDgiIHZpZXdCb3g9IjAgMCA0OCA0OCIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48cmVjdCB3aWR0aD0iNDgiIGhlaWdodD0iNDgiIGZpbGw9IiNGNUY1RjUiLz48cGF0aCBkPSJNMTIgOEMxMiA2Ljg5NTQzIDEyLjg5NTQgNiAxNCA2SDI2TDM2IDE2VjQwQzM2IDQxLjEwNDYgMzUuMTA0NiA0MiAzNCA0MkgxNEMxMi44OTU0IDQyIDEyIDQxLjEwNDYgMTIgNDBWOFoiIGZpbGw9IiM0Mjg1RjQiLz48cGF0aCBkPSJNMjYgNlYxNEgyNlYxNkgzNkwyNiA2WiIgZmlsbD0iIzFBNzNFOCIvPjxwYXRoIGQ9Ik0xOCAyMkgzME0xOCAyNkgzME0xOCAzMEgyNiIgc3Ryb2tlPSJ3aGl0ZSIgc3Ryb2tlLXdpZHRoPSIyIiBzdHJva2UtbGluZWNhcD0icm91bmQiLz48L3N2Zz4=';\n\n/**\n * Editor component provides a rich text editing experience with support for images and documents.\n * This is a managed editor that automatically synchronizes with the SmartInput state.\n * It handles block rendering, cursor positioning, and user interactions.\n *\n * @component\n * @example\n * ```tsx\n * <Editor\n * enableLineBreaks={true}\n * placeholder=\"Type something...\"\n * imageWidth=\"100px\"\n * />\n * ```\n */\nexport const Editor: FC<EditorProps> = memo(function Editor({\n enableLineBreaks = false,\n imageWidth,\n imageHeight,\n documentWidth,\n documentHeight,\n className,\n placeholder = 'Start typing',\n editorClassName,\n ...eventHandlers\n}) {\n const preRef = useRef<HTMLPreElement | null>(null);\n const { blocks, setBlocks } = useBlocks((s) => s);\n const { undoBuffer, appendToBuffer } = useBuffer((s) => s);\n const { blockRerenderHandlers } = useBlockRerenderHandlers((s) => s);\n const { characterPosition, updateCharacterPosition } = useCursorPosition(\n (s) => s,\n );\n\n // Watch for DOM mutations and notify blockRerenderHandlers of changed styled blocks\n const handleMutations = useCallback(\n (mutations: MutationRecord[]) => {\n if (!preRef.current || blockRerenderHandlers.length === 0) return;\n\n // Track unique styled blocks that have been affected\n const affectedBlockIds = new Set<string>();\n\n mutations.forEach((mutation) => {\n // Check if mutation affected a styled block\n if (mutation.type === 'childList') {\n mutation.addedNodes.forEach((node) => {\n if (node instanceof HTMLElement && node.id) {\n affectedBlockIds.add(node.id);\n }\n });\n } else if (\n mutation.type === 'attributes' ||\n mutation.type === 'characterData'\n ) {\n let target: Node | null = mutation.target;\n // Walk up the DOM to find the styled block element\n while (target && target !== preRef.current) {\n if (target instanceof HTMLElement && target.id) {\n affectedBlockIds.add(target.id);\n break;\n }\n target = target.parentNode;\n }\n }\n });\n\n if (affectedBlockIds.size > 0) {\n // Get the styled blocks that were affected with their DOM elements\n const rerenderedStyledBlocks = blocks\n .filter(\n (block): block is StyledBlock =>\n block.type === BlockType.Styled &&\n 'id' in block &&\n affectedBlockIds.has(block.id),\n )\n .map((block) => ({\n block,\n element: preRef.current?.querySelector(\n `#${block.id}`,\n ) as HTMLElement | null,\n }));\n\n if (rerenderedStyledBlocks.length > 0) {\n // Call all registered handlers\n blockRerenderHandlers.forEach((handler) => {\n handler(rerenderedStyledBlocks);\n });\n }\n }\n },\n [blocks, blockRerenderHandlers],\n );\n\n useMutationObserver(preRef.current, handleMutations, {\n childList: true,\n subtree: true,\n attributes: true,\n characterData: true,\n });\n\n const handleDeleteBlock = useCallback(\n (blockId: string) => {\n const newBlocks = blocks.filter((b) => !('id' in b) || b.id !== blockId);\n setBlocks(newBlocks);\n appendToBuffer(newBlocks);\n },\n [blocks, setBlocks, appendToBuffer],\n );\n\n const createElementOptions = useMemo(\n () => ({\n ...(imageWidth !== undefined && { imageWidth }),\n ...(imageHeight !== undefined && { imageHeight }),\n ...(documentWidth !== undefined && { documentWidth }),\n ...(documentHeight !== undefined && { documentHeight }),\n onDeleteBlock: handleDeleteBlock,\n }),\n [imageWidth, imageHeight, documentWidth, documentHeight, handleDeleteBlock],\n );\n\n useEffect(() => {\n if (!preRef.current) return;\n const preElement = preRef.current;\n let cnt = 0;\n while (cnt < blocks.length) {\n const block = blocks[cnt];\n if (!block) {\n cnt += 1;\n continue;\n }\n const domElement =\n cnt < preElement.childNodes.length\n ? (preElement.childNodes[cnt] as HTMLElement)\n : null; // get dom element at position\n if (domElement) {\n if (block.type === BlockType.Text) {\n if (domElement.nodeName !== '#text') {\n if (preContainsTextNode(preElement, block.text, cnt + 1)) {\n // text node exists further down, remove this element\n domElement.remove();\n continue;\n }\n preElement.insertBefore(\n createElement(block, createElementOptions),\n domElement,\n ); // insert text node as it is new\n } else {\n if (domElement.textContent !== block.text) {\n domElement.textContent = block.text; // text node exists but text has changed\n }\n }\n } else {\n // span, img, or div block\n const blockId = 'id' in block ? block.id : undefined;\n if (blockId && blockId === domElement.id) {\n //same block, check for changes\n if (\n block.type === BlockType.Document ||\n block.type === BlockType.Image\n ) {\n // Image/Document blocks - now wrapped in span containers\n if (domElement.nodeName === 'SPAN') {\n const imgElement = domElement.querySelector(\n 'img',\n ) as HTMLImageElement;\n if (imgElement) {\n const expectedSrc =\n block.type === BlockType.Image ? block.url : DOCUMENT_ICON;\n if (imgElement.src !== expectedSrc) {\n imgElement.src = expectedSrc;\n }\n }\n }\n } else if (block.type === BlockType.Styled) {\n const blockCss = stringifyCSSProperties(block.style ?? {});\n if (\n areStylesDifferent(block.style ?? {}, domElement.style.cssText)\n ) {\n domElement.style.cssText = blockCss; // element matches but style has changed\n }\n if (domElement.className !== (block.className ?? '')) {\n domElement.className = block.className ?? '';\n }\n if (\n domElement.isContentEditable !== !(block.uneditable ?? false)\n ) {\n domElement.contentEditable =\n block.uneditable ?? false ? 'false' : 'true';\n }\n if (getElementText(domElement) !== block.text) {\n setElementText(domElement, block.text); // element matches but text has changed\n }\n }\n } else {\n const element = createElement(block, createElementOptions);\n if (blockId && preContainsNode(preElement, blockId, cnt + 1)) {\n // dom element must have been removed\n domElement.remove();\n continue;\n }\n if (block.type === BlockType.Styled) {\n addBlockEventListeners(\n domElement as HTMLElement,\n block,\n eventHandlers,\n );\n }\n preElement.insertBefore(element, domElement); //insert element as it is new\n }\n }\n } else {\n const domElement = createElement(block, createElementOptions);\n if (block.type === BlockType.Styled) {\n addBlockEventListeners(\n domElement as HTMLElement,\n block,\n eventHandlers,\n );\n }\n preElement.appendChild(domElement); // append element as it is new and there are no more elements\n }\n cnt += 1;\n }\n let extra = 0;\n const lastBlock = blocks[blocks.length - 1];\n if (\n lastBlock &&\n blocks.length > 0 &&\n 'text' in lastBlock &&\n lastBlock.text.length > 0 &&\n lastBlock.text[lastBlock.text.length - 1] === '\\n'\n ) {\n const childNodeAtLength = preElement.childNodes[blocks.length];\n if (\n preElement.childNodes.length > blocks.length &&\n childNodeAtLength &&\n isCarridgeReturn(childNodeAtLength)\n ) {\n extra = 1;\n }\n }\n while (preElement.childNodes.length > blocks.length + extra) {\n const lastChild = preElement.lastChild;\n if (lastChild) {\n preElement.removeChild(lastChild);\n }\n }\n const range = getSelectionRange(preElement);\n const position = range ? getCursorPosition(preElement, range) : 0;\n if (position !== characterPosition) {\n setCursorPosition(preElement, characterPosition);\n }\n }, [blocks, characterPosition, createElementOptions, eventHandlers]);\n\n const handleChange = useCallback(\n (isReturn?: boolean) => {\n if (!preRef.current) return;\n const preElement = preRef.current;\n let cnt = 0;\n const newBlocks: Block[] = [];\n while (cnt < preElement.childNodes.length) {\n const domElement = preElement.childNodes[cnt] as HTMLElement | Text;\n if ('id' in domElement && domElement.id) {\n const block = blocks.find((b) => 'id' in b && b.id === domElement.id);\n if (block) {\n // For DocumentBlock and ImageBlock, preserve the block as-is (no text content)\n if (\n block.type === BlockType.Document ||\n block.type === BlockType.Image\n ) {\n newBlocks.push(block);\n } else if (block.type === BlockType.Styled) {\n const styledBlock = block as StyledBlock;\n if (getElementText(domElement) !== styledBlock.text) {\n styledBlock.text =\n replaceLineFeeds(getElementText(domElement)) ?? '';\n }\n newBlocks.push(styledBlock);\n }\n }\n } else {\n let text = domElement.textContent ?? '';\n const nextNode = preElement.childNodes[cnt + 1];\n while (\n cnt + 1 < preElement.childNodes.length &&\n nextNode &&\n (!('id' in nextNode) || !(nextNode as HTMLElement)?.id)\n ) {\n text += preElement.childNodes[cnt + 1]?.textContent ?? '';\n cnt += 1;\n }\n newBlocks.push({\n type: BlockType.Text,\n text: replaceLineFeeds(text),\n });\n }\n cnt += 1;\n }\n const deletedBlocks = blocks.filter(\n (b) =>\n 'id' in b &&\n newBlocks.findIndex((nb) => 'id' in nb && nb.id === b.id) === -1,\n );\n if (deletedBlocks.some((b) => 'undeletable' in b && b.undeletable)) {\n setBlocks([...blocks]);\n return;\n }\n const finalBlocks = !enableLineBreaks\n ? newBlocks.map((b) =>\n 'text' in b\n ? {\n ...b,\n text: b.text.replaceAll('\\n', ''),\n }\n : b,\n )\n : isReturn\n ? insertCarridgeReturn(preElement, newBlocks)\n : newBlocks;\n if (isReturn) {\n updateCharacterPosition(characterPosition + 1);\n }\n if (JSON.stringify(blocks) !== JSON.stringify(finalBlocks)) {\n setBlocks(finalBlocks);\n appendToBuffer(finalBlocks);\n }\n },\n [\n blocks,\n setBlocks,\n appendToBuffer,\n characterPosition,\n enableLineBreaks,\n updateCharacterPosition,\n ],\n );\n\n const handleUndo = useCallback(() => {\n const lastBlocks = undoBuffer();\n setBlocks(lastBlocks ?? []);\n }, [undoBuffer, setBlocks]);\n\n return (\n <div className={cx(style['editorContainer'], className)}>\n <UnmanagedEditor\n ref={preRef}\n onChange={handleChange}\n onUndo={handleUndo}\n enableLineBreaks={enableLineBreaks}\n placeholder={placeholder}\n className={editorClassName}\n />\n </div>\n );\n});\n\nEditor.displayName = 'Editor';\n","const reduxImpl = (reducer, initial) => (set, _get, api) => {\n api.dispatch = (action) => {\n set((state) => reducer(state, action), false, action);\n return action;\n };\n api.dispatchFromDevtools = true;\n return { dispatch: (...a) => api.dispatch(...a), ...initial };\n};\nconst redux = reduxImpl;\n\nconst trackedConnections = /* @__PURE__ */ new Map();\nconst getTrackedConnectionState = (name) => {\n const api = trackedConnections.get(name);\n if (!api) return {};\n return Object.fromEntries(\n Object.entries(api.stores).map(([key, api2]) => [key, api2.getState()])\n );\n};\nconst extractConnectionInformation = (store, extensionConnector, options) => {\n if (store === void 0) {\n return {\n type: \"untracked\",\n connection: extensionConnector.connect(options)\n };\n }\n const existingConnection = trackedConnections.get(options.name);\n if (existingConnection) {\n return { type: \"tracked\", store, ...existingConnection };\n }\n const newConnection = {\n connection: extensionConnector.connect(options),\n stores: {}\n };\n trackedConnections.set(options.name, newConnection);\n return { type: \"tracked\", store, ...newConnection };\n};\nconst devtoolsImpl = (fn, devtoolsOptions = {}) => (set, get, api) => {\n const { enabled, anonymousActionType, store, ...options } = devtoolsOptions;\n let extensionConnector;\n try {\n extensionConnector = (enabled != null ? enabled : (import.meta.env ? import.meta.env.MODE : void 0) !== \"production\") && window.__REDUX_DEVTOOLS_EXTENSION__;\n } catch (e) {\n }\n if (!extensionConnector) {\n return fn(set, get, api);\n }\n const { connection, ...connectionInformation } = extractConnectionInformation(store, extensionConnector, options);\n let isRecording = true;\n api.setState = (state, replace, nameOrAction) => {\n const r = set(state, replace);\n if (!isRecording) return r;\n const action = nameOrAction === void 0 ? { type: anonymousActionType || \"anonymous\" } : typeof nameOrAction === \"string\" ? { type: nameOrAction } : nameOrAction;\n if (store === void 0) {\n connection == null ? void 0 : connection.send(action, get());\n return r;\n }\n connection == null ? void 0 : connection.send(\n {\n ...action,\n type: `${store}/${action.type}`\n },\n {\n ...getTrackedConnectionState(options.name),\n [store]: api.getState()\n }\n );\n return r;\n };\n const setStateFromDevtools = (...a) => {\n const originalIsRecording = isRecording;\n isRecording = false;\n set(...a);\n isRecording = originalIsRecording;\n };\n const initialState = fn(api.setState, get, api);\n if (connectionInformation.type === \"untracked\") {\n connection == null ? void 0 : connection.init(initialState);\n } else {\n connectionInformation.stores[connectionInformation.store] = api;\n connection == null ? void 0 : connection.init(\n Object.fromEntries(\n Object.entries(connectionInformation.stores).map(([key, store2]) => [\n key,\n key === connectionInformation.store ? initialState : store2.getState()\n ])\n )\n );\n }\n if (api.dispatchFromDevtools && typeof api.dispatch === \"function\") {\n let didWarnAboutReservedActionType = false;\n const originalDispatch = api.dispatch;\n api.dispatch = (...a) => {\n if ((import.meta.env ? import.meta.env.MODE : void 0) !== \"production\" && a[0].type === \"__setState\" && !didWarnAboutReservedActionType) {\n console.warn(\n '[zustand devtools middleware] \"__setState\" action type is reserved to set state from the devtools. Avoid using it.'\n );\n didWarnAboutReservedActionType = true;\n }\n originalDispatch(...a);\n };\n }\n connection.subscribe((message) => {\n var _a;\n switch (message.type) {\n case \"ACTION\":\n if (typeof message.payload !== \"string\") {\n console.error(\n \"[zustand devtools middleware] Unsupported action format\"\n );\n return;\n }\n return parseJsonThen(\n message.payload,\n (action) => {\n if (action.type === \"__setState\") {\n if (store === void 0) {\n setStateFromDevtools(action.state);\n return;\n }\n if (Object.keys(action.state).length !== 1) {\n console.error(\n `\n [zustand devtools middleware] Unsupported __setState action format.\n When using 'store' option in devtools(), the 'state' should have only one key, which is a value of 'store' that was passed in devtools(),\n and value of this only key should be a state object. Example: { \"type\": \"__setState\", \"state\": { \"abc123Store\": { \"foo\": \"bar\" } } }\n `\n );\n }\n const stateFromDevtools = action.state[store];\n if (stateFromDevtools === void 0 || stateFromDevtools === null) {\n return;\n }\n if (JSON.stringify(api.getState()) !== JSON.stringify(stateFromDevtools)) {\n setStateFromDevtools(stateFromDevtools);\n }\n return;\n }\n if (!api.dispatchFromDevtools) return;\n if (typeof api.dispatch !== \"function\") return;\n api.dispatch(action);\n }\n );\n case \"DISPATCH\":\n switch (message.payload.type) {\n case \"RESET\":\n setStateFromDevtools(initialState);\n if (store === void 0) {\n return connection == null ? void 0 : connection.init(api.getState());\n }\n return connection == null ? void 0 : connection.init(getTrackedConnectionState(options.name));\n case \"COMMIT\":\n if (store === void 0) {\n connection == null ? void 0 : connection.init(api.getState());\n return;\n }\n return connection == null ? void 0 : connection.init(getTrackedConnectionState(options.name));\n case \"ROLLBACK\":\n return parseJsonThen(message.state, (state) => {\n if (store === void 0) {\n setStateFromDevtools(state);\n connection == null ? void 0 : connection.init(api.getState());\n return;\n }\n setStateFromDevtools(state[store]);\n connection == null ? void 0 : connection.init(getTrackedConnectionState(options.name));\n });\n case \"JUMP_TO_STATE\":\n case \"JUMP_TO_ACTION\":\n return parseJsonThen(message.state, (state) => {\n if (store === void 0) {\n setStateFromDevtools(state);\n return;\n }\n if (JSON.stringify(api.getState()) !== JSON.stringify(state[store])) {\n setStateFromDevtools(state[store]);\n }\n });\n case \"IMPORT_STATE\": {\n const { nextLiftedState } = message.payload;\n const lastComputedState = (_a = nextLiftedState.computedStates.slice(-1)[0]) == null ? void 0 : _a.state;\n if (!lastComputedState) return;\n if (store === void 0) {\n setStateFromDevtools(lastComputedState);\n } else {\n setStateFromDevtools(lastComputedState[store]);\n }\n connection == null ? void 0 : connection.send(\n null,\n // FIXME no-any\n nextLiftedState\n );\n return;\n }\n case \"PAUSE_RECORDING\":\n return isRecording = !isRecording;\n }\n return;\n }\n });\n return initialState;\n};\nconst devtools = devtoolsImpl;\nconst parseJsonThen = (stringified, f) => {\n let parsed;\n try {\n parsed = JSON.parse(stringified);\n } catch (e) {\n console.error(\n \"[zustand devtools middleware] Could not parse the received json\",\n e\n );\n }\n if (parsed !== void 0) f(parsed);\n};\n\nconst subscribeWithSelectorImpl = (fn) => (set, get, api) => {\n const origSubscribe = api.subscribe;\n api.subscribe = (selector, optListener, options) => {\n let listener = selector;\n if (optListener) {\n const equalityFn = (options == null ? void 0 : options.equalityFn) || Object.is;\n let currentSlice = selector(api.getState());\n listener = (state) => {\n const nextSlice = selector(state);\n if (!equalityFn(currentSlice, nextSlice)) {\n const previousSlice = currentSlice;\n optListener(currentSlice = nextSlice, previousSlice);\n }\n };\n if (options == null ? void 0 : options.fireImmediately) {\n optListener(currentSlice, currentSlice);\n }\n }\n return origSubscribe(listener);\n };\n const initialState = fn(set, get, api);\n return initialState;\n};\nconst subscribeWithSelector = subscribeWithSelectorImpl;\n\nconst combine = (initialState, create) => (...a) => Object.assign({}, initialState, create(...a));\n\nfunction createJSONStorage(getStorage, options) {\n let storage;\n try {\n storage = getStorage();\n } catch (e) {\n return;\n }\n const persistStorage = {\n getItem: (name) => {\n var _a;\n const parse = (str2) => {\n if (str2 === null) {\n return null;\n }\n return JSON.parse(str2, options == null ? void 0 : options.reviver);\n };\n const str = (_a = storage.getItem(name)) != null ? _a : null;\n if (str instanceof Promise) {\n return str.then(parse);\n }\n return parse(str);\n },\n setItem: (name, newValue) => storage.setItem(\n name,\n JSON.stringify(newValue, options == null ? void 0 : options.replacer)\n ),\n removeItem: (name) => storage.removeItem(name)\n };\n return persistStorage;\n}\nconst toThenable = (fn) => (input) => {\n try {\n const result = fn(input);\n if (result instanceof Promise) {\n return result;\n }\n return {\n then(onFulfilled) {\n return toThenable(onFulfilled)(result);\n },\n catch(_onRejected) {\n return this;\n }\n };\n } catch (e) {\n return {\n then(_onFulfilled) {\n return this;\n },\n catch(onRejected) {\n return toThenable(onRejected)(e);\n }\n };\n }\n};\nconst persistImpl = (config, baseOptions) => (set, get, api) => {\n let options = {\n storage: createJSONStorage(() => localStorage),\n partialize: (state) => state,\n version: 0,\n merge: (persistedState, currentState) => ({\n ...currentState,\n ...persistedState\n }),\n ...baseOptions\n };\n let hasHydrated = false;\n const hydrationListeners = /* @__PURE__ */ new Set();\n const finishHydrationListeners = /* @__PURE__ */ new Set();\n let storage = options.storage;\n if (!storage) {\n return config(\n (...args) => {\n console.warn(\n `[zustand persist middleware] Unable to update item '${options.name}', the given storage is currently unavailable.`\n );\n set(...args);\n },\n get,\n api\n );\n }\n const setItem = () => {\n const state = options.partialize({ ...get() });\n return storage.setItem(options.name, {\n state,\n version: options.version\n });\n };\n const savedSetState = api.setState;\n api.setState = (state, replace) => {\n savedSetState(state, replace);\n void setItem();\n };\n const configResult = config(\n (...args) => {\n set(...args);\n void setItem();\n },\n get,\n api\n );\n api.getInitialState = () => configResult;\n let stateFromStorage;\n const hydrate = () => {\n var _a, _b;\n if (!storage) return;\n hasHydrated = false;\n hydrationListeners.forEach((cb) => {\n var _a2;\n return cb((_a2 = get()) != null ? _a2 : configResult);\n });\n const postRehydrationCallback = ((_b = options.onRehydrateStorage) == null ? void 0 : _b.call(options, (_a = get()) != null ? _a : configResult)) || void 0;\n return toThenable(storage.getItem.bind(storage))(options.name).then((deserializedStorageValue) => {\n if (deserializedStorageValue) {\n if (typeof deserializedStorageValue.version === \"number\" && deserializedStorageValue.version !== options.version) {\n if (options.migrate) {\n const migration = options.migrate(\n deserializedStorageValue.state,\n deserializedStorageValue.version\n );\n if (migration instanceof Promise) {\n return migration.then((result) => [true, result]);\n }\n return [true, migration];\n }\n console.error(\n `State loaded from storage couldn't be migrated since no migrate function was provided`\n );\n } else {\n return [false, deserializedStorageValue.state];\n }\n }\n return [false, void 0];\n }).then((migrationResult) => {\n var _a2;\n const [migrated, migratedState] = migrationResult;\n stateFromStorage = options.merge(\n migratedState,\n (_a2 = get()) != null ? _a2 : configResult\n );\n set(stateFromStorage, true);\n if (migrated) {\n return setItem();\n }\n }).then(() => {\n postRehydrationCallback == null ? void 0 : postRehydrationCallback(stateFromStorage, void 0);\n stateFromStorage = get();\n hasHydrated = true;\n finishHydrationListeners.forEach((cb) => cb(stateFromStorage));\n }).catch((e) => {\n postRehydrationCallback == null ? void 0 : postRehydrationCallback(void 0, e);\n });\n };\n api.persist = {\n setOptions: (newOptions) => {\n options = {\n ...options,\n ...newOptions\n };\n if (newOptions.storage) {\n storage = newOptions.storage;\n }\n },\n clearStorage: () => {\n storage == null ? void 0 : storage.removeItem(options.name);\n },\n getOptions: () => options,\n rehydrate: () => hydrate(),\n hasHydrated: () => hasHydrated,\n onHydrate: (cb) => {\n hydrationListeners.add(cb);\n return () => {\n hydrationListeners.delete(cb);\n };\n },\n onFinishHydration: (cb) => {\n finishHydrationListeners.add(cb);\n return () => {\n finishHydrationListeners.delete(cb);\n };\n }\n };\n if (!options.skipHydration) {\n hydrate();\n }\n return stateFromStorage || configResult;\n};\nconst persist = persistImpl;\n\nexport { combine, createJSONStorage, devtools, persist, redux, subscribeWithSelector };\n","import { create, StateCreator } from 'zustand';\nimport { subscribeWithSelector } from 'zustand/middleware';\nconst creatStore = <T extends object>(initializer: StateCreator<T, [], []>) =>\n create(initializer);\n\nconst createSubscriberStore = <T extends object>(\n initializer: StateCreator<T, any, []>,\n) => create(subscribeWithSelector(initializer));\n\nexport { creatStore, createSubscriberStore };\n","import { Block } from '@atypes/block';\nimport { BlocksState } from '@atypes/state';\nimport { createSubscriberStore } from './utils';\n\nexport const createBlocksStore = () =>\n createSubscriberStore<BlocksState>((set) => ({\n blocks: [],\n setBlocks: (newBlocks: Block[]) => set({ blocks: newBlocks }),\n }));\n","import { Block } from '@atypes/block';\nimport { BlocksChangeHandler } from '@atypes/componentProps';\nimport { BlocksState, CursorPositionState } from '@atypes/state';\nimport { useTopLevelBlocksSubscriber } from '@state/useState';\nimport { useCallback } from 'react';\nimport { StoreApi, UseBoundStore } from 'zustand';\n\nexport const useChangeNotify = (\n store: UseBoundStore<StoreApi<BlocksState>>,\n cursorPositionStore: UseBoundStore<StoreApi<CursorPositionState>>,\n onBlocksChange?: BlocksChangeHandler,\n) => {\n const changeCallback = useCallback(\n (current: Block[], previous: Block[]) => {\n if (\n onBlocksChange &&\n JSON.stringify(current) !== JSON.stringify(previous)\n ) {\n const { characterPosition, cursorRect } =\n cursorPositionStore.getState();\n onBlocksChange(current, characterPosition, cursorRect);\n }\n },\n [onBlocksChange, cursorPositionStore],\n );\n\n useTopLevelBlocksSubscriber(store, (state) => state.blocks, changeCallback);\n};\n","import { Block } from '@atypes/block';\nimport { BufferState } from '@atypes/state';\nimport { createSubscriberStore } from './utils';\n\nconst MAX_BUFFER_LENGTH = 50;\nexport const createBufferStore = () =>\n createSubscriberStore<BufferState>((set, get) => ({\n buffer: [],\n appendToBuffer: (blocks: Block[]) => {\n if (\n JSON.stringify(blocks) !==\n JSON.stringify(get().buffer[get().buffer.length - 1])\n ) {\n set((state) => ({\n buffer: [...state.buffer.slice(0, MAX_BUFFER_LENGTH - 1), blocks],\n }));\n }\n },\n undoBuffer: () => {\n const { buffer } = get();\n const last = buffer.pop();\n set({ buffer: [...buffer] });\n return last ?? null;\n },\n }));\n","export interface Rect {\n top: number;\n left: number;\n bottom: number;\n right: number;\n}\n\nexport const ZERO_RECT: Rect = {\n top: 0,\n left: 0,\n bottom: 0,\n right: 0,\n};\n\nexport interface CursorPositionState {\n characterPosition: number;\n cursorRect: Rect;\n updateCharacterPosition: (characterPosition: number) => void;\n updatePosition: (characterPosition: number, cursorRect: Rect) => void;\n}\n","import { CursorPositionState, Rect, ZERO_RECT } from '@atypes/state';\nimport { createSubscriberStore } from './utils';\n\nexport const createCursorPositionStore = () =>\n createSubscriberStore<CursorPositionState>((set) => ({\n characterPosition: 0,\n cursorRect: ZERO_RECT,\n updateCharacterPosition: (characterPosition: number) =>\n set({ characterPosition }),\n updatePosition: (characterPosition: number, cursorRect: Rect) =>\n set({ characterPosition, cursorRect }),\n }));\n","import { CursorPositionChangeHanlder } from '@atypes/componentProps';\nimport { BlocksState, CursorPositionState } from '@atypes/state';\nimport { useTopLevelCursorPositionSubscriber } from '@state/useState';\n\nimport { useCallback } from 'react';\nimport { StoreApi, UseBoundStore } from 'zustand';\n\nexport const useCursorChangeNotify = (\n store: UseBoundStore<StoreApi<CursorPositionState>>,\n blockStore: UseBoundStore<StoreApi<BlocksState>>,\n onCursorPositionChange?: CursorPositionChangeHanlder,\n) => {\n const changeCallback = useCallback(\n (current: CursorPositionState, previous: CursorPositionState) => {\n if (\n current.characterPosition !== previous.characterPosition ||\n current.cursorRect.top !== previous.cursorRect.top ||\n current.cursorRect.left !== previous.cursorRect.left ||\n current.cursorRect.bottom !== previous.cursorRect.bottom ||\n current.cursorRect.right !== previous.cursorRect.right\n ) {\n const blocks = blockStore.getState().blocks;\n onCursorPositionChange?.(\n current.characterPosition,\n current.cursorRect,\n blocks,\n );\n }\n },\n [onCursorPositionChange, blockStore],\n );\n\n useTopLevelCursorPositionSubscriber(store, (state) => state, changeCallback);\n};\n","import { createSubscriberStore } from './utils';\nimport { SmartInputApi } from '@src/types/api';\nimport { ApiState } from '@src/types/state/api';\n\nexport const createApiStore = () =>\n createSubscriberStore<ApiState>((set) => ({\n api: null,\n element: null,\n setElement: (element: HTMLPreElement | null) => set({ element }),\n setApi: (api: SmartInputApi) => set({ api }),\n }));\n","import { BehaviourState } from '@atypes/state';\nimport { createSubscriberStore } from './utils';\n\nexport const createBehaviourStore = () =>\n createSubscriberStore<BehaviourState>((set, get) => ({\n selectionInProgress: false,\n setSelectionInProgress: (selectionInProgress: boolean) => {\n if (get().selectionInProgress !== selectionInProgress) {\n set({ selectionInProgress });\n }\n },\n }));\n","import { KeyCombination } from '@src/types';\nimport { createSubscriberStore } from './utils';\nimport { KeyHandlerState } from '@src/types/state/keyHandler';\n\nexport const createKeyHandlerStore = () =>\n createSubscriberStore<KeyHandlerState>((set) => ({\n keyHandlers: [],\n addKeyboardHandler: (handler: (keys: KeyCombination) => boolean) => set((state) => ({ keyHandlers: [...state.keyHandlers, handler] })),\n removeKeyboardHandler: (handler: (keys: KeyCombination) => boolean) => set((state) => ({ keyHandlers: state.keyHandlers.filter(h => h !== handler) })),\n }));\n","import { Block, StyledBlock } from './block';\n\n/**\n * Associates a styled block with its corresponding HTML element.\n */\nexport type StyledBlockElement = {\n /** The styled block */\n block: StyledBlock;\n /** The HTML element rendering the block, or null if not yet rendered */\n element: HTMLElement | null;\n};\n\n/**\n * Represents a document file in the editor.\n */\nexport interface Document {\n /** The type identifier for document items */\n type: 'document';\n /** The name of the document file */\n name: string;\n /** The File object */\n file: File;\n /** The URL for accessing the document (e.g., blob URL) */\n url: string;\n /** The content type of the image */\n contentType: string;\n}\n\n/**\n * Represents an image file in the editor.\n */\nexport interface Image {\n /** The type identifier for image items */\n type: 'image';\n /** The name of the image file */\n name: string;\n /** The File object */\n file: File;\n /** The URL for displaying the image (e.g., blob URL) */\n url: string;\n /** Alternative text for the image */\n alt?: string;\n /** The content type of the image */\n contentType: string;\n}\n\n/**\n * A commit item can be a text string, document, or image.\n */\nexport type CommitItem = string | Document | Image;\n\n/**\n * Represents a keyboard key combination for triggering commits.\n */\nexport interface CommitKeyCombination {\n /** The key value (e.g., 'Enter') */\n key: string;\n /** Whether the Alt key must be pressed */\n altKey?: boolean;\n /** Whether the Ctrl key must be pressed */\n ctrlKey?: boolean;\n /** Whether the Shift key must be pressed */\n shiftKey?: boolean;\n /** Whether the Meta/Command key must be pressed */\n metaKey?: boolean;\n}\n\n/**\n * Represents a keyboard key combination for custom key handlers.\n */\nexport interface KeyCombination {\n /** The key value (e.g., 'a', 'Enter') */\n key: string;\n /** The physical key code */\n code: string;\n /** Whether the Alt key is pressed */\n altKey?: boolean;\n /** Whether the Ctrl key is pressed */\n ctrlKey?: boolean;\n /** Whether the Shift key is pressed */\n shiftKey?: boolean;\n /** Whether the Meta/Command key is pressed */\n metaKey?: boolean;\n}\n\n/**\n * Types of drag events that can occur in the editor.\n */\nexport enum DragEventType {\n /** Fired when an element is being dragged over a valid drop target */\n DragOver = 'dragover',\n /** Fired when a dragged element leaves a valid drop target */\n DragLeave = 'dragleave',\n /** Fired when an element is dropped on a valid drop target */\n Drop = 'drop',\n}\n\n/**\n * Props for the Editor component.\n */\nexport interface EditorProps {\n /** Whether to allow line breaks in the editor (default: false) */\n enableLineBreaks?: boolean;\n /** CSS class name to apply to the editor container */\n className?: string;\n /** Custom CSS class name to apply to the editor area */\n editorClassName?: string;\n /** Width of embedded images (CSS value, e.g., '200px', '50%') */\n imageWidth?: string;\n /** Height of embedded images (CSS value) */\n imageHeight?: string;\n /** Width of embedded documents (CSS value) */\n documentWidth?: string;\n /** Height of embedded documents (CSS value) */\n documentHeight?: string;\n /** Placeholder text shown when the editor is empty */\n placeholder?: string;\n /** Called when a block is clicked */\n onBlockClick?: (block: Block, event: MouseEvent) => void;\n /** Called when a block is double-clicked */\n onBlockDblClick?: (block: Block, event: MouseEvent) => void;\n /** Called when the mouse button is released over a block */\n onBlockMouseUp?: (block: Block, event: MouseEvent) => void;\n /** Called when the mouse button is pressed over a block */\n onBlockMouseDown?: (block: Block, event: MouseEvent) => void;\n /** Called when the mouse moves over a block */\n onBlockMouseMove?: (block: Block, event: MouseEvent) => void;\n /** Called when the mouse enters a block */\n onBlockMouseEnter?: (block: Block, event: MouseEvent) => void;\n /** Called when the mouse leaves a block */\n onBlockMouseLeave?: (block: Block, event: MouseEvent) => void;\n /** Called when the mouse moves over a block (similar to onBlockMouseEnter but fires more frequently) */\n onBlockMouseOver?: (block: Block, event: MouseEvent) => void;\n}\n","import { DragHandlerState } from '@src/types/state/dragHandler';\nimport { createSubscriberStore } from './utils';\nimport { DragEventType } from '@src/types';\n\nexport const createDragHandlerStore = () =>\n createSubscriberStore<DragHandlerState>((set) => ({\n dragOverHandlers: [],\n dragLeaveHandlers: [],\n dropHandlers: [],\n addDragHandler: (\n eventType: DragEventType,\n handler: (event: React.DragEvent<HTMLPreElement>) => boolean,\n ) => {\n switch (eventType) {\n case DragEventType.DragOver:\n set((state) => ({\n dragOverHandlers: [...state.dragOverHandlers, handler],\n }));\n break;\n case DragEventType.DragLeave:\n set((state) => ({\n dragLeaveHandlers: [...state.dragLeaveHandlers, handler],\n }));\n break;\n case DragEventType.Drop:\n set((state) => ({ dropHandlers: [...state.dropHandlers, handler] }));\n break;\n }\n },\n removeDragHandler: (\n eventType: DragEventType,\n handler: (event: React.DragEvent<HTMLPreElement>) => boolean,\n ) => {\n switch (eventType) {\n case DragEventType.DragOver:\n set((state) => ({\n dragOverHandlers: state.dragOverHandlers.filter(\n (h) => h !== handler,\n ),\n }));\n break;\n case DragEventType.DragLeave:\n set((state) => ({\n dragLeaveHandlers: state.dragLeaveHandlers.filter(\n (h) => h !== handler,\n ),\n }));\n break;\n case DragEventType.Drop:\n set((state) => ({\n dropHandlers: state.dropHandlers.filter((h) => h !== handler),\n }));\n break;\n }\n },\n }));\n","import { StyledBlockElement } from '@src/types';\nimport { createSubscriberStore } from './utils';\nimport { BlockRerenderHandlerState } from '@src/types/state/blockRerenderHandler';\n\nexport const createBlockRerenderHandlerStore = () =>\n createSubscriberStore<BlockRerenderHandlerState>((set) => ({\n blockRerenderHandlers: [],\n addBlockRerenderHandlers: (\n handler: (blocks: StyledBlockElement[]) => void,\n ) =>\n set((state) => ({\n blockRerenderHandlers: [...state.blockRerenderHandlers, handler],\n })),\n removeBlockRerenderHandlers: (\n handler: (blocks: StyledBlockElement[]) => void,\n ) =>\n set((state) => ({\n blockRerenderHandlers: state.blockRerenderHandlers.filter(\n (h) => h !== handler,\n ),\n })),\n }));\n","import React, { FC, PropsWithChildren } from 'react';\nimport { createBlocksStore } from './blocksStore';\nimport { StateContext } from './state';\nimport { ComponentProps } from '@atypes/componentProps';\nimport { useChangeNotify } from '@hooks/useChangeNotify';\nimport { createBufferStore } from './bufferStore';\nimport { createCursorPositionStore } from './cursorPosition';\nimport { useCursorChangeNotify } from '@hooks/useCursorChangeNotify';\nimport { createApiStore } from './apiStore';\nimport { createBehaviourStore } from './behaviourStore';\nimport { createKeyHandlerStore } from './keyHandlerStore';\nimport { createDragHandlerStore } from './dragHandlerStore';\nimport { createBlockRerenderHandlerStore } from '@src/state/blockRerenderHandlerStore';\n\ninterface StateProviderProps {\n value: ComponentProps;\n}\n\nexport const StateProvider: FC<PropsWithChildren<StateProviderProps>> =\n React.memo(({ value, children }) => {\n const { blocks, onBlocksChange, onCursorPositionChange } = value;\n\n const keyHandlerStore = React.useMemo(createKeyHandlerStore, []);\n const bufferStore = React.useMemo(createBufferStore, []);\n const blocksStore = React.useMemo(createBlocksStore, []);\n const cursorPositionStore = React.useMemo(createCursorPositionStore, []);\n const apiStore = React.useMemo(createApiStore, []);\n const behaviourStore = React.useMemo(createBehaviourStore, []);\n const dragHandlerStore = React.useMemo(createDragHandlerStore, []);\n const blockRerenderHandlerStore = React.useMemo(\n createBlockRerenderHandlerStore,\n [],\n );\n\n useChangeNotify(blocksStore, cursorPositionStore, onBlocksChange);\n useCursorChangeNotify(\n cursorPositionStore,\n blocksStore,\n onCursorPositionChange,\n );\n\n if (\n blocks &&\n JSON.stringify(blocksStore.getState().blocks) !== JSON.stringify(blocks)\n ) {\n blocksStore.getState().setBlocks(blocks);\n bufferStore.getState().appendToBuffer(blocks);\n }\n\n const stateValue = React.useMemo(\n () => ({\n blocksStore,\n bufferStore,\n cursorPositionStore,\n apiStore,\n behaviourStore,\n keyHandlerStore,\n dragHandlerStore,\n blockRerenderHandlerStore,\n }),\n [\n blocksStore,\n bufferStore,\n cursorPositionStore,\n apiStore,\n behaviourStore,\n keyHandlerStore,\n dragHandlerStore,\n blockRerenderHandlerStore,\n ],\n );\n\n return (\n <StateContext.Provider value={stateValue}>\n {children}\n </StateContext.Provider>\n );\n });\n\nStateProvider.displayName = 'StateProvider';\n","import { Block, BlockType, Document, Image, StyledBlock } from '@src/types';\nimport { SmartInputFunctions } from '@src/types/api';\n\ntype ApiState = {\n blocks: Block[];\n characterPosition: number;\n buffer: Block[][];\n appendToBuffer: (b: Block[]) => void;\n};\n\n/**\n * Creates an internal state object for managing editor content.\n * This state holds the current blocks, cursor position, and undo/redo buffer.\n *\n * @param blocksI - Initial array of content blocks\n * @param characterPositionI - Initial character position of the cursor\n * @returns An ApiState object with getters/setters for blocks, position, and buffer\n *\n * @example\n * ```typescript\n * const state = createState([{ type: 'Text', text: 'Hello' }], 0);\n * ```\n */\nexport const createState = (\n blocksI: Block[],\n characterPositionI: number,\n): ApiState => {\n let blocks = blocksI;\n let characterPosition = characterPositionI;\n const buffer: Block[][] = [];\n const state = {\n get blocks() {\n return blocks;\n },\n set blocks(value: Block[]) {\n blocks = value;\n },\n get characterPosition() {\n return characterPosition;\n },\n set characterPosition(value: number) {\n characterPosition = value;\n },\n appendToBuffer: (b: Block[]) => {\n buffer.push(b);\n },\n get buffer() {\n return buffer;\n },\n };\n return state;\n};\n\n/**\n * Finds the block and offset within that block for a given character position.\n * Iterates through blocks to calculate which block contains the position.\n *\n * @param blocks - Array of content blocks to search\n * @param position - Character position to find (0-based)\n * @returns Object with blockIndex and offset within that block\n *\n * @internal\n */\nconst findBlockAtPosition = (\n blocks: Block[],\n position: number,\n): { blockIndex: number; offset: number } => {\n let currentPos = 0;\n for (let i = 0; i < blocks.length; i++) {\n const block = blocks[i];\n if (!block) continue;\n if (block.type === BlockType.Text || block.type === BlockType.Styled) {\n const blockLength = block.text.length;\n if (currentPos + blockLength >= position) {\n return { blockIndex: i, offset: position - currentPos };\n }\n currentPos += blockLength;\n }\n }\n return { blockIndex: blocks.length, offset: 0 };\n};\n\n/**\n * Extracts plain text from an array of blocks.\n * Filters Text and Styled blocks and concatenates their text content.\n *\n * @param blocks - Array of content blocks\n * @returns Concatenated plain text string from all text blocks\n *\n * @internal\n */\nconst extractText = (blocks: Block[]): string => {\n return blocks\n .filter(\n (b) => b && (b.type === BlockType.Text || b.type === BlockType.Styled),\n )\n .map((b) => {\n if (b.type === BlockType.Text || b.type === BlockType.Styled) {\n return b.text;\n }\n return '';\n })\n .join('');\n};\n\n/**\n * Creates the public API for manipulating editor content.\n * Provides methods for inserting, deleting, replacing text, and managing blocks.\n *\n * @param state - Internal ApiState object to operate on\n * @returns SmartInputFunctions object with all API methods\n *\n * @example\n * ```typescript\n * const state = createState([], 0);\n * const api = createApi(state);\n * api.insert('Hello', 0);\n * api.apply();\n * ```\n */\nexport const createApi = (state: ApiState): SmartInputFunctions => ({\n /**\n * Clears all content from the editor.\n * Removes all blocks and resets cursor position to 0.\n * This operation is buffered and can be undone.\n *\n * @example\n * ```typescript\n * api.clear();\n * api.apply();\n * ```\n */\n clear: () => {\n state.blocks = [];\n state.characterPosition = 0;\n state.appendToBuffer([...state.blocks]);\n },\n\n /**\n * Inserts text at the specified position.\n * If the position is within a text block, the text is inserted into that block.\n * Otherwise, a new text block is created.\n *\n * @param text - The text string to insert\n * @param position - Character position where text should be inserted (0-based)\n *\n * @example\n * ```typescript\n * api.insert('World', 5);\n * api.apply();\n * ```\n */\n insert: (text: string, position: number) => {\n const { blockIndex, offset } = findBlockAtPosition(state.blocks, position);\n const newBlocks = [...state.blocks];\n\n if (blockIndex >= newBlocks.length) {\n // Insert at the end\n newBlocks.push({ type: BlockType.Text, text });\n } else {\n const block = newBlocks[blockIndex];\n if (!block) {\n newBlocks.push({ type: BlockType.Text, text });\n } else if (\n block.type === BlockType.Text ||\n block.type === BlockType.Styled\n ) {\n const beforeText = block.text.substring(0, offset);\n const afterText = block.text.substring(offset);\n newBlocks[blockIndex] = {\n ...block,\n text: beforeText + text + afterText,\n };\n } else {\n // Insert as new text block before non-text block\n newBlocks.splice(blockIndex, 0, { type: BlockType.Text, text });\n }\n }\n\n state.blocks = newBlocks;\n state.appendToBuffer([...state.blocks]);\n },\n\n /**\n * Deletes text within the specified range.\n * Handles deletion across multiple blocks intelligently.\n *\n * @param start - Starting character position of deletion range (0-based, inclusive)\n * @param end - Ending character position of deletion range (0-based, exclusive)\n *\n * @example\n * ```typescript\n * api.delete(5, 10); // Deletes characters 5-9\n * api.apply();\n * ```\n */\n delete: (start: number, end: number) => {\n if (start >= end) return;\n\n const startInfo = findBlockAtPosition(state.blocks, start);\n const endInfo = findBlockAtPosition(state.blocks, end);\n const newBlocks: Block[] = [];\n\n for (let i = 0; i < state.blocks.length; i++) {\n const block = state.blocks[i];\n if (!block) continue;\n\n if (i < startInfo.blockIndex || i > endInfo.blockIndex) {\n // Block is completely outside the deletion range\n newBlocks.push(block);\n } else if (i === startInfo.blockIndex && i === endInfo.blockIndex) {\n // Deletion is within a single block\n if (block.type === BlockType.Text || block.type === BlockType.Styled) {\n const beforeText = block.text.substring(0, startInfo.offset);\n const afterText = block.text.substring(endInfo.offset);\n const newText = beforeText + afterText;\n if (newText.length > 0) {\n newBlocks.push({ ...block, text: newText });\n }\n }\n } else if (i === startInfo.blockIndex) {\n // First block in deletion range\n if (block.type === BlockType.Text || block.type === BlockType.Styled) {\n const beforeText = block.text.substring(0, startInfo.offset);\n if (beforeText.length > 0) {\n newBlocks.push({ ...block, text: beforeText });\n }\n }\n } else if (i === endInfo.blockIndex) {\n // Last block in deletion range\n if (block.type === BlockType.Text || block.type === BlockType.Styled) {\n const afterText = block.text.substring(endInfo.offset);\n if (afterText.length > 0) {\n newBlocks.push({ ...block, text: afterText });\n }\n }\n }\n // Blocks between start and end are completely deleted (not added to newBlocks)\n }\n\n state.blocks = newBlocks;\n state.appendToBuffer([...state.blocks]);\n },\n\n /**\n * Replaces text in the specified range with new text.\n * Equivalent to deleting the range and inserting new text.\n *\n * @param start - Starting character position of range to replace (0-based, inclusive)\n * @param end - Ending character position of range to replace (0-based, exclusive)\n * @param text - New text to insert in place of the deleted range\n *\n * @example\n * ```typescript\n * api.replace(0, 5, 'Hi'); // Replaces first 5 characters with 'Hi'\n * api.apply();\n * ```\n */\n replace: (start: number, end: number, text: string) => {\n // Delete the range first, then insert the new text\n if (start >= end) {\n createApi(state).insert(text, start);\n return;\n }\n\n createApi(state).delete(start, end);\n createApi(state).insert(text, start);\n },\n\n /**\n * Replaces the first occurrence of specified text.\n * Searches through all blocks to find and replace the text.\n *\n * @param oldText - The text string to find and replace\n * @param text - The new text to replace it with\n *\n * @example\n * ```typescript\n * api.replaceText('Hello', 'Hi');\n * api.apply();\n * ```\n */\n replaceText: (oldText: string, text: string) => {\n const fullText = extractText(state.blocks);\n const index = fullText.indexOf(oldText);\n\n if (index !== -1) {\n createApi(state).replace(index, index + oldText.length, text);\n }\n },\n\n /**\n * Replaces all occurrences of specified text.\n * Continues replacing until no more matches are found.\n *\n * @param oldText - The text string to find and replace\n * @param text - The new text to replace all occurrences with\n *\n * @example\n * ```typescript\n * api.replaceAll('foo', 'bar'); // Replaces all 'foo' with 'bar'\n * api.apply();\n * ```\n */\n replaceAll: (oldText: string, text: string) => {\n let fullText = extractText(state.blocks);\n let offset = 0;\n\n while (true) {\n const index = fullText.indexOf(oldText);\n if (index === -1) break;\n\n createApi(state).replace(\n offset + index,\n offset + index + oldText.length,\n text,\n );\n offset += index + text.length;\n fullText = fullText.substring(index + oldText.length);\n }\n },\n\n /**\n * Returns a copy of the current blocks array.\n * Useful for inspecting current editor state.\n *\n * @returns Array of Block objects representing current content\n *\n * @example\n * ```typescript\n * const blocks = api.getBlocks();\n * console.log(blocks);\n * ```\n */\n getBlocks: () => {\n return [...state.blocks];\n },\n\n setBlocks: (blocks: Block[]) => {\n state.blocks = blocks;\n },\n\n appendStyledBlock: (block: StyledBlock) => {\n const newBlocks = [...state.blocks];\n newBlocks.push(block);\n state.blocks = newBlocks;\n state.appendToBuffer([...state.blocks]);\n },\n\n /**\n * Inserts a styled block at the specified position.\n * Styled blocks contain segments with individual styling.\n *\n * @param block - StyledBlock object with segments and styles\n * @param position - Character position where block should be inserted (0-based)\n *\n * @example\n * ```typescript\n * const styledBlock: StyledBlock = {\n * type: 'Styled',\n * text: 'Hello',\n * segments: [{ id: '1', text: 'Hello', style: { color: 'red' } }]\n * };\n * api.insertStyledBlock(styledBlock, 0);\n * api.apply();\n * ```\n */\n insertStyledBlock: (block: StyledBlock, position: number) => {\n const { blockIndex, offset } = findBlockAtPosition(state.blocks, position);\n const newBlocks = [...state.blocks];\n\n if (blockIndex >= newBlocks.length) {\n // Insert at the end\n newBlocks.push(block);\n } else {\n const currentBlock = newBlocks[blockIndex];\n if (\n currentBlock &&\n (currentBlock.type === BlockType.Text ||\n currentBlock.type === BlockType.Styled)\n ) {\n const beforeText = currentBlock.text.substring(0, offset);\n const afterText = currentBlock.text.substring(offset);\n\n // Split the current block\n const splitBlocks: Block[] = [];\n if (beforeText.length > 0) {\n splitBlocks.push({ ...currentBlock, text: beforeText });\n }\n splitBlocks.push(block);\n if (afterText.length > 0) {\n splitBlocks.push({ ...currentBlock, text: afterText });\n }\n\n newBlocks.splice(blockIndex, 1, ...splitBlocks);\n } else {\n // Insert before non-text block\n newBlocks.splice(blockIndex, 0, block);\n }\n }\n\n state.blocks = newBlocks;\n state.appendToBuffer([...state.blocks]);\n },\n\n /**\n * Inserts a document block at the specified position.\n * Document blocks represent file attachments.\n *\n * @param document - Document object with name, file, and optional URL\n * @param position - Character position where document should be inserted (0-based)\n *\n * @example\n * ```typescript\n * const doc: Document = {\n * name: 'report.pdf',\n * file: pdfFile,\n * url: 'https://example.com/report.pdf'\n * };\n * api.insertDocument(doc, 0);\n * api.apply();\n * ```\n */\n insertDocument: (document: Document, position: number) => {\n const docBlock: Block = {\n type: BlockType.Document,\n id: `doc-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`,\n name: document.name,\n file: document.file,\n url: document.url,\n contentType: document.contentType,\n };\n\n const { blockIndex, offset } = findBlockAtPosition(state.blocks, position);\n const newBlocks = [...state.blocks];\n\n if (blockIndex >= newBlocks.length) {\n newBlocks.push(docBlock);\n } else {\n const currentBlock = newBlocks[blockIndex];\n if (\n currentBlock &&\n (currentBlock.type === BlockType.Text ||\n currentBlock.type === BlockType.Styled)\n ) {\n const beforeText = currentBlock.text.substring(0, offset);\n const afterText = currentBlock.text.substring(offset);\n\n const splitBlocks: Block[] = [];\n if (beforeText.length > 0) {\n splitBlocks.push({ ...currentBlock, text: beforeText });\n }\n splitBlocks.push(docBlock);\n if (afterText.length > 0) {\n splitBlocks.push({ ...currentBlock, text: afterText });\n }\n\n newBlocks.splice(blockIndex, 1, ...splitBlocks);\n } else {\n newBlocks.splice(blockIndex, 0, docBlock);\n }\n }\n\n state.blocks = newBlocks;\n state.appendToBuffer([...state.blocks]);\n },\n\n /**\n * Inserts an image block at the specified position.\n * Image blocks represent embedded images.\n *\n * @param image - Image object with name, file, url, and optional alt text\n * @param position - Character position where image should be inserted (0-based)\n *\n * @example\n * ```typescript\n * const img: Image = {\n * name: 'photo.jpg',\n * file: imageFile,\n * url: 'https://example.com/photo.jpg',\n * alt: 'A photo'\n * };\n * api.insertImage(img, 0);\n * api.apply();\n * ```\n */\n insertImage: (image: Image, position: number) => {\n const imgBlock: Block = {\n type: BlockType.Image,\n id: `img-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`,\n name: image.name,\n file: image.file,\n url: image.url,\n ...(image.alt !== undefined ? { alt: image.alt } : {}),\n contentType: image.contentType,\n };\n\n const { blockIndex, offset } = findBlockAtPosition(state.blocks, position);\n const newBlocks = [...state.blocks];\n\n if (blockIndex >= newBlocks.length) {\n newBlocks.push(imgBlock);\n } else {\n const currentBlock = newBlocks[blockIndex];\n if (\n currentBlock &&\n (currentBlock.type === BlockType.Text ||\n currentBlock.type === BlockType.Styled)\n ) {\n const beforeText = currentBlock.text.substring(0, offset);\n const afterText = currentBlock.text.substring(offset);\n\n const splitBlocks: Block[] = [];\n if (beforeText.length > 0) {\n splitBlocks.push({ ...currentBlock, text: beforeText });\n }\n splitBlocks.push(imgBlock);\n if (afterText.length > 0) {\n splitBlocks.push({ ...currentBlock, text: afterText });\n }\n\n newBlocks.splice(blockIndex, 1, ...splitBlocks);\n } else {\n newBlocks.splice(blockIndex, 0, imgBlock);\n }\n }\n\n state.blocks = newBlocks;\n state.appendToBuffer([...state.blocks]);\n },\n\n /**\n * Applies styling to the first occurrence of specified text.\n * Converts Text blocks to Styled blocks with the specified style.\n *\n * @param text - The text string to find and style\n * @param id - Unique identifier for the styled segment\n * @param style - Optional React CSSProperties object for styling\n *\n * @example\n * ```typescript\n * api.styleText('important', 'style-1', { fontWeight: 'bold', color: 'red' });\n * api.apply();\n * ```\n */\n styleText: (text: string, id: string, style?: React.CSSProperties) => {\n const fullText = extractText(state.blocks);\n const index = fullText.indexOf(text);\n\n if (index === -1) return;\n\n const startInfo = findBlockAtPosition(state.blocks, index);\n const endInfo = findBlockAtPosition(state.blocks, index + text.length);\n const newBlocks: Block[] = [];\n\n for (let i = 0; i < state.blocks.length; i++) {\n const block = state.blocks[i];\n if (!block) continue;\n\n if (i < startInfo.blockIndex || i > endInfo.blockIndex) {\n // Block is outside the style range\n newBlocks.push(block);\n } else if (i === startInfo.blockIndex && i === endInfo.blockIndex) {\n // Style is within a single block\n if (block.type === BlockType.Text || block.type === BlockType.Styled) {\n const beforeText = block.text.substring(0, startInfo.offset);\n const styledText = block.text.substring(\n startInfo.offset,\n endInfo.offset,\n );\n const afterText = block.text.substring(endInfo.offset);\n\n if (beforeText.length > 0) {\n newBlocks.push({ type: BlockType.Text, text: beforeText });\n }\n newBlocks.push({\n type: BlockType.Styled,\n id,\n text: styledText,\n ...(style ? { style } : {}),\n } as StyledBlock);\n if (afterText.length > 0) {\n newBlocks.push({ type: BlockType.Text, text: afterText });\n }\n }\n } else if (i === startInfo.blockIndex) {\n // First block in style range\n if (block.type === BlockType.Text || block.type === BlockType.Styled) {\n const beforeText = block.text.substring(0, startInfo.offset);\n const styledText = block.text.substring(startInfo.offset);\n\n if (beforeText.length > 0) {\n newBlocks.push({ type: BlockType.Text, text: beforeText });\n }\n if (styledText.length > 0) {\n newBlocks.push({\n type: BlockType.Styled,\n id: `${id}-${i}`,\n text: styledText,\n ...(style ? { style } : {}),\n } as StyledBlock);\n }\n }\n } else if (i === endInfo.blockIndex) {\n // Last block in style range\n if (block.type === BlockType.Text || block.type === BlockType.Styled) {\n const styledText = block.text.substring(0, endInfo.offset);\n const afterText = block.text.substring(endInfo.offset);\n\n if (styledText.length > 0) {\n newBlocks.push({\n type: BlockType.Styled,\n id: `${id}-${i}`,\n text: styledText,\n ...(style ? { style } : {}),\n } as StyledBlock);\n }\n if (afterText.length > 0) {\n newBlocks.push({ type: BlockType.Text, text: afterText });\n }\n }\n } else {\n // Middle block - convert entirely to styled\n if (block.type === BlockType.Text || block.type === BlockType.Styled) {\n newBlocks.push({\n type: BlockType.Styled,\n id: `${id}-${i}`,\n text: block.text,\n ...(style ? { style } : {}),\n } as StyledBlock);\n } else {\n newBlocks.push(block);\n }\n }\n }\n\n state.blocks = newBlocks;\n state.appendToBuffer([...state.blocks]);\n },\n\n getCharacterPosition: () => {\n return state.characterPosition;\n },\n setCharacterPosition: (position: number) => {\n state.characterPosition = position;\n },\n});\n","import { forwardRef, useEffect, useImperativeHandle, useMemo } from 'react';\nimport {\n useApi,\n useBuffer,\n useCursorPosition,\n useBlocks,\n} from '@src/state/useState';\nimport { SmartInputApi, SmartInputFunctions } from '@src/types/api';\nimport { Block, BlockType, CommitItem } from '@src/types';\nimport { createApi, createState } from './functions';\nimport {\n convertBlocksToCommitItems,\n getCursorPosition,\n getSelectionRange,\n setCursorPosition,\n} from '@src/utils/functions';\n\n/**\n * Api component provides the SmartInput API interface.\n * This component doesn't render any UI but exposes methods via ref to interact with the editor.\n * It manages state transformations and provides methods to manipulate blocks programmatically.\n *\n * @component\n * @example\n * ```tsx\n * const apiRef = useRef<SmartInputApi>(null);\n *\n * // Use the API\n * apiRef.current?.apply((api) => {\n * api.insertText('Hello');\n * });\n * ```\n */\nexport const Api = forwardRef<SmartInputApi>(function Api(_, ref) {\n const { blocks, setBlocks } = useBlocks((s) => s); // ensure re-render on blocks change\n const { setApi, element } = useApi((s) => s); // ensure re-render on api change\n const { characterPosition, updateCharacterPosition } = useCursorPosition(\n (s) => s,\n ); // ensure re-render on cursor position change\n const { appendToBuffer } = useBuffer((s) => s);\n\n const api = useMemo<SmartInputApi>(\n () => ({\n apply: (fn: (api: SmartInputFunctions) => void) => {\n const state = createState(blocks, characterPosition);\n const functions = createApi(state);\n fn(functions);\n if (JSON.stringify(state.blocks) !== JSON.stringify(blocks)) {\n setBlocks(state.blocks);\n }\n if (state.characterPosition !== characterPosition) {\n updateCharacterPosition(state.characterPosition);\n }\n if (state.buffer.length > 0) {\n state.buffer.forEach((b) => appendToBuffer(b));\n }\n },\n getBlockAtPosition: (position: number): Block | null => {\n let blockIndex = -1;\n let blockStart = 0;\n for (let i = 0; i < blocks.length; i++) {\n const b = blocks[i];\n if (!b) continue;\n if (b.type === BlockType.Text || b.type === BlockType.Styled) {\n const blockLength = b.text.length;\n if (position >= blockStart && position < blockStart + blockLength) {\n blockIndex = i;\n const foundBlock = blocks[blockIndex];\n return foundBlock ?? null;\n }\n blockStart += blockLength;\n }\n }\n return null;\n },\n get: (): CommitItem[] => {\n return convertBlocksToCommitItems(blocks);\n },\n getElementById: (id: string): HTMLElement | null => {\n return document.getElementById(id);\n },\n focus: (): void => {\n if (element) {\n element.focus();\n // Move cursor to end of content\n if (element.childNodes.length === 0) {\n const selection = window.getSelection();\n if (selection) {\n const range = document.createRange();\n range.setStart(element, 0);\n range.collapse(true);\n selection.removeAllRanges();\n selection.addRange(range);\n }\n }\n }\n },\n getCursorPosition: (): number => {\n if (!element) return 0;\n const range = getSelectionRange(element);\n if (!range) return 0;\n return getCursorPosition(element, range);\n },\n setCursorPosition: (position: number): void => {\n if (!element) return;\n setCursorPosition(element, position);\n },\n getText: (): string => {\n return blocks\n .map((b) =>\n b.type === BlockType.Text || b.type === BlockType.Styled\n ? b.text\n : '',\n )\n .join('');\n },\n getTextLength: (): number => {\n return blocks.reduce((length, b) => {\n if (b.type === BlockType.Text || b.type === BlockType.Styled) {\n return length + b.text.length;\n }\n return length;\n }, 0);\n },\n }),\n [\n blocks,\n characterPosition,\n setBlocks,\n updateCharacterPosition,\n appendToBuffer,\n element,\n ],\n );\n\n useEffect(() => {\n setApi(api);\n }, [api, setApi]);\n\n useImperativeHandle(ref, () => api, [api]);\n\n return null;\n});\n","import React, { forwardRef, PropsWithChildren } from 'react';\nimport { StateProvider } from '@state/StateProvider';\nimport { ComponentProps } from '@atypes/componentProps';\nimport { Api } from '../Api';\nimport { SmartInputApi } from '@src/types/api';\nimport cx from 'classnames';\nimport style from './SmartInput.module.less';\n\n/**\n * SmartInput is the main container component for the rich text editor.\n * It provides state management and API access to all child components.\n * Use this component as the root wrapper for Editor and other editor-related components.\n *\n * @component\n * @example\n * ```tsx\n * const apiRef = useRef<SmartInputApi>(null);\n *\n * <SmartInput ref={apiRef} blocks={initialBlocks} onBlocksChange={handleChange}>\n * <Editor enableLineBreaks={true} />\n * <CommitNotifier onCommit={handleCommit} />\n * </SmartInput>\n * ```\n */\nexport const SmartInput = forwardRef<\n SmartInputApi,\n PropsWithChildren<ComponentProps>\n>(function SmartInput({ children, className, id, ...props }, ref) {\n return (\n <StateProvider value={props}>\n <Api ref={ref} />\n <div id={id} className={cx(style['SmartInput'], className)}>\n {children}\n </div>\n </StateProvider>\n );\n});\n\nSmartInput.displayName = 'SmartInput';\n","import React, { Component, ReactNode, ErrorInfo } from 'react';\nimport styles from './ErrorBoundary.module.less';\n\n/**\n * Error information displayed when an error occurs\n */\nexport interface ErrorDetails {\n /** The error that was caught */\n error: Error;\n /** React component stack trace */\n errorInfo: ErrorInfo;\n /** Timestamp when the error occurred */\n timestamp: Date;\n}\n\n/**\n * Props for the ErrorBoundary component\n */\nexport interface ErrorBoundaryProps {\n /** Child components to render */\n children: ReactNode;\n /** Optional fallback UI to display on error */\n fallback?: (error: ErrorDetails) => ReactNode;\n /** Callback invoked when an error is caught */\n onError?: (error: ErrorDetails) => void;\n /** Optional custom error message */\n errorMessage?: string;\n /** Whether to show detailed error information (default: only in development) */\n showDetails?: boolean;\n /** Whether to allow reset/retry (default: true) */\n allowReset?: boolean;\n}\n\n/**\n * State for the ErrorBoundary component\n */\ninterface ErrorBoundaryState {\n hasError: boolean;\n error: Error | null;\n errorInfo: ErrorInfo | null;\n timestamp: Date | null;\n}\n\n/**\n * ErrorBoundary component catches JavaScript errors anywhere in the child component tree,\n * logs those errors, and displays a fallback UI instead of crashing the whole application.\n *\n * @component\n * @example\n * ```tsx\n * <ErrorBoundary\n * onError={({ error }) => logErrorToService(error)}\n * errorMessage=\"Something went wrong with the editor\"\n * >\n * <SmartInput>\n * <Editor />\n * </SmartInput>\n * </ErrorBoundary>\n * ```\n */\nexport class ErrorBoundary extends Component<\n ErrorBoundaryProps,\n ErrorBoundaryState\n> {\n constructor(props: ErrorBoundaryProps) {\n super(props);\n this.state = {\n hasError: false,\n error: null,\n errorInfo: null,\n timestamp: null,\n };\n }\n\n static getDerivedStateFromError(error: Error): Partial<ErrorBoundaryState> {\n // Update state so the next render will show the fallback UI\n return {\n hasError: true,\n error,\n timestamp: new Date(),\n };\n }\n\n componentDidCatch(error: Error, errorInfo: ErrorInfo): void {\n const errorDetails: ErrorDetails = {\n error,\n errorInfo,\n timestamp: new Date(),\n };\n\n // Log error details to console in development\n if (\n typeof process !== 'undefined' &&\n process.env?.['NODE_ENV'] === 'development'\n ) {\n console.error('ErrorBoundary caught an error:', error);\n console.error('Component stack:', errorInfo.componentStack);\n }\n\n // Call optional error callback\n if (this.props.onError) {\n this.props.onError(errorDetails);\n }\n\n // Update state with error info\n this.setState({ errorInfo });\n }\n\n handleReset = (): void => {\n this.setState({\n hasError: false,\n error: null,\n errorInfo: null,\n timestamp: null,\n });\n };\n\n render(): ReactNode {\n const { hasError, error, errorInfo, timestamp } = this.state;\n const {\n children,\n fallback,\n errorMessage,\n showDetails = typeof process !== 'undefined' &&\n process.env?.['NODE_ENV'] === 'development',\n allowReset = true,\n } = this.props;\n\n if (hasError && error && errorInfo && timestamp) {\n const errorDetails: ErrorDetails = { error, errorInfo, timestamp };\n\n // Use custom fallback if provided\n if (fallback) {\n return fallback(errorDetails);\n }\n\n // Default error UI\n return (\n <div className={styles['errorBoundary']} role=\"alert\">\n <div className={styles['errorContainer']}>\n <h2 className={styles['errorTitle']}>\n {errorMessage || 'Something went wrong'}\n </h2>\n\n <p className={styles['errorDescription']}>\n An error occurred while rendering this component. Please try\n refreshing the page or contact support if the problem persists.\n </p>\n\n {showDetails && (\n <details className={styles['errorDetails']}>\n <summary className={styles['errorSummary']}>\n Error Details\n </summary>\n <div className={styles['errorContent']}>\n <div className={styles['errorSection']}>\n <strong>Error:</strong>\n <pre className={styles['errorPre']}>{error.toString()}</pre>\n </div>\n\n {error.stack && (\n <div className={styles['errorSection']}>\n <strong>Stack Trace:</strong>\n <pre className={styles['errorPre']}>{error.stack}</pre>\n </div>\n )}\n\n <div className={styles['errorSection']}>\n <strong>Component Stack:</strong>\n <pre className={styles['errorPre']}>\n {errorInfo.componentStack}\n </pre>\n </div>\n\n <div className={styles['errorSection']}>\n <strong>Timestamp:</strong>\n <pre className={styles['errorPre']}>\n {timestamp.toISOString()}\n </pre>\n </div>\n </div>\n </details>\n )}\n\n {allowReset && (\n <button\n className={styles['errorButton']}\n onClick={this.handleReset}\n type=\"button\"\n >\n Try Again\n </button>\n )}\n </div>\n </div>\n );\n }\n\n return children;\n }\n}\n","/** Predefined color palette for editor components */\nexport const Colours = {\n buttons: {\n buttonDefault: 'black',\n buttonDefaultHover: 'black',\n buttonDefaultBackground: 'white',\n buttonDefaultHoverBackground: 'lightgray',\n },\n\n backgrounds: {\n standard: '#626262',\n hover: '#444444',\n locked: '#44444',\n selected: '#1C1C1C',\n multiSelect: '#202020',\n\n errorHover: '#e60000',\n error: '#da0000',\n },\n};\n","/** The MIME type used for clipboard operations with JSON data */\nexport const CLIPBOARD_FORMAT = 'text/json';\n/** Characters that delimit blocks when pasting content */\nexport const DELIMITERS = [',', '\\t', '\\n'];\n\n/** Height in pixels for compact editor size */\nexport const COMPACT_HEIGHT = 24;\n/** Height in pixels for normal editor size */\nexport const NORMAL_HEIGHT = 30;\n/** Height in pixels for large editor size */\nexport const LARGE_HEIGHT = 36;\n\n/** Height in pixels for compact pill/block size */\nexport const COMPACT_PILL_HEIGHT = 18;\n/** Height in pixels for normal pill/block size */\nexport const NORMAL_PILL_HEIGHT = 22;\n/** Height in pixels for large pill/block size */\nexport const LARGE_PILL_HEIGHT = 26;\n\n/** Keyboard key constants for common keys used in the editor */\nexport const KeyBoardkeys = {\n ArrowRight: 'ArrowRight',\n ArrowLeft: 'ArrowLeft',\n ArrowUp: 'ArrowUp',\n ArrowDown: 'ArrowDown',\n PageUp: 'PageUp',\n PageDown: 'PageDown',\n Home: 'Home',\n End: 'End',\n Enter: 'Enter',\n Tab: 'Tab',\n c: 'c',\n C: 'C',\n x: 'x',\n X: 'X',\n v: 'v',\n V: 'V',\n z: 'z',\n Z: 'Z',\n Space: ' ',\n Escape: 'Escape',\n};\n","/**\n * Debug logging utility for Open Input\n *\n * Provides structured logging with namespace support, similar to the 'debug' package.\n * Logs are only output when debugging is enabled via localStorage or environment variables.\n *\n * @example\n * ```ts\n * import { createLogger } from '@smart-input/core';\n *\n * const log = createLogger('editor:state');\n * log('Blocks updated', { count: blocks.length });\n * log.warn('Large content detected', { size: content.length });\n * log.error('Failed to parse', error);\n * ```\n */\n\n/**\n * Log level for filtering messages\n */\nexport enum LogLevel {\n DEBUG = 0,\n INFO = 1,\n WARN = 2,\n ERROR = 3,\n NONE = 4,\n}\n\n/**\n * Logger configuration\n */\ninterface LoggerConfig {\n /** Minimum log level to display */\n level: LogLevel;\n /** Whether to include timestamps */\n timestamps: boolean;\n /** Custom output function (default: console) */\n output?: typeof console;\n}\n\n/**\n * Logger instance for a specific namespace\n */\nexport interface Logger {\n /** Log a debug message */\n (message: string, ...args: unknown[]): void;\n /** Log an info message */\n info: (message: string, ...args: unknown[]) => void;\n /** Log a warning message */\n warn: (message: string, ...args: unknown[]) => void;\n /** Log an error message */\n error: (message: string, ...args: unknown[]) => void;\n /** Check if namespace is enabled */\n enabled: boolean;\n /** The namespace of this logger */\n namespace: string;\n}\n\n// Global configuration\nlet globalConfig: LoggerConfig = {\n level:\n typeof process !== 'undefined' &&\n process.env?.['NODE_ENV'] === 'development'\n ? LogLevel.DEBUG\n : LogLevel.WARN,\n timestamps: true,\n output: console,\n};\n\n// Store enabled namespaces\nconst enabledNamespaces = new Set<string>();\n\n/**\n * Check if localStorage is available\n */\nfunction hasLocalStorage(): boolean {\n try {\n return typeof localStorage !== 'undefined';\n } catch {\n return false;\n }\n}\n\n/**\n * Load debug configuration from localStorage or environment\n */\nfunction loadDebugConfig(): void {\n // Check localStorage for debug flag\n if (hasLocalStorage()) {\n const debugValue = localStorage.getItem('debug');\n if (debugValue) {\n parseDebugString(debugValue);\n }\n }\n\n // Check environment variable (for Node.js environments)\n if (typeof process !== 'undefined' && process.env?.['DEBUG']) {\n parseDebugString(process.env?.['DEBUG'] || '');\n }\n}\n\n/**\n * Parse debug string and enable matching namespaces\n * Examples: 'smart-input:*', 'smart-input:editor:*', 'smart-input:editor:state'\n */\nfunction parseDebugString(debugStr: string): void {\n const patterns = debugStr.split(',').map((s) => s.trim());\n\n patterns.forEach((pattern) => {\n if (pattern === '*' || pattern === 'smart-input:*') {\n // Enable all smart-input namespaces\n enabledNamespaces.add('*');\n } else if (pattern.startsWith('smart-input:')) {\n enabledNamespaces.add(pattern);\n }\n });\n}\n\n/**\n * Check if a namespace is enabled\n */\nfunction isNamespaceEnabled(namespace: string): boolean {\n // Always disabled in production unless explicitly enabled\n if (\n typeof process !== 'undefined' &&\n process.env?.['NODE_ENV'] === 'production' &&\n enabledNamespaces.size === 0\n ) {\n return false;\n }\n\n // Check if all namespaces are enabled\n if (enabledNamespaces.has('*')) {\n return true;\n }\n\n // Check exact match\n const fullNamespace = `smart-input:${namespace}`;\n if (enabledNamespaces.has(fullNamespace)) {\n return true;\n }\n\n // Check wildcard patterns\n for (const pattern of enabledNamespaces) {\n if (pattern.endsWith(':*')) {\n const prefix = pattern.slice(0, -2);\n if (fullNamespace.startsWith(prefix)) {\n return true;\n }\n }\n }\n\n return false;\n}\n\n/**\n * Format log message with timestamp and namespace\n */\nfunction formatMessage(\n namespace: string,\n level: string,\n message: string,\n): string {\n const parts: string[] = [];\n\n if (globalConfig.timestamps) {\n const timestamp = new Date().toISOString();\n parts.push(`[${timestamp}]`);\n }\n\n parts.push(`[${level.toUpperCase()}]`);\n parts.push(`[smart-input:${namespace}]`);\n parts.push(message);\n\n return parts.join(' ');\n}\n\n/**\n * Create a logger for a specific namespace\n *\n * @param namespace - Namespace for the logger (e.g., 'editor:state', 'typeahead')\n * @returns Logger instance\n */\nexport function createLogger(namespace: string): Logger {\n const log = (message: string, ...args: unknown[]): void => {\n if (!isNamespaceEnabled(namespace) || globalConfig.level > LogLevel.DEBUG)\n return;\n const formatted = formatMessage(namespace, 'debug', message);\n globalConfig.output?.log(formatted, ...args);\n };\n\n log.info = (message: string, ...args: unknown[]): void => {\n if (!isNamespaceEnabled(namespace) || globalConfig.level > LogLevel.INFO)\n return;\n const formatted = formatMessage(namespace, 'info', message);\n globalConfig.output?.info(formatted, ...args);\n };\n\n log.warn = (message: string, ...args: unknown[]): void => {\n if (!isNamespaceEnabled(namespace) || globalConfig.level > LogLevel.WARN)\n return;\n const formatted = formatMessage(namespace, 'warn', message);\n globalConfig.output?.warn(formatted, ...args);\n };\n\n log.error = (message: string, ...args: unknown[]): void => {\n if (!isNamespaceEnabled(namespace) || globalConfig.level > LogLevel.ERROR)\n return;\n const formatted = formatMessage(namespace, 'error', message);\n globalConfig.output?.error(formatted, ...args);\n };\n\n // Make enabled a getter so it's always up-to-date\n Object.defineProperty(log, 'enabled', {\n get() {\n return isNamespaceEnabled(namespace);\n },\n enumerable: true,\n configurable: true,\n });\n\n log.namespace = namespace;\n\n return log as Logger;\n}\n\n/**\n * Enable debugging for specific namespaces\n *\n * @param namespaces - Namespace pattern(s) to enable (e.g., '*', 'editor:*', 'typeahead')\n *\n * @example\n * ```ts\n * // Enable all namespaces\n * enableDebug('*');\n *\n * // Enable specific namespace\n * enableDebug('editor:state');\n *\n * // Enable all editor namespaces\n * enableDebug('editor:*');\n *\n * // Enable multiple namespaces\n * enableDebug('editor:*,typeahead');\n * ```\n */\nexport function enableDebug(namespaces: string): void {\n parseDebugString(`smart-input:${namespaces}`);\n\n // Save to localStorage if available\n if (hasLocalStorage()) {\n const currentDebug = localStorage.getItem('debug') || '';\n const newDebug = currentDebug\n ? `${currentDebug},smart-input:${namespaces}`\n : `smart-input:${namespaces}`;\n localStorage.setItem('debug', newDebug);\n }\n}\n\n/**\n * Disable all debugging\n */\nexport function disableDebug(): void {\n enabledNamespaces.clear();\n\n if (hasLocalStorage()) {\n localStorage.removeItem('debug');\n }\n}\n\n/**\n * Configure global logger settings\n *\n * @param config - Partial configuration to update\n */\nexport function configureLogger(config: Partial<LoggerConfig>): void {\n globalConfig = { ...globalConfig, ...config };\n}\n\n/**\n * Get current logger configuration\n */\nexport function getLoggerConfig(): Readonly<LoggerConfig> {\n return { ...globalConfig };\n}\n\n// Load configuration on module import\nloadDebugConfig();\n\n/**\n * Development mode warning utility\n * Shows warnings only in development mode\n */\nexport function devWarn(message: string, ...args: unknown[]): void {\n if (\n typeof process !== 'undefined' &&\n process.env?.['NODE_ENV'] === 'development'\n ) {\n console.warn(`[smart-input] ${message}`, ...args);\n }\n}\n\n/**\n * Development mode error utility\n * Shows errors only in development mode\n */\nexport function devError(message: string, ...args: unknown[]): void {\n if (\n typeof process !== 'undefined' &&\n process.env?.['NODE_ENV'] === 'development'\n ) {\n console.error(`[smart-input] ${message}`, ...args);\n }\n}\n\n/**\n * Assert a condition in development mode\n * Throws an error if the condition is false\n */\nexport function devAssert(\n condition: boolean,\n message: string,\n): asserts condition {\n if (\n typeof process !== 'undefined' &&\n process.env?.['NODE_ENV'] === 'development' &&\n !condition\n ) {\n throw new Error(`[smart-input] Assertion failed: ${message}`);\n }\n}\n"],"names":["StateContext","React","useState","storeSelector","selector","store","useStore","useTopLevelSubscribe","callback","useEffect","unsubscribe","useSubscribe","useBlocks","s","useBuffer","useCursorPosition","useApi","useBehaviour","useKeyHandlers","useDragHandlers","useBlockRerenderHandlers","useTopLevelBlocksSubscriber","useBlocksSubscriber","useTopLevelCursorPositionSubscriber","useCursorPositionSubscriber","unitlessKeys","DEFAULT_UNIT","isCSSPropertyValue","value","camelToKebab","str","match","applyCssUnits","property","unit","isUnitless","unitless","resolvedUnit","stringifyStyleDeclaration","styleDeclaration","options","importantSuffix","_","stringifyCSSProperties","cssProperties","optionsOrImportant","BlockType","convertBlocksToCommitItems","blocks","items","currentText","block","getCursorPosition","preElement","selRange","charCount","i","node","j","childNode","getPositionAndRect","range","pre","rect","DOCUMENT_ICON","createElement","container","e","img","width","height","deleteBtn","element","preContainsTextNode","text","start","preContainsNode","id","getSelectionRange","selection","replaceLineFeeds","getBlockAndOffset","position","pos","b","len","last","lastLen","insertCarridgeReturnInString","offset","end","insertCarridgeReturn","characterPosition","index","newBlock","setCursorPosition","idx","isCarridgeReturn","newRange","sel","foundStart","nodeLength","nextCharCount","removeMatchedText","matchedText","regex","getBlockIndexAtPosition","blockStart","blockLength","replaceTextAtPosition","oldText","newText","currentBlocks","blockIndex","currentBlock","blockText","blockPos","oldTextIndex","newBlockText","newBlocks","insertStyledBlockAtPosition","style","posInBlock","beforeText","afterText","transformToTextBlocks","blockIndexes","sortedIndices","bi","a","blockToTransform","precedingBlock","mergedText","splitTextFromStyledBlock","styled","lookup","isAfter","generateId","isImageFile","file","getCaretRangeFromPoint","clientX","clientY","hasValidContent","dataTransfer","isDraggableBlock","blockId","useElementObserver","lastPositionRef","useRef","callbackRef","rafId","isObserving","triggerCallback","checkPosition","currentPosition","resizeObserver","intersectionObserver","UnmanagedEditor","memo","forwardRef","props","ref","onChange","onUndo","enableLineBreaks","placeholder","className","keyHandlers","dragOverHandlers","dragLeaveHandlers","dropHandlers","preRef","updatePosition","setElement","selectionInProgress","setRef","useCallback","handleKeyDown","event","handler","updateCursorPosition","handleKeyUp","handleChange","handleCopy","fragment","html","handlePaste","handleDragOver","handleDragLeave","handleDrop","jsx","styles","useMutationObserver","targetNode","observer","hasOwn","classNames","classes","arg","appendClass","parseValue","key","newClass","module","addBlockEventListeners","onBlockClick","onBlockDblClick","onBlockMouseUp","onBlockMouseDown","onBlockMouseEnter","onBlockMouseLeave","onBlockMouseOver","onBlockMouseMove","getElementText","setElementText","areStylesDifferent","blockStyle","elementStyle","blockCss","elementCss","Editor","imageWidth","imageHeight","documentWidth","documentHeight","editorClassName","eventHandlers","setBlocks","undoBuffer","appendToBuffer","blockRerenderHandlers","updateCharacterPosition","handleMutations","mutations","affectedBlockIds","mutation","target","rerenderedStyledBlocks","handleDeleteBlock","createElementOptions","useMemo","cnt","domElement","imgElement","expectedSrc","extra","lastBlock","childNodeAtLength","lastChild","isReturn","styledBlock","nextNode","nb","finalBlocks","handleUndo","lastBlocks","cx","subscribeWithSelectorImpl","fn","set","get","api","origSubscribe","optListener","listener","equalityFn","currentSlice","state","nextSlice","previousSlice","subscribeWithSelector","createSubscriberStore","initializer","create","createBlocksStore","useChangeNotify","cursorPositionStore","onBlocksChange","changeCallback","current","previous","cursorRect","MAX_BUFFER_LENGTH","createBufferStore","buffer","ZERO_RECT","createCursorPositionStore","useCursorChangeNotify","blockStore","onCursorPositionChange","createApiStore","createBehaviourStore","createKeyHandlerStore","h","DragEventType","createDragHandlerStore","eventType","createBlockRerenderHandlerStore","StateProvider","children","keyHandlerStore","bufferStore","blocksStore","apiStore","behaviourStore","dragHandlerStore","blockRerenderHandlerStore","stateValue","createState","blocksI","characterPositionI","findBlockAtPosition","currentPos","extractText","createApi","startInfo","endInfo","fullText","splitBlocks","document","docBlock","image","imgBlock","styledText","Api","setApi","functions","length","useImperativeHandle","SmartInput","jsxs","ErrorBoundary","Component","error","errorInfo","errorDetails","hasError","timestamp","fallback","errorMessage","showDetails","allowReset","Colours","CLIPBOARD_FORMAT","DELIMITERS","COMPACT_HEIGHT","NORMAL_HEIGHT","LARGE_HEIGHT","COMPACT_PILL_HEIGHT","NORMAL_PILL_HEIGHT","LARGE_PILL_HEIGHT","KeyBoardkeys","LogLevel","globalConfig","enabledNamespaces","hasLocalStorage","loadDebugConfig","debugValue","parseDebugString","debugStr","pattern","isNamespaceEnabled","namespace","fullNamespace","prefix","formatMessage","level","message","parts","createLogger","log","args","formatted","enableDebug","namespaces","currentDebug","newDebug","disableDebug","configureLogger","config","getLoggerConfig","devWarn","devError","devAssert","condition"],"mappings":"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","x_google_ignoreList":[2,3,9,12]}
|
|
1
|
+
{"version":3,"file":"core.min.mjs","sources":["../src/state/state.ts","../src/state/useState.ts","../../../node_modules/.pnpm/@emotion+unitless@0.10.0/node_modules/@emotion/unitless/dist/emotion-unitless.esm.js","../../../node_modules/.pnpm/react-style-stringify@1.2.0/node_modules/react-style-stringify/dist/index.mjs","../src/types/block.ts","../src/utils/functions.ts","../src/hooks/useElementObserver.ts","../src/components/UnmanagedEditor/UnmanagedEditor.tsx","../src/hooks/useMutationObserver.ts","../../../node_modules/.pnpm/classnames@2.5.1/node_modules/classnames/index.js","../src/components/Editor/functions.ts","../src/components/Editor/Editor.tsx","../../../node_modules/.pnpm/zustand@5.0.2_@types+react@18.3.12_react@18.3.1/node_modules/zustand/esm/middleware.mjs","../src/state/utils.ts","../src/state/blocksStore.ts","../src/hooks/useChangeNotify.ts","../src/state/bufferStore.ts","../src/types/state/cursorPosition.ts","../src/state/cursorPosition.ts","../src/hooks/useCursorChangeNotify.ts","../src/state/apiStore.ts","../src/state/behaviourStore.ts","../src/state/keyHandlerStore.ts","../src/types/editorProps.ts","../src/state/dragHandlerStore.ts","../src/state/blockRerenderHandlerStore.ts","../src/state/StateProvider.tsx","../src/components/Api/functions.ts","../src/components/Api/Api.tsx","../src/components/SmartInput/SmartInput.tsx","../src/components/ErrorBoundary/ErrorBoundary.tsx","../src/utils/colours.ts","../src/utils/constants.ts","../src/utils/logger.ts"],"sourcesContent":["import React from 'react';\nimport { State } from '@atypes/state';\n\n// @ts-expect-error initialisation later\nexport const StateContext = React.createContext<State>();\n","import React, { useEffect } from 'react';\nimport { StoreApi, UseBoundStore, useStore } from 'zustand';\nimport { StateContext } from '@state/state';\n\nimport {\n BehaviourState,\n BlocksState,\n BufferState,\n CursorPositionState,\n State,\n} from '@atypes/state';\nimport { ApiState } from '@src/types/state/api';\nimport { KeyHandlerState } from '@src/types/state/keyHandler';\nimport { DragHandlerState } from '@src/types/state/dragHandler';\nimport { BlockRerenderHandlerState } from '@src/types/state/blockRerenderHandler';\n\nconst useState = <T extends object, U = unknown>(\n storeSelector: (state: State) => UseBoundStore<StoreApi<T>>,\n selector: (state: T) => U,\n) => {\n const store = storeSelector(React.useContext(StateContext));\n\n if (store === null) {\n throw new Error('useState must be used within StateProvider');\n }\n return useStore<UseBoundStore<StoreApi<T>>, U>(store, selector);\n};\n\nconst useTopLevelSubscribe = <T extends object, U = unknown>(\n store: UseBoundStore<StoreApi<T>>,\n selector: (state: T) => U,\n callback: (current: U, previous: U) => void,\n) => {\n useEffect(() => {\n // @ts-expect-error not a genuine error\n const unsubscribe = store.subscribe(selector, callback);\n return () => {\n unsubscribe();\n };\n }, [store, selector, callback]);\n};\n\nconst useSubscribe = <T extends object, U = unknown>(\n storeSelector: (state: State) => UseBoundStore<StoreApi<T>>,\n selector: (state: T) => U,\n callback: (current: U, previous: U) => void,\n) => {\n const store = storeSelector(React.useContext(StateContext));\n\n if (store === null) {\n throw new Error('useState must be used within StateProvider');\n }\n useEffect(() => {\n // @ts-expect-error not a genuine error\n const unsubscribe = store.subscribe(selector, callback);\n return () => {\n unsubscribe();\n };\n }, [store, selector, callback]);\n};\n\nconst useBlocks = <U = unknown>(selector: (state: BlocksState) => U) =>\n useState((s) => s.blocksStore, selector);\n\nconst useBuffer = <U = unknown>(selector: (state: BufferState) => U) =>\n useState((s) => s.bufferStore, selector);\n\nconst useCursorPosition = <U = unknown>(\n selector: (state: CursorPositionState) => U,\n) => useState((s) => s.cursorPositionStore, selector);\n\nconst useApi = <U = unknown>(selector: (state: ApiState) => U) =>\n useState((s) => s.apiStore, selector);\n\nconst useBehaviour = <U = unknown>(selector: (state: BehaviourState) => U) =>\n useState((s) => s.behaviourStore, selector);\n\nconst useKeyHandlers = <U = unknown>(selector: (state: KeyHandlerState) => U) =>\n useState((s) => s.keyHandlerStore, selector);\n\nconst useDragHandlers = <U = unknown>(\n selector: (state: DragHandlerState) => U,\n) => useState((s) => s.dragHandlerStore, selector);\n\nconst useBlockRerenderHandlers = <U = unknown>(\n selector: (state: BlockRerenderHandlerState) => U,\n) => useState((s) => s.blockRerenderHandlerStore, selector);\n\nconst useTopLevelBlocksSubscriber = <U = unknown>(\n store: UseBoundStore<StoreApi<BlocksState>>,\n selector: (state: BlocksState) => U,\n callback: (current: U, previous: U) => void,\n) => useTopLevelSubscribe(store, selector, callback);\n\nconst useBlocksSubscriber = <U = unknown>(\n selector: (state: BlocksState) => U,\n callback: (current: U, previous: U) => void,\n) => useSubscribe((s) => s.blocksStore, selector, callback);\n\nconst useTopLevelCursorPositionSubscriber = <U = unknown>(\n store: UseBoundStore<StoreApi<CursorPositionState>>,\n selector: (state: CursorPositionState) => U,\n callback: (current: U, previous: U) => void,\n) => useTopLevelSubscribe(store, selector, callback);\n\nconst useCursorPositionSubscriber = <U = unknown>(\n selector: (state: CursorPositionState) => U,\n callback: (current: U, previous: U) => void,\n) => useSubscribe((s) => s.cursorPositionStore, selector, callback);\n\nexport {\n useBlocks,\n useBuffer,\n useCursorPosition,\n useApi,\n useBehaviour,\n useKeyHandlers,\n useDragHandlers,\n useBlockRerenderHandlers,\n useBlocksSubscriber,\n useTopLevelBlocksSubscriber,\n useCursorPositionSubscriber,\n useTopLevelCursorPositionSubscriber,\n};\n","var unitlessKeys = {\n animationIterationCount: 1,\n aspectRatio: 1,\n borderImageOutset: 1,\n borderImageSlice: 1,\n borderImageWidth: 1,\n boxFlex: 1,\n boxFlexGroup: 1,\n boxOrdinalGroup: 1,\n columnCount: 1,\n columns: 1,\n flex: 1,\n flexGrow: 1,\n flexPositive: 1,\n flexShrink: 1,\n flexNegative: 1,\n flexOrder: 1,\n gridRow: 1,\n gridRowEnd: 1,\n gridRowSpan: 1,\n gridRowStart: 1,\n gridColumn: 1,\n gridColumnEnd: 1,\n gridColumnSpan: 1,\n gridColumnStart: 1,\n msGridRow: 1,\n msGridRowSpan: 1,\n msGridColumn: 1,\n msGridColumnSpan: 1,\n fontWeight: 1,\n lineHeight: 1,\n opacity: 1,\n order: 1,\n orphans: 1,\n scale: 1,\n tabSize: 1,\n widows: 1,\n zIndex: 1,\n zoom: 1,\n WebkitLineClamp: 1,\n // SVG-related properties\n fillOpacity: 1,\n floodOpacity: 1,\n stopOpacity: 1,\n strokeDasharray: 1,\n strokeDashoffset: 1,\n strokeMiterlimit: 1,\n strokeOpacity: 1,\n strokeWidth: 1\n};\n\nexport { unitlessKeys as default };\n","// src/helpers.ts\nimport unitless from \"@emotion/unitless\";\nvar DEFAULT_UNIT = \"px\";\nvar isCSSPropertyValue = (value) => typeof value === \"number\" || typeof value === \"string\";\nfunction camelToKebab(str) {\n return str.replace(/[A-Z]/g, (match) => `-${match.toLowerCase()}`);\n}\nfunction trimCssSelector(selector) {\n return selector.replace(/\\s*([+~>])\\s*/g, \"$1\").replace(/\\s{2,}/g, \" \").trim();\n}\nfunction applyCssUnits(property, value, unit = DEFAULT_UNIT) {\n if (typeof value !== \"string\" && typeof value !== \"number\") {\n throw new Error(\n \"Invalid input: value of 'cssProperties' must be string or number.\"\n );\n }\n const isUnitless = unitless[property] === 1;\n if (typeof value === \"string\" || value === 0 || isUnitless) {\n return `${value}`;\n }\n const resolvedUnit = (typeof unit === \"string\" ? unit : unit[property]) || DEFAULT_UNIT;\n return `${value}${resolvedUnit}`;\n}\n\n// src/stringifyStyleDeclaration.ts\nfunction stringifyStyleDeclaration(styleDeclaration, options) {\n if (typeof styleDeclaration !== \"object\" || styleDeclaration === null) {\n throw new TypeError(\n `[stringifyStyleDeclaration]: Expected 'styleDeclaration' to be a non-null object, but received ${styleDeclaration} (type:${typeof styleDeclaration}).`\n );\n }\n const importantSuffix = options?.important ? \"!important\" : \"\";\n return Object.entries(styleDeclaration).filter(([_, value]) => isCSSPropertyValue(value)).map(\n ([property, value]) => `${camelToKebab(property)}:${applyCssUnits(\n property,\n value,\n options?.unit\n )}${importantSuffix};`\n ).join(\"\");\n}\n\n// src/stringifyStyleRule.ts\nfunction stringifyStyleRule(styleRule, options) {\n if (typeof styleRule !== \"object\" || styleRule === null) {\n throw new TypeError(\n `[stringifyStyleRule]: Expected 'styleRule' to be a non-null object, but received ${styleRule} (type:${typeof styleRule}).`\n );\n }\n return Object.entries(styleRule).reduce((result, [selector, declaration]) => {\n if (Object.keys(declaration).length > 0) {\n result.push(\n `${trimCssSelector(selector)}{${stringifyStyleDeclaration(\n declaration,\n options\n )}}`\n );\n }\n return result;\n }, []).join(\"\");\n}\n\n// src/stringify-react-styles.ts\nfunction stringifyCSSProperties(cssProperties, optionsOrImportant = false) {\n if (typeof cssProperties !== \"object\" || cssProperties === null) {\n throw new TypeError(\n `[stringifyCSSProperties]: Expected 'cssProperties' to be a non-null object, but received ${cssProperties} (type:${typeof cssProperties}).`\n );\n }\n const options = typeof optionsOrImportant === \"boolean\" ? {\n important: optionsOrImportant\n } : optionsOrImportant;\n return stringifyStyleDeclaration(cssProperties, options);\n}\nfunction stringifyStyleMap(styleMap, optionsOrImportant = false) {\n if (typeof styleMap !== \"object\" || styleMap === null) {\n throw new TypeError(\n `[stringifyStyleMap]: Expected 'styleMap' to be a non-null object, but received ${styleMap} (type:${typeof styleMap}).`\n );\n }\n const options = typeof optionsOrImportant === \"boolean\" ? {\n important: optionsOrImportant\n } : optionsOrImportant;\n return stringifyStyleRule(styleMap, options);\n}\nexport {\n stringifyCSSProperties,\n stringifyStyleDeclaration,\n stringifyStyleMap,\n stringifyStyleRule\n};\n//# sourceMappingURL=index.mjs.map","import { CSSProperties } from 'react';\n\n/**\n * The type of block in the editor.\n */\nexport enum BlockType {\n /** Plain text block */\n Text = 'text',\n /** Styled block with custom styling and behavior */\n Styled = 'styled',\n /** Document/file attachment block */\n Document = 'document',\n /** Image block */\n Image = 'image',\n}\n\n/**\n * Represents a plain text block in the editor.\n */\nexport interface TextBlock {\n /** The block type identifier */\n type: BlockType.Text;\n /** The text content of the block */\n text: string;\n}\n\n/**\n * Represents a styled block in the editor with custom styling and behavior.\n * Styled blocks can have custom CSS styles, classes, and can be made uneditable or undeletable.\n */\nexport interface StyledBlock {\n /** The block type identifier */\n type: BlockType.Styled;\n /** Unique identifier for the block */\n id: string;\n /** The text content of the block */\n text: string;\n /** Custom CSS styles to apply to the block */\n style?: CSSProperties | undefined;\n /** CSS class name to apply to the block */\n className?: string;\n /** If true, the block's content cannot be edited */\n uneditable?: boolean | undefined;\n /** If true, the block cannot be deleted by the user */\n undeletable?: boolean | undefined;\n}\n\n/**\n * Represents a document/file attachment block in the editor.\n */\nexport interface DocumentBlock {\n /** The block type identifier */\n type: BlockType.Document;\n /** Unique identifier for the block */\n id: string;\n /** The name of the document file */\n name: string;\n /** The File object representing the document */\n file: File;\n /** The URL for accessing the document (e.g., blob URL) */\n url: string;\n /** The MIME content type of the document */\n contentType: string;\n /** If true, the block cannot be deleted by the user */\n undeletable?: boolean | undefined;\n}\n\n/**\n * Represents an image block in the editor.\n */\nexport interface ImageBlock {\n /** The block type identifier */\n type: BlockType.Image;\n /** Unique identifier for the block */\n id: string;\n /** The name of the image file */\n name: string;\n /** The File object representing the image */\n file: File;\n /** The URL for displaying the image (e.g., blob URL) */\n url: string;\n /** Alternative text for accessibility */\n alt?: string | undefined;\n /** The MIME content type of the image */\n contentType: string;\n /** If true, the block cannot be deleted by the user */\n undeletable?: boolean | undefined;\n}\n\n/**\n * A block can be any of the supported block types in the editor.\n */\nexport type Block = TextBlock | StyledBlock | DocumentBlock | ImageBlock;\n","import { Block, BlockType, StyledBlock } from '@atypes/block';\nimport { CommitItem } from '@src/types';\nimport { BlockIndex } from '@src/types/api';\n\nimport { stringifyCSSProperties } from 'react-style-stringify';\n\nconst convertBlocksToCommitItems = (blocks: Block[]): CommitItem[] => {\n const items: CommitItem[] = [];\n let currentText = '';\n\n blocks.forEach((block) => {\n if (block.type === BlockType.Text || block.type === BlockType.Styled) {\n // Accumulate text from text and styled blocks\n currentText += 'text' in block ? block.text : '';\n } else if (block.type === BlockType.Document) {\n // When we hit a document, push accumulated text first\n if (currentText) {\n items.push(currentText);\n currentText = '';\n }\n // Transform DocumentBlock to Document type\n items.push({\n type: 'document',\n name: block.name,\n file: block.file,\n url: block.url,\n contentType: block.contentType,\n });\n } else if (block.type === BlockType.Image) {\n // When we hit an image, push accumulated text first\n if (currentText) {\n items.push(currentText);\n currentText = '';\n }\n // Transform ImageBlock to Image type\n items.push({\n type: 'image',\n name: block.name,\n file: block.file,\n url: block.url,\n ...(block.alt !== undefined ? { alt: block.alt } : {}),\n contentType: block.contentType,\n });\n }\n });\n\n // Push any remaining text at the end\n if (currentText) {\n items.push(currentText);\n }\n\n return items;\n};\n\nconst getCursorPosition = (preElement: HTMLPreElement, selRange: Range) => {\n let charCount = 0;\n\n // Walk through only direct children and their direct text nodes\n for (let i = 0; i < preElement.childNodes.length; i++) {\n const node = preElement.childNodes[i];\n if (!node) continue;\n\n // Check if we've reached the selection container\n if (node === selRange.startContainer) {\n return charCount + selRange.startOffset;\n }\n\n // If the selection is inside this node, we need to check its direct children only\n if (node.contains(selRange.startContainer)) {\n // For elements, check their direct text children only\n if (node.nodeType === Node.ELEMENT_NODE) {\n for (let j = 0; j < node.childNodes.length; j++) {\n const childNode = node.childNodes[j];\n if (!childNode) continue;\n if (childNode === selRange.startContainer) {\n return charCount + selRange.startOffset;\n }\n if (childNode.nodeType === Node.TEXT_NODE) {\n if (childNode.contains(selRange.startContainer)) {\n return charCount + selRange.startOffset;\n }\n charCount += (childNode as Text).length;\n }\n }\n // If we didn't find it in direct children, just return current count\n return charCount;\n } else if (node.nodeType === Node.TEXT_NODE) {\n return charCount + selRange.startOffset;\n }\n }\n\n // Count characters in this top-level node\n if (node.nodeType === Node.TEXT_NODE) {\n charCount += (node as Text).length;\n } else if (node.nodeType === Node.ELEMENT_NODE) {\n const element = node as HTMLElement;\n // Count BR elements as single characters\n if (element.tagName === 'BR') {\n charCount += 1;\n } else {\n // Only count direct text node children of this element\n for (let j = 0; j < node.childNodes.length; j++) {\n const childNode = node.childNodes[j];\n if (!childNode) continue;\n if (childNode.nodeType === Node.TEXT_NODE) {\n charCount += (childNode as Text).length;\n } else if (childNode.nodeType === Node.ELEMENT_NODE) {\n const childElement = childNode as HTMLElement;\n if (childElement.tagName === 'BR') {\n charCount += 1;\n }\n }\n }\n }\n }\n }\n\n return charCount;\n};\n\nconst getPositionAndRect = (range: Range, pre: HTMLPreElement | null) => {\n const rect = range.getBoundingClientRect();\n const characterPosition = pre ? getCursorPosition(pre, range) : 0;\n\n return {\n characterPosition,\n rect: {\n left: rect.left,\n top: rect.top,\n right: rect.right,\n bottom: rect.bottom,\n },\n };\n};\n\n// Document icon as data URI (simple document/file icon)\nconst DOCUMENT_ICON =\n 'data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNDgiIGhlaWdodD0iNDgiIHZpZXdCb3g9IjAgMCA0OCA0OCIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48cmVjdCB3aWR0aD0iNDgiIGhlaWdodD0iNDgiIGZpbGw9IiNGNUY1RjUiLz48cGF0aCBkPSJNMTIgOEMxMiA2Ljg5NTQzIDEyLjg5NTQgNiAxNCA2SDI2TDM2IDE2VjQwQzM2IDQxLjEwNDYgMzUuMTA0NiA0MiAzNCA0MkgxNEMxMi44OTU0IDQyIDEyIDQxLjEwNDYgMTIgNDBWOFoiIGZpbGw9IiM0Mjg1RjQiLz48cGF0aCBkPSJNMjYgNlYxNEgyNlYxNkgzNkwyNiA2WiIgZmlsbD0iIzFBNzNFOCIvPjxwYXRoIGQ9Ik0xOCAyMkgzME0xOCAyNkgzME0xOCAzMEgyNiIgc3Ryb2tlPSJ3aGl0ZSIgc3Ryb2tlLXdpZHRoPSIyIiBzdHJva2UtbGluZWNhcD0icm91bmQiLz48L3N2Zz4=';\n\ninterface CreateElementOptions {\n imageWidth?: string;\n imageHeight?: string;\n documentWidth?: string;\n documentHeight?: string;\n onDeleteBlock?: (blockId: string) => void;\n}\n\nconst createElement = (block: Block, options?: CreateElementOptions): Node => {\n if (block.type === BlockType.Text) {\n return document.createTextNode(block.text);\n }\n if (block.type === BlockType.Document) {\n const container = document.createElement('span');\n container.id = block.id;\n container.style.cssText =\n 'position: relative; display: inline-block; vertical-align: middle; margin: 2px; cursor: pointer;';\n container.setAttribute('data-block-type', 'document');\n container.setAttribute('contenteditable', 'false');\n container.classList.add('media-block-container');\n\n // Open in new window on double click\n container.ondblclick = (e) => {\n e.preventDefault();\n e.stopPropagation();\n if (block.url) {\n window.open(block.url, '_blank');\n }\n };\n\n const img = document.createElement('img');\n img.src = DOCUMENT_ICON;\n img.alt = block.name;\n img.title = block.name;\n const width = options?.documentWidth || '32px';\n const height = options?.documentHeight || '32px';\n img.style.cssText = `width: ${width}; height: ${height}; display: block;`;\n img.setAttribute('contenteditable', 'false');\n\n const deleteBtn = document.createElement('button');\n deleteBtn.innerHTML = '×';\n deleteBtn.className = 'media-delete-btn';\n deleteBtn.setAttribute('contenteditable', 'false');\n deleteBtn.style.cssText =\n 'position: absolute; top: -8px; right: -8px; width: 20px; height: 20px; border-radius: 50%; background: #ff4444; color: white; border: 2px solid white; cursor: pointer; font-size: 16px; line-height: 16px; padding: 0; display: none; z-index: 10;';\n if (options?.onDeleteBlock) {\n deleteBtn.onclick = (e) => {\n e.preventDefault();\n e.stopPropagation();\n options.onDeleteBlock?.(block.id);\n };\n }\n\n container.appendChild(img);\n container.appendChild(deleteBtn);\n return container;\n }\n if (block.type === BlockType.Image) {\n const container = document.createElement('span');\n container.id = block.id;\n container.style.cssText =\n 'position: relative; display: inline-block; vertical-align: middle; margin: 2px; cursor: pointer;';\n container.setAttribute('data-block-type', 'image');\n container.setAttribute('contenteditable', 'false');\n container.classList.add('media-block-container');\n\n // Open in new window on double click\n container.ondblclick = (e) => {\n e.preventDefault();\n e.stopPropagation();\n if (block.url) {\n window.open(block.url, '_blank');\n }\n };\n\n const img = document.createElement('img');\n img.src = block.url;\n img.alt = block.alt || block.name;\n img.title = block.name;\n const width = options?.imageWidth || '32px';\n const height = options?.imageHeight || '32px';\n img.style.cssText = `max-width: ${width}; max-height: ${height}; display: block;`;\n img.setAttribute('contenteditable', 'false');\n\n const deleteBtn = document.createElement('button');\n deleteBtn.innerHTML = '×';\n deleteBtn.className = 'media-delete-btn';\n deleteBtn.setAttribute('contenteditable', 'false');\n deleteBtn.style.cssText =\n 'position: absolute; top: -8px; right: -8px; width: 20px; height: 20px; border-radius: 50%; background: #ff4444; color: white; border: 2px solid white; cursor: pointer; font-size: 16px; line-height: 16px; padding: 0; display: none; z-index: 10;';\n if (options?.onDeleteBlock) {\n deleteBtn.onclick = (e) => {\n e.preventDefault();\n e.stopPropagation();\n options.onDeleteBlock?.(block.id);\n };\n }\n\n container.appendChild(img);\n container.appendChild(deleteBtn);\n return container;\n }\n const element = document.createElement('span');\n element.id = block.id;\n element.textContent = block.text;\n if ('style' in block && block.style) {\n element.style.cssText = stringifyCSSProperties(block.style);\n }\n return element;\n};\n\nconst preContainsTextNode = (\n preElement: HTMLPreElement,\n text: string,\n start: number,\n): boolean => {\n for (let i = start; i < preElement.childNodes.length; i++) {\n const element = preElement.childNodes[i];\n if (!element) continue;\n if (element.nodeName === '#text' && element.textContent === text) {\n return true;\n }\n }\n return false;\n};\n\nconst preContainsNode = (\n preElement: HTMLPreElement,\n id: string,\n start: number,\n): boolean => {\n for (let i = start; i < preElement.childNodes.length; i++) {\n const element = preElement.childNodes[i];\n if (!element) continue;\n if ('id' in element && element.id === id) {\n return true;\n }\n }\n return false;\n};\n\nconst getSelectionRange = (preElement: HTMLPreElement) => {\n const selection = document.getSelection();\n if (!selection) return null;\n if (selection.anchorNode === preElement && preElement.lastChild) {\n const range = document.createRange();\n if (preElement.lastChild) {\n if (preElement.lastChild.nodeType === Node.ELEMENT_NODE) {\n range.setStartAfter(preElement.lastChild);\n }\n // If it's a text node, place cursor at the end of the text\n else if (preElement.lastChild.nodeType === Node.TEXT_NODE) {\n range.setStart(\n preElement.lastChild,\n (preElement.lastChild as Text).length,\n );\n }\n range.collapse(true);\n return range;\n }\n }\n if (selection.rangeCount > 0) {\n return selection.getRangeAt(0);\n }\n return null;\n};\n\nconst replaceLineFeeds = (text: string) => {\n return text.replaceAll('\\r\\n', '\\n').replaceAll('\\r', '\\n');\n};\n\nconst getBlockAndOffset = (position: number, blocks: Block[]) => {\n let pos = Math.max(0, Math.floor(position));\n for (let i = 0; i < blocks.length; i++) {\n const b = blocks[i];\n if (!b) continue;\n if (b.type !== BlockType.Text && b.type !== BlockType.Styled) {\n continue;\n }\n const len = 'text' in b ? (b.text?.length ?? 0) : 0;\n if (pos <= len) {\n return { index: i, offset: pos, block: b };\n }\n pos -= len;\n }\n // position beyond end -> return last block end (or empty)\n if (blocks.length === 0)\n return { index: 0, offset: 0, block: undefined as unknown as Block };\n const last = blocks[blocks.length - 1];\n if (!last) {\n return { index: 0, offset: 0, block: undefined as unknown as Block };\n }\n const lastLen =\n last.type === BlockType.Text\n ? 'text' in last\n ? (last.text?.length ?? 0)\n : 0\n : 'text' in last\n ? (last.text?.length ?? 0)\n : 0;\n return { index: blocks.length - 1, offset: lastLen, block: last };\n};\n\nconst insertCarridgeReturnInString = (text: string, offset: number) => {\n const start = offset > 0 ? text.substring(0, offset) : '';\n const end = offset < text.length ? text.substring(offset, text.length) : '';\n return start + '\\n' + end;\n};\n\nconst insertCarridgeReturn = (pre: HTMLPreElement, blocks: Block[]) => {\n const range = getSelectionRange(pre);\n const characterPosition = range ? getCursorPosition(pre, range) : 0;\n const { index, block, offset } = getBlockAndOffset(characterPosition, blocks);\n if (\n !block ||\n (block.type !== BlockType.Text && block.type !== BlockType.Styled)\n ) {\n return blocks;\n }\n const newBlock = {\n ...block,\n text: insertCarridgeReturnInString(block.text, offset),\n };\n setCursorPosition(pre, characterPosition + 1);\n return blocks.map((b, idx) => (idx === index ? newBlock : b));\n};\n\nconst isCarridgeReturn = (childNode: ChildNode) => {\n return (\n childNode.nodeName === 'DIV' &&\n childNode.childNodes.length > 0 &&\n childNode.firstChild?.nodeName === 'BR'\n );\n};\n\nconst setCursorPosition = (\n preElement: HTMLElement,\n characterPosition: number,\n) => {\n // set cursor position to characterPosition\n const newRange = document.createRange();\n const sel = window.getSelection();\n let charCount = 0;\n let foundStart = false;\n\n // Walk through only direct children and their direct text nodes\n for (let i = 0; i < preElement.childNodes.length; i++) {\n const node = preElement.childNodes[i];\n if (!node) continue;\n\n if (node.nodeType === Node.TEXT_NODE) {\n // Top-level text node\n const nodeLength = (node as Text).length;\n const nextCharCount = charCount + nodeLength;\n if (\n characterPosition === nextCharCount &&\n node.nextSibling &&\n 'contentEditable' in node.nextSibling &&\n node.nextSibling.contentEditable !== 'true'\n ) {\n foundStart = true;\n newRange.setStartAfter(node.nextSibling);\n break;\n }\n if (characterPosition <= nextCharCount) {\n foundStart = true;\n newRange.setStart(node, characterPosition - charCount);\n break;\n }\n charCount = nextCharCount;\n } else if (node.nodeType === Node.ELEMENT_NODE) {\n const element = node as HTMLElement;\n // Handle BR elements as single characters\n if (element.tagName === 'BR') {\n const nextCharCount = charCount + 1;\n if (characterPosition <= nextCharCount) {\n foundStart = true;\n newRange.setStart(node, 0);\n break;\n }\n charCount = nextCharCount;\n } else {\n // Only count direct text node children of this element\n for (let j = 0; j < node.childNodes.length; j++) {\n const childNode = node.childNodes[j];\n if (!childNode) continue;\n if (childNode.nodeType === Node.TEXT_NODE) {\n const nodeLength = (childNode as Text).length;\n const nextCharCount = charCount + nodeLength;\n if (characterPosition <= nextCharCount) {\n foundStart = true;\n newRange.setStart(childNode, characterPosition - charCount);\n break;\n }\n charCount = nextCharCount;\n } else if (childNode.nodeType === Node.ELEMENT_NODE) {\n const childElement = childNode as HTMLElement;\n if (childElement.tagName === 'BR') {\n const nextCharCount = charCount + 1;\n if (characterPosition <= nextCharCount) {\n foundStart = true;\n newRange.setStart(childNode, 0);\n break;\n }\n charCount = nextCharCount;\n }\n }\n }\n if (foundStart) {\n break;\n }\n }\n }\n }\n\n if (!foundStart && preElement.lastChild) {\n newRange.setStartAfter(preElement.lastChild);\n }\n newRange.collapse(true);\n if (sel) {\n sel.removeAllRanges();\n sel.addRange(newRange);\n }\n};\n\nconst removeMatchedText = (text: string, matchedText: string): string => {\n const regex = new RegExp(\n matchedText.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&'),\n 'i',\n );\n return text.replace(regex, '');\n};\n\nconst getBlockIndexAtPosition = (\n position: number,\n blocks: Block[],\n): { index: number; offset: number } | null => {\n let blockStart = 0;\n for (let i = 0; i < blocks.length; i++) {\n const block = blocks[i];\n if (!block) continue;\n const blockLength = 'text' in block ? block.text.length : 0;\n if (position >= blockStart && position < blockStart + blockLength) {\n return {\n index: i,\n offset: position - blockStart,\n };\n }\n blockStart += blockLength;\n }\n return null;\n};\n\nconst replaceTextAtPosition = (\n blocks: Block[],\n position: number,\n oldText: string,\n newText: string,\n) => {\n const currentBlocks = blocks ?? [];\n const pos = Math.max(0, position ?? 0);\n\n // Find the block that contains the position\n let blockIndex = -1;\n let blockStart = 0;\n for (let i = 0; i < currentBlocks.length; i++) {\n const block = currentBlocks[i];\n if (!block) continue;\n const blockLength = 'text' in block ? block.text.length : 0;\n if (pos >= blockStart && pos < blockStart + blockLength) {\n blockIndex = i;\n break;\n }\n blockStart += blockLength;\n }\n\n // If no block found or oldText is not in the block, return false\n if (blockIndex === -1) {\n return null;\n }\n\n const currentBlock = currentBlocks[blockIndex];\n if (!currentBlock || !('text' in currentBlock)) {\n return null; // Can't replace text in non-text blocks\n }\n\n const blockText = currentBlock.text;\n const blockPos = pos - blockStart; // position within the block\n\n // Check if oldText is completely within the block\n const oldTextIndex = blockText.indexOf(oldText, blockPos);\n if (oldTextIndex !== blockPos) {\n return null; // oldText not found at the correct position\n }\n\n const newBlockText =\n blockText.slice(0, oldTextIndex) +\n newText +\n blockText.slice(oldTextIndex + oldText.length);\n const newBlocks = [...currentBlocks];\n newBlocks[blockIndex] = {\n ...currentBlock,\n text: newBlockText,\n };\n return {\n newBlocks,\n newPosition: position + newText.length,\n };\n};\n\nconst insertStyledBlockAtPosition = (\n blocks: Block[],\n position: number,\n oldText: string,\n id: string,\n text: string,\n style: React.CSSProperties,\n) => {\n const currentBlocks = blocks ?? [];\n let blockIndex = -1;\n let blockStart = 0;\n\n // Find the block that contains the position\n for (let i = 0; i < currentBlocks.length; i++) {\n const block = currentBlocks[i];\n if (!block) continue;\n const blockLength = 'text' in block ? block.text.length : 0;\n if (position >= blockStart && position < blockStart + blockLength) {\n blockIndex = i;\n break;\n }\n blockStart += blockLength;\n }\n\n const newBlocks = [...currentBlocks];\n const posInBlock = position - blockStart;\n\n if (blockIndex === -1) {\n // Position is at the end or before any blocks\n newBlocks.push({\n id,\n type: BlockType.Styled,\n text: text,\n style: style,\n } as Block);\n } else {\n // Split the current block and insert the styled block\n const currentBlock = newBlocks[blockIndex];\n if (!currentBlock) {\n return { newBlocks: currentBlocks, newPosition: position };\n }\n\n // Only process blocks that have text\n if (!('text' in currentBlock)) {\n return { newBlocks: currentBlocks, newPosition: position };\n }\n\n const beforeText = currentBlock.text.slice(0, posInBlock);\n const afterText = currentBlock.text.slice(posInBlock + oldText.length);\n\n if (posInBlock > 0) {\n newBlocks[blockIndex] = { ...currentBlock, text: beforeText };\n } else {\n newBlocks.splice(blockIndex, 1);\n blockIndex -= 1;\n }\n newBlocks.splice(blockIndex + 1, 0, {\n id,\n type: BlockType.Styled,\n text: text,\n style: style,\n } as Block);\n\n if (afterText) {\n newBlocks.splice(blockIndex + 2, 0, { ...currentBlock, text: afterText });\n }\n }\n\n return {\n newBlocks,\n newPosition: position + text.length,\n };\n};\n\nconst transformToTextBlocks = (blocks: Block[], blockIndexes: BlockIndex[]) => {\n const currentBlocks = blocks ?? [];\n\n // Sort indices in descending order to safely remove blocks without affecting earlier indices\n const sortedIndices = blockIndexes\n .map((bi) => (typeof bi === 'number' ? bi : bi.idx))\n .sort((a, b) => b - a);\n\n const newBlocks = [...currentBlocks];\n\n for (const idx of sortedIndices) {\n if (idx < 0 || idx >= newBlocks.length) continue;\n\n const blockToTransform = newBlocks[idx];\n if (!blockToTransform) continue;\n\n // Skip blocks without text property\n if (!('text' in blockToTransform)) continue;\n\n const precedingBlock = idx > 0 ? newBlocks[idx - 1] : null;\n\n // If there's a preceding text block, merge with it\n if (precedingBlock && precedingBlock.type === BlockType.Text) {\n const mergedText = precedingBlock.text + blockToTransform.text;\n newBlocks[idx - 1] = { ...precedingBlock, text: mergedText };\n newBlocks.splice(idx, 1);\n } else {\n // Otherwise, convert to text block\n newBlocks[idx] = { ...blockToTransform, type: BlockType.Text };\n }\n }\n return {\n newBlocks,\n };\n};\n\nconst splitTextFromStyledBlock = (\n blocks: Block[],\n styled: StyledBlock,\n index: number,\n lookup: string,\n) => {\n const isAfter = styled.text.indexOf(lookup) === 0;\n const newText = styled.text.replace(lookup, '');\n const newBlocks: Block[] = [\n ...blocks.slice(0, index),\n ...(!isAfter\n ? [\n {\n type: BlockType.Text,\n text: newText,\n } as Block,\n ]\n : []),\n {\n ...styled,\n text: lookup,\n } as Block,\n ...(isAfter\n ? [\n {\n type: BlockType.Text,\n text: newText,\n } as Block,\n ]\n : []),\n ...blocks.slice(index + 1),\n ];\n return {\n newBlocks,\n };\n};\n\n/**\n * Generate a unique ID for blocks\n */\nconst generateId = (): string => {\n return `${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;\n};\n\n/**\n * Check if a file is an image\n */\nconst isImageFile = (file: File): boolean => {\n return file.type.startsWith('image/');\n};\n\n/**\n * Get caret range from point with cross-browser support\n */\nconst getCaretRangeFromPoint = (\n clientX: number,\n clientY: number,\n): Range | null => {\n if (document.caretRangeFromPoint) {\n return document.caretRangeFromPoint(clientX, clientY);\n } else if ((document as any).caretPositionFromPoint) {\n const position = (document as any).caretPositionFromPoint(clientX, clientY);\n if (position) {\n const range = document.createRange();\n range.setStart(position.offsetNode, position.offset);\n return range;\n }\n }\n return null;\n};\n\n/**\n * Check if a DataTransfer contains valid file content\n */\nconst hasValidContent = (dataTransfer: DataTransfer): boolean => {\n // During dragover, files array may be empty for security reasons\n // Check types or items instead\n if (dataTransfer.types && dataTransfer.types.includes('Files')) {\n return true;\n }\n // Fallback to checking files (available in drop event)\n return dataTransfer.files && dataTransfer.files.length > 0;\n};\n\n/**\n * Check if a block is draggable (Image, Document, or uneditable Styled blocks)\n */\nconst isDraggableBlock = (block: Block, blockId: string): boolean => {\n if (!('id' in block) || block.id !== blockId) return false;\n // Allow dragging of Image and Document blocks\n if (block.type === BlockType.Image || block.type === BlockType.Document)\n return true;\n // For Styled blocks, only allow dragging if they are uneditable\n if (block.type === BlockType.Styled) return block.uneditable === true;\n return false;\n};\n\nexport {\n convertBlocksToCommitItems,\n getCursorPosition,\n getPositionAndRect,\n setCursorPosition,\n preContainsTextNode,\n createElement,\n preContainsNode,\n getSelectionRange,\n replaceLineFeeds,\n insertCarridgeReturn,\n isCarridgeReturn,\n removeMatchedText,\n getBlockIndexAtPosition,\n replaceTextAtPosition,\n insertStyledBlockAtPosition,\n transformToTextBlocks,\n splitTextFromStyledBlock,\n generateId,\n isImageFile,\n getCaretRangeFromPoint,\n hasValidContent,\n isDraggableBlock,\n};\n","import { useEffect, useRef } from 'react';\n\n/**\n * Hook that observes an element for position and size changes.\n * Calls the provided callback when either the element's size changes\n * or its position changes (due to scrolling or layout shifts).\n *\n * @param element - The DOM element to observe\n * @param callback - Function to call when position or size changes\n *\n * @example\n * ```tsx\n * const preRef = useRef<HTMLPreElement>(null);\n *\n * useElementObserver(preRef.current, () => {\n * console.log('Element position or size changed');\n * updateCursorPosition();\n * });\n * ```\n */\nexport const useElementObserver = (\n element: HTMLElement | null,\n callback: () => void,\n) => {\n const lastPositionRef = useRef({ top: 0, left: 0 });\n const callbackRef = useRef(callback);\n\n // Keep callback ref up to date\n useEffect(() => {\n callbackRef.current = callback;\n }, [callback]);\n\n useEffect(() => {\n if (!element) return;\n\n let rafId: number | null = null;\n let isObserving = true;\n\n const triggerCallback = () => {\n callbackRef.current();\n };\n\n // Check for position changes using requestAnimationFrame\n const checkPosition = () => {\n if (!isObserving || !element) return;\n\n const rect = element.getBoundingClientRect();\n const currentPosition = { top: rect.top, left: rect.left };\n\n // Check if position has changed\n if (\n currentPosition.top !== lastPositionRef.current.top ||\n currentPosition.left !== lastPositionRef.current.left\n ) {\n lastPositionRef.current = currentPosition;\n triggerCallback();\n }\n\n rafId = requestAnimationFrame(checkPosition);\n };\n\n // Use ResizeObserver for size changes\n let resizeObserver: ResizeObserver | null = null;\n if (typeof ResizeObserver !== 'undefined') {\n resizeObserver = new ResizeObserver(triggerCallback);\n resizeObserver.observe(element);\n }\n\n // Use IntersectionObserver to detect position changes efficiently\n let intersectionObserver: IntersectionObserver | null = null;\n if (typeof IntersectionObserver !== 'undefined') {\n intersectionObserver = new IntersectionObserver(triggerCallback, {\n root: null, // viewport\n threshold: [0, 0.25, 0.5, 0.75, 1],\n });\n intersectionObserver.observe(element);\n }\n\n // Listen for scroll events on window and scrollable ancestors\n window.addEventListener('scroll', triggerCallback, true);\n window.addEventListener('resize', triggerCallback);\n\n // Start position checking as fallback\n rafId = requestAnimationFrame(checkPosition);\n\n return () => {\n isObserving = false;\n if (rafId !== null) {\n cancelAnimationFrame(rafId);\n }\n if (resizeObserver) {\n resizeObserver.disconnect();\n }\n if (intersectionObserver) {\n intersectionObserver.disconnect();\n }\n window.removeEventListener('scroll', triggerCallback, true);\n window.removeEventListener('resize', triggerCallback);\n };\n }, [element]);\n};\n","import React, {\n ClipboardEvent,\n forwardRef,\n KeyboardEvent,\n memo,\n useCallback,\n useRef,\n} from 'react';\nimport {\n useApi,\n useBehaviour,\n useCursorPosition,\n useDragHandlers,\n useKeyHandlers,\n} from '@state/useState';\nimport { getPositionAndRect, getSelectionRange } from '../../utils/functions';\nimport { useElementObserver } from '../../hooks/useElementObserver';\nimport styles from './UnmanagedEditor.module.less';\n\n/**\n * Props for the UnmanagedEditor component.\n */\ninterface UnmanagedEditorProps {\n /** Callback invoked when the editor content changes */\n onChange: (isReturn?: boolean) => void;\n /** Callback invoked when undo is triggered (Ctrl/Cmd+Z) */\n onUndo: () => void;\n /** Whether to allow line breaks (default: false) */\n enableLineBreaks?: boolean;\n /** Placeholder text shown when editor is empty */\n placeholder?: string;\n /** Custom CSS class name to apply to the editor area */\n className?: string | undefined;\n}\n\n/**\n * UnmanagedEditor provides the low-level contentEditable interface.\n * This component handles keyboard events, cursor tracking, and user interactions.\n * It's typically used internally by the Editor component rather than directly.\n *\n * @component\n * @internal\n */\nexport const UnmanagedEditor = memo(\n forwardRef<HTMLPreElement, UnmanagedEditorProps>((props, ref) => {\n const {\n onChange,\n onUndo,\n enableLineBreaks = false,\n placeholder = 'Start typing',\n className,\n } = props;\n const keyHandlers = useKeyHandlers((s) => s.keyHandlers);\n const { dragOverHandlers, dragLeaveHandlers, dropHandlers } =\n useDragHandlers((s) => s);\n const preRef = useRef<HTMLPreElement | null>(null);\n const { updatePosition } = useCursorPosition((s) => s);\n const { setElement } = useApi((s) => s);\n const selectionInProgress = useBehaviour((s) => s.selectionInProgress);\n\n const setRef = useCallback(\n (element: HTMLPreElement | null) => {\n if (!ref) return;\n if (typeof ref === 'function') {\n ref(element);\n } else {\n // Type assertion to allow assignment to current\n (ref as React.MutableRefObject<HTMLPreElement | null>).current =\n element;\n }\n preRef.current = element;\n setElement(preRef.current);\n },\n [ref, setElement],\n );\n\n const handleKeyDown = useCallback(\n (event: KeyboardEvent<HTMLPreElement>) => {\n if (keyHandlers.length > 0) {\n for (const handler of keyHandlers) {\n if (handler({ ...event })) {\n event.preventDefault();\n event.stopPropagation();\n break;\n }\n }\n }\n if (\n event.key === 'Enter' &&\n (selectionInProgress || !enableLineBreaks)\n ) {\n event.preventDefault();\n return;\n }\n if (event.key === 'z' && (event.ctrlKey || event.metaKey)) {\n onUndo();\n event.preventDefault();\n return;\n }\n },\n [onUndo, selectionInProgress, enableLineBreaks, keyHandlers],\n );\n\n const updateCursorPosition = useCallback(() => {\n if (!preRef.current) return;\n const range = getSelectionRange(preRef.current);\n if (range) {\n const { characterPosition, rect } = getPositionAndRect(\n range,\n preRef.current,\n );\n updatePosition(characterPosition, rect);\n }\n }, [updatePosition]);\n\n // Monitor pre element for position and size changes\n useElementObserver(preRef.current, updateCursorPosition);\n\n const handleKeyUp = useCallback(\n (event: KeyboardEvent) => {\n if (\n event.key === 'Enter' &&\n (selectionInProgress || !enableLineBreaks)\n ) {\n event.preventDefault();\n return;\n }\n updateCursorPosition();\n onChange(event.key === 'Enter');\n },\n [updateCursorPosition, onChange, enableLineBreaks, selectionInProgress],\n );\n\n const handleChange = useCallback(() => {\n updateCursorPosition();\n onChange();\n }, [updateCursorPosition, onChange]);\n\n const handleCopy = useCallback((event: ClipboardEvent<HTMLPreElement>) => {\n const selection = document.getSelection();\n if (selection && selection.rangeCount > 0) {\n const range = selection.getRangeAt(0);\n const fragment = range.cloneContents();\n const container = document.createElement('div');\n container.appendChild(fragment);\n const text = container.textContent ?? '';\n const html = container.innerHTML ?? '';\n event.clipboardData.setData('text/plain', text);\n event.clipboardData.setData('text/html', html);\n event.preventDefault();\n } else if (preRef.current) {\n const text = preRef.current.textContent ?? '';\n const html = preRef.current.innerHTML ?? text;\n event.clipboardData.setData('text/plain', text);\n event.clipboardData.setData('text/html', html);\n event.preventDefault();\n }\n }, []);\n\n const handlePaste = useCallback(\n (event: React.ClipboardEvent<HTMLPreElement>) => {\n const text = event.clipboardData.getData('text/plain');\n document.execCommand('insertText', false, text);\n event.preventDefault();\n },\n [],\n );\n\n const handleDragOver = useCallback(\n (event: React.DragEvent<HTMLPreElement>) => {\n for (let index = 0; index < dragOverHandlers.length; index++) {\n const handler = dragOverHandlers[index];\n if (handler && handler(event)) {\n event.preventDefault();\n break;\n }\n }\n },\n [dragOverHandlers],\n );\n\n const handleDragLeave = useCallback(\n (event: React.DragEvent<HTMLPreElement>) => {\n for (let index = 0; index < dragLeaveHandlers.length; index++) {\n const handler = dragLeaveHandlers[index];\n if (handler && handler(event)) {\n event.preventDefault();\n break;\n }\n }\n },\n [dragLeaveHandlers],\n );\n\n const handleDrop = useCallback(\n (event: React.DragEvent<HTMLPreElement>) => {\n for (let index = 0; index < dropHandlers.length; index++) {\n const handler = dropHandlers[index];\n if (handler && handler(event)) {\n event.preventDefault();\n break;\n }\n }\n },\n [dropHandlers],\n );\n\n return (\n <pre\n id=\"si-edit-element\"\n className={`${styles['editor']} ${className ?? ''}`}\n contentEditable={true}\n role=\"textbox\"\n tabIndex={0}\n aria-label={placeholder}\n aria-multiline={enableLineBreaks}\n ref={setRef}\n autoCapitalize=\"none\"\n autoCorrect=\"off\"\n spellCheck=\"false\"\n onChange={handleChange}\n onKeyDown={handleKeyDown}\n onKeyUp={handleKeyUp}\n onMouseUp={updateCursorPosition}\n onClick={updateCursorPosition}\n onCopy={handleCopy}\n onPaste={handlePaste}\n onDragOver={handleDragOver}\n onDragLeave={handleDragLeave}\n onDrop={handleDrop}\n data-placeholder={placeholder}\n />\n );\n }),\n);\n\nUnmanagedEditor.displayName = 'UnmanagedEditor';\n","import { useEffect } from 'react';\n\n/**\n * Hook that sets up a MutationObserver to watch for changes in the DOM tree.\n * Useful for reacting to dynamic DOM changes in the editor.\n *\n * @param targetNode - The DOM node to observe\n * @param callback - Function to call when mutations are observed\n * @param options - MutationObserver configuration options\n *\n * @example\n * ```tsx\n * const editorRef = useRef<HTMLDivElement>(null);\n *\n * useMutationObserver(\n * editorRef.current?.querySelector('pre'),\n * (mutations) => {\n * console.log('DOM changed:', mutations);\n * // Reattach event listeners or update state\n * },\n * { childList: true, subtree: true }\n * );\n * ```\n */\nexport const useMutationObserver = (\n targetNode: Node | null,\n callback: MutationCallback,\n options?: MutationObserverInit,\n) => {\n useEffect(() => {\n if (!targetNode) return;\n\n const observer = new MutationObserver(callback);\n\n observer.observe(targetNode, options);\n\n callback([], observer);\n return () => observer.disconnect();\n }, [options, targetNode, callback]);\n};\n","/*!\n\tCopyright (c) 2018 Jed Watson.\n\tLicensed under the MIT License (MIT), see\n\thttp://jedwatson.github.io/classnames\n*/\n/* global define */\n\n(function () {\n\t'use strict';\n\n\tvar hasOwn = {}.hasOwnProperty;\n\n\tfunction classNames () {\n\t\tvar classes = '';\n\n\t\tfor (var i = 0; i < arguments.length; i++) {\n\t\t\tvar arg = arguments[i];\n\t\t\tif (arg) {\n\t\t\t\tclasses = appendClass(classes, parseValue(arg));\n\t\t\t}\n\t\t}\n\n\t\treturn classes;\n\t}\n\n\tfunction parseValue (arg) {\n\t\tif (typeof arg === 'string' || typeof arg === 'number') {\n\t\t\treturn arg;\n\t\t}\n\n\t\tif (typeof arg !== 'object') {\n\t\t\treturn '';\n\t\t}\n\n\t\tif (Array.isArray(arg)) {\n\t\t\treturn classNames.apply(null, arg);\n\t\t}\n\n\t\tif (arg.toString !== Object.prototype.toString && !arg.toString.toString().includes('[native code]')) {\n\t\t\treturn arg.toString();\n\t\t}\n\n\t\tvar classes = '';\n\n\t\tfor (var key in arg) {\n\t\t\tif (hasOwn.call(arg, key) && arg[key]) {\n\t\t\t\tclasses = appendClass(classes, key);\n\t\t\t}\n\t\t}\n\n\t\treturn classes;\n\t}\n\n\tfunction appendClass (value, newClass) {\n\t\tif (!newClass) {\n\t\t\treturn value;\n\t\t}\n\t\n\t\tif (value) {\n\t\t\treturn value + ' ' + newClass;\n\t\t}\n\t\n\t\treturn value + newClass;\n\t}\n\n\tif (typeof module !== 'undefined' && module.exports) {\n\t\tclassNames.default = classNames;\n\t\tmodule.exports = classNames;\n\t} else if (typeof define === 'function' && typeof define.amd === 'object' && define.amd) {\n\t\t// register as 'classnames', consistent with npm package name\n\t\tdefine('classnames', [], function () {\n\t\t\treturn classNames;\n\t\t});\n\t} else {\n\t\twindow.classNames = classNames;\n\t}\n}());\n","import { Block, EditorProps } from '@src/types';\nimport { stringifyCSSProperties } from 'react-style-stringify';\n\nconst addBlockEventListeners = (\n element: HTMLElement,\n block: Block,\n options: EditorProps,\n) => {\n (window as any).lastAddBlockEventListeners = {\n blockId: 'id' in block ? block.id : 'no-id',\n optionsKeys: Object.keys(options),\n hasOnBlockClick: !!options.onBlockClick,\n };\n const {\n onBlockClick,\n onBlockDblClick,\n onBlockMouseUp,\n onBlockMouseDown,\n onBlockMouseEnter,\n onBlockMouseLeave,\n onBlockMouseOver,\n onBlockMouseMove,\n } = options;\n if (onBlockClick)\n element.onclick = (event: MouseEvent) => onBlockClick?.(block, event);\n if (onBlockDblClick)\n element.ondblclick = (event: MouseEvent) => onBlockDblClick?.(block, event);\n if (onBlockMouseUp)\n element.onmouseup = (event: MouseEvent) => onBlockMouseUp?.(block, event);\n if (onBlockMouseDown)\n element.onmousedown = (event: MouseEvent) =>\n onBlockMouseDown?.(block, event);\n if (onBlockMouseEnter)\n element.onmouseenter = (event: MouseEvent) =>\n onBlockMouseEnter?.(block, event);\n if (onBlockMouseLeave)\n element.onmouseleave = (event: MouseEvent) =>\n onBlockMouseLeave?.(block, event);\n if (onBlockMouseOver)\n element.onmouseover = (event: MouseEvent) =>\n onBlockMouseOver?.(block, event);\n if (onBlockMouseMove)\n element.onmousemove = (event: MouseEvent) =>\n onBlockMouseMove?.(block, event);\n};\n\nconst getElementText = (element: HTMLElement): string => {\n if (element.childElementCount === 0) {\n return element.textContent ?? '';\n }\n for (let index = 0; index < element.childNodes.length; index++) {\n const node = element.childNodes[index];\n if (node && node.nodeType === Node.TEXT_NODE) {\n return node.textContent ?? '';\n }\n }\n return '';\n};\n\nconst setElementText = (element: HTMLElement, text: string): void => {\n if (element.childElementCount === 0) {\n element.textContent = text;\n return;\n }\n for (let index = 0; index < element.childNodes.length; index++) {\n const node = element.childNodes[index];\n if (node && node.nodeType === Node.TEXT_NODE) {\n node.textContent = text;\n return;\n }\n }\n};\n\nconst areStylesDifferent = (\n blockStyle: React.CSSProperties,\n elementStyle: string,\n): boolean => {\n const blockCss = stringifyCSSProperties(blockStyle).replace(/\\s/g, '');\n const elementCss = elementStyle\n .replace(/\\s/g, '')\n .replace('cursor:grab;', '')\n .replace('-webkit-user-drag:element;', '');\n return blockCss !== elementCss;\n};\n\nexport {\n addBlockEventListeners,\n getElementText,\n setElementText,\n areStylesDifferent,\n};\n","import React, {\n FC,\n memo,\n useCallback,\n useEffect,\n useMemo,\n useRef,\n} from 'react';\nimport {\n useBlockRerenderHandlers,\n useBlocks,\n useBuffer,\n useCursorPosition,\n} from '@state/useState';\nimport { stringifyCSSProperties } from 'react-style-stringify';\nimport { UnmanagedEditor } from '@components/UnmanagedEditor';\nimport { Block, BlockType, StyledBlock } from '@atypes/block';\nimport { useMutationObserver } from '@hooks/useMutationObserver';\nimport {\n createElement,\n getCursorPosition,\n getSelectionRange,\n insertCarridgeReturn,\n isCarridgeReturn,\n preContainsNode,\n preContainsTextNode,\n replaceLineFeeds,\n setCursorPosition,\n} from '../../utils/functions';\nimport { EditorProps } from '@src/types';\nimport cx from 'classnames';\nimport {\n addBlockEventListeners,\n areStylesDifferent,\n getElementText,\n setElementText,\n} from './functions';\nimport style from './Editor.module.less';\n\n// Document icon as data URI (same as in functions.ts)\nconst DOCUMENT_ICON =\n 'data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNDgiIGhlaWdodD0iNDgiIHZpZXdCb3g9IjAgMCA0OCA0OCIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48cmVjdCB3aWR0aD0iNDgiIGhlaWdodD0iNDgiIGZpbGw9IiNGNUY1RjUiLz48cGF0aCBkPSJNMTIgOEMxMiA2Ljg5NTQzIDEyLjg5NTQgNiAxNCA2SDI2TDM2IDE2VjQwQzM2IDQxLjEwNDYgMzUuMTA0NiA0MiAzNCA0MkgxNEMxMi44OTU0IDQyIDEyIDQxLjEwNDYgMTIgNDBWOFoiIGZpbGw9IiM0Mjg1RjQiLz48cGF0aCBkPSJNMjYgNlYxNEgyNlYxNkgzNkwyNiA2WiIgZmlsbD0iIzFBNzNFOCIvPjxwYXRoIGQ9Ik0xOCAyMkgzME0xOCAyNkgzME0xOCAzMEgyNiIgc3Ryb2tlPSJ3aGl0ZSIgc3Ryb2tlLXdpZHRoPSIyIiBzdHJva2UtbGluZWNhcD0icm91bmQiLz48L3N2Zz4=';\n\n/**\n * Editor component provides a rich text editing experience with support for images and documents.\n * This is a managed editor that automatically synchronizes with the SmartInput state.\n * It handles block rendering, cursor positioning, and user interactions.\n *\n * @component\n * @example\n * ```tsx\n * <Editor\n * enableLineBreaks={true}\n * placeholder=\"Type something...\"\n * imageWidth=\"100px\"\n * />\n * ```\n */\nexport const Editor: FC<EditorProps> = memo(function Editor({\n enableLineBreaks = false,\n imageWidth,\n imageHeight,\n documentWidth,\n documentHeight,\n className,\n placeholder = 'Start typing',\n editorClassName,\n ...eventHandlers\n}) {\n const preRef = useRef<HTMLPreElement | null>(null);\n const { blocks, setBlocks } = useBlocks((s) => s);\n const { undoBuffer, appendToBuffer } = useBuffer((s) => s);\n const { blockRerenderHandlers } = useBlockRerenderHandlers((s) => s);\n const { characterPosition, updateCharacterPosition } = useCursorPosition(\n (s) => s,\n );\n\n // Watch for DOM mutations and notify blockRerenderHandlers of changed styled blocks\n const handleMutations = useCallback(\n (mutations: MutationRecord[]) => {\n if (!preRef.current || blockRerenderHandlers.length === 0) return;\n\n // Track unique styled blocks that have been affected\n const affectedBlockIds = new Set<string>();\n\n mutations.forEach((mutation) => {\n // Check if mutation affected a styled block\n if (mutation.type === 'childList') {\n mutation.addedNodes.forEach((node) => {\n if (node instanceof HTMLElement && node.id) {\n affectedBlockIds.add(node.id);\n }\n });\n } else if (\n mutation.type === 'attributes' ||\n mutation.type === 'characterData'\n ) {\n let target: Node | null = mutation.target;\n // Walk up the DOM to find the styled block element\n while (target && target !== preRef.current) {\n if (target instanceof HTMLElement && target.id) {\n affectedBlockIds.add(target.id);\n break;\n }\n target = target.parentNode;\n }\n }\n });\n\n if (affectedBlockIds.size > 0) {\n // Get the styled blocks that were affected with their DOM elements\n const rerenderedStyledBlocks = blocks\n .filter(\n (block): block is StyledBlock =>\n block.type === BlockType.Styled &&\n 'id' in block &&\n affectedBlockIds.has(block.id),\n )\n .map((block) => ({\n block,\n element: preRef.current?.querySelector(\n `#${block.id}`,\n ) as HTMLElement | null,\n }));\n\n if (rerenderedStyledBlocks.length > 0) {\n // Call all registered handlers\n blockRerenderHandlers.forEach((handler) => {\n handler(rerenderedStyledBlocks);\n });\n }\n }\n },\n [blocks, blockRerenderHandlers],\n );\n\n useMutationObserver(preRef.current, handleMutations, {\n childList: true,\n subtree: true,\n attributes: true,\n characterData: true,\n });\n\n const handleDeleteBlock = useCallback(\n (blockId: string) => {\n const newBlocks = blocks.filter((b) => !('id' in b) || b.id !== blockId);\n setBlocks(newBlocks);\n appendToBuffer(newBlocks);\n },\n [blocks, setBlocks, appendToBuffer],\n );\n\n const createElementOptions = useMemo(\n () => ({\n ...(imageWidth !== undefined && { imageWidth }),\n ...(imageHeight !== undefined && { imageHeight }),\n ...(documentWidth !== undefined && { documentWidth }),\n ...(documentHeight !== undefined && { documentHeight }),\n onDeleteBlock: handleDeleteBlock,\n }),\n [imageWidth, imageHeight, documentWidth, documentHeight, handleDeleteBlock],\n );\n\n useEffect(() => {\n if (!preRef.current) return;\n const preElement = preRef.current;\n let cnt = 0;\n while (cnt < blocks.length) {\n const block = blocks[cnt];\n if (!block) {\n cnt += 1;\n continue;\n }\n const domElement =\n cnt < preElement.childNodes.length\n ? (preElement.childNodes[cnt] as HTMLElement)\n : null; // get dom element at position\n if (domElement) {\n if (block.type === BlockType.Text) {\n if (domElement.nodeName !== '#text') {\n if (preContainsTextNode(preElement, block.text, cnt + 1)) {\n // text node exists further down, remove this element\n domElement.remove();\n continue;\n }\n preElement.insertBefore(\n createElement(block, createElementOptions),\n domElement,\n ); // insert text node as it is new\n } else {\n if (domElement.textContent !== block.text) {\n domElement.textContent = block.text; // text node exists but text has changed\n }\n }\n } else {\n // span, img, or div block\n const blockId = 'id' in block ? block.id : undefined;\n if (blockId && blockId === domElement.id) {\n //same block, check for changes\n if (\n block.type === BlockType.Document ||\n block.type === BlockType.Image\n ) {\n // Image/Document blocks - now wrapped in span containers\n if (domElement.nodeName === 'SPAN') {\n const imgElement = domElement.querySelector(\n 'img',\n ) as HTMLImageElement;\n if (imgElement) {\n const expectedSrc =\n block.type === BlockType.Image ? block.url : DOCUMENT_ICON;\n if (imgElement.src !== expectedSrc) {\n imgElement.src = expectedSrc;\n }\n }\n }\n } else if (block.type === BlockType.Styled) {\n const blockCss = stringifyCSSProperties(block.style ?? {});\n if (\n areStylesDifferent(block.style ?? {}, domElement.style.cssText)\n ) {\n domElement.style.cssText = blockCss; // element matches but style has changed\n }\n if (domElement.className !== (block.className ?? '')) {\n domElement.className = block.className ?? '';\n }\n if (\n domElement.isContentEditable !== !(block.uneditable ?? false)\n ) {\n domElement.contentEditable =\n (block.uneditable ?? false) ? 'false' : 'true';\n }\n if (getElementText(domElement) !== block.text) {\n setElementText(domElement, block.text); // element matches but text has changed\n }\n }\n } else {\n const element = createElement(block, createElementOptions);\n if (blockId && preContainsNode(preElement, blockId, cnt + 1)) {\n // dom element must have been removed\n domElement.remove();\n continue;\n }\n if (block.type === BlockType.Styled) {\n addBlockEventListeners(\n domElement as HTMLElement,\n block,\n eventHandlers,\n );\n }\n preElement.insertBefore(element, domElement); //insert element as it is new\n }\n }\n } else {\n const domElement = createElement(block, createElementOptions);\n if (block.type === BlockType.Styled) {\n addBlockEventListeners(\n domElement as HTMLElement,\n block,\n eventHandlers,\n );\n }\n preElement.appendChild(domElement); // append element as it is new and there are no more elements\n }\n cnt += 1;\n }\n let extra = 0;\n const lastBlock = blocks[blocks.length - 1];\n if (\n lastBlock &&\n blocks.length > 0 &&\n 'text' in lastBlock &&\n lastBlock.text.length > 0 &&\n lastBlock.text[lastBlock.text.length - 1] === '\\n'\n ) {\n const childNodeAtLength = preElement.childNodes[blocks.length];\n if (\n preElement.childNodes.length > blocks.length &&\n childNodeAtLength &&\n isCarridgeReturn(childNodeAtLength)\n ) {\n extra = 1;\n }\n }\n while (preElement.childNodes.length > blocks.length + extra) {\n const lastChild = preElement.lastChild;\n if (lastChild) {\n preElement.removeChild(lastChild);\n }\n }\n const range = getSelectionRange(preElement);\n const position = range ? getCursorPosition(preElement, range) : 0;\n if (position !== characterPosition) {\n setCursorPosition(preElement, characterPosition);\n }\n }, [blocks, characterPosition, createElementOptions, eventHandlers]);\n\n const handleChange = useCallback(\n (isReturn?: boolean) => {\n if (!preRef.current) return;\n const preElement = preRef.current;\n let cnt = 0;\n const newBlocks: Block[] = [];\n while (cnt < preElement.childNodes.length) {\n const domElement = preElement.childNodes[cnt] as HTMLElement | Text;\n if ('id' in domElement && domElement.id) {\n const block = blocks.find((b) => 'id' in b && b.id === domElement.id);\n if (block) {\n // For DocumentBlock and ImageBlock, preserve the block as-is (no text content)\n if (\n block.type === BlockType.Document ||\n block.type === BlockType.Image\n ) {\n newBlocks.push(block);\n } else if (block.type === BlockType.Styled) {\n const styledBlock = block as StyledBlock;\n if (getElementText(domElement) !== styledBlock.text) {\n styledBlock.text =\n replaceLineFeeds(getElementText(domElement)) ?? '';\n }\n newBlocks.push(styledBlock);\n }\n }\n } else {\n let text = domElement.textContent ?? '';\n const nextNode = preElement.childNodes[cnt + 1];\n while (\n cnt + 1 < preElement.childNodes.length &&\n nextNode &&\n (!('id' in nextNode) || !(nextNode as HTMLElement)?.id)\n ) {\n text += preElement.childNodes[cnt + 1]?.textContent ?? '';\n cnt += 1;\n }\n newBlocks.push({\n type: BlockType.Text,\n text: replaceLineFeeds(text),\n });\n }\n cnt += 1;\n }\n const deletedBlocks = blocks.filter(\n (b) =>\n 'id' in b &&\n newBlocks.findIndex((nb) => 'id' in nb && nb.id === b.id) === -1,\n );\n if (deletedBlocks.some((b) => 'undeletable' in b && b.undeletable)) {\n setBlocks([...blocks]);\n return;\n }\n const finalBlocks = !enableLineBreaks\n ? newBlocks.map((b) =>\n 'text' in b\n ? {\n ...b,\n text: b.text.replaceAll('\\n', ''),\n }\n : b,\n )\n : isReturn\n ? insertCarridgeReturn(preElement, newBlocks)\n : newBlocks;\n if (isReturn) {\n updateCharacterPosition(characterPosition + 1);\n }\n if (JSON.stringify(blocks) !== JSON.stringify(finalBlocks)) {\n setBlocks(finalBlocks);\n appendToBuffer(finalBlocks);\n }\n },\n [\n blocks,\n setBlocks,\n appendToBuffer,\n characterPosition,\n enableLineBreaks,\n updateCharacterPosition,\n ],\n );\n\n const handleUndo = useCallback(() => {\n const lastBlocks = undoBuffer();\n setBlocks(lastBlocks ?? []);\n }, [undoBuffer, setBlocks]);\n\n return (\n <div className={cx(style['editorContainer'], className)}>\n <UnmanagedEditor\n ref={preRef}\n onChange={handleChange}\n onUndo={handleUndo}\n enableLineBreaks={enableLineBreaks}\n placeholder={placeholder}\n className={editorClassName}\n />\n </div>\n );\n});\n\nEditor.displayName = 'Editor';\n","const reduxImpl = (reducer, initial) => (set, _get, api) => {\n api.dispatch = (action) => {\n set((state) => reducer(state, action), false, action);\n return action;\n };\n api.dispatchFromDevtools = true;\n return { dispatch: (...a) => api.dispatch(...a), ...initial };\n};\nconst redux = reduxImpl;\n\nconst trackedConnections = /* @__PURE__ */ new Map();\nconst getTrackedConnectionState = (name) => {\n const api = trackedConnections.get(name);\n if (!api) return {};\n return Object.fromEntries(\n Object.entries(api.stores).map(([key, api2]) => [key, api2.getState()])\n );\n};\nconst extractConnectionInformation = (store, extensionConnector, options) => {\n if (store === void 0) {\n return {\n type: \"untracked\",\n connection: extensionConnector.connect(options)\n };\n }\n const existingConnection = trackedConnections.get(options.name);\n if (existingConnection) {\n return { type: \"tracked\", store, ...existingConnection };\n }\n const newConnection = {\n connection: extensionConnector.connect(options),\n stores: {}\n };\n trackedConnections.set(options.name, newConnection);\n return { type: \"tracked\", store, ...newConnection };\n};\nconst devtoolsImpl = (fn, devtoolsOptions = {}) => (set, get, api) => {\n const { enabled, anonymousActionType, store, ...options } = devtoolsOptions;\n let extensionConnector;\n try {\n extensionConnector = (enabled != null ? enabled : (import.meta.env ? import.meta.env.MODE : void 0) !== \"production\") && window.__REDUX_DEVTOOLS_EXTENSION__;\n } catch (e) {\n }\n if (!extensionConnector) {\n return fn(set, get, api);\n }\n const { connection, ...connectionInformation } = extractConnectionInformation(store, extensionConnector, options);\n let isRecording = true;\n api.setState = (state, replace, nameOrAction) => {\n const r = set(state, replace);\n if (!isRecording) return r;\n const action = nameOrAction === void 0 ? { type: anonymousActionType || \"anonymous\" } : typeof nameOrAction === \"string\" ? { type: nameOrAction } : nameOrAction;\n if (store === void 0) {\n connection == null ? void 0 : connection.send(action, get());\n return r;\n }\n connection == null ? void 0 : connection.send(\n {\n ...action,\n type: `${store}/${action.type}`\n },\n {\n ...getTrackedConnectionState(options.name),\n [store]: api.getState()\n }\n );\n return r;\n };\n const setStateFromDevtools = (...a) => {\n const originalIsRecording = isRecording;\n isRecording = false;\n set(...a);\n isRecording = originalIsRecording;\n };\n const initialState = fn(api.setState, get, api);\n if (connectionInformation.type === \"untracked\") {\n connection == null ? void 0 : connection.init(initialState);\n } else {\n connectionInformation.stores[connectionInformation.store] = api;\n connection == null ? void 0 : connection.init(\n Object.fromEntries(\n Object.entries(connectionInformation.stores).map(([key, store2]) => [\n key,\n key === connectionInformation.store ? initialState : store2.getState()\n ])\n )\n );\n }\n if (api.dispatchFromDevtools && typeof api.dispatch === \"function\") {\n let didWarnAboutReservedActionType = false;\n const originalDispatch = api.dispatch;\n api.dispatch = (...a) => {\n if ((import.meta.env ? import.meta.env.MODE : void 0) !== \"production\" && a[0].type === \"__setState\" && !didWarnAboutReservedActionType) {\n console.warn(\n '[zustand devtools middleware] \"__setState\" action type is reserved to set state from the devtools. Avoid using it.'\n );\n didWarnAboutReservedActionType = true;\n }\n originalDispatch(...a);\n };\n }\n connection.subscribe((message) => {\n var _a;\n switch (message.type) {\n case \"ACTION\":\n if (typeof message.payload !== \"string\") {\n console.error(\n \"[zustand devtools middleware] Unsupported action format\"\n );\n return;\n }\n return parseJsonThen(\n message.payload,\n (action) => {\n if (action.type === \"__setState\") {\n if (store === void 0) {\n setStateFromDevtools(action.state);\n return;\n }\n if (Object.keys(action.state).length !== 1) {\n console.error(\n `\n [zustand devtools middleware] Unsupported __setState action format.\n When using 'store' option in devtools(), the 'state' should have only one key, which is a value of 'store' that was passed in devtools(),\n and value of this only key should be a state object. Example: { \"type\": \"__setState\", \"state\": { \"abc123Store\": { \"foo\": \"bar\" } } }\n `\n );\n }\n const stateFromDevtools = action.state[store];\n if (stateFromDevtools === void 0 || stateFromDevtools === null) {\n return;\n }\n if (JSON.stringify(api.getState()) !== JSON.stringify(stateFromDevtools)) {\n setStateFromDevtools(stateFromDevtools);\n }\n return;\n }\n if (!api.dispatchFromDevtools) return;\n if (typeof api.dispatch !== \"function\") return;\n api.dispatch(action);\n }\n );\n case \"DISPATCH\":\n switch (message.payload.type) {\n case \"RESET\":\n setStateFromDevtools(initialState);\n if (store === void 0) {\n return connection == null ? void 0 : connection.init(api.getState());\n }\n return connection == null ? void 0 : connection.init(getTrackedConnectionState(options.name));\n case \"COMMIT\":\n if (store === void 0) {\n connection == null ? void 0 : connection.init(api.getState());\n return;\n }\n return connection == null ? void 0 : connection.init(getTrackedConnectionState(options.name));\n case \"ROLLBACK\":\n return parseJsonThen(message.state, (state) => {\n if (store === void 0) {\n setStateFromDevtools(state);\n connection == null ? void 0 : connection.init(api.getState());\n return;\n }\n setStateFromDevtools(state[store]);\n connection == null ? void 0 : connection.init(getTrackedConnectionState(options.name));\n });\n case \"JUMP_TO_STATE\":\n case \"JUMP_TO_ACTION\":\n return parseJsonThen(message.state, (state) => {\n if (store === void 0) {\n setStateFromDevtools(state);\n return;\n }\n if (JSON.stringify(api.getState()) !== JSON.stringify(state[store])) {\n setStateFromDevtools(state[store]);\n }\n });\n case \"IMPORT_STATE\": {\n const { nextLiftedState } = message.payload;\n const lastComputedState = (_a = nextLiftedState.computedStates.slice(-1)[0]) == null ? void 0 : _a.state;\n if (!lastComputedState) return;\n if (store === void 0) {\n setStateFromDevtools(lastComputedState);\n } else {\n setStateFromDevtools(lastComputedState[store]);\n }\n connection == null ? void 0 : connection.send(\n null,\n // FIXME no-any\n nextLiftedState\n );\n return;\n }\n case \"PAUSE_RECORDING\":\n return isRecording = !isRecording;\n }\n return;\n }\n });\n return initialState;\n};\nconst devtools = devtoolsImpl;\nconst parseJsonThen = (stringified, f) => {\n let parsed;\n try {\n parsed = JSON.parse(stringified);\n } catch (e) {\n console.error(\n \"[zustand devtools middleware] Could not parse the received json\",\n e\n );\n }\n if (parsed !== void 0) f(parsed);\n};\n\nconst subscribeWithSelectorImpl = (fn) => (set, get, api) => {\n const origSubscribe = api.subscribe;\n api.subscribe = (selector, optListener, options) => {\n let listener = selector;\n if (optListener) {\n const equalityFn = (options == null ? void 0 : options.equalityFn) || Object.is;\n let currentSlice = selector(api.getState());\n listener = (state) => {\n const nextSlice = selector(state);\n if (!equalityFn(currentSlice, nextSlice)) {\n const previousSlice = currentSlice;\n optListener(currentSlice = nextSlice, previousSlice);\n }\n };\n if (options == null ? void 0 : options.fireImmediately) {\n optListener(currentSlice, currentSlice);\n }\n }\n return origSubscribe(listener);\n };\n const initialState = fn(set, get, api);\n return initialState;\n};\nconst subscribeWithSelector = subscribeWithSelectorImpl;\n\nconst combine = (initialState, create) => (...a) => Object.assign({}, initialState, create(...a));\n\nfunction createJSONStorage(getStorage, options) {\n let storage;\n try {\n storage = getStorage();\n } catch (e) {\n return;\n }\n const persistStorage = {\n getItem: (name) => {\n var _a;\n const parse = (str2) => {\n if (str2 === null) {\n return null;\n }\n return JSON.parse(str2, options == null ? void 0 : options.reviver);\n };\n const str = (_a = storage.getItem(name)) != null ? _a : null;\n if (str instanceof Promise) {\n return str.then(parse);\n }\n return parse(str);\n },\n setItem: (name, newValue) => storage.setItem(\n name,\n JSON.stringify(newValue, options == null ? void 0 : options.replacer)\n ),\n removeItem: (name) => storage.removeItem(name)\n };\n return persistStorage;\n}\nconst toThenable = (fn) => (input) => {\n try {\n const result = fn(input);\n if (result instanceof Promise) {\n return result;\n }\n return {\n then(onFulfilled) {\n return toThenable(onFulfilled)(result);\n },\n catch(_onRejected) {\n return this;\n }\n };\n } catch (e) {\n return {\n then(_onFulfilled) {\n return this;\n },\n catch(onRejected) {\n return toThenable(onRejected)(e);\n }\n };\n }\n};\nconst persistImpl = (config, baseOptions) => (set, get, api) => {\n let options = {\n storage: createJSONStorage(() => localStorage),\n partialize: (state) => state,\n version: 0,\n merge: (persistedState, currentState) => ({\n ...currentState,\n ...persistedState\n }),\n ...baseOptions\n };\n let hasHydrated = false;\n const hydrationListeners = /* @__PURE__ */ new Set();\n const finishHydrationListeners = /* @__PURE__ */ new Set();\n let storage = options.storage;\n if (!storage) {\n return config(\n (...args) => {\n console.warn(\n `[zustand persist middleware] Unable to update item '${options.name}', the given storage is currently unavailable.`\n );\n set(...args);\n },\n get,\n api\n );\n }\n const setItem = () => {\n const state = options.partialize({ ...get() });\n return storage.setItem(options.name, {\n state,\n version: options.version\n });\n };\n const savedSetState = api.setState;\n api.setState = (state, replace) => {\n savedSetState(state, replace);\n void setItem();\n };\n const configResult = config(\n (...args) => {\n set(...args);\n void setItem();\n },\n get,\n api\n );\n api.getInitialState = () => configResult;\n let stateFromStorage;\n const hydrate = () => {\n var _a, _b;\n if (!storage) return;\n hasHydrated = false;\n hydrationListeners.forEach((cb) => {\n var _a2;\n return cb((_a2 = get()) != null ? _a2 : configResult);\n });\n const postRehydrationCallback = ((_b = options.onRehydrateStorage) == null ? void 0 : _b.call(options, (_a = get()) != null ? _a : configResult)) || void 0;\n return toThenable(storage.getItem.bind(storage))(options.name).then((deserializedStorageValue) => {\n if (deserializedStorageValue) {\n if (typeof deserializedStorageValue.version === \"number\" && deserializedStorageValue.version !== options.version) {\n if (options.migrate) {\n const migration = options.migrate(\n deserializedStorageValue.state,\n deserializedStorageValue.version\n );\n if (migration instanceof Promise) {\n return migration.then((result) => [true, result]);\n }\n return [true, migration];\n }\n console.error(\n `State loaded from storage couldn't be migrated since no migrate function was provided`\n );\n } else {\n return [false, deserializedStorageValue.state];\n }\n }\n return [false, void 0];\n }).then((migrationResult) => {\n var _a2;\n const [migrated, migratedState] = migrationResult;\n stateFromStorage = options.merge(\n migratedState,\n (_a2 = get()) != null ? _a2 : configResult\n );\n set(stateFromStorage, true);\n if (migrated) {\n return setItem();\n }\n }).then(() => {\n postRehydrationCallback == null ? void 0 : postRehydrationCallback(stateFromStorage, void 0);\n stateFromStorage = get();\n hasHydrated = true;\n finishHydrationListeners.forEach((cb) => cb(stateFromStorage));\n }).catch((e) => {\n postRehydrationCallback == null ? void 0 : postRehydrationCallback(void 0, e);\n });\n };\n api.persist = {\n setOptions: (newOptions) => {\n options = {\n ...options,\n ...newOptions\n };\n if (newOptions.storage) {\n storage = newOptions.storage;\n }\n },\n clearStorage: () => {\n storage == null ? void 0 : storage.removeItem(options.name);\n },\n getOptions: () => options,\n rehydrate: () => hydrate(),\n hasHydrated: () => hasHydrated,\n onHydrate: (cb) => {\n hydrationListeners.add(cb);\n return () => {\n hydrationListeners.delete(cb);\n };\n },\n onFinishHydration: (cb) => {\n finishHydrationListeners.add(cb);\n return () => {\n finishHydrationListeners.delete(cb);\n };\n }\n };\n if (!options.skipHydration) {\n hydrate();\n }\n return stateFromStorage || configResult;\n};\nconst persist = persistImpl;\n\nexport { combine, createJSONStorage, devtools, persist, redux, subscribeWithSelector };\n","import { create, StateCreator } from 'zustand';\nimport { subscribeWithSelector } from 'zustand/middleware';\nconst creatStore = <T extends object>(initializer: StateCreator<T, [], []>) =>\n create(initializer);\n\nconst createSubscriberStore = <T extends object>(\n initializer: StateCreator<T, any, []>,\n) => create(subscribeWithSelector(initializer));\n\nexport { creatStore, createSubscriberStore };\n","import { Block } from '@atypes/block';\nimport { BlocksState } from '@atypes/state';\nimport { createSubscriberStore } from './utils';\n\nexport const createBlocksStore = () =>\n createSubscriberStore<BlocksState>((set) => ({\n blocks: [],\n setBlocks: (newBlocks: Block[]) => set({ blocks: newBlocks }),\n }));\n","import { Block } from '@atypes/block';\nimport { BlocksChangeHandler } from '@atypes/componentProps';\nimport { BlocksState, CursorPositionState } from '@atypes/state';\nimport { useTopLevelBlocksSubscriber } from '@state/useState';\nimport { useCallback } from 'react';\nimport { StoreApi, UseBoundStore } from 'zustand';\n\nexport const useChangeNotify = (\n store: UseBoundStore<StoreApi<BlocksState>>,\n cursorPositionStore: UseBoundStore<StoreApi<CursorPositionState>>,\n onBlocksChange?: BlocksChangeHandler,\n) => {\n const changeCallback = useCallback(\n (current: Block[], previous: Block[]) => {\n if (\n onBlocksChange &&\n JSON.stringify(current) !== JSON.stringify(previous)\n ) {\n const { characterPosition, cursorRect } =\n cursorPositionStore.getState();\n onBlocksChange(current, characterPosition, cursorRect);\n }\n },\n [onBlocksChange, cursorPositionStore],\n );\n\n useTopLevelBlocksSubscriber(store, (state) => state.blocks, changeCallback);\n};\n","import { Block } from '@atypes/block';\nimport { BufferState } from '@atypes/state';\nimport { createSubscriberStore } from './utils';\n\nconst MAX_BUFFER_LENGTH = 50;\nexport const createBufferStore = () =>\n createSubscriberStore<BufferState>((set, get) => ({\n buffer: [],\n appendToBuffer: (blocks: Block[]) => {\n if (\n JSON.stringify(blocks) !==\n JSON.stringify(get().buffer[get().buffer.length - 1])\n ) {\n set((state) => ({\n buffer: [...state.buffer.slice(0, MAX_BUFFER_LENGTH - 1), blocks],\n }));\n }\n },\n undoBuffer: () => {\n const { buffer } = get();\n const last = buffer.pop();\n set({ buffer: [...buffer] });\n return last ?? null;\n },\n }));\n","export interface Rect {\n top: number;\n left: number;\n bottom: number;\n right: number;\n}\n\nexport const ZERO_RECT: Rect = {\n top: 0,\n left: 0,\n bottom: 0,\n right: 0,\n};\n\nexport interface CursorPositionState {\n characterPosition: number;\n cursorRect: Rect;\n updateCharacterPosition: (characterPosition: number) => void;\n updatePosition: (characterPosition: number, cursorRect: Rect) => void;\n}\n","import { CursorPositionState, Rect, ZERO_RECT } from '@atypes/state';\nimport { createSubscriberStore } from './utils';\n\nexport const createCursorPositionStore = () =>\n createSubscriberStore<CursorPositionState>((set) => ({\n characterPosition: 0,\n cursorRect: ZERO_RECT,\n updateCharacterPosition: (characterPosition: number) =>\n set({ characterPosition }),\n updatePosition: (characterPosition: number, cursorRect: Rect) =>\n set({ characterPosition, cursorRect }),\n }));\n","import { CursorPositionChangeHanlder } from '@atypes/componentProps';\nimport { BlocksState, CursorPositionState } from '@atypes/state';\nimport { useTopLevelCursorPositionSubscriber } from '@state/useState';\n\nimport { useCallback } from 'react';\nimport { StoreApi, UseBoundStore } from 'zustand';\n\nexport const useCursorChangeNotify = (\n store: UseBoundStore<StoreApi<CursorPositionState>>,\n blockStore: UseBoundStore<StoreApi<BlocksState>>,\n onCursorPositionChange?: CursorPositionChangeHanlder,\n) => {\n const changeCallback = useCallback(\n (current: CursorPositionState, previous: CursorPositionState) => {\n if (\n current.characterPosition !== previous.characterPosition ||\n current.cursorRect.top !== previous.cursorRect.top ||\n current.cursorRect.left !== previous.cursorRect.left ||\n current.cursorRect.bottom !== previous.cursorRect.bottom ||\n current.cursorRect.right !== previous.cursorRect.right\n ) {\n const blocks = blockStore.getState().blocks;\n onCursorPositionChange?.(\n current.characterPosition,\n current.cursorRect,\n blocks,\n );\n }\n },\n [onCursorPositionChange, blockStore],\n );\n\n useTopLevelCursorPositionSubscriber(store, (state) => state, changeCallback);\n};\n","import { createSubscriberStore } from './utils';\nimport { SmartInputApi } from '@src/types/api';\nimport { ApiState } from '@src/types/state/api';\n\nexport const createApiStore = () =>\n createSubscriberStore<ApiState>((set) => ({\n api: null,\n element: null,\n setElement: (element: HTMLPreElement | null) => set({ element }),\n setApi: (api: SmartInputApi) => set({ api }),\n }));\n","import { BehaviourState } from '@atypes/state';\nimport { createSubscriberStore } from './utils';\n\nexport const createBehaviourStore = () =>\n createSubscriberStore<BehaviourState>((set, get) => ({\n selectionInProgress: false,\n setSelectionInProgress: (selectionInProgress: boolean) => {\n if (get().selectionInProgress !== selectionInProgress) {\n set({ selectionInProgress });\n }\n },\n }));\n","import { KeyCombination } from '@src/types';\nimport { createSubscriberStore } from './utils';\nimport { KeyHandlerState } from '@src/types/state/keyHandler';\n\nexport const createKeyHandlerStore = () =>\n createSubscriberStore<KeyHandlerState>((set) => ({\n keyHandlers: [],\n addKeyboardHandler: (handler: (keys: KeyCombination) => boolean) =>\n set((state) => ({ keyHandlers: [...state.keyHandlers, handler] })),\n removeKeyboardHandler: (handler: (keys: KeyCombination) => boolean) =>\n set((state) => ({\n keyHandlers: state.keyHandlers.filter((h) => h !== handler),\n })),\n }));\n","import { Block, StyledBlock } from './block';\n\n/**\n * Associates a styled block with its corresponding HTML element.\n */\nexport type StyledBlockElement = {\n /** The styled block */\n block: StyledBlock;\n /** The HTML element rendering the block, or null if not yet rendered */\n element: HTMLElement | null;\n};\n\n/**\n * Represents a document file in the editor.\n */\nexport interface Document {\n /** The type identifier for document items */\n type: 'document';\n /** The name of the document file */\n name: string;\n /** The File object */\n file: File;\n /** The URL for accessing the document (e.g., blob URL) */\n url: string;\n /** The content type of the image */\n contentType: string;\n}\n\n/**\n * Represents an image file in the editor.\n */\nexport interface Image {\n /** The type identifier for image items */\n type: 'image';\n /** The name of the image file */\n name: string;\n /** The File object */\n file: File;\n /** The URL for displaying the image (e.g., blob URL) */\n url: string;\n /** Alternative text for the image */\n alt?: string;\n /** The content type of the image */\n contentType: string;\n}\n\n/**\n * A commit item can be a text string, document, or image.\n */\nexport type CommitItem = string | Document | Image;\n\n/**\n * Represents a keyboard key combination for triggering commits.\n */\nexport interface CommitKeyCombination {\n /** The key value (e.g., 'Enter') */\n key: string;\n /** Whether the Alt key must be pressed */\n altKey?: boolean;\n /** Whether the Ctrl key must be pressed */\n ctrlKey?: boolean;\n /** Whether the Shift key must be pressed */\n shiftKey?: boolean;\n /** Whether the Meta/Command key must be pressed */\n metaKey?: boolean;\n}\n\n/**\n * Represents a keyboard key combination for custom key handlers.\n */\nexport interface KeyCombination {\n /** The key value (e.g., 'a', 'Enter') */\n key: string;\n /** The physical key code */\n code: string;\n /** Whether the Alt key is pressed */\n altKey?: boolean;\n /** Whether the Ctrl key is pressed */\n ctrlKey?: boolean;\n /** Whether the Shift key is pressed */\n shiftKey?: boolean;\n /** Whether the Meta/Command key is pressed */\n metaKey?: boolean;\n}\n\n/**\n * Types of drag events that can occur in the editor.\n */\nexport enum DragEventType {\n /** Fired when an element is being dragged over a valid drop target */\n DragOver = 'dragover',\n /** Fired when a dragged element leaves a valid drop target */\n DragLeave = 'dragleave',\n /** Fired when an element is dropped on a valid drop target */\n Drop = 'drop',\n}\n\n/**\n * Props for the Editor component.\n */\nexport interface EditorProps {\n /** Whether to allow line breaks in the editor (default: false) */\n enableLineBreaks?: boolean;\n /** CSS class name to apply to the editor container */\n className?: string;\n /** Custom CSS class name to apply to the editor area */\n editorClassName?: string;\n /** Width of embedded images (CSS value, e.g., '200px', '50%') */\n imageWidth?: string;\n /** Height of embedded images (CSS value) */\n imageHeight?: string;\n /** Width of embedded documents (CSS value) */\n documentWidth?: string;\n /** Height of embedded documents (CSS value) */\n documentHeight?: string;\n /** Placeholder text shown when the editor is empty */\n placeholder?: string;\n /** Called when a block is clicked */\n onBlockClick?: (block: Block, event: MouseEvent) => void;\n /** Called when a block is double-clicked */\n onBlockDblClick?: (block: Block, event: MouseEvent) => void;\n /** Called when the mouse button is released over a block */\n onBlockMouseUp?: (block: Block, event: MouseEvent) => void;\n /** Called when the mouse button is pressed over a block */\n onBlockMouseDown?: (block: Block, event: MouseEvent) => void;\n /** Called when the mouse moves over a block */\n onBlockMouseMove?: (block: Block, event: MouseEvent) => void;\n /** Called when the mouse enters a block */\n onBlockMouseEnter?: (block: Block, event: MouseEvent) => void;\n /** Called when the mouse leaves a block */\n onBlockMouseLeave?: (block: Block, event: MouseEvent) => void;\n /** Called when the mouse moves over a block (similar to onBlockMouseEnter but fires more frequently) */\n onBlockMouseOver?: (block: Block, event: MouseEvent) => void;\n}\n","import { DragHandlerState } from '@src/types/state/dragHandler';\nimport { createSubscriberStore } from './utils';\nimport { DragEventType } from '@src/types';\n\nexport const createDragHandlerStore = () =>\n createSubscriberStore<DragHandlerState>((set) => ({\n dragOverHandlers: [],\n dragLeaveHandlers: [],\n dropHandlers: [],\n addDragHandler: (\n eventType: DragEventType,\n handler: (event: React.DragEvent<HTMLPreElement>) => boolean,\n ) => {\n switch (eventType) {\n case DragEventType.DragOver:\n set((state) => ({\n dragOverHandlers: [...state.dragOverHandlers, handler],\n }));\n break;\n case DragEventType.DragLeave:\n set((state) => ({\n dragLeaveHandlers: [...state.dragLeaveHandlers, handler],\n }));\n break;\n case DragEventType.Drop:\n set((state) => ({ dropHandlers: [...state.dropHandlers, handler] }));\n break;\n }\n },\n removeDragHandler: (\n eventType: DragEventType,\n handler: (event: React.DragEvent<HTMLPreElement>) => boolean,\n ) => {\n switch (eventType) {\n case DragEventType.DragOver:\n set((state) => ({\n dragOverHandlers: state.dragOverHandlers.filter(\n (h) => h !== handler,\n ),\n }));\n break;\n case DragEventType.DragLeave:\n set((state) => ({\n dragLeaveHandlers: state.dragLeaveHandlers.filter(\n (h) => h !== handler,\n ),\n }));\n break;\n case DragEventType.Drop:\n set((state) => ({\n dropHandlers: state.dropHandlers.filter((h) => h !== handler),\n }));\n break;\n }\n },\n }));\n","import { StyledBlockElement } from '@src/types';\nimport { createSubscriberStore } from './utils';\nimport { BlockRerenderHandlerState } from '@src/types/state/blockRerenderHandler';\n\nexport const createBlockRerenderHandlerStore = () =>\n createSubscriberStore<BlockRerenderHandlerState>((set) => ({\n blockRerenderHandlers: [],\n addBlockRerenderHandlers: (\n handler: (blocks: StyledBlockElement[]) => void,\n ) =>\n set((state) => ({\n blockRerenderHandlers: [...state.blockRerenderHandlers, handler],\n })),\n removeBlockRerenderHandlers: (\n handler: (blocks: StyledBlockElement[]) => void,\n ) =>\n set((state) => ({\n blockRerenderHandlers: state.blockRerenderHandlers.filter(\n (h) => h !== handler,\n ),\n })),\n }));\n","import React, { FC, PropsWithChildren } from 'react';\nimport { createBlocksStore } from './blocksStore';\nimport { StateContext } from './state';\nimport { ComponentProps } from '@atypes/componentProps';\nimport { useChangeNotify } from '@hooks/useChangeNotify';\nimport { createBufferStore } from './bufferStore';\nimport { createCursorPositionStore } from './cursorPosition';\nimport { useCursorChangeNotify } from '@hooks/useCursorChangeNotify';\nimport { createApiStore } from './apiStore';\nimport { createBehaviourStore } from './behaviourStore';\nimport { createKeyHandlerStore } from './keyHandlerStore';\nimport { createDragHandlerStore } from './dragHandlerStore';\nimport { createBlockRerenderHandlerStore } from '@src/state/blockRerenderHandlerStore';\n\ninterface StateProviderProps {\n value: ComponentProps;\n}\n\nexport const StateProvider: FC<PropsWithChildren<StateProviderProps>> =\n React.memo(({ value, children }) => {\n const { blocks, onBlocksChange, onCursorPositionChange } = value;\n\n const keyHandlerStore = React.useMemo(createKeyHandlerStore, []);\n const bufferStore = React.useMemo(createBufferStore, []);\n const blocksStore = React.useMemo(createBlocksStore, []);\n const cursorPositionStore = React.useMemo(createCursorPositionStore, []);\n const apiStore = React.useMemo(createApiStore, []);\n const behaviourStore = React.useMemo(createBehaviourStore, []);\n const dragHandlerStore = React.useMemo(createDragHandlerStore, []);\n const blockRerenderHandlerStore = React.useMemo(\n createBlockRerenderHandlerStore,\n [],\n );\n\n useChangeNotify(blocksStore, cursorPositionStore, onBlocksChange);\n useCursorChangeNotify(\n cursorPositionStore,\n blocksStore,\n onCursorPositionChange,\n );\n\n if (\n blocks &&\n JSON.stringify(blocksStore.getState().blocks) !== JSON.stringify(blocks)\n ) {\n blocksStore.getState().setBlocks(blocks);\n bufferStore.getState().appendToBuffer(blocks);\n }\n\n const stateValue = React.useMemo(\n () => ({\n blocksStore,\n bufferStore,\n cursorPositionStore,\n apiStore,\n behaviourStore,\n keyHandlerStore,\n dragHandlerStore,\n blockRerenderHandlerStore,\n }),\n [\n blocksStore,\n bufferStore,\n cursorPositionStore,\n apiStore,\n behaviourStore,\n keyHandlerStore,\n dragHandlerStore,\n blockRerenderHandlerStore,\n ],\n );\n\n return (\n <StateContext.Provider value={stateValue}>\n {children}\n </StateContext.Provider>\n );\n });\n\nStateProvider.displayName = 'StateProvider';\n","import { Block, BlockType, Document, Image, StyledBlock } from '@src/types';\nimport { SmartInputFunctions } from '@src/types/api';\n\ntype ApiState = {\n blocks: Block[];\n characterPosition: number;\n buffer: Block[][];\n appendToBuffer: (b: Block[]) => void;\n};\n\n/**\n * Creates an internal state object for managing editor content.\n * This state holds the current blocks, cursor position, and undo/redo buffer.\n *\n * @param blocksI - Initial array of content blocks\n * @param characterPositionI - Initial character position of the cursor\n * @returns An ApiState object with getters/setters for blocks, position, and buffer\n *\n * @example\n * ```typescript\n * const state = createState([{ type: 'Text', text: 'Hello' }], 0);\n * ```\n */\nexport const createState = (\n blocksI: Block[],\n characterPositionI: number,\n): ApiState => {\n let blocks = blocksI;\n let characterPosition = characterPositionI;\n const buffer: Block[][] = [];\n const state = {\n get blocks() {\n return blocks;\n },\n set blocks(value: Block[]) {\n blocks = value;\n },\n get characterPosition() {\n return characterPosition;\n },\n set characterPosition(value: number) {\n characterPosition = value;\n },\n appendToBuffer: (b: Block[]) => {\n buffer.push(b);\n },\n get buffer() {\n return buffer;\n },\n };\n return state;\n};\n\n/**\n * Finds the block and offset within that block for a given character position.\n * Iterates through blocks to calculate which block contains the position.\n *\n * @param blocks - Array of content blocks to search\n * @param position - Character position to find (0-based)\n * @returns Object with blockIndex and offset within that block\n *\n * @internal\n */\nconst findBlockAtPosition = (\n blocks: Block[],\n position: number,\n): { blockIndex: number; offset: number } => {\n let currentPos = 0;\n for (let i = 0; i < blocks.length; i++) {\n const block = blocks[i];\n if (!block) continue;\n if (block.type === BlockType.Text || block.type === BlockType.Styled) {\n const blockLength = block.text.length;\n if (currentPos + blockLength >= position) {\n return { blockIndex: i, offset: position - currentPos };\n }\n currentPos += blockLength;\n }\n }\n return { blockIndex: blocks.length, offset: 0 };\n};\n\n/**\n * Extracts plain text from an array of blocks.\n * Filters Text and Styled blocks and concatenates their text content.\n *\n * @param blocks - Array of content blocks\n * @returns Concatenated plain text string from all text blocks\n *\n * @internal\n */\nconst extractText = (blocks: Block[]): string => {\n return blocks\n .filter(\n (b) => b && (b.type === BlockType.Text || b.type === BlockType.Styled),\n )\n .map((b) => {\n if (b.type === BlockType.Text || b.type === BlockType.Styled) {\n return b.text;\n }\n return '';\n })\n .join('');\n};\n\n/**\n * Creates the public API for manipulating editor content.\n * Provides methods for inserting, deleting, replacing text, and managing blocks.\n *\n * @param state - Internal ApiState object to operate on\n * @returns SmartInputFunctions object with all API methods\n *\n * @example\n * ```typescript\n * const state = createState([], 0);\n * const api = createApi(state);\n * api.insert('Hello', 0);\n * api.apply();\n * ```\n */\nexport const createApi = (state: ApiState): SmartInputFunctions => ({\n /**\n * Clears all content from the editor.\n * Removes all blocks and resets cursor position to 0.\n * This operation is buffered and can be undone.\n *\n * @example\n * ```typescript\n * api.clear();\n * api.apply();\n * ```\n */\n clear: () => {\n state.blocks = [];\n state.characterPosition = 0;\n state.appendToBuffer([...state.blocks]);\n },\n\n /**\n * Inserts text at the specified position.\n * If the position is within a text block, the text is inserted into that block.\n * Otherwise, a new text block is created.\n *\n * @param text - The text string to insert\n * @param position - Character position where text should be inserted (0-based)\n *\n * @example\n * ```typescript\n * api.insert('World', 5);\n * api.apply();\n * ```\n */\n insert: (text: string, position: number) => {\n const { blockIndex, offset } = findBlockAtPosition(state.blocks, position);\n const newBlocks = [...state.blocks];\n\n if (blockIndex >= newBlocks.length) {\n // Insert at the end\n newBlocks.push({ type: BlockType.Text, text });\n } else {\n const block = newBlocks[blockIndex];\n if (!block) {\n newBlocks.push({ type: BlockType.Text, text });\n } else if (\n block.type === BlockType.Text ||\n block.type === BlockType.Styled\n ) {\n const beforeText = block.text.substring(0, offset);\n const afterText = block.text.substring(offset);\n newBlocks[blockIndex] = {\n ...block,\n text: beforeText + text + afterText,\n };\n } else {\n // Insert as new text block before non-text block\n newBlocks.splice(blockIndex, 0, { type: BlockType.Text, text });\n }\n }\n\n state.blocks = newBlocks;\n state.appendToBuffer([...state.blocks]);\n },\n\n /**\n * Deletes text within the specified range.\n * Handles deletion across multiple blocks intelligently.\n *\n * @param start - Starting character position of deletion range (0-based, inclusive)\n * @param end - Ending character position of deletion range (0-based, exclusive)\n *\n * @example\n * ```typescript\n * api.delete(5, 10); // Deletes characters 5-9\n * api.apply();\n * ```\n */\n delete: (start: number, end: number) => {\n if (start >= end) return;\n\n const startInfo = findBlockAtPosition(state.blocks, start);\n const endInfo = findBlockAtPosition(state.blocks, end);\n const newBlocks: Block[] = [];\n\n for (let i = 0; i < state.blocks.length; i++) {\n const block = state.blocks[i];\n if (!block) continue;\n\n if (i < startInfo.blockIndex || i > endInfo.blockIndex) {\n // Block is completely outside the deletion range\n newBlocks.push(block);\n } else if (i === startInfo.blockIndex && i === endInfo.blockIndex) {\n // Deletion is within a single block\n if (block.type === BlockType.Text || block.type === BlockType.Styled) {\n const beforeText = block.text.substring(0, startInfo.offset);\n const afterText = block.text.substring(endInfo.offset);\n const newText = beforeText + afterText;\n if (newText.length > 0) {\n newBlocks.push({ ...block, text: newText });\n }\n }\n } else if (i === startInfo.blockIndex) {\n // First block in deletion range\n if (block.type === BlockType.Text || block.type === BlockType.Styled) {\n const beforeText = block.text.substring(0, startInfo.offset);\n if (beforeText.length > 0) {\n newBlocks.push({ ...block, text: beforeText });\n }\n }\n } else if (i === endInfo.blockIndex) {\n // Last block in deletion range\n if (block.type === BlockType.Text || block.type === BlockType.Styled) {\n const afterText = block.text.substring(endInfo.offset);\n if (afterText.length > 0) {\n newBlocks.push({ ...block, text: afterText });\n }\n }\n }\n // Blocks between start and end are completely deleted (not added to newBlocks)\n }\n\n state.blocks = newBlocks;\n state.appendToBuffer([...state.blocks]);\n },\n\n /**\n * Replaces text in the specified range with new text.\n * Equivalent to deleting the range and inserting new text.\n *\n * @param start - Starting character position of range to replace (0-based, inclusive)\n * @param end - Ending character position of range to replace (0-based, exclusive)\n * @param text - New text to insert in place of the deleted range\n *\n * @example\n * ```typescript\n * api.replace(0, 5, 'Hi'); // Replaces first 5 characters with 'Hi'\n * api.apply();\n * ```\n */\n replace: (start: number, end: number, text: string) => {\n // Delete the range first, then insert the new text\n if (start >= end) {\n createApi(state).insert(text, start);\n return;\n }\n\n createApi(state).delete(start, end);\n createApi(state).insert(text, start);\n },\n\n /**\n * Replaces the first occurrence of specified text.\n * Searches through all blocks to find and replace the text.\n *\n * @param oldText - The text string to find and replace\n * @param text - The new text to replace it with\n *\n * @example\n * ```typescript\n * api.replaceText('Hello', 'Hi');\n * api.apply();\n * ```\n */\n replaceText: (oldText: string, text: string) => {\n const fullText = extractText(state.blocks);\n const index = fullText.indexOf(oldText);\n\n if (index !== -1) {\n createApi(state).replace(index, index + oldText.length, text);\n }\n },\n\n /**\n * Replaces all occurrences of specified text.\n * Continues replacing until no more matches are found.\n *\n * @param oldText - The text string to find and replace\n * @param text - The new text to replace all occurrences with\n *\n * @example\n * ```typescript\n * api.replaceAll('foo', 'bar'); // Replaces all 'foo' with 'bar'\n * api.apply();\n * ```\n */\n replaceAll: (oldText: string, text: string) => {\n let fullText = extractText(state.blocks);\n let offset = 0;\n\n while (true) {\n const index = fullText.indexOf(oldText);\n if (index === -1) break;\n\n createApi(state).replace(\n offset + index,\n offset + index + oldText.length,\n text,\n );\n offset += index + text.length;\n fullText = fullText.substring(index + oldText.length);\n }\n },\n\n /**\n * Returns a copy of the current blocks array.\n * Useful for inspecting current editor state.\n *\n * @returns Array of Block objects representing current content\n *\n * @example\n * ```typescript\n * const blocks = api.getBlocks();\n * console.log(blocks);\n * ```\n */\n getBlocks: () => {\n return [...state.blocks];\n },\n\n setBlocks: (blocks: Block[]) => {\n state.blocks = blocks;\n },\n\n appendStyledBlock: (block: StyledBlock) => {\n const newBlocks = [...state.blocks];\n newBlocks.push(block);\n state.blocks = newBlocks;\n state.appendToBuffer([...state.blocks]);\n },\n\n /**\n * Inserts a styled block at the specified position.\n * Styled blocks contain segments with individual styling.\n *\n * @param block - StyledBlock object with segments and styles\n * @param position - Character position where block should be inserted (0-based)\n *\n * @example\n * ```typescript\n * const styledBlock: StyledBlock = {\n * type: 'Styled',\n * text: 'Hello',\n * segments: [{ id: '1', text: 'Hello', style: { color: 'red' } }]\n * };\n * api.insertStyledBlock(styledBlock, 0);\n * api.apply();\n * ```\n */\n insertStyledBlock: (block: StyledBlock, position: number) => {\n const { blockIndex, offset } = findBlockAtPosition(state.blocks, position);\n const newBlocks = [...state.blocks];\n\n if (blockIndex >= newBlocks.length) {\n // Insert at the end\n newBlocks.push(block);\n } else {\n const currentBlock = newBlocks[blockIndex];\n if (\n currentBlock &&\n (currentBlock.type === BlockType.Text ||\n currentBlock.type === BlockType.Styled)\n ) {\n const beforeText = currentBlock.text.substring(0, offset);\n const afterText = currentBlock.text.substring(offset);\n\n // Split the current block\n const splitBlocks: Block[] = [];\n if (beforeText.length > 0) {\n splitBlocks.push({ ...currentBlock, text: beforeText });\n }\n splitBlocks.push(block);\n if (afterText.length > 0) {\n splitBlocks.push({ ...currentBlock, text: afterText });\n }\n\n newBlocks.splice(blockIndex, 1, ...splitBlocks);\n } else {\n // Insert before non-text block\n newBlocks.splice(blockIndex, 0, block);\n }\n }\n\n state.blocks = newBlocks;\n state.appendToBuffer([...state.blocks]);\n },\n\n /**\n * Inserts a document block at the specified position.\n * Document blocks represent file attachments.\n *\n * @param document - Document object with name, file, and optional URL\n * @param position - Character position where document should be inserted (0-based)\n *\n * @example\n * ```typescript\n * const doc: Document = {\n * name: 'report.pdf',\n * file: pdfFile,\n * url: 'https://example.com/report.pdf'\n * };\n * api.insertDocument(doc, 0);\n * api.apply();\n * ```\n */\n insertDocument: (document: Document, position: number) => {\n const docBlock: Block = {\n type: BlockType.Document,\n id: `doc-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`,\n name: document.name,\n file: document.file,\n url: document.url,\n contentType: document.contentType,\n };\n\n const { blockIndex, offset } = findBlockAtPosition(state.blocks, position);\n const newBlocks = [...state.blocks];\n\n if (blockIndex >= newBlocks.length) {\n newBlocks.push(docBlock);\n } else {\n const currentBlock = newBlocks[blockIndex];\n if (\n currentBlock &&\n (currentBlock.type === BlockType.Text ||\n currentBlock.type === BlockType.Styled)\n ) {\n const beforeText = currentBlock.text.substring(0, offset);\n const afterText = currentBlock.text.substring(offset);\n\n const splitBlocks: Block[] = [];\n if (beforeText.length > 0) {\n splitBlocks.push({ ...currentBlock, text: beforeText });\n }\n splitBlocks.push(docBlock);\n if (afterText.length > 0) {\n splitBlocks.push({ ...currentBlock, text: afterText });\n }\n\n newBlocks.splice(blockIndex, 1, ...splitBlocks);\n } else {\n newBlocks.splice(blockIndex, 0, docBlock);\n }\n }\n\n state.blocks = newBlocks;\n state.appendToBuffer([...state.blocks]);\n },\n\n /**\n * Inserts an image block at the specified position.\n * Image blocks represent embedded images.\n *\n * @param image - Image object with name, file, url, and optional alt text\n * @param position - Character position where image should be inserted (0-based)\n *\n * @example\n * ```typescript\n * const img: Image = {\n * name: 'photo.jpg',\n * file: imageFile,\n * url: 'https://example.com/photo.jpg',\n * alt: 'A photo'\n * };\n * api.insertImage(img, 0);\n * api.apply();\n * ```\n */\n insertImage: (image: Image, position: number) => {\n const imgBlock: Block = {\n type: BlockType.Image,\n id: `img-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`,\n name: image.name,\n file: image.file,\n url: image.url,\n ...(image.alt !== undefined ? { alt: image.alt } : {}),\n contentType: image.contentType,\n };\n\n const { blockIndex, offset } = findBlockAtPosition(state.blocks, position);\n const newBlocks = [...state.blocks];\n\n if (blockIndex >= newBlocks.length) {\n newBlocks.push(imgBlock);\n } else {\n const currentBlock = newBlocks[blockIndex];\n if (\n currentBlock &&\n (currentBlock.type === BlockType.Text ||\n currentBlock.type === BlockType.Styled)\n ) {\n const beforeText = currentBlock.text.substring(0, offset);\n const afterText = currentBlock.text.substring(offset);\n\n const splitBlocks: Block[] = [];\n if (beforeText.length > 0) {\n splitBlocks.push({ ...currentBlock, text: beforeText });\n }\n splitBlocks.push(imgBlock);\n if (afterText.length > 0) {\n splitBlocks.push({ ...currentBlock, text: afterText });\n }\n\n newBlocks.splice(blockIndex, 1, ...splitBlocks);\n } else {\n newBlocks.splice(blockIndex, 0, imgBlock);\n }\n }\n\n state.blocks = newBlocks;\n state.appendToBuffer([...state.blocks]);\n },\n\n /**\n * Applies styling to the first occurrence of specified text.\n * Converts Text blocks to Styled blocks with the specified style.\n *\n * @param text - The text string to find and style\n * @param id - Unique identifier for the styled segment\n * @param style - Optional React CSSProperties object for styling\n *\n * @example\n * ```typescript\n * api.styleText('important', 'style-1', { fontWeight: 'bold', color: 'red' });\n * api.apply();\n * ```\n */\n styleText: (text: string, id: string, style?: React.CSSProperties) => {\n const fullText = extractText(state.blocks);\n const index = fullText.indexOf(text);\n\n if (index === -1) return;\n\n const startInfo = findBlockAtPosition(state.blocks, index);\n const endInfo = findBlockAtPosition(state.blocks, index + text.length);\n const newBlocks: Block[] = [];\n\n for (let i = 0; i < state.blocks.length; i++) {\n const block = state.blocks[i];\n if (!block) continue;\n\n if (i < startInfo.blockIndex || i > endInfo.blockIndex) {\n // Block is outside the style range\n newBlocks.push(block);\n } else if (i === startInfo.blockIndex && i === endInfo.blockIndex) {\n // Style is within a single block\n if (block.type === BlockType.Text || block.type === BlockType.Styled) {\n const beforeText = block.text.substring(0, startInfo.offset);\n const styledText = block.text.substring(\n startInfo.offset,\n endInfo.offset,\n );\n const afterText = block.text.substring(endInfo.offset);\n\n if (beforeText.length > 0) {\n newBlocks.push({ type: BlockType.Text, text: beforeText });\n }\n newBlocks.push({\n type: BlockType.Styled,\n id,\n text: styledText,\n ...(style ? { style } : {}),\n } as StyledBlock);\n if (afterText.length > 0) {\n newBlocks.push({ type: BlockType.Text, text: afterText });\n }\n }\n } else if (i === startInfo.blockIndex) {\n // First block in style range\n if (block.type === BlockType.Text || block.type === BlockType.Styled) {\n const beforeText = block.text.substring(0, startInfo.offset);\n const styledText = block.text.substring(startInfo.offset);\n\n if (beforeText.length > 0) {\n newBlocks.push({ type: BlockType.Text, text: beforeText });\n }\n if (styledText.length > 0) {\n newBlocks.push({\n type: BlockType.Styled,\n id: `${id}-${i}`,\n text: styledText,\n ...(style ? { style } : {}),\n } as StyledBlock);\n }\n }\n } else if (i === endInfo.blockIndex) {\n // Last block in style range\n if (block.type === BlockType.Text || block.type === BlockType.Styled) {\n const styledText = block.text.substring(0, endInfo.offset);\n const afterText = block.text.substring(endInfo.offset);\n\n if (styledText.length > 0) {\n newBlocks.push({\n type: BlockType.Styled,\n id: `${id}-${i}`,\n text: styledText,\n ...(style ? { style } : {}),\n } as StyledBlock);\n }\n if (afterText.length > 0) {\n newBlocks.push({ type: BlockType.Text, text: afterText });\n }\n }\n } else {\n // Middle block - convert entirely to styled\n if (block.type === BlockType.Text || block.type === BlockType.Styled) {\n newBlocks.push({\n type: BlockType.Styled,\n id: `${id}-${i}`,\n text: block.text,\n ...(style ? { style } : {}),\n } as StyledBlock);\n } else {\n newBlocks.push(block);\n }\n }\n }\n\n state.blocks = newBlocks;\n state.appendToBuffer([...state.blocks]);\n },\n\n getCharacterPosition: () => {\n return state.characterPosition;\n },\n setCharacterPosition: (position: number) => {\n state.characterPosition = position;\n },\n});\n","import { forwardRef, useEffect, useImperativeHandle, useMemo } from 'react';\nimport {\n useApi,\n useBuffer,\n useCursorPosition,\n useBlocks,\n} from '@src/state/useState';\nimport { SmartInputApi, SmartInputFunctions } from '@src/types/api';\nimport { Block, BlockType, CommitItem } from '@src/types';\nimport { createApi, createState } from './functions';\nimport {\n convertBlocksToCommitItems,\n getCursorPosition,\n getSelectionRange,\n setCursorPosition,\n} from '@src/utils/functions';\n\n/**\n * Api component provides the SmartInput API interface.\n * This component doesn't render any UI but exposes methods via ref to interact with the editor.\n * It manages state transformations and provides methods to manipulate blocks programmatically.\n *\n * @component\n * @example\n * ```tsx\n * const apiRef = useRef<SmartInputApi>(null);\n *\n * // Use the API\n * apiRef.current?.apply((api) => {\n * api.insertText('Hello');\n * });\n * ```\n */\nexport const Api = forwardRef<SmartInputApi>(function Api(_, ref) {\n const { blocks, setBlocks } = useBlocks((s) => s); // ensure re-render on blocks change\n const { setApi, element } = useApi((s) => s); // ensure re-render on api change\n const { characterPosition, updateCharacterPosition } = useCursorPosition(\n (s) => s,\n ); // ensure re-render on cursor position change\n const { appendToBuffer } = useBuffer((s) => s);\n\n const api = useMemo<SmartInputApi>(\n () => ({\n apply: (fn: (api: SmartInputFunctions) => void) => {\n const state = createState(blocks, characterPosition);\n const functions = createApi(state);\n fn(functions);\n if (JSON.stringify(state.blocks) !== JSON.stringify(blocks)) {\n setBlocks(state.blocks);\n }\n if (state.characterPosition !== characterPosition) {\n updateCharacterPosition(state.characterPosition);\n }\n if (state.buffer.length > 0) {\n state.buffer.forEach((b) => appendToBuffer(b));\n }\n },\n getBlockAtPosition: (position: number): Block | null => {\n let blockIndex = -1;\n let blockStart = 0;\n for (let i = 0; i < blocks.length; i++) {\n const b = blocks[i];\n if (!b) continue;\n if (b.type === BlockType.Text || b.type === BlockType.Styled) {\n const blockLength = b.text.length;\n if (position >= blockStart && position < blockStart + blockLength) {\n blockIndex = i;\n const foundBlock = blocks[blockIndex];\n return foundBlock ?? null;\n }\n blockStart += blockLength;\n }\n }\n return null;\n },\n get: (): CommitItem[] => {\n return convertBlocksToCommitItems(blocks);\n },\n getElementById: (id: string): HTMLElement | null => {\n return document.getElementById(id);\n },\n focus: (): void => {\n if (element) {\n element.focus();\n // Move cursor to end of content\n if (element.childNodes.length === 0) {\n const selection = window.getSelection();\n if (selection) {\n const range = document.createRange();\n range.setStart(element, 0);\n range.collapse(true);\n selection.removeAllRanges();\n selection.addRange(range);\n }\n }\n }\n },\n getCursorPosition: (): number => {\n if (!element) return 0;\n const range = getSelectionRange(element);\n if (!range) return 0;\n return getCursorPosition(element, range);\n },\n setCursorPosition: (position: number): void => {\n if (!element) return;\n setCursorPosition(element, position);\n },\n getText: (): string => {\n return blocks\n .map((b) =>\n b.type === BlockType.Text || b.type === BlockType.Styled\n ? b.text\n : '',\n )\n .join('');\n },\n getTextLength: (): number => {\n return blocks.reduce((length, b) => {\n if (b.type === BlockType.Text || b.type === BlockType.Styled) {\n return length + b.text.length;\n }\n return length;\n }, 0);\n },\n }),\n [\n blocks,\n characterPosition,\n setBlocks,\n updateCharacterPosition,\n appendToBuffer,\n element,\n ],\n );\n\n useEffect(() => {\n setApi(api);\n }, [api, setApi]);\n\n useImperativeHandle(ref, () => api, [api]);\n\n return null;\n});\n","import React, { forwardRef, PropsWithChildren } from 'react';\nimport { StateProvider } from '@state/StateProvider';\nimport { ComponentProps } from '@atypes/componentProps';\nimport { Api } from '../Api';\nimport { SmartInputApi } from '@src/types/api';\nimport cx from 'classnames';\nimport style from './SmartInput.module.less';\n\n/**\n * SmartInput is the main container component for the rich text editor.\n * It provides state management and API access to all child components.\n * Use this component as the root wrapper for Editor and other editor-related components.\n *\n * @component\n * @example\n * ```tsx\n * const apiRef = useRef<SmartInputApi>(null);\n *\n * <SmartInput ref={apiRef} blocks={initialBlocks} onBlocksChange={handleChange}>\n * <Editor enableLineBreaks={true} />\n * <CommitNotifier onCommit={handleCommit} />\n * </SmartInput>\n * ```\n */\nexport const SmartInput = forwardRef<\n SmartInputApi,\n PropsWithChildren<ComponentProps>\n>(function SmartInput({ children, className, id, ...props }, ref) {\n return (\n <StateProvider value={props}>\n <Api ref={ref} />\n <div id={id} className={cx(style['SmartInput'], className)}>\n {children}\n </div>\n </StateProvider>\n );\n});\n\nSmartInput.displayName = 'SmartInput';\n","import React, { Component, ReactNode, ErrorInfo } from 'react';\nimport styles from './ErrorBoundary.module.less';\n\n/**\n * Error information displayed when an error occurs\n */\nexport interface ErrorDetails {\n /** The error that was caught */\n error: Error;\n /** React component stack trace */\n errorInfo: ErrorInfo;\n /** Timestamp when the error occurred */\n timestamp: Date;\n}\n\n/**\n * Props for the ErrorBoundary component\n */\nexport interface ErrorBoundaryProps {\n /** Child components to render */\n children: ReactNode;\n /** Optional fallback UI to display on error */\n fallback?: (error: ErrorDetails) => ReactNode;\n /** Callback invoked when an error is caught */\n onError?: (error: ErrorDetails) => void;\n /** Optional custom error message */\n errorMessage?: string;\n /** Whether to show detailed error information (default: only in development) */\n showDetails?: boolean;\n /** Whether to allow reset/retry (default: true) */\n allowReset?: boolean;\n}\n\n/**\n * State for the ErrorBoundary component\n */\ninterface ErrorBoundaryState {\n hasError: boolean;\n error: Error | null;\n errorInfo: ErrorInfo | null;\n timestamp: Date | null;\n}\n\n/**\n * ErrorBoundary component catches JavaScript errors anywhere in the child component tree,\n * logs those errors, and displays a fallback UI instead of crashing the whole application.\n *\n * @component\n * @example\n * ```tsx\n * <ErrorBoundary\n * onError={({ error }) => logErrorToService(error)}\n * errorMessage=\"Something went wrong with the editor\"\n * >\n * <SmartInput>\n * <Editor />\n * </SmartInput>\n * </ErrorBoundary>\n * ```\n */\nexport class ErrorBoundary extends Component<\n ErrorBoundaryProps,\n ErrorBoundaryState\n> {\n constructor(props: ErrorBoundaryProps) {\n super(props);\n this.state = {\n hasError: false,\n error: null,\n errorInfo: null,\n timestamp: null,\n };\n }\n\n static getDerivedStateFromError(error: Error): Partial<ErrorBoundaryState> {\n // Update state so the next render will show the fallback UI\n return {\n hasError: true,\n error,\n timestamp: new Date(),\n };\n }\n\n componentDidCatch(error: Error, errorInfo: ErrorInfo): void {\n const errorDetails: ErrorDetails = {\n error,\n errorInfo,\n timestamp: new Date(),\n };\n\n // Log error details to console in development\n if (\n typeof process !== 'undefined' &&\n process.env?.['NODE_ENV'] === 'development'\n ) {\n console.error('ErrorBoundary caught an error:', error);\n console.error('Component stack:', errorInfo.componentStack);\n }\n\n // Call optional error callback\n if (this.props.onError) {\n this.props.onError(errorDetails);\n }\n\n // Update state with error info\n this.setState({ errorInfo });\n }\n\n handleReset = (): void => {\n this.setState({\n hasError: false,\n error: null,\n errorInfo: null,\n timestamp: null,\n });\n };\n\n render(): ReactNode {\n const { hasError, error, errorInfo, timestamp } = this.state;\n const {\n children,\n fallback,\n errorMessage,\n showDetails = typeof process !== 'undefined' &&\n process.env?.['NODE_ENV'] === 'development',\n allowReset = true,\n } = this.props;\n\n if (hasError && error && errorInfo && timestamp) {\n const errorDetails: ErrorDetails = { error, errorInfo, timestamp };\n\n // Use custom fallback if provided\n if (fallback) {\n return fallback(errorDetails);\n }\n\n // Default error UI\n return (\n <div className={styles['errorBoundary']} role=\"alert\">\n <div className={styles['errorContainer']}>\n <h2 className={styles['errorTitle']}>\n {errorMessage || 'Something went wrong'}\n </h2>\n\n <p className={styles['errorDescription']}>\n An error occurred while rendering this component. Please try\n refreshing the page or contact support if the problem persists.\n </p>\n\n {showDetails && (\n <details className={styles['errorDetails']}>\n <summary className={styles['errorSummary']}>\n Error Details\n </summary>\n <div className={styles['errorContent']}>\n <div className={styles['errorSection']}>\n <strong>Error:</strong>\n <pre className={styles['errorPre']}>{error.toString()}</pre>\n </div>\n\n {error.stack && (\n <div className={styles['errorSection']}>\n <strong>Stack Trace:</strong>\n <pre className={styles['errorPre']}>{error.stack}</pre>\n </div>\n )}\n\n <div className={styles['errorSection']}>\n <strong>Component Stack:</strong>\n <pre className={styles['errorPre']}>\n {errorInfo.componentStack}\n </pre>\n </div>\n\n <div className={styles['errorSection']}>\n <strong>Timestamp:</strong>\n <pre className={styles['errorPre']}>\n {timestamp.toISOString()}\n </pre>\n </div>\n </div>\n </details>\n )}\n\n {allowReset && (\n <button\n className={styles['errorButton']}\n onClick={this.handleReset}\n type=\"button\"\n >\n Try Again\n </button>\n )}\n </div>\n </div>\n );\n }\n\n return children;\n }\n}\n","/** Predefined color palette for editor components */\nexport const Colours = {\n buttons: {\n buttonDefault: 'black',\n buttonDefaultHover: 'black',\n buttonDefaultBackground: 'white',\n buttonDefaultHoverBackground: 'lightgray',\n },\n\n backgrounds: {\n standard: '#626262',\n hover: '#444444',\n locked: '#44444',\n selected: '#1C1C1C',\n multiSelect: '#202020',\n\n errorHover: '#e60000',\n error: '#da0000',\n },\n};\n","/** The MIME type used for clipboard operations with JSON data */\nexport const CLIPBOARD_FORMAT = 'text/json';\n/** Characters that delimit blocks when pasting content */\nexport const DELIMITERS = [',', '\\t', '\\n'];\n\n/** Height in pixels for compact editor size */\nexport const COMPACT_HEIGHT = 24;\n/** Height in pixels for normal editor size */\nexport const NORMAL_HEIGHT = 30;\n/** Height in pixels for large editor size */\nexport const LARGE_HEIGHT = 36;\n\n/** Height in pixels for compact pill/block size */\nexport const COMPACT_PILL_HEIGHT = 18;\n/** Height in pixels for normal pill/block size */\nexport const NORMAL_PILL_HEIGHT = 22;\n/** Height in pixels for large pill/block size */\nexport const LARGE_PILL_HEIGHT = 26;\n\n/** Keyboard key constants for common keys used in the editor */\nexport const KeyBoardkeys = {\n ArrowRight: 'ArrowRight',\n ArrowLeft: 'ArrowLeft',\n ArrowUp: 'ArrowUp',\n ArrowDown: 'ArrowDown',\n PageUp: 'PageUp',\n PageDown: 'PageDown',\n Home: 'Home',\n End: 'End',\n Enter: 'Enter',\n Tab: 'Tab',\n c: 'c',\n C: 'C',\n x: 'x',\n X: 'X',\n v: 'v',\n V: 'V',\n z: 'z',\n Z: 'Z',\n Space: ' ',\n Escape: 'Escape',\n};\n","/**\n * Debug logging utility for Open Input\n *\n * Provides structured logging with namespace support, similar to the 'debug' package.\n * Logs are only output when debugging is enabled via localStorage or environment variables.\n *\n * @example\n * ```ts\n * import { createLogger } from '@smart-input/core';\n *\n * const log = createLogger('editor:state');\n * log('Blocks updated', { count: blocks.length });\n * log.warn('Large content detected', { size: content.length });\n * log.error('Failed to parse', error);\n * ```\n */\n\n/**\n * Log level for filtering messages\n */\nexport enum LogLevel {\n DEBUG = 0,\n INFO = 1,\n WARN = 2,\n ERROR = 3,\n NONE = 4,\n}\n\n/**\n * Logger configuration\n */\ninterface LoggerConfig {\n /** Minimum log level to display */\n level: LogLevel;\n /** Whether to include timestamps */\n timestamps: boolean;\n /** Custom output function (default: console) */\n output?: typeof console;\n}\n\n/**\n * Logger instance for a specific namespace\n */\nexport interface Logger {\n /** Log a debug message */\n (message: string, ...args: unknown[]): void;\n /** Log an info message */\n info: (message: string, ...args: unknown[]) => void;\n /** Log a warning message */\n warn: (message: string, ...args: unknown[]) => void;\n /** Log an error message */\n error: (message: string, ...args: unknown[]) => void;\n /** Check if namespace is enabled */\n enabled: boolean;\n /** The namespace of this logger */\n namespace: string;\n}\n\n// Global configuration\nlet globalConfig: LoggerConfig = {\n level:\n typeof process !== 'undefined' &&\n process.env?.['NODE_ENV'] === 'development'\n ? LogLevel.DEBUG\n : LogLevel.WARN,\n timestamps: true,\n output: console,\n};\n\n// Store enabled namespaces\nconst enabledNamespaces = new Set<string>();\n\n/**\n * Check if localStorage is available\n */\nfunction hasLocalStorage(): boolean {\n try {\n return typeof localStorage !== 'undefined';\n } catch {\n return false;\n }\n}\n\n/**\n * Load debug configuration from localStorage or environment\n */\nfunction loadDebugConfig(): void {\n // Check localStorage for debug flag\n if (hasLocalStorage()) {\n const debugValue = localStorage.getItem('debug');\n if (debugValue) {\n parseDebugString(debugValue);\n }\n }\n\n // Check environment variable (for Node.js environments)\n if (typeof process !== 'undefined' && process.env?.['DEBUG']) {\n parseDebugString(process.env?.['DEBUG'] || '');\n }\n}\n\n/**\n * Parse debug string and enable matching namespaces\n * Examples: 'smart-input:*', 'smart-input:editor:*', 'smart-input:editor:state'\n */\nfunction parseDebugString(debugStr: string): void {\n const patterns = debugStr.split(',').map((s) => s.trim());\n\n patterns.forEach((pattern) => {\n if (pattern === '*' || pattern === 'smart-input:*') {\n // Enable all smart-input namespaces\n enabledNamespaces.add('*');\n } else if (pattern.startsWith('smart-input:')) {\n enabledNamespaces.add(pattern);\n }\n });\n}\n\n/**\n * Check if a namespace is enabled\n */\nfunction isNamespaceEnabled(namespace: string): boolean {\n // Always disabled in production unless explicitly enabled\n if (\n typeof process !== 'undefined' &&\n process.env?.['NODE_ENV'] === 'production' &&\n enabledNamespaces.size === 0\n ) {\n return false;\n }\n\n // Check if all namespaces are enabled\n if (enabledNamespaces.has('*')) {\n return true;\n }\n\n // Check exact match\n const fullNamespace = `smart-input:${namespace}`;\n if (enabledNamespaces.has(fullNamespace)) {\n return true;\n }\n\n // Check wildcard patterns\n for (const pattern of enabledNamespaces) {\n if (pattern.endsWith(':*')) {\n const prefix = pattern.slice(0, -2);\n if (fullNamespace.startsWith(prefix)) {\n return true;\n }\n }\n }\n\n return false;\n}\n\n/**\n * Format log message with timestamp and namespace\n */\nfunction formatMessage(\n namespace: string,\n level: string,\n message: string,\n): string {\n const parts: string[] = [];\n\n if (globalConfig.timestamps) {\n const timestamp = new Date().toISOString();\n parts.push(`[${timestamp}]`);\n }\n\n parts.push(`[${level.toUpperCase()}]`);\n parts.push(`[smart-input:${namespace}]`);\n parts.push(message);\n\n return parts.join(' ');\n}\n\n/**\n * Create a logger for a specific namespace\n *\n * @param namespace - Namespace for the logger (e.g., 'editor:state', 'typeahead')\n * @returns Logger instance\n */\nexport function createLogger(namespace: string): Logger {\n const log = (message: string, ...args: unknown[]): void => {\n if (!isNamespaceEnabled(namespace) || globalConfig.level > LogLevel.DEBUG)\n return;\n const formatted = formatMessage(namespace, 'debug', message);\n globalConfig.output?.log(formatted, ...args);\n };\n\n log.info = (message: string, ...args: unknown[]): void => {\n if (!isNamespaceEnabled(namespace) || globalConfig.level > LogLevel.INFO)\n return;\n const formatted = formatMessage(namespace, 'info', message);\n globalConfig.output?.info(formatted, ...args);\n };\n\n log.warn = (message: string, ...args: unknown[]): void => {\n if (!isNamespaceEnabled(namespace) || globalConfig.level > LogLevel.WARN)\n return;\n const formatted = formatMessage(namespace, 'warn', message);\n globalConfig.output?.warn(formatted, ...args);\n };\n\n log.error = (message: string, ...args: unknown[]): void => {\n if (!isNamespaceEnabled(namespace) || globalConfig.level > LogLevel.ERROR)\n return;\n const formatted = formatMessage(namespace, 'error', message);\n globalConfig.output?.error(formatted, ...args);\n };\n\n // Make enabled a getter so it's always up-to-date\n Object.defineProperty(log, 'enabled', {\n get() {\n return isNamespaceEnabled(namespace);\n },\n enumerable: true,\n configurable: true,\n });\n\n log.namespace = namespace;\n\n return log as Logger;\n}\n\n/**\n * Enable debugging for specific namespaces\n *\n * @param namespaces - Namespace pattern(s) to enable (e.g., '*', 'editor:*', 'typeahead')\n *\n * @example\n * ```ts\n * // Enable all namespaces\n * enableDebug('*');\n *\n * // Enable specific namespace\n * enableDebug('editor:state');\n *\n * // Enable all editor namespaces\n * enableDebug('editor:*');\n *\n * // Enable multiple namespaces\n * enableDebug('editor:*,typeahead');\n * ```\n */\nexport function enableDebug(namespaces: string): void {\n parseDebugString(`smart-input:${namespaces}`);\n\n // Save to localStorage if available\n if (hasLocalStorage()) {\n const currentDebug = localStorage.getItem('debug') || '';\n const newDebug = currentDebug\n ? `${currentDebug},smart-input:${namespaces}`\n : `smart-input:${namespaces}`;\n localStorage.setItem('debug', newDebug);\n }\n}\n\n/**\n * Disable all debugging\n */\nexport function disableDebug(): void {\n enabledNamespaces.clear();\n\n if (hasLocalStorage()) {\n localStorage.removeItem('debug');\n }\n}\n\n/**\n * Configure global logger settings\n *\n * @param config - Partial configuration to update\n */\nexport function configureLogger(config: Partial<LoggerConfig>): void {\n globalConfig = { ...globalConfig, ...config };\n}\n\n/**\n * Get current logger configuration\n */\nexport function getLoggerConfig(): Readonly<LoggerConfig> {\n return { ...globalConfig };\n}\n\n// Load configuration on module import\nloadDebugConfig();\n\n/**\n * Development mode warning utility\n * Shows warnings only in development mode\n */\nexport function devWarn(message: string, ...args: unknown[]): void {\n if (\n typeof process !== 'undefined' &&\n process.env?.['NODE_ENV'] === 'development'\n ) {\n console.warn(`[smart-input] ${message}`, ...args);\n }\n}\n\n/**\n * Development mode error utility\n * Shows errors only in development mode\n */\nexport function devError(message: string, ...args: unknown[]): void {\n if (\n typeof process !== 'undefined' &&\n process.env?.['NODE_ENV'] === 'development'\n ) {\n console.error(`[smart-input] ${message}`, ...args);\n }\n}\n\n/**\n * Assert a condition in development mode\n * Throws an error if the condition is false\n */\nexport function devAssert(\n condition: boolean,\n message: string,\n): asserts condition {\n if (\n typeof process !== 'undefined' &&\n process.env?.['NODE_ENV'] === 'development' &&\n !condition\n ) {\n throw new Error(`[smart-input] Assertion failed: ${message}`);\n }\n}\n"],"names":["StateContext","React","useState","storeSelector","selector","store","useStore","useTopLevelSubscribe","callback","useEffect","unsubscribe","useSubscribe","useBlocks","s","useBuffer","useCursorPosition","useApi","useBehaviour","useKeyHandlers","useDragHandlers","useBlockRerenderHandlers","useTopLevelBlocksSubscriber","useBlocksSubscriber","useTopLevelCursorPositionSubscriber","useCursorPositionSubscriber","unitlessKeys","DEFAULT_UNIT","isCSSPropertyValue","value","camelToKebab","str","match","applyCssUnits","property","unit","isUnitless","unitless","resolvedUnit","stringifyStyleDeclaration","styleDeclaration","options","importantSuffix","_","stringifyCSSProperties","cssProperties","optionsOrImportant","BlockType","convertBlocksToCommitItems","blocks","items","currentText","block","getCursorPosition","preElement","selRange","charCount","i","node","j","childNode","getPositionAndRect","range","pre","rect","DOCUMENT_ICON","createElement","container","e","img","width","height","deleteBtn","element","preContainsTextNode","text","start","preContainsNode","id","getSelectionRange","selection","replaceLineFeeds","getBlockAndOffset","position","pos","b","len","last","lastLen","insertCarridgeReturnInString","offset","end","insertCarridgeReturn","characterPosition","index","newBlock","setCursorPosition","idx","isCarridgeReturn","newRange","sel","foundStart","nodeLength","nextCharCount","removeMatchedText","matchedText","regex","getBlockIndexAtPosition","blockStart","blockLength","replaceTextAtPosition","oldText","newText","currentBlocks","blockIndex","currentBlock","blockText","blockPos","oldTextIndex","newBlockText","newBlocks","insertStyledBlockAtPosition","style","posInBlock","beforeText","afterText","transformToTextBlocks","blockIndexes","sortedIndices","bi","a","blockToTransform","precedingBlock","mergedText","splitTextFromStyledBlock","styled","lookup","isAfter","generateId","isImageFile","file","getCaretRangeFromPoint","clientX","clientY","hasValidContent","dataTransfer","isDraggableBlock","blockId","useElementObserver","lastPositionRef","useRef","callbackRef","rafId","isObserving","triggerCallback","checkPosition","currentPosition","resizeObserver","intersectionObserver","UnmanagedEditor","memo","forwardRef","props","ref","onChange","onUndo","enableLineBreaks","placeholder","className","keyHandlers","dragOverHandlers","dragLeaveHandlers","dropHandlers","preRef","updatePosition","setElement","selectionInProgress","setRef","useCallback","handleKeyDown","event","handler","updateCursorPosition","handleKeyUp","handleChange","handleCopy","fragment","html","handlePaste","handleDragOver","handleDragLeave","handleDrop","jsx","styles","useMutationObserver","targetNode","observer","hasOwn","classNames","classes","arg","appendClass","parseValue","key","newClass","module","addBlockEventListeners","onBlockClick","onBlockDblClick","onBlockMouseUp","onBlockMouseDown","onBlockMouseEnter","onBlockMouseLeave","onBlockMouseOver","onBlockMouseMove","getElementText","setElementText","areStylesDifferent","blockStyle","elementStyle","blockCss","elementCss","Editor","imageWidth","imageHeight","documentWidth","documentHeight","editorClassName","eventHandlers","setBlocks","undoBuffer","appendToBuffer","blockRerenderHandlers","updateCharacterPosition","handleMutations","mutations","affectedBlockIds","mutation","target","rerenderedStyledBlocks","handleDeleteBlock","createElementOptions","useMemo","cnt","domElement","imgElement","expectedSrc","extra","lastBlock","childNodeAtLength","lastChild","isReturn","styledBlock","nextNode","nb","finalBlocks","handleUndo","lastBlocks","cx","subscribeWithSelectorImpl","fn","set","get","api","origSubscribe","optListener","listener","equalityFn","currentSlice","state","nextSlice","previousSlice","subscribeWithSelector","createSubscriberStore","initializer","create","createBlocksStore","useChangeNotify","cursorPositionStore","onBlocksChange","changeCallback","current","previous","cursorRect","MAX_BUFFER_LENGTH","createBufferStore","buffer","ZERO_RECT","createCursorPositionStore","useCursorChangeNotify","blockStore","onCursorPositionChange","createApiStore","createBehaviourStore","createKeyHandlerStore","h","DragEventType","createDragHandlerStore","eventType","createBlockRerenderHandlerStore","StateProvider","children","keyHandlerStore","bufferStore","blocksStore","apiStore","behaviourStore","dragHandlerStore","blockRerenderHandlerStore","stateValue","createState","blocksI","characterPositionI","findBlockAtPosition","currentPos","extractText","createApi","startInfo","endInfo","fullText","splitBlocks","document","docBlock","image","imgBlock","styledText","Api","setApi","functions","length","useImperativeHandle","SmartInput","jsxs","ErrorBoundary","Component","error","errorInfo","errorDetails","hasError","timestamp","fallback","errorMessage","showDetails","allowReset","Colours","CLIPBOARD_FORMAT","DELIMITERS","COMPACT_HEIGHT","NORMAL_HEIGHT","LARGE_HEIGHT","COMPACT_PILL_HEIGHT","NORMAL_PILL_HEIGHT","LARGE_PILL_HEIGHT","KeyBoardkeys","LogLevel","globalConfig","enabledNamespaces","hasLocalStorage","loadDebugConfig","debugValue","parseDebugString","debugStr","pattern","isNamespaceEnabled","namespace","fullNamespace","prefix","formatMessage","level","message","parts","createLogger","log","args","formatted","enableDebug","namespaces","currentDebug","newDebug","disableDebug","configureLogger","config","getLoggerConfig","devWarn","devError","devAssert","condition"],"mappings":"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","x_google_ignoreList":[2,3,9,12]}
|