@openim/im-composer 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/LICENSE +1 -1
- package/README.md +214 -203
- package/dist/index.css +1 -518
- package/dist/index.d.mts +617 -0
- package/dist/index.d.ts +487 -276
- package/dist/index.js +24 -2641
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +32 -0
- package/dist/index.mjs.map +1 -0
- package/package.json +136 -82
- package/CHANGELOG.md +0 -37
- package/dist/index.cjs +0 -2603
- package/dist/index.cjs.map +0 -1
- package/dist/index.css.map +0 -1
- package/dist/index.d.cts +0 -406
package/dist/index.cjs.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/IMComposer.tsx","../src/nodes/MentionNode.tsx","../src/nodes/ImageNode.tsx","../src/nodes/EmojiNode.ts","../src/nodes/QuoteNode.tsx","../src/plugins/MentionPlugin.tsx","../src/plugins/PlainTextPastePlugin.tsx","../src/plugins/RichTextPastePlugin.tsx","../src/utils/helpers.ts","../src/utils/exportPayload.ts","../src/utils/editorUtils.ts","../src/hooks/useImageUpload.ts","../src/plugins/ToolbarPlugin.tsx","../src/components/Icons.tsx","../src/LocaleContext.tsx","../src/plugins/KeymapPlugin.tsx","../src/plugins/DeletionPlugin.tsx","../src/plugins/QuoteRemovalListenerPlugin.tsx","../src/plugins/LinkShortcutPlugin.tsx","../src/plugins/LinkEditPlugin.tsx","../src/components/AttachmentPreviewBar.tsx","../src/hooks/useAttachments.ts","../src/themes/EditorTheme.ts"],"sourcesContent":["// Main component\nexport { IMComposer } from './IMComposer';\n\n// Types\nexport type {\n Attachment,\n MentionInfo,\n PlainMessagePayload,\n MarkdownMessagePayload,\n MessagePayload,\n Member,\n ComposerMode,\n UploadImageResult,\n UploadImageFn,\n MarkdownSyntaxOptions,\n SendKey,\n IMComposerProps,\n IMComposerRef,\n QuoteInfo,\n IMComposerLocale,\n} from './types';\n\n// Nodes (for advanced usage)\nexport { MentionNode, $createMentionNode, $isMentionNode } from './nodes/MentionNode';\nexport { ImageNode, $createImageNode, $isImageNode } from './nodes/ImageNode';\nexport { EmojiNode, $createEmojiNode, $isEmojiNode } from './nodes/EmojiNode';\nexport { QuoteNode, $createQuoteNode, $isQuoteNode } from './nodes/QuoteNode';\n\n// Hooks (for custom integrations)\nexport { useAttachments } from './hooks/useAttachments';\nexport { useImageUpload } from './hooks/useImageUpload';\n","import {\n forwardRef,\n useImperativeHandle,\n useCallback,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from 'react';\nimport { LexicalComposer } from '@lexical/react/LexicalComposer';\nimport { RichTextPlugin } from '@lexical/react/LexicalRichTextPlugin';\nimport { ContentEditable } from '@lexical/react/LexicalContentEditable';\nimport { HistoryPlugin } from '@lexical/react/LexicalHistoryPlugin';\nimport { LexicalErrorBoundary } from '@lexical/react/LexicalErrorBoundary';\nimport { MarkdownShortcutPlugin } from '@lexical/react/LexicalMarkdownShortcutPlugin';\nimport { ListPlugin } from '@lexical/react/LexicalListPlugin';\nimport { LinkPlugin } from '@lexical/react/LexicalLinkPlugin';\nimport { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext';\nimport { TRANSFORMERS } from '@lexical/markdown';\nimport { HeadingNode, QuoteNode as MarkdownQuoteNode } from '@lexical/rich-text';\nimport { ListNode, ListItemNode } from '@lexical/list';\nimport { CodeNode } from '@lexical/code';\nimport { LinkNode, AutoLinkNode } from '@lexical/link';\nimport { LexicalEditor, $getRoot, $getSelection, $isRangeSelection, LexicalNode, $createTextNode, $createParagraphNode } from 'lexical';\n\nimport type {\n IMComposerProps,\n IMComposerRef,\n ComposerMode,\n Attachment,\n Member,\n} from './types';\nimport { MentionNode, $createMentionNode } from './nodes/MentionNode';\nimport { ImageNode } from './nodes/ImageNode';\nimport { EmojiNode } from './nodes/EmojiNode';\nimport { QuoteNode, $createQuoteNode, $isQuoteNode } from './nodes/QuoteNode';\nimport { MentionPlugin } from './plugins/MentionPlugin';\nimport { PlainTextPastePlugin } from './plugins/PlainTextPastePlugin';\nimport { RichTextPastePlugin } from './plugins/RichTextPastePlugin';\nimport { ToolbarPlugin } from './plugins/ToolbarPlugin';\nimport { KeymapPlugin } from './plugins/KeymapPlugin';\nimport { EmojiPlugin } from './plugins/EmojiPlugin';\nimport { DeletionPlugin } from './plugins/DeletionPlugin';\nimport { QuoteRemovalListenerPlugin } from './plugins/QuoteRemovalListenerPlugin';\nimport { LinkShortcutPlugin } from './plugins/LinkShortcutPlugin';\nimport { LinkEditPlugin } from './plugins/LinkEditPlugin';\nimport { AttachmentPreviewBar } from './components/AttachmentPreviewBar';\nimport { useAttachments } from './hooks/useAttachments';\nimport { exportPlainPayload, exportMarkdownPayload, clearEditor, isEditorEmpty, importMarkdownToEditor } from './utils';\nimport { EditorTheme } from './themes/EditorTheme';\nimport { LocaleContext, mergeLocale } from './LocaleContext';\nimport './IMComposer.css';\n\n// Internal component that has access to the editor context\ninterface EditorInnerProps extends Omit<IMComposerProps, 'mode' | 'defaultMode'> {\n mode: ComposerMode;\n attachments: Attachment[];\n onFilePaste: (files: File[]) => void;\n onRemoveAttachment: (id: string) => void;\n isUploading: boolean;\n onUploadStart: () => void;\n onUploadEnd: () => void;\n editorRef: React.MutableRefObject<LexicalEditor | null>;\n}\n\nfunction EditorInner({\n mode,\n onSend,\n enableMention = true,\n mentionProvider,\n maxMentions,\n renderMentionItem,\n enableAttachments = true,\n showAttachmentPreview = true,\n attachmentPreviewPlacement = 'bottom',\n attachments,\n onFilePaste,\n onRemoveAttachment,\n markdownOptions,\n uploadImage,\n keymap,\n placeholder,\n disabled,\n isUploading,\n onUploadStart,\n onUploadEnd,\n editorRef,\n onQuoteRemoved,\n onChange,\n className,\n ...restProps\n}: EditorInnerProps) {\n const [editor] = useLexicalComposerContext();\n\n // Store editor reference\n editorRef.current = editor;\n\n // Register update listener for onChange callback\n useEffect(() => {\n if (!onChange) return;\n return editor.registerUpdateListener(({ editorState, dirtyElements, dirtyLeaves }) => {\n // Only fire if there are actual content changes\n if (dirtyElements.size > 0 || dirtyLeaves.size > 0) {\n onChange();\n }\n });\n }, [editor, onChange]);\n\n const placeholderText = useMemo((): string => {\n if (typeof placeholder === 'string') return placeholder;\n if (typeof placeholder === 'object') {\n const text = mode === 'plain' ? placeholder.plain : placeholder.rich;\n if (text) return text;\n }\n return mode === 'plain' ? 'Type a message...' : 'Type with Markdown...';\n }, [placeholder, mode]);\n\n const canSend = useCallback(() => {\n if (disabled || isUploading) return false;\n\n const isEmpty = isEditorEmpty(editor);\n\n // Allow send if there are attachments (plain mode only)\n if (mode === 'plain' && attachments.length > 0) {\n return true;\n }\n\n return !isEmpty;\n }, [editor, disabled, isUploading, mode, attachments.length]);\n\n const handleSend = useCallback(() => {\n if (!canSend()) return;\n\n if (mode === 'plain') {\n const payload = exportPlainPayload(editor, attachments);\n onSend?.(payload);\n } else {\n const payload = exportMarkdownPayload(editor);\n onSend?.(payload);\n }\n }, [editor, mode, attachments, onSend, canSend]);\n\n const handleError = useCallback((error: Error) => {\n console.error('IMComposer error:', error);\n }, []);\n\n // Merge internal and custom classNames\n const mergedClassName = [\n 'im-composer',\n `im-composer-${mode}`,\n disabled ? 'im-composer-disabled' : '',\n className,\n ].filter(Boolean).join(' ');\n\n return (\n <div\n className={mergedClassName}\n {...restProps}\n >\n {mode === 'rich' && (\n <ToolbarPlugin\n uploadImage={uploadImage}\n enabledSyntax={markdownOptions?.enabledSyntax}\n onUploadStart={onUploadStart}\n onUploadEnd={onUploadEnd}\n onError={handleError}\n />\n )}\n\n {mode === 'plain' && attachmentPreviewPlacement === 'top' && enableAttachments && showAttachmentPreview && (\n <AttachmentPreviewBar\n attachments={attachments}\n onRemove={onRemoveAttachment}\n placement=\"top\"\n />\n )}\n\n <div className=\"im-composer-editor-container\">\n <RichTextPlugin\n contentEditable={\n <ContentEditable\n className=\"im-composer-editor\"\n aria-placeholder={placeholderText}\n placeholder={<div className=\"im-composer-placeholder\">{placeholderText}</div>}\n />\n }\n ErrorBoundary={LexicalErrorBoundary}\n />\n <HistoryPlugin />\n <ListPlugin />\n <LinkPlugin />\n\n {mode === 'plain' && (\n <>\n <MentionPlugin\n mentionProvider={mentionProvider}\n enabled={enableMention}\n maxMentions={maxMentions}\n renderMentionItem={renderMentionItem}\n />\n <PlainTextPastePlugin\n onFilePaste={enableAttachments ? onFilePaste : undefined}\n />\n <DeletionPlugin />\n <QuoteRemovalListenerPlugin onQuoteRemoved={onQuoteRemoved} />\n </>\n )}\n\n {mode === 'rich' && (\n <>\n <MarkdownShortcutPlugin transformers={TRANSFORMERS} />\n <RichTextPastePlugin\n uploadImage={uploadImage}\n onUploadStart={onUploadStart}\n onUploadEnd={onUploadEnd}\n onError={handleError}\n />\n <LinkShortcutPlugin />\n <LinkEditPlugin />\n <DeletionPlugin />\n </>\n )}\n\n <KeymapPlugin\n sendKey={keymap?.send}\n onSend={handleSend}\n canSend={canSend}\n disabled={disabled}\n />\n </div>\n\n {mode === 'plain' && attachmentPreviewPlacement === 'bottom' && enableAttachments && showAttachmentPreview && (\n <AttachmentPreviewBar\n attachments={attachments}\n onRemove={onRemoveAttachment}\n placement=\"bottom\"\n />\n )}\n\n {isUploading && (\n <div className=\"im-composer-uploading\">Uploading...</div>\n )}\n </div>\n );\n}\n\nexport const IMComposer = forwardRef<IMComposerRef, IMComposerProps>(\n function IMComposer(props, ref) {\n const {\n mode: controlledMode,\n defaultMode = 'plain',\n maxAttachments,\n maxFileSize,\n allowedMimeTypes,\n onAttachmentLimitExceeded,\n onFilesChange,\n ...restProps\n } = props;\n\n const [uncontrolledMode, setUncontrolledMode] = useState<ComposerMode>(defaultMode);\n const mode = controlledMode ?? uncontrolledMode;\n\n const editorRef = useRef<LexicalEditor | null>(null);\n const [uploadCount, setUploadCount] = useState(0);\n\n const {\n attachments,\n addFiles,\n removeAttachment,\n clearAttachments,\n setAttachments,\n } = useAttachments({\n maxAttachments,\n maxFileSize,\n allowedMimeTypes,\n onLimitExceeded: onAttachmentLimitExceeded,\n });\n\n const handleUploadStart = useCallback(() => {\n setUploadCount((c) => c + 1);\n }, []);\n\n const handleUploadEnd = useCallback(() => {\n setUploadCount((c) => c - 1);\n }, []);\n\n // Notify parent when attachments change\n useEffect(() => {\n onFilesChange?.(attachments);\n }, [attachments, onFilesChange]);\n\n // Lexical configuration\n const initialConfig = useMemo(\n () => ({\n namespace: 'IMComposer',\n theme: EditorTheme,\n nodes: [\n ImageNode,\n EmojiNode,\n MentionNode,\n HeadingNode,\n MarkdownQuoteNode,\n QuoteNode,\n ListNode,\n ListItemNode,\n CodeNode,\n LinkNode,\n AutoLinkNode,\n ],\n onError: (error: Error) => {\n console.error('Lexical error:', error);\n },\n editable: !props.disabled,\n }),\n [props.disabled]\n );\n\n // Expose ref methods\n useImperativeHandle(\n ref,\n () => ({\n focus: () => {\n editorRef.current?.focus();\n },\n clear: () => {\n if (editorRef.current) {\n clearEditor(editorRef.current);\n }\n clearAttachments();\n },\n exportPayload: () => {\n if (!editorRef.current) return null;\n if (mode === 'plain') {\n return exportPlainPayload(editorRef.current, attachments);\n } else {\n return exportMarkdownPayload(editorRef.current);\n }\n },\n importMarkdown: (markdown: string) => {\n if (editorRef.current && mode === 'rich') {\n importMarkdownToEditor(editorRef.current, markdown);\n }\n },\n getAttachments: () => attachments,\n setAttachments,\n insertQuote: (title: string, content: string) => {\n if (editorRef.current && mode === 'plain') {\n editorRef.current.update(() => {\n const root = $getRoot();\n const newQuoteNode = $createQuoteNode(title, content);\n\n // Find existing quote and replace it (not remove+insert)\n const children = root.getChildren();\n let existingQuote: LexicalNode | null = null;\n for (const child of children) {\n if ($isQuoteNode(child)) {\n existingQuote = child;\n break;\n }\n }\n\n if (existingQuote) {\n // Replace existing quote (won't trigger 'destroyed' mutation)\n existingQuote.replace(newQuoteNode);\n } else {\n // Insert new quote at start\n const firstChild = root.getFirstChild();\n if (firstChild) {\n firstChild.insertBefore(newQuoteNode);\n } else {\n root.append(newQuoteNode);\n }\n }\n });\n }\n },\n addFiles,\n removeAttachment,\n clearAttachments,\n insertMention: (userId: string, display: string) => {\n if (editorRef.current && mode === 'plain') {\n editorRef.current.update(() => {\n const selection = $getSelection();\n if ($isRangeSelection(selection)) {\n const mentionNode = $createMentionNode(userId, display);\n selection.insertNodes([mentionNode]);\n }\n });\n }\n },\n getDraft: () => {\n let editorState = '';\n let text = '';\n if (editorRef.current) {\n editorRef.current.getEditorState().read(() => {\n text = $getRoot().getTextContent().trim();\n });\n // Only save editor state if there's actual content\n if (text) {\n editorState = JSON.stringify(editorRef.current.getEditorState().toJSON());\n }\n }\n return {\n editorState,\n text,\n attachments: attachments.map(a => ({\n ...a,\n file: a.file, // Note: File objects can't be serialized to JSON\n })),\n };\n },\n setDraft: (draft: { editorState: string; attachments?: Attachment[] }) => {\n if (editorRef.current && draft.editorState) {\n try {\n const parsedState = editorRef.current.parseEditorState(draft.editorState);\n editorRef.current.setEditorState(parsedState);\n } catch (e) {\n console.error('Failed to restore editor state:', e);\n }\n }\n if (draft.attachments) {\n setAttachments(draft.attachments);\n }\n },\n setText: (text: string, mentions?: Member[]) => {\n const editor = editorRef.current;\n if (!editor) return;\n\n editor.update(() => {\n const root = $getRoot();\n root.clear();\n const paragraph = $createParagraphNode();\n\n if (!text) {\n root.append(paragraph);\n return;\n }\n\n if (!mentions || mentions.length === 0) {\n paragraph.append($createTextNode(text));\n root.append(paragraph);\n return;\n }\n\n const pattern = /@(\\S+?)\\b/g;\n let lastIndex = 0;\n let match;\n\n while ((match = pattern.exec(text)) !== null) {\n const [fullMatch, userId] = match;\n const matchIndex = match.index;\n\n if (matchIndex > lastIndex) {\n paragraph.append($createTextNode(text.slice(lastIndex, matchIndex)));\n }\n\n const member = mentions.find((m) => m.userId === userId);\n\n if (member) {\n const mentionNode = $createMentionNode(member.userId, member.display);\n paragraph.append(mentionNode);\n } else {\n paragraph.append($createTextNode(fullMatch));\n }\n\n lastIndex = matchIndex + fullMatch.length;\n }\n\n if (lastIndex < text.length) {\n paragraph.append($createTextNode(text.slice(lastIndex)));\n }\n\n root.append(paragraph);\n });\n },\n insertText: (text: string) => {\n const editor = editorRef.current;\n if (!editor) return;\n\n editor.update(() => {\n const selection = $getSelection();\n if ($isRangeSelection(selection)) {\n selection.insertText(text);\n } else {\n // If no selection, append to end\n const root = $getRoot();\n const lastChild = root.getLastChild();\n if (lastChild) {\n lastChild.selectEnd();\n const newSelection = $getSelection();\n if ($isRangeSelection(newSelection)) {\n newSelection.insertText(text);\n }\n }\n }\n });\n },\n }),\n [mode, attachments, clearAttachments, setAttachments, addFiles, removeAttachment]\n );\n\n const mergedLocale = useMemo(() => mergeLocale(restProps.locale), [restProps.locale]);\n\n return (\n <LocaleContext.Provider value={mergedLocale}>\n <LexicalComposer initialConfig={initialConfig}>\n <EditorInner\n {...restProps}\n mode={mode}\n attachments={attachments}\n onFilePaste={addFiles}\n onRemoveAttachment={removeAttachment}\n isUploading={uploadCount > 0}\n onUploadStart={handleUploadStart}\n onUploadEnd={handleUploadEnd}\n editorRef={editorRef}\n />\n </LexicalComposer>\n </LocaleContext.Provider>\n );\n }\n);\n","import {\n DecoratorNode,\n DOMConversionMap,\n DOMExportOutput,\n EditorConfig,\n LexicalNode,\n NodeKey,\n SerializedLexicalNode,\n Spread,\n} from 'lexical';\nimport { ReactNode } from 'react';\n\nexport type SerializedMentionNode = Spread<\n {\n userId: string;\n display: string;\n },\n SerializedLexicalNode\n>;\n\nexport class MentionNode extends DecoratorNode<ReactNode> {\n __userId: string;\n __display: string;\n\n static getType(): string {\n return 'mention';\n }\n\n static clone(node: MentionNode): MentionNode {\n return new MentionNode(node.__userId, node.__display, node.__key);\n }\n\n constructor(userId: string, display: string, key?: NodeKey) {\n super(key);\n this.__userId = userId;\n this.__display = display;\n }\n\n createDOM(config: EditorConfig): HTMLElement {\n const span = document.createElement('span');\n span.className = 'im-composer-mention';\n span.setAttribute('data-user-id', this.__userId);\n span.setAttribute('data-lexical-mention', 'true');\n span.textContent = `@${this.__display}`;\n return span;\n }\n\n updateDOM(): boolean {\n return false;\n }\n\n exportDOM(): DOMExportOutput {\n const span = document.createElement('span');\n span.className = 'im-composer-mention';\n span.setAttribute('data-user-id', this.__userId);\n span.textContent = `@${this.__display}`;\n return { element: span };\n }\n\n static importDOM(): DOMConversionMap | null {\n return null;\n }\n\n static importJSON(serializedNode: SerializedMentionNode): MentionNode {\n return new MentionNode(serializedNode.userId, serializedNode.display);\n }\n\n exportJSON(): SerializedMentionNode {\n return {\n type: 'mention',\n version: 1,\n userId: this.__userId,\n display: this.__display,\n };\n }\n\n getUserId(): string {\n return this.__userId;\n }\n\n getDisplay(): string {\n return this.__display;\n }\n\n getTextContent(): string {\n return `@${this.__userId} `;\n }\n\n isIsolated(): boolean {\n return true;\n }\n\n isInline(): boolean {\n return true;\n }\n\n canInsertTextBefore(): boolean {\n return false;\n }\n\n canInsertTextAfter(): boolean {\n return false;\n }\n\n decorate(): ReactNode {\n return null; // Text content is rendered via createDOM\n }\n}\n\nexport function $createMentionNode(userId: string, display: string): MentionNode {\n return new MentionNode(userId, display);\n}\n\nexport function $isMentionNode(node: LexicalNode | null | undefined): node is MentionNode {\n return node instanceof MentionNode;\n}\n","import {\n DecoratorNode,\n DOMConversionMap,\n DOMExportOutput,\n EditorConfig,\n LexicalEditor,\n LexicalNode,\n NodeKey,\n SerializedLexicalNode,\n Spread,\n $getNodeByKey,\n} from 'lexical';\nimport { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext';\nimport { useLexicalNodeSelection } from '@lexical/react/useLexicalNodeSelection';\nimport { mergeRegister } from '@lexical/utils';\nimport {\n $getSelection,\n $isNodeSelection,\n CLICK_COMMAND,\n COMMAND_PRIORITY_LOW,\n KEY_BACKSPACE_COMMAND,\n KEY_DELETE_COMMAND,\n} from 'lexical';\nimport { ReactNode, useCallback, useEffect, useRef } from 'react';\n\nexport type SerializedImageNode = Spread<\n {\n src: string;\n alt: string;\n width?: number;\n height?: number;\n },\n SerializedLexicalNode\n>;\n\nfunction ImageComponent({\n src,\n alt,\n width,\n height,\n nodeKey,\n}: {\n src: string;\n alt: string;\n width?: number;\n height?: number;\n nodeKey: NodeKey;\n}) {\n const [editor] = useLexicalComposerContext();\n const imageRef = useRef<HTMLImageElement>(null);\n const [isSelected, setSelected, clearSelection] = useLexicalNodeSelection(nodeKey);\n\n const onDelete = useCallback(\n (event: KeyboardEvent) => {\n if (isSelected && $isNodeSelection($getSelection())) {\n event.preventDefault();\n editor.update(() => {\n const node = $getNodeByKey(nodeKey);\n if (node) {\n node.remove();\n }\n });\n return true;\n }\n return false;\n },\n [editor, isSelected, nodeKey]\n );\n\n useEffect(() => {\n return mergeRegister(\n editor.registerCommand(\n CLICK_COMMAND,\n (event: MouseEvent) => {\n if (imageRef.current && imageRef.current.contains(event.target as Node)) {\n if (!event.shiftKey) {\n clearSelection();\n }\n setSelected(true);\n return true;\n }\n return false;\n },\n COMMAND_PRIORITY_LOW\n ),\n editor.registerCommand(\n KEY_DELETE_COMMAND,\n onDelete,\n COMMAND_PRIORITY_LOW\n ),\n editor.registerCommand(\n KEY_BACKSPACE_COMMAND,\n onDelete,\n COMMAND_PRIORITY_LOW\n )\n );\n }, [editor, clearSelection, setSelected, onDelete]);\n\n return (\n <div className={`im-composer-image-wrapper ${isSelected ? 'selected' : ''}`}>\n <img\n ref={imageRef}\n src={src}\n alt={alt || ''}\n width={width}\n height={height}\n className=\"im-composer-image\"\n draggable={false}\n />\n </div>\n );\n}\n\nexport class ImageNode extends DecoratorNode<ReactNode> {\n __src: string;\n __alt: string;\n __width?: number;\n __height?: number;\n\n static getType(): string {\n return 'image';\n }\n\n static clone(node: ImageNode): ImageNode {\n return new ImageNode(node.__src, node.__alt, node.__width, node.__height, node.__key);\n }\n\n constructor(src: string, alt: string, width?: number, height?: number, key?: NodeKey) {\n super(key);\n this.__src = src;\n this.__alt = alt;\n this.__width = width;\n this.__height = height;\n }\n\n createDOM(config: EditorConfig): HTMLElement {\n const div = document.createElement('div');\n div.className = 'im-composer-image-container';\n return div;\n }\n\n updateDOM(): boolean {\n return false;\n }\n\n exportDOM(editor: LexicalEditor): DOMExportOutput {\n const img = document.createElement('img');\n img.src = this.__src;\n img.alt = this.__alt || '';\n if (this.__width) img.width = this.__width;\n if (this.__height) img.height = this.__height;\n return { element: img };\n }\n\n static importDOM(): DOMConversionMap | null {\n return {\n img: () => ({\n conversion: (element: HTMLElement) => {\n const img = element as HTMLImageElement;\n const src = img.src;\n const alt = img.alt || '';\n return { node: new ImageNode(src, alt, img.width, img.height) };\n },\n priority: 0,\n }),\n };\n }\n\n static importJSON(serializedNode: SerializedImageNode): ImageNode {\n return new ImageNode(\n serializedNode.src,\n serializedNode.alt,\n serializedNode.width,\n serializedNode.height\n );\n }\n\n exportJSON(): SerializedImageNode {\n return {\n type: 'image',\n version: 1,\n src: this.__src,\n alt: this.__alt,\n width: this.__width,\n height: this.__height,\n };\n }\n\n getSrc(): string {\n return this.__src;\n }\n\n getAlt(): string {\n return this.__alt;\n }\n\n getTextContent(): string {\n return '';\n }\n\n isInline(): boolean {\n return false;\n }\n\n decorate(): ReactNode {\n return (\n <ImageComponent\n src={this.__src}\n alt={this.__alt}\n width={this.__width}\n height={this.__height}\n nodeKey={this.__key}\n />\n );\n }\n}\n\nexport function $createImageNode(\n src: string,\n alt: string = '',\n width?: number,\n height?: number\n): ImageNode {\n return new ImageNode(src, alt, width, height);\n}\n\nexport function $isImageNode(node: LexicalNode | null | undefined): node is ImageNode {\n return node instanceof ImageNode;\n}\n","import {\n DecoratorNode,\n DOMConversionMap,\n DOMExportOutput,\n EditorConfig,\n LexicalNode,\n NodeKey,\n SerializedLexicalNode,\n Spread,\n $applyNodeReplacement,\n} from 'lexical';\nimport { ReactNode } from 'react';\n\nexport type SerializedEmojiNode = Spread<\n {\n emoji: string;\n },\n SerializedLexicalNode\n>;\n\n/**\n * Get Twemoji URL for an emoji\n */\nfunction getEmojiUrl(emoji: string): string {\n const codePoints = [...emoji]\n .map((char) => {\n const cp = char.codePointAt(0);\n // Skip variation selectors\n if (cp === 0xfe0f) return null;\n return cp?.toString(16);\n })\n .filter(Boolean)\n .join('-');\n\n return `https://cdn.jsdelivr.net/gh/twitter/twemoji@14.0.2/assets/72x72/${codePoints}.png`;\n}\n\nexport class EmojiNode extends DecoratorNode<ReactNode> {\n __emoji: string;\n\n static getType(): string {\n return 'emoji';\n }\n\n static clone(node: EmojiNode): EmojiNode {\n return new EmojiNode(node.__emoji, node.__key);\n }\n\n constructor(emoji: string, key?: NodeKey) {\n super(key);\n this.__emoji = emoji;\n }\n\n createDOM(config: EditorConfig): HTMLElement {\n const span = document.createElement('span');\n span.className = 'im-composer-emoji';\n\n const img = document.createElement('img');\n img.src = getEmojiUrl(this.__emoji);\n img.alt = this.__emoji;\n img.className = 'im-composer-emoji-img';\n img.draggable = false;\n img.setAttribute('data-emoji', this.__emoji);\n\n span.appendChild(img);\n return span;\n }\n\n updateDOM(): boolean {\n return false;\n }\n\n exportDOM(): DOMExportOutput {\n // Export as just the emoji text for clipboard\n const span = document.createElement('span');\n span.textContent = this.__emoji;\n return { element: span };\n }\n\n static importDOM(): DOMConversionMap | null {\n return {\n img: (node: HTMLElement) => {\n const img = node as HTMLImageElement;\n const emoji = img.getAttribute('data-emoji');\n if (emoji) {\n return {\n conversion: () => ({ node: new EmojiNode(emoji) }),\n priority: 1,\n };\n }\n return null;\n },\n };\n }\n\n static importJSON(serializedNode: SerializedEmojiNode): EmojiNode {\n return new EmojiNode(serializedNode.emoji);\n }\n\n exportJSON(): SerializedEmojiNode {\n return {\n type: 'emoji',\n version: 1,\n emoji: this.__emoji,\n };\n }\n\n getEmoji(): string {\n return this.__emoji;\n }\n\n getTextContent(): string {\n // Return the original unicode emoji for text operations\n return this.__emoji;\n }\n\n isIsolated(): boolean {\n return true;\n }\n\n isInline(): boolean {\n return true;\n }\n\n canInsertTextBefore(): boolean {\n return true;\n }\n\n canInsertTextAfter(): boolean {\n return true;\n }\n\n decorate(): ReactNode {\n return null; // Rendered via createDOM\n }\n}\n\nexport function $createEmojiNode(emoji: string): EmojiNode {\n return $applyNodeReplacement(new EmojiNode(emoji));\n}\n\nexport function $isEmojiNode(node: LexicalNode | null | undefined): node is EmojiNode {\n return node instanceof EmojiNode;\n}\n","import {\n DecoratorNode,\n DOMConversionMap,\n DOMExportOutput,\n EditorConfig,\n LexicalNode,\n NodeKey,\n SerializedLexicalNode,\n Spread,\n $applyNodeReplacement,\n $getNodeByKey,\n} from 'lexical';\nimport { ReactNode } from 'react';\nimport { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext';\n\nexport type SerializedQuoteNode = Spread<\n {\n title: string;\n content: string;\n },\n SerializedLexicalNode\n>;\n\nfunction QuoteMessageComponent({ title, content, nodeKey }: { title: string; content: string; nodeKey: NodeKey }) {\n const [editor] = useLexicalComposerContext();\n\n const handleDelete = (e: React.MouseEvent) => {\n e.preventDefault();\n e.stopPropagation();\n editor.update(() => {\n const node = $getNodeByKey(nodeKey);\n node?.remove();\n });\n };\n\n return (\n <div className=\"im-composer-quote\">\n <span className=\"im-composer-quote-text\">\n <span className=\"im-composer-quote-title\">{title}</span>\n <span className=\"im-composer-quote-content\">{content}</span>\n </span>\n <button className=\"im-composer-quote-close\" onClick={handleDelete}>\n ×\n </button>\n </div>\n );\n}\n\nexport class QuoteNode extends DecoratorNode<ReactNode> {\n __title: string;\n __content: string;\n\n static getType(): string {\n return 'quote-message';\n }\n\n static clone(node: QuoteNode): QuoteNode {\n return new QuoteNode(node.__title, node.__content, node.__key);\n }\n\n constructor(title: string, content: string, key?: NodeKey) {\n super(key);\n this.__title = title;\n this.__content = content;\n }\n\n createDOM(config: EditorConfig): HTMLElement {\n const div = document.createElement('div');\n div.className = 'im-composer-quote-wrapper';\n div.contentEditable = 'false';\n return div;\n }\n\n updateDOM(): boolean {\n return false;\n }\n\n exportDOM(): DOMExportOutput {\n const element = document.createElement('blockquote');\n element.setAttribute('data-title', this.__title);\n element.textContent = this.__content;\n return { element };\n }\n\n static importDOM(): DOMConversionMap | null {\n return {\n blockquote: () => ({\n conversion: (element: HTMLElement) => {\n const title = element.getAttribute('data-title') || '';\n const content = element.textContent || '';\n return { node: new QuoteNode(title, content) };\n },\n priority: 0,\n }),\n };\n }\n\n static importJSON(serializedNode: SerializedQuoteNode): QuoteNode {\n return new QuoteNode(serializedNode.title, serializedNode.content);\n }\n\n exportJSON(): SerializedQuoteNode {\n return {\n type: 'quote-message',\n version: 1,\n title: this.__title,\n content: this.__content,\n };\n }\n\n getTitle(): string {\n return this.__title;\n }\n\n getContent(): string {\n return this.__content;\n }\n\n getTextContent(): string {\n return '';\n }\n\n isIsolated(): boolean {\n return true;\n }\n\n isInline(): boolean {\n return false;\n }\n\n decorate(): ReactNode {\n return (\n <QuoteMessageComponent\n title={this.__title}\n content={this.__content}\n nodeKey={this.__key}\n />\n );\n }\n}\n\nexport function $createQuoteNode(title: string, content: string): QuoteNode {\n return $applyNodeReplacement(new QuoteNode(title, content));\n}\n\nexport function $isQuoteNode(node: LexicalNode | null | undefined): node is QuoteNode {\n return node instanceof QuoteNode;\n}\n","import { useEffect, useCallback, useState, useRef } from 'react';\nimport { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext';\nimport {\n $getSelection,\n $isRangeSelection,\n COMMAND_PRIORITY_LOW,\n COMMAND_PRIORITY_CRITICAL,\n KEY_ARROW_DOWN_COMMAND,\n KEY_ARROW_UP_COMMAND,\n KEY_ENTER_COMMAND,\n KEY_ESCAPE_COMMAND,\n TextNode,\n $createTextNode,\n $getRoot,\n} from 'lexical';\nimport { $createMentionNode, $isMentionNode } from '../nodes/MentionNode';\nimport type { Member } from '../types';\n\nexport interface MentionPluginProps {\n mentionProvider?: (query: string) => Promise<Member[]>;\n enabled?: boolean;\n maxMentions?: number;\n /** Custom render function for mention list items */\n renderMentionItem?: (props: { member: Member; isSelected: boolean }) => React.ReactNode;\n}\n\ninterface MentionMatch {\n leadOffset: number;\n matchingString: string;\n replaceableString: string;\n}\n\nexport function MentionPlugin({ mentionProvider, enabled = true, maxMentions, renderMentionItem }: MentionPluginProps) {\n const [editor] = useLexicalComposerContext();\n const [isOpen, setIsOpen] = useState(false);\n const [members, setMembers] = useState<Member[]>([]);\n const [selectedIndex, setSelectedIndex] = useState(0);\n const [matchInfo, setMatchInfo] = useState<MentionMatch | null>(null);\n const [cursorBottom, setCursorBottom] = useState(0);\n const [menuLeft, setMenuLeft] = useState(0);\n const isComposingRef = useRef(false);\n const menuRef = useRef<HTMLDivElement>(null);\n const itemRefs = useRef<Map<number, HTMLDivElement>>(new Map());\n\n // Check for @ trigger\n const checkForMention = useCallback(() => {\n if (!enabled || isComposingRef.current) {\n setIsOpen(false);\n return;\n }\n\n editor.getEditorState().read(() => {\n const selection = $getSelection();\n if (!$isRangeSelection(selection) || !selection.isCollapsed()) {\n setIsOpen(false);\n return;\n }\n\n // Check max mentions limit\n if (maxMentions !== undefined) {\n const root = $getRoot();\n let mentionCount = 0;\n const countMentions = (node: any) => {\n if ($isMentionNode(node)) {\n mentionCount++;\n }\n if (node.getChildren) {\n node.getChildren().forEach(countMentions);\n }\n };\n countMentions(root);\n if (mentionCount >= maxMentions) {\n setIsOpen(false);\n return;\n }\n }\n\n const anchor = selection.anchor;\n const anchorNode = anchor.getNode();\n\n if (!(anchorNode instanceof TextNode)) {\n setIsOpen(false);\n return;\n }\n\n const text = anchorNode.getTextContent();\n const offset = anchor.offset;\n\n // Find @ symbol before cursor\n let atIndex = -1;\n for (let i = offset - 1; i >= 0; i--) {\n const char = text[i];\n if (char === '@') {\n atIndex = i;\n break;\n }\n // Stop at whitespace or newline\n if (/\\s/.test(char)) {\n break;\n }\n }\n\n if (atIndex === -1) {\n setIsOpen(false);\n return;\n }\n\n const query = text.slice(atIndex + 1, offset);\n const replaceableString = text.slice(atIndex, offset);\n\n setMatchInfo({\n leadOffset: atIndex,\n matchingString: query,\n replaceableString,\n });\n\n // Store cursor position for menu placement (menu will appear above)\n const domSelection = window.getSelection();\n if (domSelection && domSelection.rangeCount > 0) {\n const range = domSelection.getRangeAt(0);\n const rect = range.getBoundingClientRect();\n setCursorBottom(window.innerHeight - rect.top + 4);\n setMenuLeft(rect.left);\n }\n\n // Fetch members\n if (mentionProvider) {\n mentionProvider(query).then((results) => {\n setMembers(results);\n setSelectedIndex(0);\n setIsOpen(results.length > 0);\n });\n }\n });\n }, [editor, enabled, mentionProvider, maxMentions]);\n\n // Track IME composition state\n useEffect(() => {\n const root = editor.getRootElement();\n if (!root) return;\n\n const handleCompositionStart = () => {\n isComposingRef.current = true;\n };\n\n const handleCompositionEnd = () => {\n isComposingRef.current = false;\n // Re-check for mention after IME input is confirmed\n setTimeout(() => {\n checkForMention();\n }, 0);\n };\n\n root.addEventListener('compositionstart', handleCompositionStart);\n root.addEventListener('compositionend', handleCompositionEnd);\n\n return () => {\n root.removeEventListener('compositionstart', handleCompositionStart);\n root.removeEventListener('compositionend', handleCompositionEnd);\n };\n }, [editor, checkForMention]);\n\n // Listen for text changes\n useEffect(() => {\n return editor.registerUpdateListener(({ dirtyLeaves }) => {\n if (dirtyLeaves.size > 0) {\n checkForMention();\n }\n });\n }, [editor, checkForMention]);\n\n // Insert mention\n const insertMention = useCallback(\n (member: Member) => {\n if (!matchInfo) return;\n\n editor.update(() => {\n const selection = $getSelection();\n if (!$isRangeSelection(selection)) return;\n\n const anchor = selection.anchor;\n const anchorNode = anchor.getNode();\n\n if (!(anchorNode instanceof TextNode)) return;\n\n const text = anchorNode.getTextContent();\n const beforeAt = text.slice(0, matchInfo.leadOffset);\n const afterQuery = text.slice(matchInfo.leadOffset + matchInfo.replaceableString.length);\n\n // Create new structure\n const mentionNode = $createMentionNode(member.userId, member.display);\n\n if (beforeAt) {\n const beforeNode = $createTextNode(beforeAt);\n anchorNode.replace(beforeNode);\n beforeNode.insertAfter(mentionNode);\n } else {\n anchorNode.replace(mentionNode);\n }\n\n if (afterQuery) {\n const afterNode = $createTextNode(afterQuery);\n mentionNode.insertAfter(afterNode);\n afterNode.selectStart();\n } else {\n mentionNode.selectNext();\n }\n });\n\n setIsOpen(false);\n setMatchInfo(null);\n },\n [editor, matchInfo]\n );\n\n // Keyboard navigation with wrap-around\n useEffect(() => {\n if (!isOpen) return;\n\n const removeArrowDown = editor.registerCommand(\n KEY_ARROW_DOWN_COMMAND,\n (event) => {\n event.preventDefault();\n setSelectedIndex((i) => (i + 1) % members.length);\n return true;\n },\n COMMAND_PRIORITY_LOW\n );\n\n const removeArrowUp = editor.registerCommand(\n KEY_ARROW_UP_COMMAND,\n (event) => {\n event.preventDefault();\n setSelectedIndex((i) => (i - 1 + members.length) % members.length);\n return true;\n },\n COMMAND_PRIORITY_LOW\n );\n\n const removeEnter = editor.registerCommand(\n KEY_ENTER_COMMAND,\n (event) => {\n if (members[selectedIndex]) {\n event?.preventDefault();\n insertMention(members[selectedIndex]);\n return true;\n }\n return false;\n },\n COMMAND_PRIORITY_CRITICAL\n );\n\n const removeEscape = editor.registerCommand(\n KEY_ESCAPE_COMMAND,\n () => {\n setIsOpen(false);\n return true;\n },\n COMMAND_PRIORITY_LOW\n );\n\n return () => {\n removeArrowDown();\n removeArrowUp();\n removeEnter();\n removeEscape();\n };\n }, [editor, isOpen, members, selectedIndex, insertMention]);\n\n // Auto-scroll selected item into view\n useEffect(() => {\n if (isOpen && itemRefs.current.has(selectedIndex)) {\n const item = itemRefs.current.get(selectedIndex);\n item?.scrollIntoView({ block: 'nearest', behavior: 'smooth' });\n }\n }, [isOpen, selectedIndex]);\n\n if (!isOpen || members.length === 0) {\n return null;\n }\n\n return (\n <div\n ref={menuRef}\n className=\"im-composer-mention-menu\"\n style={{\n position: 'fixed',\n bottom: cursorBottom,\n left: menuLeft,\n }}\n >\n {members.map((member, index) => (\n <div\n key={member.userId}\n ref={(el) => {\n if (el) {\n itemRefs.current.set(index, el);\n } else {\n itemRefs.current.delete(index);\n }\n }}\n className={`im-composer-mention-item ${index === selectedIndex ? 'selected' : ''}`}\n onClick={() => insertMention(member)}\n onMouseEnter={() => setSelectedIndex(index)}\n >\n {renderMentionItem ? (\n renderMentionItem({ member, isSelected: index === selectedIndex })\n ) : (\n <>\n {member.avatarUrl && (\n <img\n src={member.avatarUrl}\n alt=\"\"\n className=\"im-composer-mention-avatar\"\n />\n )}\n <span className=\"im-composer-mention-name\">{member.display}</span>\n </>\n )}\n </div>\n ))}\n </div>\n );\n}\n","import { useEffect, useRef } from 'react';\nimport { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext';\nimport {\n $getSelection,\n $isRangeSelection,\n COMMAND_PRIORITY_HIGH,\n PASTE_COMMAND,\n $createParagraphNode,\n $createTextNode,\n} from 'lexical';\n\nexport interface PlainTextPastePluginProps {\n onFilePaste?: (files: File[]) => void;\n}\n\nexport function PlainTextPastePlugin({ onFilePaste }: PlainTextPastePluginProps) {\n const [editor] = useLexicalComposerContext();\n const isComposingRef = useRef(false);\n\n // Track IME composition\n useEffect(() => {\n const root = editor.getRootElement();\n if (!root) return;\n\n const handleCompositionStart = () => {\n isComposingRef.current = true;\n };\n\n const handleCompositionEnd = () => {\n isComposingRef.current = false;\n };\n\n root.addEventListener('compositionstart', handleCompositionStart);\n root.addEventListener('compositionend', handleCompositionEnd);\n\n return () => {\n root.removeEventListener('compositionstart', handleCompositionStart);\n root.removeEventListener('compositionend', handleCompositionEnd);\n };\n }, [editor]);\n\n useEffect(() => {\n return editor.registerCommand(\n PASTE_COMMAND,\n (event: ClipboardEvent) => {\n // Don't handle during IME composition\n if (isComposingRef.current) {\n return false;\n }\n\n const clipboardData = event.clipboardData;\n if (!clipboardData) return false;\n\n // Handle file paste\n if (clipboardData.files && clipboardData.files.length > 0) {\n event.preventDefault();\n const files = Array.from(clipboardData.files);\n onFilePaste?.(files);\n return true;\n }\n\n // Force plain text paste\n const text = clipboardData.getData('text/plain');\n if (text) {\n event.preventDefault();\n\n editor.update(() => {\n const selection = $getSelection();\n if (!$isRangeSelection(selection)) return;\n\n // Split by newlines and insert appropriately\n const lines = text.split(/\\r?\\n/);\n\n if (lines.length === 1) {\n // Single line - just insert text\n selection.insertText(lines[0]);\n } else {\n // Multiple lines - insert with paragraph breaks\n lines.forEach((line, index) => {\n if (index > 0) {\n // Insert new paragraph for subsequent lines\n const paragraph = $createParagraphNode();\n const textNode = $createTextNode(line);\n paragraph.append(textNode);\n\n const currentSelection = $getSelection();\n if ($isRangeSelection(currentSelection)) {\n currentSelection.insertParagraph();\n if (line) {\n currentSelection.insertText(line);\n }\n }\n } else {\n selection.insertText(line);\n }\n });\n }\n });\n\n return true;\n }\n\n return false;\n },\n COMMAND_PRIORITY_HIGH\n );\n }, [editor, onFilePaste]);\n\n return null;\n}\n","import { useEffect, useRef } from 'react';\nimport { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext';\nimport { COMMAND_PRIORITY_HIGH, PASTE_COMMAND } from 'lexical';\nimport type { UploadImageFn } from '../types';\nimport { isImageFile } from '../utils';\nimport { useImageUpload } from '../hooks/useImageUpload';\n\nexport interface RichTextPastePluginProps {\n uploadImage?: UploadImageFn;\n onUploadStart?: () => void;\n onUploadEnd?: () => void;\n onError?: (error: Error) => void;\n}\n\nexport function RichTextPastePlugin({\n uploadImage,\n onUploadStart,\n onUploadEnd,\n onError,\n}: RichTextPastePluginProps) {\n const [editor] = useLexicalComposerContext();\n const isComposingRef = useRef(false);\n\n // Use image upload hook\n const { uploadAndInsert } = useImageUpload({\n uploadImage,\n onUploadStart,\n onUploadEnd,\n onError,\n });\n\n // Track IME composition\n useEffect(() => {\n const root = editor.getRootElement();\n if (!root) return;\n\n const handleCompositionStart = () => {\n isComposingRef.current = true;\n };\n\n const handleCompositionEnd = () => {\n isComposingRef.current = false;\n };\n\n root.addEventListener('compositionstart', handleCompositionStart);\n root.addEventListener('compositionend', handleCompositionEnd);\n\n return () => {\n root.removeEventListener('compositionstart', handleCompositionStart);\n root.removeEventListener('compositionend', handleCompositionEnd);\n };\n }, [editor]);\n\n useEffect(() => {\n return editor.registerCommand(\n PASTE_COMMAND,\n (event: ClipboardEvent) => {\n // Don't handle during IME composition\n if (isComposingRef.current) {\n return false;\n }\n\n const clipboardData = event.clipboardData;\n if (!clipboardData) return false;\n\n // Handle image paste\n if (clipboardData.files && clipboardData.files.length > 0 && uploadImage) {\n const files = Array.from(clipboardData.files);\n const imageFiles = files.filter(isImageFile);\n\n if (imageFiles.length > 0) {\n event.preventDefault();\n\n // Upload each image file\n imageFiles.forEach(async (file) => {\n await uploadAndInsert(file, editor);\n });\n\n return true;\n }\n }\n\n // Let other paste handlers (HTML/text) handle it\n return false;\n },\n COMMAND_PRIORITY_HIGH\n );\n }, [editor, uploadImage, uploadAndInsert]);\n\n return null;\n}\n","/**\n * Generate a unique ID for attachments\n */\nexport function generateId(): string {\n return `${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;\n}\n\n/**\n * Format file size to human-readable string\n */\nexport function formatFileSize(bytes: number): string {\n if (bytes === 0) return '0 B';\n\n const units = ['B', 'KB', 'MB', 'GB', 'TB'];\n const k = 1024;\n const i = Math.floor(Math.log(bytes) / Math.log(k));\n\n return `${parseFloat((bytes / Math.pow(k, i)).toFixed(2))} ${units[i]}`;\n}\n\n/**\n * Check if a MIME type matches any pattern in the allowed list\n */\nexport function isMimeTypeAllowed(mime: string, allowedTypes?: string[]): boolean {\n if (!allowedTypes || allowedTypes.length === 0) {\n return true;\n }\n\n return allowedTypes.some((pattern) => {\n if (pattern.endsWith('/*')) {\n const prefix = pattern.slice(0, -1);\n return mime.startsWith(prefix);\n }\n return mime === pattern;\n });\n}\n\n/**\n * Check if a file is an image\n */\nexport function isImageFile(file: File): boolean {\n return file.type.startsWith('image/');\n}\n\n/**\n * Validate URL protocol\n */\nconst ALLOWED_PROTOCOLS = ['http:', 'https:', 'mailto:'];\n\nexport function isUrlProtocolAllowed(url: string): boolean {\n try {\n const parsed = new URL(url);\n return ALLOWED_PROTOCOLS.includes(parsed.protocol);\n } catch {\n return false;\n }\n}\n\n/**\n * Sanitize URL - ensure it uses allowed protocols\n */\nexport function sanitizeUrl(url: string): string | null {\n if (!url) return null;\n\n // If it doesn't have a protocol, assume https\n if (!url.includes('://') && !url.startsWith('mailto:')) {\n url = 'https://' + url;\n }\n\n if (isUrlProtocolAllowed(url)) {\n return url;\n }\n\n return null;\n}\n\n/**\n * Check if a URL is a safe image URL (https, blob, or data URLs)\n */\nexport function isSafeImageUrl(url: string): boolean {\n try {\n const parsed = new URL(url);\n // Allow https, blob (for local previews), and data URLs\n return parsed.protocol === 'https:' ||\n parsed.protocol === 'http:' ||\n parsed.protocol === 'blob:' ||\n parsed.protocol === 'data:';\n } catch {\n return false;\n }\n}\n\n/**\n * Escape characters for Markdown\n */\nexport function escapeMarkdown(text: string): string {\n return text.replace(/([*_`~\\[\\]()#>+\\-.!\\\\])/g, '\\\\$1');\n}\n\n/**\n * Check if text is only whitespace\n */\nexport function isOnlyWhitespace(text: string): boolean {\n return /^\\s*$/.test(text);\n}\n\n/**\n * Check if text contains only emoji\n */\nexport function isOnlyEmoji(text: string): boolean {\n const emojiRegex =\n /^[\\s\\u{1F600}-\\u{1F64F}\\u{1F300}-\\u{1F5FF}\\u{1F680}-\\u{1F6FF}\\u{1F1E0}-\\u{1F1FF}\\u{2600}-\\u{26FF}\\u{2700}-\\u{27BF}\\u{FE00}-\\u{FE0F}\\u{1F900}-\\u{1F9FF}\\u{1FA00}-\\u{1FA6F}\\u{1FA70}-\\u{1FAFF}\\u{231A}-\\u{231B}\\u{23E9}-\\u{23F3}\\u{23F8}-\\u{23FA}\\u{25AA}-\\u{25AB}\\u{25B6}\\u{25C0}\\u{25FB}-\\u{25FE}\\u{2614}-\\u{2615}\\u{2648}-\\u{2653}\\u{267F}\\u{2693}\\u{26A1}\\u{26AA}-\\u{26AB}\\u{26BD}-\\u{26BE}\\u{26C4}-\\u{26C5}\\u{26CE}\\u{26D4}\\u{26EA}\\u{26F2}-\\u{26F3}\\u{26F5}\\u{26FA}\\u{26FD}\\u{2702}\\u{2705}\\u{2708}-\\u{270D}\\u{270F}]+$/u;\n return emojiRegex.test(text.trim());\n}\n","import { $getRoot, LexicalEditor, $isElementNode, LexicalNode } from 'lexical';\nimport { $convertToMarkdownString, TRANSFORMERS, ElementTransformer } from '@lexical/markdown';\nimport { MentionNode, $isMentionNode } from '../nodes/MentionNode';\nimport { ImageNode, $isImageNode } from '../nodes/ImageNode';\nimport { QuoteNode, $isQuoteNode } from '../nodes/QuoteNode';\nimport type { PlainMessagePayload, MarkdownMessagePayload, MentionInfo, Attachment, QuoteInfo } from '../types';\n\n/**\n * Export plain text payload from editor\n */\nexport function exportPlainPayload(\n editor: LexicalEditor,\n attachments: Attachment[]\n): PlainMessagePayload {\n let plainText = '';\n const mentions: MentionInfo[] = [];\n\n let quote: QuoteInfo | undefined;\n\n editor.getEditorState().read(() => {\n const root = $getRoot();\n const children = root.getChildren();\n\n children.forEach((child) => {\n // Handle QuoteNode (extract and skip text)\n if ($isQuoteNode(child)) {\n quote = {\n title: child.getTitle(),\n content: child.getContent(),\n };\n return;\n }\n\n // For other blocks (Paragraphs, etc.), add newline separator if not first text\n if (plainText.length > 0) {\n plainText += '\\n';\n }\n\n const descendants = $isElementNode(child) ? child.getChildren() : [];\n\n descendants.forEach((node) => {\n if ($isMentionNode(node)) {\n const userId = node.getUserId();\n const display = node.getDisplay();\n const mentionText = `@${userId} `; // Use userId with trailing space for regex matching\n const start = plainText.length;\n const end = start + mentionText.length - 1; // Exclude trailing space from mention range\n\n mentions.push({\n userId,\n display,\n start,\n end,\n });\n\n plainText += mentionText;\n } else {\n plainText += node.getTextContent();\n }\n });\n });\n });\n\n return {\n type: 'text',\n plainText,\n mentions,\n attachments,\n quote,\n };\n}\n\n/**\n * Custom transformer for ImageNode to markdown\n */\nconst IMAGE_TRANSFORMER: ElementTransformer = {\n dependencies: [ImageNode],\n export: (node: unknown) => {\n if ($isImageNode(node as LexicalNode)) {\n const src = (node as ImageNode).getSrc();\n const alt = (node as ImageNode).getAlt();\n return ``;\n }\n return null;\n },\n type: 'element',\n regExp: /!\\[([^\\]]*)\\]\\(([^)]*)\\)/, // Dummy regex to satisfy type\n replace: () => { }, // Dummy replace to satisfy type\n};\n\n/**\n * Export markdown payload from editor\n */\nexport function exportMarkdownPayload(editor: LexicalEditor): MarkdownMessagePayload {\n let markdown = '';\n\n editor.getEditorState().read(() => {\n // Include custom image transformer\n const allTransformers = [...TRANSFORMERS, IMAGE_TRANSFORMER];\n markdown = $convertToMarkdownString(allTransformers);\n });\n\n return {\n type: 'markdown',\n markdown,\n };\n}\n","import { LexicalEditor, $getRoot, $createParagraphNode, $createTextNode } from 'lexical';\nimport { $convertFromMarkdownString, TRANSFORMERS } from '@lexical/markdown';\n\n/**\n * Import markdown string into the editor\n */\nexport function importMarkdownToEditor(editor: LexicalEditor, markdown: string): void {\n editor.update(() => {\n // Clear existing content\n const root = $getRoot();\n root.clear();\n\n // Convert markdown to Lexical nodes\n $convertFromMarkdownString(markdown, TRANSFORMERS);\n });\n}\n\n/**\n * Clear editor content\n */\nexport function clearEditor(editor: LexicalEditor): void {\n editor.update(() => {\n const root = $getRoot();\n root.clear();\n const paragraph = $createParagraphNode();\n root.append(paragraph);\n paragraph.select();\n });\n}\n\n/**\n * Check if editor is empty\n */\nexport function isEditorEmpty(editor: LexicalEditor): boolean {\n let isEmpty = true;\n\n editor.getEditorState().read(() => {\n const root = $getRoot();\n const textContent = root.getTextContent().trim();\n isEmpty = textContent.length === 0;\n });\n\n return isEmpty;\n}\n","import { useState, useCallback } from 'react';\nimport { LexicalEditor, $createParagraphNode } from 'lexical';\nimport { $insertNodes } from 'lexical';\nimport { $createImageNode } from '../nodes/ImageNode';\nimport type { UploadImageFn } from '../types';\n\n/**\n * Check if URL is safe for image embedding\n */\nfunction isSafeImageUrl(url: string): boolean {\n try {\n const parsedUrl = new URL(url);\n return ['https:', 'http:', 'blob:', 'data:'].includes(parsedUrl.protocol);\n } catch {\n return false;\n }\n}\n\nexport interface UseImageUploadOptions {\n /** Image upload function */\n uploadImage?: UploadImageFn;\n /** Callback when upload starts */\n onUploadStart?: () => void;\n /** Callback when upload ends */\n onUploadEnd?: () => void;\n /** Callback when error occurs */\n onError?: (error: Error) => void;\n}\n\nexport interface UseImageUploadResult {\n /** Whether any upload is in progress */\n isUploading: boolean;\n /** Number of concurrent uploads */\n uploadCount: number;\n /** Upload image and get result */\n upload: (file: File) => Promise<{ url: string; alt?: string } | null>;\n /** Upload image and insert into editor */\n uploadAndInsert: (file: File, editor: LexicalEditor) => Promise<boolean>;\n}\n\nexport function useImageUpload(options: UseImageUploadOptions = {}): UseImageUploadResult {\n const { uploadImage, onUploadStart, onUploadEnd, onError } = options;\n const [uploadCount, setUploadCount] = useState(0);\n\n const upload = useCallback(\n async (file: File): Promise<{ url: string; alt?: string } | null> => {\n if (!uploadImage) {\n return null;\n }\n\n setUploadCount((c) => c + 1);\n\n try {\n const result = await uploadImage(file);\n\n // Validate URL protocol\n if (!isSafeImageUrl(result.url)) {\n throw new Error('Image URL must use HTTPS, HTTP, blob:, or data: protocol');\n }\n\n return result;\n } catch (error) {\n onError?.(error instanceof Error ? error : new Error('Upload failed'));\n return null;\n } finally {\n setUploadCount((c) => c - 1);\n }\n },\n [uploadImage, onError]\n );\n\n const uploadAndInsert = useCallback(\n async (file: File, editor: LexicalEditor): Promise<boolean> => {\n if (!uploadImage) {\n return false;\n }\n\n onUploadStart?.();\n setUploadCount((c) => c + 1);\n\n try {\n const result = await uploadImage(file);\n\n if (!result || !result.url) {\n return false;\n }\n\n // Validate URL protocol\n if (!isSafeImageUrl(result.url)) {\n throw new Error('Image URL must use HTTPS, HTTP, blob:, or data: protocol');\n }\n\n // Insert image node into editor\n editor.update(() => {\n const imageNode = $createImageNode(result.url, result.alt || file.name);\n const paragraphNode = $createParagraphNode();\n $insertNodes([imageNode, paragraphNode]);\n // Move selection to the new paragraph\n paragraphNode.select();\n });\n\n // Restore focus after async operation\n setTimeout(() => {\n editor.focus();\n }, 0);\n\n return true;\n } catch (error) {\n onError?.(error instanceof Error ? error : new Error('Upload failed'));\n return false;\n } finally {\n setUploadCount((c) => c - 1);\n onUploadEnd?.();\n }\n },\n [uploadImage, onUploadStart, onUploadEnd, onError]\n );\n\n return {\n isUploading: uploadCount > 0,\n uploadCount,\n upload,\n uploadAndInsert,\n };\n}\n","import { useCallback, useState, useRef, useEffect } from 'react';\nimport { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext';\nimport {\n $getSelection,\n $isRangeSelection,\n $setSelection,\n FORMAT_TEXT_COMMAND,\n $createParagraphNode,\n $createTextNode,\n RangeSelection,\n} from 'lexical';\nimport {\n $setBlocksType,\n} from '@lexical/selection';\nimport { $createHeadingNode, $createQuoteNode, HeadingTagType } from '@lexical/rich-text';\nimport {\n INSERT_ORDERED_LIST_COMMAND,\n INSERT_UNORDERED_LIST_COMMAND,\n} from '@lexical/list';\nimport { $createCodeNode } from '@lexical/code';\nimport { $createLinkNode, TOGGLE_LINK_COMMAND } from '@lexical/link';\nimport type { UploadImageFn, MarkdownSyntaxOptions } from '../types';\nimport { sanitizeUrl } from '../utils';\nimport { useImageUpload } from '../hooks/useImageUpload';\nimport {\n BoldIcon,\n CodeIcon,\n ItalicIcon,\n StrikeIcon,\n H1Icon,\n H2Icon,\n H3Icon,\n BulletListIcon,\n OrderedListIcon,\n QuoteIcon,\n LinkIcon,\n ImageIcon,\n} from '../components/Icons';\nimport { useLocale } from '../LocaleContext';\n\nexport interface ToolbarPluginProps {\n uploadImage?: UploadImageFn;\n enabledSyntax?: MarkdownSyntaxOptions;\n onUploadStart?: () => void;\n onUploadEnd?: () => void;\n onError?: (error: Error) => void;\n}\n\nexport function ToolbarPlugin({\n uploadImage,\n enabledSyntax,\n onUploadStart,\n onUploadEnd,\n onError,\n}: ToolbarPluginProps) {\n const [editor] = useLexicalComposerContext();\n const locale = useLocale();\n const [showLinkDialog, setShowLinkDialog] = useState(false);\n const [linkUrl, setLinkUrl] = useState('');\n const [linkText, setLinkText] = useState('');\n const [savedSelection, setSavedSelection] = useState<RangeSelection | null>(null);\n const fileInputRef = useRef<HTMLInputElement>(null);\n\n const [isBold, setIsBold] = useState(false);\n const [isItalic, setIsItalic] = useState(false);\n const [isStrike, setIsStrike] = useState(false);\n const [isCode, setIsCode] = useState(false);\n\n // Use image upload hook\n const { uploadAndInsert } = useImageUpload({\n uploadImage,\n onUploadStart,\n onUploadEnd,\n onError,\n });\n\n // We could track block types technically (heading etc) but keeping it simple for now as per user request\n const updateToolbar = useCallback(() => {\n const selection = $getSelection();\n if ($isRangeSelection(selection)) {\n setIsBold(selection.hasFormat('bold'));\n setIsItalic(selection.hasFormat('italic'));\n setIsStrike(selection.hasFormat('strikethrough'));\n setIsCode(selection.hasFormat('code'));\n }\n }, []);\n\n useEffect(() => {\n return editor.registerUpdateListener(({ editorState }) => {\n editorState.read(() => {\n updateToolbar();\n });\n });\n }, [editor, updateToolbar]);\n\n const syntax: MarkdownSyntaxOptions = {\n heading: enabledSyntax?.heading ?? true,\n bold: enabledSyntax?.bold ?? true,\n italic: enabledSyntax?.italic ?? true,\n strike: enabledSyntax?.strike ?? true,\n codeInline: enabledSyntax?.codeInline ?? true,\n codeBlock: enabledSyntax?.codeBlock ?? true,\n quote: enabledSyntax?.quote ?? true,\n list: enabledSyntax?.list ?? true,\n link: enabledSyntax?.link ?? true,\n image: enabledSyntax?.image ?? true,\n };\n\n const formatBold = useCallback(() => {\n editor.dispatchCommand(FORMAT_TEXT_COMMAND, 'bold');\n }, [editor]);\n\n const formatItalic = useCallback(() => {\n editor.dispatchCommand(FORMAT_TEXT_COMMAND, 'italic');\n }, [editor]);\n\n const formatStrike = useCallback(() => {\n editor.dispatchCommand(FORMAT_TEXT_COMMAND, 'strikethrough');\n }, [editor]);\n\n const formatHeading = useCallback(\n (headingSize: HeadingTagType) => {\n editor.update(() => {\n const selection = $getSelection();\n if ($isRangeSelection(selection)) {\n $setBlocksType(selection, () => $createHeadingNode(headingSize));\n }\n });\n },\n [editor]\n );\n\n const formatBulletList = useCallback(() => {\n editor.dispatchCommand(INSERT_UNORDERED_LIST_COMMAND, undefined);\n }, [editor]);\n\n const formatOrderedList = useCallback(() => {\n editor.dispatchCommand(INSERT_ORDERED_LIST_COMMAND, undefined);\n }, [editor]);\n\n const formatQuote = useCallback(() => {\n editor.update(() => {\n const selection = $getSelection();\n if ($isRangeSelection(selection)) {\n $setBlocksType(selection, () => $createQuoteNode());\n }\n });\n }, [editor]);\n\n const formatCodeBlock = useCallback(() => {\n editor.update(() => {\n const selection = $getSelection();\n if ($isRangeSelection(selection)) {\n $setBlocksType(selection, () => $createCodeNode());\n }\n });\n }, [editor]);\n\n const handleLinkSubmit = useCallback(() => {\n const url = sanitizeUrl(linkUrl);\n if (!url) {\n onError?.(new Error('Invalid URL'));\n return;\n }\n\n // Restore selection and insert link\n editor.update(() => {\n // Restore the saved selection if available\n if (savedSelection) {\n $setSelection(savedSelection);\n }\n const selection = $getSelection();\n if ($isRangeSelection(selection)) {\n if (selection.isCollapsed()) {\n // No selection, insert link with text (use URL as text if linkText is empty)\n const linkNode = $createLinkNode(url);\n const textNode = $createTextNode(linkText || url);\n linkNode.append(textNode);\n // Use $insertNodes from lexical\n const { $insertNodes } = require('lexical');\n $insertNodes([linkNode]);\n } else {\n // Wrap selection in link\n editor.dispatchCommand(TOGGLE_LINK_COMMAND, url);\n }\n }\n });\n\n setSavedSelection(null);\n\n setShowLinkDialog(false);\n setLinkUrl('');\n setLinkText('');\n }, [editor, linkUrl, linkText, savedSelection, onError]);\n\n const handleImageSelect = useCallback(\n async (event: React.ChangeEvent<HTMLInputElement>) => {\n const file = event.target.files?.[0];\n if (!file) return;\n\n // Reset input\n event.target.value = '';\n\n // Use hook to upload and insert\n await uploadAndInsert(file, editor);\n },\n [editor, uploadAndInsert]\n );\n\n return (\n <div className=\"im-composer-toolbar\">\n {syntax.bold && (\n <button\n type=\"button\"\n className={`im-composer-toolbar-btn ${isBold ? 'active' : ''}`}\n onClick={formatBold}\n title=\"Bold (Ctrl+B)\"\n >\n <BoldIcon />\n </button>\n )}\n\n {syntax.italic && (\n <button\n type=\"button\"\n className={`im-composer-toolbar-btn ${isItalic ? 'active' : ''}`}\n onClick={formatItalic}\n title=\"Italic (Ctrl+I)\"\n >\n <ItalicIcon />\n </button>\n )}\n\n {syntax.strike && (\n <button\n type=\"button\"\n className={`im-composer-toolbar-btn ${isStrike ? 'active' : ''}`}\n onClick={formatStrike}\n title=\"Strikethrough\"\n >\n <StrikeIcon />\n </button>\n )}\n\n <span className=\"im-composer-toolbar-divider\" />\n\n {syntax.heading && (\n <>\n <button\n type=\"button\"\n className=\"im-composer-toolbar-btn\"\n onClick={() => formatHeading('h1')}\n title=\"Heading 1\"\n >\n <H1Icon />\n </button>\n <button\n type=\"button\"\n className=\"im-composer-toolbar-btn\"\n onClick={() => formatHeading('h2')}\n title=\"Heading 2\"\n >\n <H2Icon />\n </button>\n <button\n type=\"button\"\n className=\"im-composer-toolbar-btn\"\n onClick={() => formatHeading('h3')}\n title=\"Heading 3\"\n >\n <H3Icon />\n </button>\n </>\n )}\n\n {syntax.list && (\n <>\n <button\n type=\"button\"\n className=\"im-composer-toolbar-btn\"\n onClick={formatBulletList}\n title=\"Bullet List\"\n >\n <BulletListIcon />\n </button>\n <button\n type=\"button\"\n className=\"im-composer-toolbar-btn\"\n onClick={formatOrderedList}\n title=\"Ordered List\"\n >\n <OrderedListIcon />\n </button>\n </>\n )}\n\n {syntax.quote && (\n <button\n type=\"button\"\n className=\"im-composer-toolbar-btn\"\n onClick={formatQuote}\n title=\"Quote\"\n >\n <QuoteIcon />\n </button>\n )}\n\n {syntax.codeBlock && (\n <button\n type=\"button\"\n className=\"im-composer-toolbar-btn\"\n onClick={formatCodeBlock}\n title=\"Code Block\"\n >\n <CodeIcon />\n </button>\n )}\n\n <span className=\"im-composer-toolbar-divider\" />\n\n {syntax.link && (\n <button\n type=\"button\"\n className=\"im-composer-toolbar-btn\"\n onClick={() => {\n // Save current selection before opening dialog\n editor.getEditorState().read(() => {\n const selection = $getSelection();\n if ($isRangeSelection(selection)) {\n setSavedSelection(selection.clone());\n // If there's selected text, use it as the link text\n const selectedText = selection.getTextContent();\n if (selectedText) {\n setLinkText(selectedText);\n }\n }\n });\n setShowLinkDialog(true);\n }}\n title=\"Insert Link\"\n >\n <LinkIcon />\n </button>\n )}\n\n {syntax.image && uploadImage && (\n <>\n <button\n type=\"button\"\n className=\"im-composer-toolbar-btn\"\n onClick={() => fileInputRef.current?.click()}\n title=\"Insert Image\"\n >\n <ImageIcon />\n </button>\n <input\n ref={fileInputRef}\n type=\"file\"\n accept=\"image/*\"\n style={{ display: 'none' }}\n onChange={handleImageSelect}\n />\n </>\n )}\n\n\n {showLinkDialog && (\n <div className=\"im-composer-link-edit-popup ignore-drag\" style={{ position: 'fixed', top: '50%', left: '50%', transform: 'translate(-50%, -50%)', zIndex: 99999, width: 220 }}>\n <div className=\"im-composer-link-edit-content\">\n <div className=\"im-composer-link-edit-field\">\n <label>{locale.linkDialog.textLabel}</label>\n <input\n type=\"text\"\n value={linkText}\n onChange={(e) => setLinkText(e.target.value)}\n autoFocus\n />\n </div>\n <div className=\"im-composer-link-edit-field\">\n <label>{locale.linkDialog.urlLabel}</label>\n <input\n type=\"url\"\n value={linkUrl}\n onChange={(e) => setLinkUrl(e.target.value)}\n placeholder=\"https://example.com\"\n />\n </div>\n <div className=\"im-composer-link-edit-buttons\">\n <button\n type=\"button\"\n className=\"remove\"\n onClick={() => {\n setShowLinkDialog(false);\n setLinkUrl('');\n setLinkText('');\n setSavedSelection(null);\n }}\n >\n {locale.linkDialog.cancelButton}\n </button>\n <button type=\"button\" className=\"save\" onClick={handleLinkSubmit}>\n {locale.linkDialog.insertButton}\n </button>\n </div>\n </div>\n </div>\n )}\n </div>\n );\n}\n","import React from 'react';\n\nexport const BoldIcon = () => (\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <path d=\"M6 4h8a4 4 0 0 1 4 4 4 4 0 0 1-4 4H6z\" />\n <path d=\"M6 12h9a4 4 0 0 1 4 4 4 4 0 0 1-4 4H6z\" />\n </svg>\n);\n\nexport const ItalicIcon = () => (\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <line x1=\"19\" y1=\"4\" x2=\"10\" y2=\"4\" />\n <line x1=\"14\" y1=\"20\" x2=\"5\" y2=\"20\" />\n <line x1=\"15\" y1=\"4\" x2=\"9\" y2=\"20\" />\n </svg>\n);\n\nexport const StrikeIcon = () => (\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <path d=\"M17.3 19c-1.4 1.3-3.2 2-5.3 2-4.7 0-8.5-4-8.5-9s3.8-9 8.5-9c2.1 0 3.9.7 5.3 2\" />\n <line x1=\"4\" y1=\"12\" x2=\"20\" y2=\"12\" />\n </svg>\n);\n\nexport const H1Icon = () => (\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <path d=\"M4 12h8\" />\n <path d=\"M4 18V6\" />\n <path d=\"M12 18V6\" />\n <path d=\"m17 12 3-2v8\" />\n </svg>\n);\n\nexport const H2Icon = () => (\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <path d=\"M4 12h8\" />\n <path d=\"M4 18V6\" />\n <path d=\"M12 18V6\" />\n <path d=\"M21 18h-4c0-4 4-3 4-6 0-1.5-2-2.5-4-1\" />\n </svg>\n);\n\nexport const H3Icon = () => (\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <path d=\"M4 12h8\" />\n <path d=\"M4 18V6\" />\n <path d=\"M12 18V6\" />\n <path d=\"M17.5 11.5c.5-.5 2.5-.5 3 0s.5 2 0 2.5-2 .5-2 .5 1.5 0 2 .5.5 2.5 0 3-2.5.5-3 0\" />\n </svg>\n);\n\nexport const BulletListIcon = () => (\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <line x1=\"8\" y1=\"6\" x2=\"21\" y2=\"6\" />\n <line x1=\"8\" y1=\"12\" x2=\"21\" y2=\"12\" />\n <line x1=\"8\" y1=\"18\" x2=\"21\" y2=\"18\" />\n <line x1=\"3\" y1=\"6\" x2=\"3.01\" y2=\"6\" />\n <line x1=\"3\" y1=\"12\" x2=\"3.01\" y2=\"12\" />\n <line x1=\"3\" y1=\"18\" x2=\"3.01\" y2=\"18\" />\n </svg>\n);\n\nexport const OrderedListIcon = () => (\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <line x1=\"10\" y1=\"6\" x2=\"21\" y2=\"6\" />\n <line x1=\"10\" y1=\"12\" x2=\"21\" y2=\"12\" />\n <line x1=\"10\" y1=\"18\" x2=\"21\" y2=\"18\" />\n <path d=\"M4 6h1v4\" />\n <path d=\"M4 10h2\" />\n <path d=\"M6 18H4c0-1 2-2 2-3s-1-1.5-2-1\" />\n </svg>\n);\n\nexport const QuoteIcon = () => (\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <path d=\"M3 21c3 0 7-1 7-8V5c0-1.25-.756-2.017-2-2H4c-1.25 0-2 .75-2 1.972V11c0 1.25.75 2 2 2 1 0 1 0 1 1v1c0 1-1 2-2 2s-1 .008-1 1.031V20c0 1 0 1 1 1z\" transform=\"scale(0.8) translate(3, 3)\" />\n <path d=\"M15 21c3 0 7-1 7-8V5c0-1.25-.757-2.017-2-2h-4c-1.25 0-2 .75-2 1.972V11c0 1.25.75 2 2 2 1 0 1 0 1 1v1c0 1-1 2-2 2s-1 .008-1 1.031V20c0 1 0 1 1 1z\" transform=\"scale(0.8) translate(3, 3)\" />\n </svg>\n);\n\nexport const CodeIcon = () => (\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <polyline points=\"16 18 22 12 16 6\" />\n <polyline points=\"8 6 2 12 8 18\" />\n </svg>\n);\n\nexport const CodeBlockIcon = () => (\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <rect x=\"4\" y=\"4\" width=\"16\" height=\"16\" rx=\"2\" />\n <line x1=\"8\" y1=\"12\" x2=\"16\" y2=\"12\" />\n </svg>\n);\n\nexport const LinkIcon = () => (\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <path d=\"M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71\" />\n <path d=\"M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71\" />\n </svg>\n);\n\nexport const ImageIcon = () => (\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <rect x=\"3\" y=\"3\" width=\"18\" height=\"18\" rx=\"2\" ry=\"2\" />\n <circle cx=\"8.5\" cy=\"8.5\" r=\"1.5\" />\n <polyline points=\"21 15 16 10 5 21\" />\n </svg>\n);\n\nexport const ParagraphIcon = () => (\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <path d=\"M13 4v16\" />\n <path d=\"M17 4v16\" />\n <path d=\"M19 4H9.5a4.5 4.5 0 0 0 0 9H13\" />\n </svg>\n);\n","import { createContext, useContext } from 'react';\nimport type { IMComposerLocale } from './types';\n\nexport const defaultLocale: Required<IMComposerLocale> = {\n linkDialog: {\n textLabel: 'Text',\n urlLabel: 'URL',\n cancelButton: 'Cancel',\n insertButton: 'Insert',\n saveButton: 'Save',\n },\n toolbar: {\n bold: 'Bold',\n italic: 'Italic',\n strikethrough: 'Strikethrough',\n code: 'Code',\n heading1: 'Heading 1',\n heading2: 'Heading 2',\n heading3: 'Heading 3',\n bulletList: 'Bullet List',\n orderedList: 'Ordered List',\n quote: 'Quote',\n codeBlock: 'Code Block',\n link: 'Insert Link',\n image: 'Insert Image',\n },\n};\n\nexport const LocaleContext = createContext<Required<IMComposerLocale>>(defaultLocale);\n\nexport function useLocale(): Required<IMComposerLocale> {\n return useContext(LocaleContext);\n}\n\nexport function mergeLocale(custom?: IMComposerLocale): Required<IMComposerLocale> {\n if (!custom) return defaultLocale;\n\n return {\n linkDialog: { ...defaultLocale.linkDialog, ...custom.linkDialog },\n toolbar: { ...defaultLocale.toolbar, ...custom.toolbar },\n };\n}\n","import { useEffect, useRef, useCallback } from 'react';\nimport { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext';\nimport {\n COMMAND_PRIORITY_HIGH,\n KEY_ENTER_COMMAND,\n $getRoot,\n} from 'lexical';\nimport type { SendKey } from '../types';\nimport { isOnlyWhitespace } from '../utils';\n\nexport interface KeymapPluginProps {\n sendKey?: SendKey;\n onSend: () => void;\n canSend: () => boolean;\n disabled?: boolean;\n}\n\nexport function KeymapPlugin({ sendKey = 'enter', onSend, canSend, disabled }: KeymapPluginProps) {\n const [editor] = useLexicalComposerContext();\n const isComposingRef = useRef(false);\n\n // Track IME composition\n useEffect(() => {\n const root = editor.getRootElement();\n if (!root) return;\n\n const handleCompositionStart = () => {\n isComposingRef.current = true;\n };\n\n const handleCompositionEnd = () => {\n isComposingRef.current = false;\n };\n\n root.addEventListener('compositionstart', handleCompositionStart);\n root.addEventListener('compositionend', handleCompositionEnd);\n\n return () => {\n root.removeEventListener('compositionstart', handleCompositionStart);\n root.removeEventListener('compositionend', handleCompositionEnd);\n };\n }, [editor]);\n\n const shouldSend = useCallback(\n (event: KeyboardEvent | null): boolean => {\n if (!event || disabled || isComposingRef.current) return false;\n\n switch (sendKey) {\n case 'enter':\n return !event.shiftKey && !event.ctrlKey && !event.metaKey;\n case 'ctrlEnter':\n return event.ctrlKey && !event.metaKey;\n case 'cmdEnter':\n return event.metaKey && !event.ctrlKey;\n default:\n return false;\n }\n },\n [sendKey, disabled]\n );\n\n useEffect(() => {\n return editor.registerCommand(\n KEY_ENTER_COMMAND,\n (event: KeyboardEvent | null) => {\n if (shouldSend(event) && canSend()) {\n event?.preventDefault();\n onSend();\n return true;\n }\n return false;\n },\n COMMAND_PRIORITY_HIGH\n );\n }, [editor, shouldSend, canSend, onSend]);\n\n return null;\n}\n","import { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext';\nimport {\n $getSelection,\n $isRangeSelection,\n KEY_BACKSPACE_COMMAND,\n COMMAND_PRIORITY_HIGH,\n $isNodeSelection,\n $isElementNode,\n $isTextNode,\n $isParagraphNode,\n} from 'lexical';\nimport { useEffect } from 'react';\nimport { $isQuoteNode } from '../nodes/QuoteNode';\nimport { $isEmojiNode } from '../nodes/EmojiNode';\nimport { $isMentionNode } from '../nodes/MentionNode';\nimport { $isImageNode } from '../nodes/ImageNode';\n\n/**\n * Unified plugin for handling backspace deletion of special nodes:\n * - ImageNode: Delete when cursor is right after image\n * - QuoteNode: Delete when cursor is at start of next block\n * - EmojiNode: Delete when cursor is right after emoji\n * - MentionNode: Delete when cursor is right after mention\n */\nexport function DeletionPlugin() {\n const [editor] = useLexicalComposerContext();\n\n useEffect(() => {\n return editor.registerCommand(\n KEY_BACKSPACE_COMMAND,\n (event) => {\n const selection = $getSelection();\n\n if ($isRangeSelection(selection) && selection.isCollapsed()) {\n const anchor = selection.anchor;\n const anchorNode = anchor.getNode();\n\n if (anchor.offset === 0) {\n // 1. Check for ImageNode deletion\n // Check direct sibling\n let prevNode = anchorNode.getPreviousSibling();\n\n // Check parent's sibling if no direct sibling\n if (!prevNode) {\n const parent = anchorNode.getParent();\n if (parent) {\n prevNode = parent.getPreviousSibling();\n }\n }\n\n // Check top-level element's sibling\n if (!prevNode || !$isImageNode(prevNode)) {\n const topElement = anchorNode.getTopLevelElement();\n if (topElement) {\n const topPrevSibling = topElement.getPreviousSibling();\n if (topPrevSibling && $isImageNode(topPrevSibling)) {\n prevNode = topPrevSibling;\n }\n }\n }\n\n if (prevNode && $isImageNode(prevNode)) {\n event.preventDefault();\n prevNode.remove();\n return true;\n }\n\n // 2. Check for QuoteNode deletion\n const topLevelElement = anchorNode.getTopLevelElement();\n if (topLevelElement) {\n const isAtStartOfBlock =\n (anchor.type === 'text' && anchor.offset === 0 && anchorNode.getPreviousSibling() === null) ||\n (anchor.type === 'element' && anchor.offset === 0);\n\n if (isAtStartOfBlock) {\n const quotePrevSibling = topLevelElement.getPreviousSibling();\n if ($isQuoteNode(quotePrevSibling)) {\n quotePrevSibling.remove();\n return true;\n }\n }\n }\n }\n\n // 3. Check for inline node deletion (EmojiNode, MentionNode)\n let rawPrevNode = null;\n\n if ($isTextNode(anchorNode)) {\n if (anchor.offset === 0) {\n rawPrevNode = anchorNode.getPreviousSibling();\n }\n } else if ($isElementNode(anchorNode)) {\n if (anchor.offset > 0) {\n const children = anchorNode.getChildren();\n rawPrevNode = children[anchor.offset - 1];\n }\n }\n\n if ($isEmojiNode(rawPrevNode) || $isMentionNode(rawPrevNode)) {\n rawPrevNode.remove();\n return true;\n }\n } else if ($isNodeSelection(selection)) {\n // Handle node selection deletion\n const nodes = selection.getNodes();\n let handled = false;\n for (const node of nodes) {\n if ($isQuoteNode(node) || $isEmojiNode(node) || $isMentionNode(node) || $isImageNode(node)) {\n node.remove();\n handled = true;\n }\n }\n if (handled) return true;\n }\n\n return false;\n },\n COMMAND_PRIORITY_HIGH\n );\n }, [editor]);\n\n return null;\n}\n","import { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext';\nimport { useEffect } from 'react';\nimport { QuoteNode } from '../nodes/QuoteNode';\n\nexport interface QuoteRemovalListenerPluginProps {\n onQuoteRemoved?: () => void;\n}\n\nexport function QuoteRemovalListenerPlugin({ onQuoteRemoved }: QuoteRemovalListenerPluginProps) {\n const [editor] = useLexicalComposerContext();\n\n useEffect(() => {\n if (!onQuoteRemoved) return;\n\n return editor.registerMutationListener(QuoteNode, (mutations) => {\n let hasDestroyed = false;\n let hasCreated = false;\n\n for (const [, mutation] of mutations) {\n if (mutation === 'destroyed') {\n hasDestroyed = true;\n }\n if (mutation === 'created') {\n hasCreated = true;\n }\n }\n\n // Only trigger if quote was destroyed without a new one being created\n // This distinguishes between user delete and quote replacement\n if (hasDestroyed && !hasCreated) {\n onQuoteRemoved();\n }\n });\n }, [editor, onQuoteRemoved]);\n\n return null;\n}\n\n","import { useEffect } from 'react';\nimport { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext';\nimport {\n $getSelection,\n $isRangeSelection,\n $createTextNode,\n $isTextNode,\n TextNode,\n} from 'lexical';\nimport { $createLinkNode } from '@lexical/link';\n\n// Regex to match markdown link syntax: [text](url)\n// URL must not be empty and must contain http:// or https://\nconst MARKDOWN_LINK_REGEX = /\\[([^\\]]+)\\]\\((https?:\\/\\/[^)\\s]+)\\)\\s$/;\n\nexport function LinkShortcutPlugin() {\n const [editor] = useLexicalComposerContext();\n\n useEffect(() => {\n // Use update listener to detect when text ends with markdown link + space\n const removeListener = editor.registerUpdateListener(({ editorState, prevEditorState, tags }) => {\n // Skip if this is not a user input\n if (tags.has('history-merge') || tags.has('collaboration')) {\n return;\n }\n\n editorState.read(() => {\n const selection = $getSelection();\n if (!$isRangeSelection(selection) || !selection.isCollapsed()) {\n return;\n }\n\n const anchorNode = selection.anchor.getNode();\n if (!$isTextNode(anchorNode)) {\n return;\n }\n\n const textContent = anchorNode.getTextContent();\n const match = textContent.match(MARKDOWN_LINK_REGEX);\n\n if (!match) {\n return;\n }\n\n const [fullMatch, linkText, url] = match;\n\n // Validate URL\n try {\n new URL(url);\n } catch {\n return;\n }\n\n // Schedule the conversion\n editor.update(() => {\n const currentSelection = $getSelection();\n if (!$isRangeSelection(currentSelection) || !currentSelection.isCollapsed()) {\n return;\n }\n\n const currentNode = currentSelection.anchor.getNode();\n if (!$isTextNode(currentNode)) {\n return;\n }\n\n const currentText = currentNode.getTextContent();\n const currentMatch = currentText.match(MARKDOWN_LINK_REGEX);\n\n if (!currentMatch) {\n return;\n }\n\n const matchStart = currentText.indexOf(currentMatch[0]);\n const beforeText = currentText.slice(0, matchStart);\n const afterText = ''; // The trailing space is consumed by the regex\n\n // Create the link node\n const linkNode = $createLinkNode(currentMatch[2]);\n const linkTextNode = $createTextNode(currentMatch[1]);\n linkNode.append(linkTextNode);\n\n // Create a space node after link\n const spaceNode = $createTextNode(' ');\n\n if (beforeText) {\n const beforeNode = $createTextNode(beforeText);\n currentNode.replace(beforeNode);\n beforeNode.insertAfter(linkNode);\n linkNode.insertAfter(spaceNode);\n } else {\n currentNode.replace(linkNode);\n linkNode.insertAfter(spaceNode);\n }\n\n // Move cursor after the space\n spaceNode.select(1, 1);\n });\n });\n });\n\n return removeListener;\n }, [editor]);\n\n return null;\n}\n","import { useCallback, useEffect, useState, useRef } from 'react';\nimport { createPortal } from 'react-dom';\nimport { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext';\nimport {\n $getSelection,\n $isRangeSelection,\n $createTextNode,\n COMMAND_PRIORITY_LOW,\n CLICK_COMMAND,\n $getNodeByKey,\n} from 'lexical';\nimport { $isLinkNode, LinkNode } from '@lexical/link';\nimport { sanitizeUrl } from '../utils';\nimport { useLocale } from '../LocaleContext';\n\ninterface LinkEditState {\n isOpen: boolean;\n linkKey: string | null;\n text: string;\n url: string;\n position: { top: number; left: number };\n}\n\nconst POPUP_WIDTH = 220;\nconst POPUP_HEIGHT = 160;\nconst POPUP_MARGIN = 6;\n\nexport function LinkEditPlugin() {\n const [editor] = useLexicalComposerContext();\n const locale = useLocale();\n const [editState, setEditState] = useState<LinkEditState>({\n isOpen: false,\n linkKey: null,\n text: '',\n url: '',\n position: { top: 0, left: 0 },\n });\n const popupRef = useRef<HTMLDivElement>(null);\n\n // Calculate best position for popup, constrained within editor bounds\n const calculatePosition = useCallback((linkRect: DOMRect, editorRect: DOMRect) => {\n // Try to position below the link first\n let top = linkRect.bottom + POPUP_MARGIN;\n let left = linkRect.left;\n\n // Constrain to editor right edge\n const maxRight = editorRect.right - POPUP_MARGIN;\n if (left + POPUP_WIDTH > maxRight) {\n left = Math.max(editorRect.left + POPUP_MARGIN, maxRight - POPUP_WIDTH);\n }\n\n // Constrain to editor left edge\n const minLeft = editorRect.left + POPUP_MARGIN;\n if (left < minLeft) {\n left = minLeft;\n }\n\n // If goes below editor bottom, show above the link (above linkRect.top, not bottom)\n const maxBottom = editorRect.bottom - POPUP_MARGIN;\n if (top + POPUP_HEIGHT > maxBottom) {\n // Position above the link - popup bottom should be above link top\n top = linkRect.top - POPUP_HEIGHT - POPUP_MARGIN;\n }\n\n // Ensure minimum top within editor\n const minTop = editorRect.top + POPUP_MARGIN;\n if (top < minTop) {\n top = minTop;\n }\n\n return { top, left };\n }, []);\n\n // Close popup when clicking outside\n useEffect(() => {\n if (!editState.isOpen) return;\n\n const handleClickOutside = (event: MouseEvent) => {\n if (popupRef.current && !popupRef.current.contains(event.target as Node)) {\n setEditState(prev => ({ ...prev, isOpen: false }));\n }\n };\n\n const timer = setTimeout(() => {\n document.addEventListener('mousedown', handleClickOutside, true);\n }, 50);\n\n return () => {\n clearTimeout(timer);\n document.removeEventListener('mousedown', handleClickOutside, true);\n };\n }, [editState.isOpen]);\n\n useEffect(() => {\n return editor.registerCommand(\n CLICK_COMMAND,\n (event: MouseEvent) => {\n const target = event.target as HTMLElement;\n const linkElement = target.closest('a');\n const editorElement = editor.getRootElement();\n\n if (linkElement && editorElement && editorElement.contains(linkElement)) {\n event.preventDefault();\n event.stopPropagation();\n\n // Get the closest im-composer container for bounds\n const composerContainer = editorElement.closest('.im-composer') || editorElement;\n const containerRect = composerContainer.getBoundingClientRect();\n const linkRect = linkElement.getBoundingClientRect();\n const position = calculatePosition(linkRect, containerRect);\n\n editor.getEditorState().read(() => {\n const selection = $getSelection();\n if (!$isRangeSelection(selection)) return;\n\n const node = selection.anchor.getNode();\n const parent = node.getParent();\n\n const linkNode = $isLinkNode(node) ? node : ($isLinkNode(parent) ? parent : null);\n\n if (linkNode && $isLinkNode(linkNode)) {\n setEditState({\n isOpen: true,\n linkKey: linkNode.getKey(),\n text: linkNode.getTextContent(),\n url: linkNode.getURL(),\n position,\n });\n }\n });\n\n return true;\n }\n\n return false;\n },\n COMMAND_PRIORITY_LOW\n );\n }, [editor, calculatePosition]);\n\n const handleSave = useCallback(() => {\n if (!editState.linkKey) return;\n\n const url = sanitizeUrl(editState.url);\n if (!url) return;\n\n editor.update(() => {\n const linkNode = $getNodeByKey(editState.linkKey!) as LinkNode | null;\n if (linkNode && $isLinkNode(linkNode)) {\n // Update URL\n linkNode.setURL(url);\n\n // Update text if changed\n const currentText = linkNode.getTextContent();\n if (currentText !== editState.text && editState.text.trim()) {\n // Get all children and update/replace them\n const children = linkNode.getChildren();\n if (children.length > 0) {\n // Keep only first child and update its text\n for (let i = children.length - 1; i > 0; i--) {\n children[i].remove();\n }\n const firstChild = children[0];\n if (firstChild.getType() === 'text') {\n (firstChild as any).setTextContent(editState.text);\n } else {\n const newTextNode = $createTextNode(editState.text);\n firstChild.replace(newTextNode);\n }\n } else {\n // No children, add new text node\n linkNode.append($createTextNode(editState.text));\n }\n }\n }\n });\n\n setEditState(prev => ({ ...prev, isOpen: false }));\n }, [editor, editState]);\n\n const handleCancel = useCallback(() => {\n setEditState(prev => ({ ...prev, isOpen: false }));\n }, []);\n\n const handleKeyDown = useCallback((e: React.KeyboardEvent) => {\n if (e.key === 'Enter') {\n e.preventDefault();\n handleSave();\n } else if (e.key === 'Escape') {\n handleCancel();\n }\n }, [handleSave, handleCancel]);\n\n if (!editState.isOpen) {\n return null;\n }\n\n return createPortal(\n <div\n ref={popupRef}\n className=\"im-composer-link-edit-popup ignore-drag\"\n style={{\n position: 'fixed',\n top: editState.position.top,\n left: editState.position.left,\n width: POPUP_WIDTH,\n zIndex: 99999,\n }}\n onKeyDown={handleKeyDown}\n >\n <div className=\"im-composer-link-edit-content\">\n <div className=\"im-composer-link-edit-field\">\n <label>{locale.linkDialog.textLabel}</label>\n <input\n type=\"text\"\n value={editState.text}\n onChange={(e) => setEditState(prev => ({ ...prev, text: e.target.value }))}\n autoFocus\n />\n </div>\n <div className=\"im-composer-link-edit-field\">\n <label>{locale.linkDialog.urlLabel}</label>\n <input\n type=\"text\"\n value={editState.url}\n onChange={(e) => setEditState(prev => ({ ...prev, url: e.target.value }))}\n />\n </div>\n <div className=\"im-composer-link-edit-buttons\">\n <button type=\"button\" onClick={handleCancel} className=\"remove\">\n {locale.linkDialog.cancelButton}\n </button>\n <button type=\"button\" onClick={handleSave} className=\"save\">\n {locale.linkDialog.saveButton}\n </button>\n </div>\n </div>\n </div>,\n document.body\n );\n}\n","import type { Attachment } from '../types';\nimport { formatFileSize, isImageFile } from '../utils';\n\nexport interface AttachmentPreviewBarProps {\n attachments: Attachment[];\n onRemove: (id: string) => void;\n placement?: 'top' | 'bottom';\n}\n\nexport function AttachmentPreviewBar({\n attachments,\n onRemove,\n placement = 'bottom',\n}: AttachmentPreviewBarProps) {\n if (attachments.length === 0) {\n return null;\n }\n\n return (\n <div className={`im-composer-attachments im-composer-attachments-${placement}`}>\n {attachments.map((attachment) => (\n <div key={attachment.id} className=\"im-composer-attachment-item\">\n {attachment.previewUrl && isImageFile(attachment.file) ? (\n <img\n src={attachment.previewUrl}\n alt={attachment.name}\n className=\"im-composer-attachment-preview\"\n />\n ) : (\n <div className=\"im-composer-attachment-icon\">📄</div>\n )}\n <div className=\"im-composer-attachment-info\">\n <span className=\"im-composer-attachment-name\" title={attachment.name}>\n {attachment.name}\n </span>\n <span className=\"im-composer-attachment-size\">\n {formatFileSize(attachment.size)}\n </span>\n </div>\n <button\n type=\"button\"\n className=\"im-composer-attachment-remove\"\n onClick={() => onRemove(attachment.id)}\n title=\"Remove attachment\"\n >\n ×\n </button>\n </div>\n ))}\n </div>\n );\n}\n","import { useState, useCallback, useEffect, useRef } from 'react';\nimport type { Attachment } from '../types';\nimport { generateId, isMimeTypeAllowed, isImageFile } from '../utils';\n\nexport interface UseAttachmentsOptions {\n maxAttachments?: number;\n maxFileSize?: number;\n allowedMimeTypes?: string[];\n onLimitExceeded?: (reason: 'count' | 'size' | 'mime', file: File) => void;\n}\n\nexport interface UseAttachmentsResult {\n attachments: Attachment[];\n addFiles: (files: FileList | File[]) => void;\n removeAttachment: (id: string) => void;\n clearAttachments: () => void;\n setAttachments: (attachments: Attachment[]) => void;\n}\n\nexport function useAttachments(options: UseAttachmentsOptions = {}): UseAttachmentsResult {\n const {\n maxAttachments = 10,\n maxFileSize,\n allowedMimeTypes,\n onLimitExceeded,\n } = options;\n\n const [attachments, setAttachments] = useState<Attachment[]>([]);\n const previewUrlsRef = useRef<Set<string>>(new Set());\n\n // Cleanup preview URLs on unmount\n useEffect(() => {\n return () => {\n previewUrlsRef.current.forEach((url) => {\n URL.revokeObjectURL(url);\n });\n previewUrlsRef.current.clear();\n };\n }, []);\n\n const createPreviewUrl = useCallback((file: File): string | undefined => {\n if (isImageFile(file)) {\n const url = URL.createObjectURL(file);\n previewUrlsRef.current.add(url);\n return url;\n }\n return undefined;\n }, []);\n\n const revokePreviewUrl = useCallback((url: string | undefined) => {\n if (url && previewUrlsRef.current.has(url)) {\n URL.revokeObjectURL(url);\n previewUrlsRef.current.delete(url);\n }\n }, []);\n\n const addFiles = useCallback(\n (files: FileList | File[]) => {\n const fileArray = Array.from(files);\n\n setAttachments((prev) => {\n const newAttachments: Attachment[] = [];\n\n for (const file of fileArray) {\n // Check count limit\n if (prev.length + newAttachments.length >= maxAttachments) {\n onLimitExceeded?.('count', file);\n continue;\n }\n\n // Check size limit\n if (maxFileSize && file.size > maxFileSize) {\n onLimitExceeded?.('size', file);\n continue;\n }\n\n // Check MIME type\n if (!isMimeTypeAllowed(file.type, allowedMimeTypes)) {\n onLimitExceeded?.('mime', file);\n continue;\n }\n\n const attachment: Attachment = {\n id: generateId(),\n file,\n name: file.name,\n size: file.size,\n mime: file.type || 'application/octet-stream',\n lastModified: file.lastModified,\n previewUrl: createPreviewUrl(file),\n };\n\n newAttachments.push(attachment);\n }\n\n return [...prev, ...newAttachments];\n });\n },\n [maxAttachments, maxFileSize, allowedMimeTypes, onLimitExceeded, createPreviewUrl]\n );\n\n const removeAttachment = useCallback(\n (id: string) => {\n setAttachments((prev) => {\n const attachment = prev.find((a) => a.id === id);\n if (attachment) {\n revokePreviewUrl(attachment.previewUrl);\n }\n return prev.filter((a) => a.id !== id);\n });\n },\n [revokePreviewUrl]\n );\n\n const clearAttachments = useCallback(() => {\n setAttachments((prev) => {\n prev.forEach((attachment) => {\n revokePreviewUrl(attachment.previewUrl);\n });\n return [];\n });\n }, [revokePreviewUrl]);\n\n const setAttachmentsExternal = useCallback(\n (newAttachments: Attachment[]) => {\n // Revoke old URLs\n attachments.forEach((attachment) => {\n revokePreviewUrl(attachment.previewUrl);\n });\n setAttachments(newAttachments);\n },\n [attachments, revokePreviewUrl]\n );\n\n return {\n attachments,\n addFiles,\n removeAttachment,\n clearAttachments,\n setAttachments: setAttachmentsExternal,\n };\n}\n","import type { EditorThemeClasses } from 'lexical';\n\nexport const EditorTheme: EditorThemeClasses = {\n ltr: 'ltr',\n rtl: 'rtl',\n paragraph: 'im-composer-paragraph',\n quote: 'im-composer-quote',\n heading: {\n h1: 'im-composer-heading-h1',\n h2: 'im-composer-heading-h2',\n h3: 'im-composer-heading-h3',\n h4: 'im-composer-heading-h4',\n h5: 'im-composer-heading-h5',\n h6: 'im-composer-heading-h6',\n },\n list: {\n nested: {\n listitem: 'im-composer-nested-listitem',\n },\n ol: 'im-composer-list-ol',\n ul: 'im-composer-list-ul',\n listitem: 'im-composer-list-item',\n },\n image: 'im-composer-image',\n link: 'im-composer-link',\n text: {\n bold: 'im-composer-text-bold',\n italic: 'im-composer-text-italic',\n overflowed: 'im-composer-text-overflowed',\n hashtag: 'im-composer-text-hashtag',\n underline: 'im-composer-text-underline',\n strikethrough: 'im-composer-text-strikethrough',\n underlineStrikethrough: 'im-composer-text-underline-strikethrough',\n code: 'im-composer-text-code',\n },\n code: 'im-composer-code',\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACAA,IAAAA,iBAQO;AACP,6BAAgC;AAChC,mCAA+B;AAC/B,oCAAgC;AAChC,kCAA8B;AAC9B,kCAAqC;AACrC,2CAAuC;AACvC,+BAA2B;AAC3B,+BAA2B;AAC3B,IAAAC,kCAA0C;AAC1C,IAAAC,mBAA6B;AAC7B,IAAAC,oBAA4D;AAC5D,IAAAC,eAAuC;AACvC,IAAAC,eAAyB;AACzB,IAAAC,eAAuC;AACvC,IAAAC,mBAA8H;;;ACvB9H,qBASO;AAWA,IAAM,cAAN,MAAM,qBAAoB,6BAAyB;AAAA,EAItD,OAAO,UAAkB;AACrB,WAAO;AAAA,EACX;AAAA,EAEA,OAAO,MAAM,MAAgC;AACzC,WAAO,IAAI,aAAY,KAAK,UAAU,KAAK,WAAW,KAAK,KAAK;AAAA,EACpE;AAAA,EAEA,YAAY,QAAgB,SAAiB,KAAe;AACxD,UAAM,GAAG;AACT,SAAK,WAAW;AAChB,SAAK,YAAY;AAAA,EACrB;AAAA,EAEA,UAAU,QAAmC;AACzC,UAAM,OAAO,SAAS,cAAc,MAAM;AAC1C,SAAK,YAAY;AACjB,SAAK,aAAa,gBAAgB,KAAK,QAAQ;AAC/C,SAAK,aAAa,wBAAwB,MAAM;AAChD,SAAK,cAAc,IAAI,KAAK,SAAS;AACrC,WAAO;AAAA,EACX;AAAA,EAEA,YAAqB;AACjB,WAAO;AAAA,EACX;AAAA,EAEA,YAA6B;AACzB,UAAM,OAAO,SAAS,cAAc,MAAM;AAC1C,SAAK,YAAY;AACjB,SAAK,aAAa,gBAAgB,KAAK,QAAQ;AAC/C,SAAK,cAAc,IAAI,KAAK,SAAS;AACrC,WAAO,EAAE,SAAS,KAAK;AAAA,EAC3B;AAAA,EAEA,OAAO,YAAqC;AACxC,WAAO;AAAA,EACX;AAAA,EAEA,OAAO,WAAW,gBAAoD;AAClE,WAAO,IAAI,aAAY,eAAe,QAAQ,eAAe,OAAO;AAAA,EACxE;AAAA,EAEA,aAAoC;AAChC,WAAO;AAAA,MACH,MAAM;AAAA,MACN,SAAS;AAAA,MACT,QAAQ,KAAK;AAAA,MACb,SAAS,KAAK;AAAA,IAClB;AAAA,EACJ;AAAA,EAEA,YAAoB;AAChB,WAAO,KAAK;AAAA,EAChB;AAAA,EAEA,aAAqB;AACjB,WAAO,KAAK;AAAA,EAChB;AAAA,EAEA,iBAAyB;AACrB,WAAO,IAAI,KAAK,QAAQ;AAAA,EAC5B;AAAA,EAEA,aAAsB;AAClB,WAAO;AAAA,EACX;AAAA,EAEA,WAAoB;AAChB,WAAO;AAAA,EACX;AAAA,EAEA,sBAA+B;AAC3B,WAAO;AAAA,EACX;AAAA,EAEA,qBAA8B;AAC1B,WAAO;AAAA,EACX;AAAA,EAEA,WAAsB;AAClB,WAAO;AAAA,EACX;AACJ;AAEO,SAAS,mBAAmB,QAAgB,SAA8B;AAC7E,SAAO,IAAI,YAAY,QAAQ,OAAO;AAC1C;AAEO,SAAS,eAAe,MAA2D;AACtF,SAAO,gBAAgB;AAC3B;;;ACnHA,IAAAC,kBAWO;AACP,oCAA0C;AAC1C,qCAAwC;AACxC,mBAA8B;AAC9B,IAAAA,kBAOO;AACP,mBAA0D;AA6E9C;AAjEZ,SAAS,eAAe;AAAA,EACpB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACJ,GAMG;AACC,QAAM,CAAC,MAAM,QAAI,yDAA0B;AAC3C,QAAM,eAAW,qBAAyB,IAAI;AAC9C,QAAM,CAAC,YAAY,aAAa,cAAc,QAAI,wDAAwB,OAAO;AAEjF,QAAM,eAAW;AAAA,IACb,CAAC,UAAyB;AACtB,UAAI,kBAAc,sCAAiB,+BAAc,CAAC,GAAG;AACjD,cAAM,eAAe;AACrB,eAAO,OAAO,MAAM;AAChB,gBAAM,WAAO,+BAAc,OAAO;AAClC,cAAI,MAAM;AACN,iBAAK,OAAO;AAAA,UAChB;AAAA,QACJ,CAAC;AACD,eAAO;AAAA,MACX;AACA,aAAO;AAAA,IACX;AAAA,IACA,CAAC,QAAQ,YAAY,OAAO;AAAA,EAChC;AAEA,8BAAU,MAAM;AACZ,eAAO;AAAA,MACH,OAAO;AAAA,QACH;AAAA,QACA,CAAC,UAAsB;AACnB,cAAI,SAAS,WAAW,SAAS,QAAQ,SAAS,MAAM,MAAc,GAAG;AACrE,gBAAI,CAAC,MAAM,UAAU;AACjB,6BAAe;AAAA,YACnB;AACA,wBAAY,IAAI;AAChB,mBAAO;AAAA,UACX;AACA,iBAAO;AAAA,QACX;AAAA,QACA;AAAA,MACJ;AAAA,MACA,OAAO;AAAA,QACH;AAAA,QACA;AAAA,QACA;AAAA,MACJ;AAAA,MACA,OAAO;AAAA,QACH;AAAA,QACA;AAAA,QACA;AAAA,MACJ;AAAA,IACJ;AAAA,EACJ,GAAG,CAAC,QAAQ,gBAAgB,aAAa,QAAQ,CAAC;AAElD,SACI,4CAAC,SAAI,WAAW,6BAA6B,aAAa,aAAa,EAAE,IACrE;AAAA,IAAC;AAAA;AAAA,MACG,KAAK;AAAA,MACL;AAAA,MACA,KAAK,OAAO;AAAA,MACZ;AAAA,MACA;AAAA,MACA,WAAU;AAAA,MACV,WAAW;AAAA;AAAA,EACf,GACJ;AAER;AAEO,IAAM,YAAN,MAAM,mBAAkB,8BAAyB;AAAA,EAMpD,OAAO,UAAkB;AACrB,WAAO;AAAA,EACX;AAAA,EAEA,OAAO,MAAM,MAA4B;AACrC,WAAO,IAAI,WAAU,KAAK,OAAO,KAAK,OAAO,KAAK,SAAS,KAAK,UAAU,KAAK,KAAK;AAAA,EACxF;AAAA,EAEA,YAAY,KAAa,KAAa,OAAgB,QAAiB,KAAe;AAClF,UAAM,GAAG;AACT,SAAK,QAAQ;AACb,SAAK,QAAQ;AACb,SAAK,UAAU;AACf,SAAK,WAAW;AAAA,EACpB;AAAA,EAEA,UAAU,QAAmC;AACzC,UAAM,MAAM,SAAS,cAAc,KAAK;AACxC,QAAI,YAAY;AAChB,WAAO;AAAA,EACX;AAAA,EAEA,YAAqB;AACjB,WAAO;AAAA,EACX;AAAA,EAEA,UAAU,QAAwC;AAC9C,UAAM,MAAM,SAAS,cAAc,KAAK;AACxC,QAAI,MAAM,KAAK;AACf,QAAI,MAAM,KAAK,SAAS;AACxB,QAAI,KAAK,QAAS,KAAI,QAAQ,KAAK;AACnC,QAAI,KAAK,SAAU,KAAI,SAAS,KAAK;AACrC,WAAO,EAAE,SAAS,IAAI;AAAA,EAC1B;AAAA,EAEA,OAAO,YAAqC;AACxC,WAAO;AAAA,MACH,KAAK,OAAO;AAAA,QACR,YAAY,CAAC,YAAyB;AAClC,gBAAM,MAAM;AACZ,gBAAM,MAAM,IAAI;AAChB,gBAAM,MAAM,IAAI,OAAO;AACvB,iBAAO,EAAE,MAAM,IAAI,WAAU,KAAK,KAAK,IAAI,OAAO,IAAI,MAAM,EAAE;AAAA,QAClE;AAAA,QACA,UAAU;AAAA,MACd;AAAA,IACJ;AAAA,EACJ;AAAA,EAEA,OAAO,WAAW,gBAAgD;AAC9D,WAAO,IAAI;AAAA,MACP,eAAe;AAAA,MACf,eAAe;AAAA,MACf,eAAe;AAAA,MACf,eAAe;AAAA,IACnB;AAAA,EACJ;AAAA,EAEA,aAAkC;AAC9B,WAAO;AAAA,MACH,MAAM;AAAA,MACN,SAAS;AAAA,MACT,KAAK,KAAK;AAAA,MACV,KAAK,KAAK;AAAA,MACV,OAAO,KAAK;AAAA,MACZ,QAAQ,KAAK;AAAA,IACjB;AAAA,EACJ;AAAA,EAEA,SAAiB;AACb,WAAO,KAAK;AAAA,EAChB;AAAA,EAEA,SAAiB;AACb,WAAO,KAAK;AAAA,EAChB;AAAA,EAEA,iBAAyB;AACrB,WAAO;AAAA,EACX;AAAA,EAEA,WAAoB;AAChB,WAAO;AAAA,EACX;AAAA,EAEA,WAAsB;AAClB,WACI;AAAA,MAAC;AAAA;AAAA,QACG,KAAK,KAAK;AAAA,QACV,KAAK,KAAK;AAAA,QACV,OAAO,KAAK;AAAA,QACZ,QAAQ,KAAK;AAAA,QACb,SAAS,KAAK;AAAA;AAAA,IAClB;AAAA,EAER;AACJ;AAEO,SAAS,iBACZ,KACA,MAAc,IACd,OACA,QACS;AACT,SAAO,IAAI,UAAU,KAAK,KAAK,OAAO,MAAM;AAChD;AAEO,SAAS,aAAa,MAAyD;AAClF,SAAO,gBAAgB;AAC3B;;;ACpOA,IAAAC,kBAUO;AAaP,SAAS,YAAY,OAAuB;AACxC,QAAM,aAAa,CAAC,GAAG,KAAK,EACvB,IAAI,CAAC,SAAS;AACX,UAAM,KAAK,KAAK,YAAY,CAAC;AAE7B,QAAI,OAAO,MAAQ,QAAO;AAC1B,WAAO,IAAI,SAAS,EAAE;AAAA,EAC1B,CAAC,EACA,OAAO,OAAO,EACd,KAAK,GAAG;AAEb,SAAO,mEAAmE,UAAU;AACxF;AAEO,IAAM,YAAN,MAAM,mBAAkB,8BAAyB;AAAA,EAGpD,OAAO,UAAkB;AACrB,WAAO;AAAA,EACX;AAAA,EAEA,OAAO,MAAM,MAA4B;AACrC,WAAO,IAAI,WAAU,KAAK,SAAS,KAAK,KAAK;AAAA,EACjD;AAAA,EAEA,YAAY,OAAe,KAAe;AACtC,UAAM,GAAG;AACT,SAAK,UAAU;AAAA,EACnB;AAAA,EAEA,UAAU,QAAmC;AACzC,UAAM,OAAO,SAAS,cAAc,MAAM;AAC1C,SAAK,YAAY;AAEjB,UAAM,MAAM,SAAS,cAAc,KAAK;AACxC,QAAI,MAAM,YAAY,KAAK,OAAO;AAClC,QAAI,MAAM,KAAK;AACf,QAAI,YAAY;AAChB,QAAI,YAAY;AAChB,QAAI,aAAa,cAAc,KAAK,OAAO;AAE3C,SAAK,YAAY,GAAG;AACpB,WAAO;AAAA,EACX;AAAA,EAEA,YAAqB;AACjB,WAAO;AAAA,EACX;AAAA,EAEA,YAA6B;AAEzB,UAAM,OAAO,SAAS,cAAc,MAAM;AAC1C,SAAK,cAAc,KAAK;AACxB,WAAO,EAAE,SAAS,KAAK;AAAA,EAC3B;AAAA,EAEA,OAAO,YAAqC;AACxC,WAAO;AAAA,MACH,KAAK,CAAC,SAAsB;AACxB,cAAM,MAAM;AACZ,cAAM,QAAQ,IAAI,aAAa,YAAY;AAC3C,YAAI,OAAO;AACP,iBAAO;AAAA,YACH,YAAY,OAAO,EAAE,MAAM,IAAI,WAAU,KAAK,EAAE;AAAA,YAChD,UAAU;AAAA,UACd;AAAA,QACJ;AACA,eAAO;AAAA,MACX;AAAA,IACJ;AAAA,EACJ;AAAA,EAEA,OAAO,WAAW,gBAAgD;AAC9D,WAAO,IAAI,WAAU,eAAe,KAAK;AAAA,EAC7C;AAAA,EAEA,aAAkC;AAC9B,WAAO;AAAA,MACH,MAAM;AAAA,MACN,SAAS;AAAA,MACT,OAAO,KAAK;AAAA,IAChB;AAAA,EACJ;AAAA,EAEA,WAAmB;AACf,WAAO,KAAK;AAAA,EAChB;AAAA,EAEA,iBAAyB;AAErB,WAAO,KAAK;AAAA,EAChB;AAAA,EAEA,aAAsB;AAClB,WAAO;AAAA,EACX;AAAA,EAEA,WAAoB;AAChB,WAAO;AAAA,EACX;AAAA,EAEA,sBAA+B;AAC3B,WAAO;AAAA,EACX;AAAA,EAEA,qBAA8B;AAC1B,WAAO;AAAA,EACX;AAAA,EAEA,WAAsB;AAClB,WAAO;AAAA,EACX;AACJ;AAEO,SAAS,iBAAiB,OAA0B;AACvD,aAAO,uCAAsB,IAAI,UAAU,KAAK,CAAC;AACrD;AAEO,SAAS,aAAa,MAAyD;AAClF,SAAO,gBAAgB;AAC3B;;;AC/IA,IAAAC,kBAWO;AAEP,IAAAC,iCAA0C;AAwB9B,IAAAC,sBAAA;AAdZ,SAAS,sBAAsB,EAAE,OAAO,SAAS,QAAQ,GAAyD;AAC9G,QAAM,CAAC,MAAM,QAAI,0DAA0B;AAE3C,QAAM,eAAe,CAAC,MAAwB;AAC1C,MAAE,eAAe;AACjB,MAAE,gBAAgB;AAClB,WAAO,OAAO,MAAM;AAChB,YAAM,WAAO,+BAAc,OAAO;AAClC,YAAM,OAAO;AAAA,IACjB,CAAC;AAAA,EACL;AAEA,SACI,8CAAC,SAAI,WAAU,qBACX;AAAA,kDAAC,UAAK,WAAU,0BACZ;AAAA,mDAAC,UAAK,WAAU,2BAA2B,iBAAM;AAAA,MACjD,6CAAC,UAAK,WAAU,6BAA6B,mBAAQ;AAAA,OACzD;AAAA,IACA,6CAAC,YAAO,WAAU,2BAA0B,SAAS,cAAc,kBAEnE;AAAA,KACJ;AAER;AAEO,IAAM,YAAN,MAAM,mBAAkB,8BAAyB;AAAA,EAIpD,OAAO,UAAkB;AACrB,WAAO;AAAA,EACX;AAAA,EAEA,OAAO,MAAM,MAA4B;AACrC,WAAO,IAAI,WAAU,KAAK,SAAS,KAAK,WAAW,KAAK,KAAK;AAAA,EACjE;AAAA,EAEA,YAAY,OAAe,SAAiB,KAAe;AACvD,UAAM,GAAG;AACT,SAAK,UAAU;AACf,SAAK,YAAY;AAAA,EACrB;AAAA,EAEA,UAAU,QAAmC;AACzC,UAAM,MAAM,SAAS,cAAc,KAAK;AACxC,QAAI,YAAY;AAChB,QAAI,kBAAkB;AACtB,WAAO;AAAA,EACX;AAAA,EAEA,YAAqB;AACjB,WAAO;AAAA,EACX;AAAA,EAEA,YAA6B;AACzB,UAAM,UAAU,SAAS,cAAc,YAAY;AACnD,YAAQ,aAAa,cAAc,KAAK,OAAO;AAC/C,YAAQ,cAAc,KAAK;AAC3B,WAAO,EAAE,QAAQ;AAAA,EACrB;AAAA,EAEA,OAAO,YAAqC;AACxC,WAAO;AAAA,MACH,YAAY,OAAO;AAAA,QACf,YAAY,CAAC,YAAyB;AAClC,gBAAM,QAAQ,QAAQ,aAAa,YAAY,KAAK;AACpD,gBAAM,UAAU,QAAQ,eAAe;AACvC,iBAAO,EAAE,MAAM,IAAI,WAAU,OAAO,OAAO,EAAE;AAAA,QACjD;AAAA,QACA,UAAU;AAAA,MACd;AAAA,IACJ;AAAA,EACJ;AAAA,EAEA,OAAO,WAAW,gBAAgD;AAC9D,WAAO,IAAI,WAAU,eAAe,OAAO,eAAe,OAAO;AAAA,EACrE;AAAA,EAEA,aAAkC;AAC9B,WAAO;AAAA,MACH,MAAM;AAAA,MACN,SAAS;AAAA,MACT,OAAO,KAAK;AAAA,MACZ,SAAS,KAAK;AAAA,IAClB;AAAA,EACJ;AAAA,EAEA,WAAmB;AACf,WAAO,KAAK;AAAA,EAChB;AAAA,EAEA,aAAqB;AACjB,WAAO,KAAK;AAAA,EAChB;AAAA,EAEA,iBAAyB;AACrB,WAAO;AAAA,EACX;AAAA,EAEA,aAAsB;AAClB,WAAO;AAAA,EACX;AAAA,EAEA,WAAoB;AAChB,WAAO;AAAA,EACX;AAAA,EAEA,WAAsB;AAClB,WACI;AAAA,MAAC;AAAA;AAAA,QACG,OAAO,KAAK;AAAA,QACZ,SAAS,KAAK;AAAA,QACd,SAAS,KAAK;AAAA;AAAA,IAClB;AAAA,EAER;AACJ;AAEO,SAAS,iBAAiB,OAAe,SAA4B;AACxE,aAAO,uCAAsB,IAAI,UAAU,OAAO,OAAO,CAAC;AAC9D;AAEO,SAAS,aAAa,MAAyD;AAClF,SAAO,gBAAgB;AAC3B;;;ACnJA,IAAAC,gBAAyD;AACzD,IAAAC,iCAA0C;AAC1C,IAAAC,kBAYO;AAsSiB,IAAAC,sBAAA;AApRjB,SAAS,cAAc,EAAE,iBAAiB,UAAU,MAAM,aAAa,kBAAkB,GAAuB;AACnH,QAAM,CAAC,MAAM,QAAI,0DAA0B;AAC3C,QAAM,CAAC,QAAQ,SAAS,QAAI,wBAAS,KAAK;AAC1C,QAAM,CAAC,SAAS,UAAU,QAAI,wBAAmB,CAAC,CAAC;AACnD,QAAM,CAAC,eAAe,gBAAgB,QAAI,wBAAS,CAAC;AACpD,QAAM,CAAC,WAAW,YAAY,QAAI,wBAA8B,IAAI;AACpE,QAAM,CAAC,cAAc,eAAe,QAAI,wBAAS,CAAC;AAClD,QAAM,CAAC,UAAU,WAAW,QAAI,wBAAS,CAAC;AAC1C,QAAM,qBAAiB,sBAAO,KAAK;AACnC,QAAM,cAAU,sBAAuB,IAAI;AAC3C,QAAM,eAAW,sBAAoC,oBAAI,IAAI,CAAC;AAG9D,QAAM,sBAAkB,2BAAY,MAAM;AACtC,QAAI,CAAC,WAAW,eAAe,SAAS;AACpC,gBAAU,KAAK;AACf;AAAA,IACJ;AAEA,WAAO,eAAe,EAAE,KAAK,MAAM;AAC/B,YAAM,gBAAY,+BAAc;AAChC,UAAI,KAAC,mCAAkB,SAAS,KAAK,CAAC,UAAU,YAAY,GAAG;AAC3D,kBAAU,KAAK;AACf;AAAA,MACJ;AAGA,UAAI,gBAAgB,QAAW;AAC3B,cAAM,WAAO,0BAAS;AACtB,YAAI,eAAe;AACnB,cAAM,gBAAgB,CAAC,SAAc;AACjC,cAAI,eAAe,IAAI,GAAG;AACtB;AAAA,UACJ;AACA,cAAI,KAAK,aAAa;AAClB,iBAAK,YAAY,EAAE,QAAQ,aAAa;AAAA,UAC5C;AAAA,QACJ;AACA,sBAAc,IAAI;AAClB,YAAI,gBAAgB,aAAa;AAC7B,oBAAU,KAAK;AACf;AAAA,QACJ;AAAA,MACJ;AAEA,YAAM,SAAS,UAAU;AACzB,YAAM,aAAa,OAAO,QAAQ;AAElC,UAAI,EAAE,sBAAsB,2BAAW;AACnC,kBAAU,KAAK;AACf;AAAA,MACJ;AAEA,YAAM,OAAO,WAAW,eAAe;AACvC,YAAM,SAAS,OAAO;AAGtB,UAAI,UAAU;AACd,eAAS,IAAI,SAAS,GAAG,KAAK,GAAG,KAAK;AAClC,cAAM,OAAO,KAAK,CAAC;AACnB,YAAI,SAAS,KAAK;AACd,oBAAU;AACV;AAAA,QACJ;AAEA,YAAI,KAAK,KAAK,IAAI,GAAG;AACjB;AAAA,QACJ;AAAA,MACJ;AAEA,UAAI,YAAY,IAAI;AAChB,kBAAU,KAAK;AACf;AAAA,MACJ;AAEA,YAAM,QAAQ,KAAK,MAAM,UAAU,GAAG,MAAM;AAC5C,YAAM,oBAAoB,KAAK,MAAM,SAAS,MAAM;AAEpD,mBAAa;AAAA,QACT,YAAY;AAAA,QACZ,gBAAgB;AAAA,QAChB;AAAA,MACJ,CAAC;AAGD,YAAM,eAAe,OAAO,aAAa;AACzC,UAAI,gBAAgB,aAAa,aAAa,GAAG;AAC7C,cAAM,QAAQ,aAAa,WAAW,CAAC;AACvC,cAAM,OAAO,MAAM,sBAAsB;AACzC,wBAAgB,OAAO,cAAc,KAAK,MAAM,CAAC;AACjD,oBAAY,KAAK,IAAI;AAAA,MACzB;AAGA,UAAI,iBAAiB;AACjB,wBAAgB,KAAK,EAAE,KAAK,CAAC,YAAY;AACrC,qBAAW,OAAO;AAClB,2BAAiB,CAAC;AAClB,oBAAU,QAAQ,SAAS,CAAC;AAAA,QAChC,CAAC;AAAA,MACL;AAAA,IACJ,CAAC;AAAA,EACL,GAAG,CAAC,QAAQ,SAAS,iBAAiB,WAAW,CAAC;AAGlD,+BAAU,MAAM;AACZ,UAAM,OAAO,OAAO,eAAe;AACnC,QAAI,CAAC,KAAM;AAEX,UAAM,yBAAyB,MAAM;AACjC,qBAAe,UAAU;AAAA,IAC7B;AAEA,UAAM,uBAAuB,MAAM;AAC/B,qBAAe,UAAU;AAEzB,iBAAW,MAAM;AACb,wBAAgB;AAAA,MACpB,GAAG,CAAC;AAAA,IACR;AAEA,SAAK,iBAAiB,oBAAoB,sBAAsB;AAChE,SAAK,iBAAiB,kBAAkB,oBAAoB;AAE5D,WAAO,MAAM;AACT,WAAK,oBAAoB,oBAAoB,sBAAsB;AACnE,WAAK,oBAAoB,kBAAkB,oBAAoB;AAAA,IACnE;AAAA,EACJ,GAAG,CAAC,QAAQ,eAAe,CAAC;AAG5B,+BAAU,MAAM;AACZ,WAAO,OAAO,uBAAuB,CAAC,EAAE,YAAY,MAAM;AACtD,UAAI,YAAY,OAAO,GAAG;AACtB,wBAAgB;AAAA,MACpB;AAAA,IACJ,CAAC;AAAA,EACL,GAAG,CAAC,QAAQ,eAAe,CAAC;AAG5B,QAAM,oBAAgB;AAAA,IAClB,CAAC,WAAmB;AAChB,UAAI,CAAC,UAAW;AAEhB,aAAO,OAAO,MAAM;AAChB,cAAM,gBAAY,+BAAc;AAChC,YAAI,KAAC,mCAAkB,SAAS,EAAG;AAEnC,cAAM,SAAS,UAAU;AACzB,cAAM,aAAa,OAAO,QAAQ;AAElC,YAAI,EAAE,sBAAsB,0BAAW;AAEvC,cAAM,OAAO,WAAW,eAAe;AACvC,cAAM,WAAW,KAAK,MAAM,GAAG,UAAU,UAAU;AACnD,cAAM,aAAa,KAAK,MAAM,UAAU,aAAa,UAAU,kBAAkB,MAAM;AAGvF,cAAM,cAAc,mBAAmB,OAAO,QAAQ,OAAO,OAAO;AAEpE,YAAI,UAAU;AACV,gBAAM,iBAAa,iCAAgB,QAAQ;AAC3C,qBAAW,QAAQ,UAAU;AAC7B,qBAAW,YAAY,WAAW;AAAA,QACtC,OAAO;AACH,qBAAW,QAAQ,WAAW;AAAA,QAClC;AAEA,YAAI,YAAY;AACZ,gBAAM,gBAAY,iCAAgB,UAAU;AAC5C,sBAAY,YAAY,SAAS;AACjC,oBAAU,YAAY;AAAA,QAC1B,OAAO;AACH,sBAAY,WAAW;AAAA,QAC3B;AAAA,MACJ,CAAC;AAED,gBAAU,KAAK;AACf,mBAAa,IAAI;AAAA,IACrB;AAAA,IACA,CAAC,QAAQ,SAAS;AAAA,EACtB;AAGA,+BAAU,MAAM;AACZ,QAAI,CAAC,OAAQ;AAEb,UAAM,kBAAkB,OAAO;AAAA,MAC3B;AAAA,MACA,CAAC,UAAU;AACP,cAAM,eAAe;AACrB,yBAAiB,CAAC,OAAO,IAAI,KAAK,QAAQ,MAAM;AAChD,eAAO;AAAA,MACX;AAAA,MACA;AAAA,IACJ;AAEA,UAAM,gBAAgB,OAAO;AAAA,MACzB;AAAA,MACA,CAAC,UAAU;AACP,cAAM,eAAe;AACrB,yBAAiB,CAAC,OAAO,IAAI,IAAI,QAAQ,UAAU,QAAQ,MAAM;AACjE,eAAO;AAAA,MACX;AAAA,MACA;AAAA,IACJ;AAEA,UAAM,cAAc,OAAO;AAAA,MACvB;AAAA,MACA,CAAC,UAAU;AACP,YAAI,QAAQ,aAAa,GAAG;AACxB,iBAAO,eAAe;AACtB,wBAAc,QAAQ,aAAa,CAAC;AACpC,iBAAO;AAAA,QACX;AACA,eAAO;AAAA,MACX;AAAA,MACA;AAAA,IACJ;AAEA,UAAM,eAAe,OAAO;AAAA,MACxB;AAAA,MACA,MAAM;AACF,kBAAU,KAAK;AACf,eAAO;AAAA,MACX;AAAA,MACA;AAAA,IACJ;AAEA,WAAO,MAAM;AACT,sBAAgB;AAChB,oBAAc;AACd,kBAAY;AACZ,mBAAa;AAAA,IACjB;AAAA,EACJ,GAAG,CAAC,QAAQ,QAAQ,SAAS,eAAe,aAAa,CAAC;AAG1D,+BAAU,MAAM;AACZ,QAAI,UAAU,SAAS,QAAQ,IAAI,aAAa,GAAG;AAC/C,YAAM,OAAO,SAAS,QAAQ,IAAI,aAAa;AAC/C,YAAM,eAAe,EAAE,OAAO,WAAW,UAAU,SAAS,CAAC;AAAA,IACjE;AAAA,EACJ,GAAG,CAAC,QAAQ,aAAa,CAAC;AAE1B,MAAI,CAAC,UAAU,QAAQ,WAAW,GAAG;AACjC,WAAO;AAAA,EACX;AAEA,SACI;AAAA,IAAC;AAAA;AAAA,MACG,KAAK;AAAA,MACL,WAAU;AAAA,MACV,OAAO;AAAA,QACH,UAAU;AAAA,QACV,QAAQ;AAAA,QACR,MAAM;AAAA,MACV;AAAA,MAEC,kBAAQ,IAAI,CAAC,QAAQ,UAClB;AAAA,QAAC;AAAA;AAAA,UAEG,KAAK,CAAC,OAAO;AACT,gBAAI,IAAI;AACJ,uBAAS,QAAQ,IAAI,OAAO,EAAE;AAAA,YAClC,OAAO;AACH,uBAAS,QAAQ,OAAO,KAAK;AAAA,YACjC;AAAA,UACJ;AAAA,UACA,WAAW,4BAA4B,UAAU,gBAAgB,aAAa,EAAE;AAAA,UAChF,SAAS,MAAM,cAAc,MAAM;AAAA,UACnC,cAAc,MAAM,iBAAiB,KAAK;AAAA,UAEzC,8BACG,kBAAkB,EAAE,QAAQ,YAAY,UAAU,cAAc,CAAC,IAEjE,8EACK;AAAA,mBAAO,aACJ;AAAA,cAAC;AAAA;AAAA,gBACG,KAAK,OAAO;AAAA,gBACZ,KAAI;AAAA,gBACJ,WAAU;AAAA;AAAA,YACd;AAAA,YAEJ,6CAAC,UAAK,WAAU,4BAA4B,iBAAO,SAAQ;AAAA,aAC/D;AAAA;AAAA,QAxBC,OAAO;AAAA,MA0BhB,CACH;AAAA;AAAA,EACL;AAER;;;ACnUA,IAAAC,gBAAkC;AAClC,IAAAC,iCAA0C;AAC1C,IAAAC,kBAOO;AAMA,SAAS,qBAAqB,EAAE,YAAY,GAA8B;AAC7E,QAAM,CAAC,MAAM,QAAI,0DAA0B;AAC3C,QAAM,qBAAiB,sBAAO,KAAK;AAGnC,+BAAU,MAAM;AACZ,UAAM,OAAO,OAAO,eAAe;AACnC,QAAI,CAAC,KAAM;AAEX,UAAM,yBAAyB,MAAM;AACjC,qBAAe,UAAU;AAAA,IAC7B;AAEA,UAAM,uBAAuB,MAAM;AAC/B,qBAAe,UAAU;AAAA,IAC7B;AAEA,SAAK,iBAAiB,oBAAoB,sBAAsB;AAChE,SAAK,iBAAiB,kBAAkB,oBAAoB;AAE5D,WAAO,MAAM;AACT,WAAK,oBAAoB,oBAAoB,sBAAsB;AACnE,WAAK,oBAAoB,kBAAkB,oBAAoB;AAAA,IACnE;AAAA,EACJ,GAAG,CAAC,MAAM,CAAC;AAEX,+BAAU,MAAM;AACZ,WAAO,OAAO;AAAA,MACV;AAAA,MACA,CAAC,UAA0B;AAEvB,YAAI,eAAe,SAAS;AACxB,iBAAO;AAAA,QACX;AAEA,cAAM,gBAAgB,MAAM;AAC5B,YAAI,CAAC,cAAe,QAAO;AAG3B,YAAI,cAAc,SAAS,cAAc,MAAM,SAAS,GAAG;AACvD,gBAAM,eAAe;AACrB,gBAAM,QAAQ,MAAM,KAAK,cAAc,KAAK;AAC5C,wBAAc,KAAK;AACnB,iBAAO;AAAA,QACX;AAGA,cAAM,OAAO,cAAc,QAAQ,YAAY;AAC/C,YAAI,MAAM;AACN,gBAAM,eAAe;AAErB,iBAAO,OAAO,MAAM;AAChB,kBAAM,gBAAY,+BAAc;AAChC,gBAAI,KAAC,mCAAkB,SAAS,EAAG;AAGnC,kBAAM,QAAQ,KAAK,MAAM,OAAO;AAEhC,gBAAI,MAAM,WAAW,GAAG;AAEpB,wBAAU,WAAW,MAAM,CAAC,CAAC;AAAA,YACjC,OAAO;AAEH,oBAAM,QAAQ,CAAC,MAAM,UAAU;AAC3B,oBAAI,QAAQ,GAAG;AAEX,wBAAM,gBAAY,sCAAqB;AACvC,wBAAM,eAAW,iCAAgB,IAAI;AACrC,4BAAU,OAAO,QAAQ;AAEzB,wBAAM,uBAAmB,+BAAc;AACvC,0BAAI,mCAAkB,gBAAgB,GAAG;AACrC,qCAAiB,gBAAgB;AACjC,wBAAI,MAAM;AACN,uCAAiB,WAAW,IAAI;AAAA,oBACpC;AAAA,kBACJ;AAAA,gBACJ,OAAO;AACH,4BAAU,WAAW,IAAI;AAAA,gBAC7B;AAAA,cACJ,CAAC;AAAA,YACL;AAAA,UACJ,CAAC;AAED,iBAAO;AAAA,QACX;AAEA,eAAO;AAAA,MACX;AAAA,MACA;AAAA,IACJ;AAAA,EACJ,GAAG,CAAC,QAAQ,WAAW,CAAC;AAExB,SAAO;AACX;;;AC7GA,IAAAC,gBAAkC;AAClC,IAAAC,iCAA0C;AAC1C,IAAAC,mBAAqD;;;ACC9C,SAAS,aAAqB;AACjC,SAAO,GAAG,KAAK,IAAI,CAAC,IAAI,KAAK,OAAO,EAAE,SAAS,EAAE,EAAE,OAAO,GAAG,CAAC,CAAC;AACnE;AAKO,SAAS,eAAe,OAAuB;AAClD,MAAI,UAAU,EAAG,QAAO;AAExB,QAAM,QAAQ,CAAC,KAAK,MAAM,MAAM,MAAM,IAAI;AAC1C,QAAM,IAAI;AACV,QAAM,IAAI,KAAK,MAAM,KAAK,IAAI,KAAK,IAAI,KAAK,IAAI,CAAC,CAAC;AAElD,SAAO,GAAG,YAAY,QAAQ,KAAK,IAAI,GAAG,CAAC,GAAG,QAAQ,CAAC,CAAC,CAAC,IAAI,MAAM,CAAC,CAAC;AACzE;AAKO,SAAS,kBAAkB,MAAc,cAAkC;AAC9E,MAAI,CAAC,gBAAgB,aAAa,WAAW,GAAG;AAC5C,WAAO;AAAA,EACX;AAEA,SAAO,aAAa,KAAK,CAAC,YAAY;AAClC,QAAI,QAAQ,SAAS,IAAI,GAAG;AACxB,YAAM,SAAS,QAAQ,MAAM,GAAG,EAAE;AAClC,aAAO,KAAK,WAAW,MAAM;AAAA,IACjC;AACA,WAAO,SAAS;AAAA,EACpB,CAAC;AACL;AAKO,SAAS,YAAY,MAAqB;AAC7C,SAAO,KAAK,KAAK,WAAW,QAAQ;AACxC;AAKA,IAAM,oBAAoB,CAAC,SAAS,UAAU,SAAS;AAEhD,SAAS,qBAAqB,KAAsB;AACvD,MAAI;AACA,UAAM,SAAS,IAAI,IAAI,GAAG;AAC1B,WAAO,kBAAkB,SAAS,OAAO,QAAQ;AAAA,EACrD,QAAQ;AACJ,WAAO;AAAA,EACX;AACJ;AAKO,SAAS,YAAY,KAA4B;AACpD,MAAI,CAAC,IAAK,QAAO;AAGjB,MAAI,CAAC,IAAI,SAAS,KAAK,KAAK,CAAC,IAAI,WAAW,SAAS,GAAG;AACpD,UAAM,aAAa;AAAA,EACvB;AAEA,MAAI,qBAAqB,GAAG,GAAG;AAC3B,WAAO;AAAA,EACX;AAEA,SAAO;AACX;;;AC1EA,IAAAC,kBAAqE;AACrE,sBAA2E;AASpE,SAAS,mBACZ,QACA,aACmB;AACnB,MAAI,YAAY;AAChB,QAAM,WAA0B,CAAC;AAEjC,MAAI;AAEJ,SAAO,eAAe,EAAE,KAAK,MAAM;AAC/B,UAAM,WAAO,0BAAS;AACtB,UAAM,WAAW,KAAK,YAAY;AAElC,aAAS,QAAQ,CAAC,UAAU;AAExB,UAAI,aAAa,KAAK,GAAG;AACrB,gBAAQ;AAAA,UACJ,OAAO,MAAM,SAAS;AAAA,UACtB,SAAS,MAAM,WAAW;AAAA,QAC9B;AACA;AAAA,MACJ;AAGA,UAAI,UAAU,SAAS,GAAG;AACtB,qBAAa;AAAA,MACjB;AAEA,YAAM,kBAAc,gCAAe,KAAK,IAAI,MAAM,YAAY,IAAI,CAAC;AAEnE,kBAAY,QAAQ,CAAC,SAAS;AAC1B,YAAI,eAAe,IAAI,GAAG;AACtB,gBAAM,SAAS,KAAK,UAAU;AAC9B,gBAAM,UAAU,KAAK,WAAW;AAChC,gBAAM,cAAc,IAAI,MAAM;AAC9B,gBAAM,QAAQ,UAAU;AACxB,gBAAM,MAAM,QAAQ,YAAY,SAAS;AAEzC,mBAAS,KAAK;AAAA,YACV;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,UACJ,CAAC;AAED,uBAAa;AAAA,QACjB,OAAO;AACH,uBAAa,KAAK,eAAe;AAAA,QACrC;AAAA,MACJ,CAAC;AAAA,IACL,CAAC;AAAA,EACL,CAAC;AAED,SAAO;AAAA,IACH,MAAM;AAAA,IACN;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACJ;AACJ;AAKA,IAAM,oBAAwC;AAAA,EAC1C,cAAc,CAAC,SAAS;AAAA,EACxB,QAAQ,CAAC,SAAkB;AACvB,QAAI,aAAa,IAAmB,GAAG;AACnC,YAAM,MAAO,KAAmB,OAAO;AACvC,YAAM,MAAO,KAAmB,OAAO;AACvC,aAAO,KAAK,GAAG,KAAK,GAAG;AAAA,IAC3B;AACA,WAAO;AAAA,EACX;AAAA,EACA,MAAM;AAAA,EACN,QAAQ;AAAA;AAAA,EACR,SAAS,MAAM;AAAA,EAAE;AAAA;AACrB;AAKO,SAAS,sBAAsB,QAA+C;AACjF,MAAI,WAAW;AAEf,SAAO,eAAe,EAAE,KAAK,MAAM;AAE/B,UAAM,kBAAkB,CAAC,GAAG,8BAAc,iBAAiB;AAC3D,mBAAW,0CAAyB,eAAe;AAAA,EACvD,CAAC;AAED,SAAO;AAAA,IACH,MAAM;AAAA,IACN;AAAA,EACJ;AACJ;;;AC1GA,IAAAC,kBAA+E;AAC/E,IAAAC,mBAAyD;AAKlD,SAAS,uBAAuB,QAAuB,UAAwB;AAClF,SAAO,OAAO,MAAM;AAEhB,UAAM,WAAO,0BAAS;AACtB,SAAK,MAAM;AAGX,qDAA2B,UAAU,6BAAY;AAAA,EACrD,CAAC;AACL;AAKO,SAAS,YAAY,QAA6B;AACrD,SAAO,OAAO,MAAM;AAChB,UAAM,WAAO,0BAAS;AACtB,SAAK,MAAM;AACX,UAAM,gBAAY,sCAAqB;AACvC,SAAK,OAAO,SAAS;AACrB,cAAU,OAAO;AAAA,EACrB,CAAC;AACL;AAKO,SAAS,cAAc,QAAgC;AAC1D,MAAI,UAAU;AAEd,SAAO,eAAe,EAAE,KAAK,MAAM;AAC/B,UAAM,WAAO,0BAAS;AACtB,UAAM,cAAc,KAAK,eAAe,EAAE,KAAK;AAC/C,cAAU,YAAY,WAAW;AAAA,EACrC,CAAC;AAED,SAAO;AACX;;;AC3CA,IAAAC,gBAAsC;AACtC,IAAAC,mBAAoD;AACpD,IAAAA,mBAA6B;AAO7B,SAAS,eAAe,KAAsB;AAC1C,MAAI;AACA,UAAM,YAAY,IAAI,IAAI,GAAG;AAC7B,WAAO,CAAC,UAAU,SAAS,SAAS,OAAO,EAAE,SAAS,UAAU,QAAQ;AAAA,EAC5E,QAAQ;AACJ,WAAO;AAAA,EACX;AACJ;AAwBO,SAAS,eAAe,UAAiC,CAAC,GAAyB;AACtF,QAAM,EAAE,aAAa,eAAe,aAAa,QAAQ,IAAI;AAC7D,QAAM,CAAC,aAAa,cAAc,QAAI,wBAAS,CAAC;AAEhD,QAAM,aAAS;AAAA,IACX,OAAO,SAA8D;AACjE,UAAI,CAAC,aAAa;AACd,eAAO;AAAA,MACX;AAEA,qBAAe,CAAC,MAAM,IAAI,CAAC;AAE3B,UAAI;AACA,cAAM,SAAS,MAAM,YAAY,IAAI;AAGrC,YAAI,CAAC,eAAe,OAAO,GAAG,GAAG;AAC7B,gBAAM,IAAI,MAAM,0DAA0D;AAAA,QAC9E;AAEA,eAAO;AAAA,MACX,SAAS,OAAO;AACZ,kBAAU,iBAAiB,QAAQ,QAAQ,IAAI,MAAM,eAAe,CAAC;AACrE,eAAO;AAAA,MACX,UAAE;AACE,uBAAe,CAAC,MAAM,IAAI,CAAC;AAAA,MAC/B;AAAA,IACJ;AAAA,IACA,CAAC,aAAa,OAAO;AAAA,EACzB;AAEA,QAAM,sBAAkB;AAAA,IACpB,OAAO,MAAY,WAA4C;AAC3D,UAAI,CAAC,aAAa;AACd,eAAO;AAAA,MACX;AAEA,sBAAgB;AAChB,qBAAe,CAAC,MAAM,IAAI,CAAC;AAE3B,UAAI;AACA,cAAM,SAAS,MAAM,YAAY,IAAI;AAErC,YAAI,CAAC,UAAU,CAAC,OAAO,KAAK;AACxB,iBAAO;AAAA,QACX;AAGA,YAAI,CAAC,eAAe,OAAO,GAAG,GAAG;AAC7B,gBAAM,IAAI,MAAM,0DAA0D;AAAA,QAC9E;AAGA,eAAO,OAAO,MAAM;AAChB,gBAAM,YAAY,iBAAiB,OAAO,KAAK,OAAO,OAAO,KAAK,IAAI;AACtE,gBAAM,oBAAgB,uCAAqB;AAC3C,6CAAa,CAAC,WAAW,aAAa,CAAC;AAEvC,wBAAc,OAAO;AAAA,QACzB,CAAC;AAGD,mBAAW,MAAM;AACb,iBAAO,MAAM;AAAA,QACjB,GAAG,CAAC;AAEJ,eAAO;AAAA,MACX,SAAS,OAAO;AACZ,kBAAU,iBAAiB,QAAQ,QAAQ,IAAI,MAAM,eAAe,CAAC;AACrE,eAAO;AAAA,MACX,UAAE;AACE,uBAAe,CAAC,MAAM,IAAI,CAAC;AAC3B,sBAAc;AAAA,MAClB;AAAA,IACJ;AAAA,IACA,CAAC,aAAa,eAAe,aAAa,OAAO;AAAA,EACrD;AAEA,SAAO;AAAA,IACH,aAAa,cAAc;AAAA,IAC3B;AAAA,IACA;AAAA,IACA;AAAA,EACJ;AACJ;;;AJ9GO,SAAS,oBAAoB;AAAA,EAChC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACJ,GAA6B;AACzB,QAAM,CAAC,MAAM,QAAI,0DAA0B;AAC3C,QAAM,qBAAiB,sBAAO,KAAK;AAGnC,QAAM,EAAE,gBAAgB,IAAI,eAAe;AAAA,IACvC;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACJ,CAAC;AAGD,+BAAU,MAAM;AACZ,UAAM,OAAO,OAAO,eAAe;AACnC,QAAI,CAAC,KAAM;AAEX,UAAM,yBAAyB,MAAM;AACjC,qBAAe,UAAU;AAAA,IAC7B;AAEA,UAAM,uBAAuB,MAAM;AAC/B,qBAAe,UAAU;AAAA,IAC7B;AAEA,SAAK,iBAAiB,oBAAoB,sBAAsB;AAChE,SAAK,iBAAiB,kBAAkB,oBAAoB;AAE5D,WAAO,MAAM;AACT,WAAK,oBAAoB,oBAAoB,sBAAsB;AACnE,WAAK,oBAAoB,kBAAkB,oBAAoB;AAAA,IACnE;AAAA,EACJ,GAAG,CAAC,MAAM,CAAC;AAEX,+BAAU,MAAM;AACZ,WAAO,OAAO;AAAA,MACV;AAAA,MACA,CAAC,UAA0B;AAEvB,YAAI,eAAe,SAAS;AACxB,iBAAO;AAAA,QACX;AAEA,cAAM,gBAAgB,MAAM;AAC5B,YAAI,CAAC,cAAe,QAAO;AAG3B,YAAI,cAAc,SAAS,cAAc,MAAM,SAAS,KAAK,aAAa;AACtE,gBAAM,QAAQ,MAAM,KAAK,cAAc,KAAK;AAC5C,gBAAM,aAAa,MAAM,OAAO,WAAW;AAE3C,cAAI,WAAW,SAAS,GAAG;AACvB,kBAAM,eAAe;AAGrB,uBAAW,QAAQ,OAAO,SAAS;AAC/B,oBAAM,gBAAgB,MAAM,MAAM;AAAA,YACtC,CAAC;AAED,mBAAO;AAAA,UACX;AAAA,QACJ;AAGA,eAAO;AAAA,MACX;AAAA,MACA;AAAA,IACJ;AAAA,EACJ,GAAG,CAAC,QAAQ,aAAa,eAAe,CAAC;AAEzC,SAAO;AACX;;;AK1FA,IAAAC,gBAAyD;AACzD,IAAAC,iCAA0C;AAC1C,IAAAC,mBAQO;AACP,uBAEO;AACP,uBAAqE;AACrE,kBAGO;AACP,kBAAgC;AAChC,kBAAqD;;;ACjBjD,IAAAC,sBAAA;AADG,IAAM,WAAW,MACpB,8CAAC,SAAI,OAAM,MAAK,QAAO,MAAK,SAAQ,aAAY,MAAK,QAAO,QAAO,gBAAe,aAAY,KAAI,eAAc,SAAQ,gBAAe,SACnI;AAAA,+CAAC,UAAK,GAAE,yCAAwC;AAAA,EAChD,6CAAC,UAAK,GAAE,0CAAyC;AAAA,GACrD;AAGG,IAAM,aAAa,MACtB,8CAAC,SAAI,OAAM,MAAK,QAAO,MAAK,SAAQ,aAAY,MAAK,QAAO,QAAO,gBAAe,aAAY,KAAI,eAAc,SAAQ,gBAAe,SACnI;AAAA,+CAAC,UAAK,IAAG,MAAK,IAAG,KAAI,IAAG,MAAK,IAAG,KAAI;AAAA,EACpC,6CAAC,UAAK,IAAG,MAAK,IAAG,MAAK,IAAG,KAAI,IAAG,MAAK;AAAA,EACrC,6CAAC,UAAK,IAAG,MAAK,IAAG,KAAI,IAAG,KAAI,IAAG,MAAK;AAAA,GACxC;AAGG,IAAM,aAAa,MACtB,8CAAC,SAAI,OAAM,MAAK,QAAO,MAAK,SAAQ,aAAY,MAAK,QAAO,QAAO,gBAAe,aAAY,KAAI,eAAc,SAAQ,gBAAe,SACnI;AAAA,+CAAC,UAAK,GAAE,iFAAgF;AAAA,EACxF,6CAAC,UAAK,IAAG,KAAI,IAAG,MAAK,IAAG,MAAK,IAAG,MAAK;AAAA,GACzC;AAGG,IAAM,SAAS,MAClB,8CAAC,SAAI,OAAM,MAAK,QAAO,MAAK,SAAQ,aAAY,MAAK,QAAO,QAAO,gBAAe,aAAY,KAAI,eAAc,SAAQ,gBAAe,SACnI;AAAA,+CAAC,UAAK,GAAE,WAAU;AAAA,EAClB,6CAAC,UAAK,GAAE,WAAU;AAAA,EAClB,6CAAC,UAAK,GAAE,YAAW;AAAA,EACnB,6CAAC,UAAK,GAAE,gBAAe;AAAA,GAC3B;AAGG,IAAM,SAAS,MAClB,8CAAC,SAAI,OAAM,MAAK,QAAO,MAAK,SAAQ,aAAY,MAAK,QAAO,QAAO,gBAAe,aAAY,KAAI,eAAc,SAAQ,gBAAe,SACnI;AAAA,+CAAC,UAAK,GAAE,WAAU;AAAA,EAClB,6CAAC,UAAK,GAAE,WAAU;AAAA,EAClB,6CAAC,UAAK,GAAE,YAAW;AAAA,EACnB,6CAAC,UAAK,GAAE,yCAAwC;AAAA,GACpD;AAGG,IAAM,SAAS,MAClB,8CAAC,SAAI,OAAM,MAAK,QAAO,MAAK,SAAQ,aAAY,MAAK,QAAO,QAAO,gBAAe,aAAY,KAAI,eAAc,SAAQ,gBAAe,SACnI;AAAA,+CAAC,UAAK,GAAE,WAAU;AAAA,EAClB,6CAAC,UAAK,GAAE,WAAU;AAAA,EAClB,6CAAC,UAAK,GAAE,YAAW;AAAA,EACnB,6CAAC,UAAK,GAAE,mFAAkF;AAAA,GAC9F;AAGG,IAAM,iBAAiB,MAC1B,8CAAC,SAAI,OAAM,MAAK,QAAO,MAAK,SAAQ,aAAY,MAAK,QAAO,QAAO,gBAAe,aAAY,KAAI,eAAc,SAAQ,gBAAe,SACnI;AAAA,+CAAC,UAAK,IAAG,KAAI,IAAG,KAAI,IAAG,MAAK,IAAG,KAAI;AAAA,EACnC,6CAAC,UAAK,IAAG,KAAI,IAAG,MAAK,IAAG,MAAK,IAAG,MAAK;AAAA,EACrC,6CAAC,UAAK,IAAG,KAAI,IAAG,MAAK,IAAG,MAAK,IAAG,MAAK;AAAA,EACrC,6CAAC,UAAK,IAAG,KAAI,IAAG,KAAI,IAAG,QAAO,IAAG,KAAI;AAAA,EACrC,6CAAC,UAAK,IAAG,KAAI,IAAG,MAAK,IAAG,QAAO,IAAG,MAAK;AAAA,EACvC,6CAAC,UAAK,IAAG,KAAI,IAAG,MAAK,IAAG,QAAO,IAAG,MAAK;AAAA,GAC3C;AAGG,IAAM,kBAAkB,MAC3B,8CAAC,SAAI,OAAM,MAAK,QAAO,MAAK,SAAQ,aAAY,MAAK,QAAO,QAAO,gBAAe,aAAY,KAAI,eAAc,SAAQ,gBAAe,SACnI;AAAA,+CAAC,UAAK,IAAG,MAAK,IAAG,KAAI,IAAG,MAAK,IAAG,KAAI;AAAA,EACpC,6CAAC,UAAK,IAAG,MAAK,IAAG,MAAK,IAAG,MAAK,IAAG,MAAK;AAAA,EACtC,6CAAC,UAAK,IAAG,MAAK,IAAG,MAAK,IAAG,MAAK,IAAG,MAAK;AAAA,EACtC,6CAAC,UAAK,GAAE,YAAW;AAAA,EACnB,6CAAC,UAAK,GAAE,WAAU;AAAA,EAClB,6CAAC,UAAK,GAAE,kCAAiC;AAAA,GAC7C;AAGG,IAAM,YAAY,MACrB,8CAAC,SAAI,OAAM,MAAK,QAAO,MAAK,SAAQ,aAAY,MAAK,QAAO,QAAO,gBAAe,aAAY,KAAI,eAAc,SAAQ,gBAAe,SACnI;AAAA,+CAAC,UAAK,GAAE,kJAAiJ,WAAU,8BAA6B;AAAA,EAChM,6CAAC,UAAK,GAAE,oJAAmJ,WAAU,8BAA6B;AAAA,GACtM;AAGG,IAAM,WAAW,MACpB,8CAAC,SAAI,OAAM,MAAK,QAAO,MAAK,SAAQ,aAAY,MAAK,QAAO,QAAO,gBAAe,aAAY,KAAI,eAAc,SAAQ,gBAAe,SACnI;AAAA,+CAAC,cAAS,QAAO,oBAAmB;AAAA,EACpC,6CAAC,cAAS,QAAO,iBAAgB;AAAA,GACrC;AAUG,IAAM,WAAW,MACpB,8CAAC,SAAI,OAAM,MAAK,QAAO,MAAK,SAAQ,aAAY,MAAK,QAAO,QAAO,gBAAe,aAAY,KAAI,eAAc,SAAQ,gBAAe,SACnI;AAAA,+CAAC,UAAK,GAAE,+DAA8D;AAAA,EACtE,6CAAC,UAAK,GAAE,gEAA+D;AAAA,GAC3E;AAGG,IAAM,YAAY,MACrB,8CAAC,SAAI,OAAM,MAAK,QAAO,MAAK,SAAQ,aAAY,MAAK,QAAO,QAAO,gBAAe,aAAY,KAAI,eAAc,SAAQ,gBAAe,SACnI;AAAA,+CAAC,UAAK,GAAE,KAAI,GAAE,KAAI,OAAM,MAAK,QAAO,MAAK,IAAG,KAAI,IAAG,KAAI;AAAA,EACvD,6CAAC,YAAO,IAAG,OAAM,IAAG,OAAM,GAAE,OAAM;AAAA,EAClC,6CAAC,cAAS,QAAO,oBAAmB;AAAA,GACxC;;;AC1GJ,IAAAC,gBAA0C;AAGnC,IAAM,gBAA4C;AAAA,EACrD,YAAY;AAAA,IACR,WAAW;AAAA,IACX,UAAU;AAAA,IACV,cAAc;AAAA,IACd,cAAc;AAAA,IACd,YAAY;AAAA,EAChB;AAAA,EACA,SAAS;AAAA,IACL,MAAM;AAAA,IACN,QAAQ;AAAA,IACR,eAAe;AAAA,IACf,MAAM;AAAA,IACN,UAAU;AAAA,IACV,UAAU;AAAA,IACV,UAAU;AAAA,IACV,YAAY;AAAA,IACZ,aAAa;AAAA,IACb,OAAO;AAAA,IACP,WAAW;AAAA,IACX,MAAM;AAAA,IACN,OAAO;AAAA,EACX;AACJ;AAEO,IAAM,oBAAgB,6BAA0C,aAAa;AAE7E,SAAS,YAAwC;AACpD,aAAO,0BAAW,aAAa;AACnC;AAEO,SAAS,YAAY,QAAuD;AAC/E,MAAI,CAAC,OAAQ,QAAO;AAEpB,SAAO;AAAA,IACH,YAAY,EAAE,GAAG,cAAc,YAAY,GAAG,OAAO,WAAW;AAAA,IAChE,SAAS,EAAE,GAAG,cAAc,SAAS,GAAG,OAAO,QAAQ;AAAA,EAC3D;AACJ;;;AFiLoB,IAAAC,sBAAA;AA1Kb,SAAS,cAAc;AAAA,EAC1B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACJ,GAAuB;AACnB,QAAM,CAAC,MAAM,QAAI,0DAA0B;AAC3C,QAAM,SAAS,UAAU;AACzB,QAAM,CAAC,gBAAgB,iBAAiB,QAAI,wBAAS,KAAK;AAC1D,QAAM,CAAC,SAAS,UAAU,QAAI,wBAAS,EAAE;AACzC,QAAM,CAAC,UAAU,WAAW,QAAI,wBAAS,EAAE;AAC3C,QAAM,CAAC,gBAAgB,iBAAiB,QAAI,wBAAgC,IAAI;AAChF,QAAM,mBAAe,sBAAyB,IAAI;AAElD,QAAM,CAAC,QAAQ,SAAS,QAAI,wBAAS,KAAK;AAC1C,QAAM,CAAC,UAAU,WAAW,QAAI,wBAAS,KAAK;AAC9C,QAAM,CAAC,UAAU,WAAW,QAAI,wBAAS,KAAK;AAC9C,QAAM,CAAC,QAAQ,SAAS,QAAI,wBAAS,KAAK;AAG1C,QAAM,EAAE,gBAAgB,IAAI,eAAe;AAAA,IACvC;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACJ,CAAC;AAGD,QAAM,oBAAgB,2BAAY,MAAM;AACpC,UAAM,gBAAY,gCAAc;AAChC,YAAI,oCAAkB,SAAS,GAAG;AAC9B,gBAAU,UAAU,UAAU,MAAM,CAAC;AACrC,kBAAY,UAAU,UAAU,QAAQ,CAAC;AACzC,kBAAY,UAAU,UAAU,eAAe,CAAC;AAChD,gBAAU,UAAU,UAAU,MAAM,CAAC;AAAA,IACzC;AAAA,EACJ,GAAG,CAAC,CAAC;AAEL,+BAAU,MAAM;AACZ,WAAO,OAAO,uBAAuB,CAAC,EAAE,YAAY,MAAM;AACtD,kBAAY,KAAK,MAAM;AACnB,sBAAc;AAAA,MAClB,CAAC;AAAA,IACL,CAAC;AAAA,EACL,GAAG,CAAC,QAAQ,aAAa,CAAC;AAE1B,QAAM,SAAgC;AAAA,IAClC,SAAS,eAAe,WAAW;AAAA,IACnC,MAAM,eAAe,QAAQ;AAAA,IAC7B,QAAQ,eAAe,UAAU;AAAA,IACjC,QAAQ,eAAe,UAAU;AAAA,IACjC,YAAY,eAAe,cAAc;AAAA,IACzC,WAAW,eAAe,aAAa;AAAA,IACvC,OAAO,eAAe,SAAS;AAAA,IAC/B,MAAM,eAAe,QAAQ;AAAA,IAC7B,MAAM,eAAe,QAAQ;AAAA,IAC7B,OAAO,eAAe,SAAS;AAAA,EACnC;AAEA,QAAM,iBAAa,2BAAY,MAAM;AACjC,WAAO,gBAAgB,sCAAqB,MAAM;AAAA,EACtD,GAAG,CAAC,MAAM,CAAC;AAEX,QAAM,mBAAe,2BAAY,MAAM;AACnC,WAAO,gBAAgB,sCAAqB,QAAQ;AAAA,EACxD,GAAG,CAAC,MAAM,CAAC;AAEX,QAAM,mBAAe,2BAAY,MAAM;AACnC,WAAO,gBAAgB,sCAAqB,eAAe;AAAA,EAC/D,GAAG,CAAC,MAAM,CAAC;AAEX,QAAM,oBAAgB;AAAA,IAClB,CAAC,gBAAgC;AAC7B,aAAO,OAAO,MAAM;AAChB,cAAM,gBAAY,gCAAc;AAChC,gBAAI,oCAAkB,SAAS,GAAG;AAC9B,+CAAe,WAAW,UAAM,qCAAmB,WAAW,CAAC;AAAA,QACnE;AAAA,MACJ,CAAC;AAAA,IACL;AAAA,IACA,CAAC,MAAM;AAAA,EACX;AAEA,QAAM,uBAAmB,2BAAY,MAAM;AACvC,WAAO,gBAAgB,2CAA+B,MAAS;AAAA,EACnE,GAAG,CAAC,MAAM,CAAC;AAEX,QAAM,wBAAoB,2BAAY,MAAM;AACxC,WAAO,gBAAgB,yCAA6B,MAAS;AAAA,EACjE,GAAG,CAAC,MAAM,CAAC;AAEX,QAAM,kBAAc,2BAAY,MAAM;AAClC,WAAO,OAAO,MAAM;AAChB,YAAM,gBAAY,gCAAc;AAChC,cAAI,oCAAkB,SAAS,GAAG;AAC9B,6CAAe,WAAW,UAAM,mCAAiB,CAAC;AAAA,MACtD;AAAA,IACJ,CAAC;AAAA,EACL,GAAG,CAAC,MAAM,CAAC;AAEX,QAAM,sBAAkB,2BAAY,MAAM;AACtC,WAAO,OAAO,MAAM;AAChB,YAAM,gBAAY,gCAAc;AAChC,cAAI,oCAAkB,SAAS,GAAG;AAC9B,6CAAe,WAAW,UAAM,6BAAgB,CAAC;AAAA,MACrD;AAAA,IACJ,CAAC;AAAA,EACL,GAAG,CAAC,MAAM,CAAC;AAEX,QAAM,uBAAmB,2BAAY,MAAM;AACvC,UAAM,MAAM,YAAY,OAAO;AAC/B,QAAI,CAAC,KAAK;AACN,gBAAU,IAAI,MAAM,aAAa,CAAC;AAClC;AAAA,IACJ;AAGA,WAAO,OAAO,MAAM;AAEhB,UAAI,gBAAgB;AAChB,4CAAc,cAAc;AAAA,MAChC;AACA,YAAM,gBAAY,gCAAc;AAChC,cAAI,oCAAkB,SAAS,GAAG;AAC9B,YAAI,UAAU,YAAY,GAAG;AAEzB,gBAAM,eAAW,6BAAgB,GAAG;AACpC,gBAAM,eAAW,kCAAgB,YAAY,GAAG;AAChD,mBAAS,OAAO,QAAQ;AAExB,gBAAM,EAAE,cAAAC,cAAa,IAAI,QAAQ,SAAS;AAC1C,UAAAA,cAAa,CAAC,QAAQ,CAAC;AAAA,QAC3B,OAAO;AAEH,iBAAO,gBAAgB,iCAAqB,GAAG;AAAA,QACnD;AAAA,MACJ;AAAA,IACJ,CAAC;AAED,sBAAkB,IAAI;AAEtB,sBAAkB,KAAK;AACvB,eAAW,EAAE;AACb,gBAAY,EAAE;AAAA,EAClB,GAAG,CAAC,QAAQ,SAAS,UAAU,gBAAgB,OAAO,CAAC;AAEvD,QAAM,wBAAoB;AAAA,IACtB,OAAO,UAA+C;AAClD,YAAM,OAAO,MAAM,OAAO,QAAQ,CAAC;AACnC,UAAI,CAAC,KAAM;AAGX,YAAM,OAAO,QAAQ;AAGrB,YAAM,gBAAgB,MAAM,MAAM;AAAA,IACtC;AAAA,IACA,CAAC,QAAQ,eAAe;AAAA,EAC5B;AAEA,SACI,8CAAC,SAAI,WAAU,uBACV;AAAA,WAAO,QACJ;AAAA,MAAC;AAAA;AAAA,QACG,MAAK;AAAA,QACL,WAAW,2BAA2B,SAAS,WAAW,EAAE;AAAA,QAC5D,SAAS;AAAA,QACT,OAAM;AAAA,QAEN,uDAAC,YAAS;AAAA;AAAA,IACd;AAAA,IAGH,OAAO,UACJ;AAAA,MAAC;AAAA;AAAA,QACG,MAAK;AAAA,QACL,WAAW,2BAA2B,WAAW,WAAW,EAAE;AAAA,QAC9D,SAAS;AAAA,QACT,OAAM;AAAA,QAEN,uDAAC,cAAW;AAAA;AAAA,IAChB;AAAA,IAGH,OAAO,UACJ;AAAA,MAAC;AAAA;AAAA,QACG,MAAK;AAAA,QACL,WAAW,2BAA2B,WAAW,WAAW,EAAE;AAAA,QAC9D,SAAS;AAAA,QACT,OAAM;AAAA,QAEN,uDAAC,cAAW;AAAA;AAAA,IAChB;AAAA,IAGJ,6CAAC,UAAK,WAAU,+BAA8B;AAAA,IAE7C,OAAO,WACJ,8EACI;AAAA;AAAA,QAAC;AAAA;AAAA,UACG,MAAK;AAAA,UACL,WAAU;AAAA,UACV,SAAS,MAAM,cAAc,IAAI;AAAA,UACjC,OAAM;AAAA,UAEN,uDAAC,UAAO;AAAA;AAAA,MACZ;AAAA,MACA;AAAA,QAAC;AAAA;AAAA,UACG,MAAK;AAAA,UACL,WAAU;AAAA,UACV,SAAS,MAAM,cAAc,IAAI;AAAA,UACjC,OAAM;AAAA,UAEN,uDAAC,UAAO;AAAA;AAAA,MACZ;AAAA,MACA;AAAA,QAAC;AAAA;AAAA,UACG,MAAK;AAAA,UACL,WAAU;AAAA,UACV,SAAS,MAAM,cAAc,IAAI;AAAA,UACjC,OAAM;AAAA,UAEN,uDAAC,UAAO;AAAA;AAAA,MACZ;AAAA,OACJ;AAAA,IAGH,OAAO,QACJ,8EACI;AAAA;AAAA,QAAC;AAAA;AAAA,UACG,MAAK;AAAA,UACL,WAAU;AAAA,UACV,SAAS;AAAA,UACT,OAAM;AAAA,UAEN,uDAAC,kBAAe;AAAA;AAAA,MACpB;AAAA,MACA;AAAA,QAAC;AAAA;AAAA,UACG,MAAK;AAAA,UACL,WAAU;AAAA,UACV,SAAS;AAAA,UACT,OAAM;AAAA,UAEN,uDAAC,mBAAgB;AAAA;AAAA,MACrB;AAAA,OACJ;AAAA,IAGH,OAAO,SACJ;AAAA,MAAC;AAAA;AAAA,QACG,MAAK;AAAA,QACL,WAAU;AAAA,QACV,SAAS;AAAA,QACT,OAAM;AAAA,QAEN,uDAAC,aAAU;AAAA;AAAA,IACf;AAAA,IAGH,OAAO,aACJ;AAAA,MAAC;AAAA;AAAA,QACG,MAAK;AAAA,QACL,WAAU;AAAA,QACV,SAAS;AAAA,QACT,OAAM;AAAA,QAEN,uDAAC,YAAS;AAAA;AAAA,IACd;AAAA,IAGJ,6CAAC,UAAK,WAAU,+BAA8B;AAAA,IAE7C,OAAO,QACJ;AAAA,MAAC;AAAA;AAAA,QACG,MAAK;AAAA,QACL,WAAU;AAAA,QACV,SAAS,MAAM;AAEX,iBAAO,eAAe,EAAE,KAAK,MAAM;AAC/B,kBAAM,gBAAY,gCAAc;AAChC,oBAAI,oCAAkB,SAAS,GAAG;AAC9B,gCAAkB,UAAU,MAAM,CAAC;AAEnC,oBAAM,eAAe,UAAU,eAAe;AAC9C,kBAAI,cAAc;AACd,4BAAY,YAAY;AAAA,cAC5B;AAAA,YACJ;AAAA,UACJ,CAAC;AACD,4BAAkB,IAAI;AAAA,QAC1B;AAAA,QACA,OAAM;AAAA,QAEN,uDAAC,YAAS;AAAA;AAAA,IACd;AAAA,IAGH,OAAO,SAAS,eACb,8EACI;AAAA;AAAA,QAAC;AAAA;AAAA,UACG,MAAK;AAAA,UACL,WAAU;AAAA,UACV,SAAS,MAAM,aAAa,SAAS,MAAM;AAAA,UAC3C,OAAM;AAAA,UAEN,uDAAC,aAAU;AAAA;AAAA,MACf;AAAA,MACA;AAAA,QAAC;AAAA;AAAA,UACG,KAAK;AAAA,UACL,MAAK;AAAA,UACL,QAAO;AAAA,UACP,OAAO,EAAE,SAAS,OAAO;AAAA,UACzB,UAAU;AAAA;AAAA,MACd;AAAA,OACJ;AAAA,IAIH,kBACG,6CAAC,SAAI,WAAU,2CAA0C,OAAO,EAAE,UAAU,SAAS,KAAK,OAAO,MAAM,OAAO,WAAW,yBAAyB,QAAQ,OAAO,OAAO,IAAI,GACxK,wDAAC,SAAI,WAAU,iCACX;AAAA,oDAAC,SAAI,WAAU,+BACX;AAAA,qDAAC,WAAO,iBAAO,WAAW,WAAU;AAAA,QACpC;AAAA,UAAC;AAAA;AAAA,YACG,MAAK;AAAA,YACL,OAAO;AAAA,YACP,UAAU,CAAC,MAAM,YAAY,EAAE,OAAO,KAAK;AAAA,YAC3C,WAAS;AAAA;AAAA,QACb;AAAA,SACJ;AAAA,MACA,8CAAC,SAAI,WAAU,+BACX;AAAA,qDAAC,WAAO,iBAAO,WAAW,UAAS;AAAA,QACnC;AAAA,UAAC;AAAA;AAAA,YACG,MAAK;AAAA,YACL,OAAO;AAAA,YACP,UAAU,CAAC,MAAM,WAAW,EAAE,OAAO,KAAK;AAAA,YAC1C,aAAY;AAAA;AAAA,QAChB;AAAA,SACJ;AAAA,MACA,8CAAC,SAAI,WAAU,iCACX;AAAA;AAAA,UAAC;AAAA;AAAA,YACG,MAAK;AAAA,YACL,WAAU;AAAA,YACV,SAAS,MAAM;AACX,gCAAkB,KAAK;AACvB,yBAAW,EAAE;AACb,0BAAY,EAAE;AACd,gCAAkB,IAAI;AAAA,YAC1B;AAAA,YAEC,iBAAO,WAAW;AAAA;AAAA,QACvB;AAAA,QACA,6CAAC,YAAO,MAAK,UAAS,WAAU,QAAO,SAAS,kBAC3C,iBAAO,WAAW,cACvB;AAAA,SACJ;AAAA,OACJ,GACJ;AAAA,KAER;AAER;;;AGzZA,IAAAC,gBAA+C;AAC/C,IAAAC,iCAA0C;AAC1C,IAAAC,mBAIO;AAWA,SAAS,aAAa,EAAE,UAAU,SAAS,QAAQ,SAAS,SAAS,GAAsB;AAC9F,QAAM,CAAC,MAAM,QAAI,0DAA0B;AAC3C,QAAM,qBAAiB,sBAAO,KAAK;AAGnC,+BAAU,MAAM;AACZ,UAAM,OAAO,OAAO,eAAe;AACnC,QAAI,CAAC,KAAM;AAEX,UAAM,yBAAyB,MAAM;AACjC,qBAAe,UAAU;AAAA,IAC7B;AAEA,UAAM,uBAAuB,MAAM;AAC/B,qBAAe,UAAU;AAAA,IAC7B;AAEA,SAAK,iBAAiB,oBAAoB,sBAAsB;AAChE,SAAK,iBAAiB,kBAAkB,oBAAoB;AAE5D,WAAO,MAAM;AACT,WAAK,oBAAoB,oBAAoB,sBAAsB;AACnE,WAAK,oBAAoB,kBAAkB,oBAAoB;AAAA,IACnE;AAAA,EACJ,GAAG,CAAC,MAAM,CAAC;AAEX,QAAM,iBAAa;AAAA,IACf,CAAC,UAAyC;AACtC,UAAI,CAAC,SAAS,YAAY,eAAe,QAAS,QAAO;AAEzD,cAAQ,SAAS;AAAA,QACb,KAAK;AACD,iBAAO,CAAC,MAAM,YAAY,CAAC,MAAM,WAAW,CAAC,MAAM;AAAA,QACvD,KAAK;AACD,iBAAO,MAAM,WAAW,CAAC,MAAM;AAAA,QACnC,KAAK;AACD,iBAAO,MAAM,WAAW,CAAC,MAAM;AAAA,QACnC;AACI,iBAAO;AAAA,MACf;AAAA,IACJ;AAAA,IACA,CAAC,SAAS,QAAQ;AAAA,EACtB;AAEA,+BAAU,MAAM;AACZ,WAAO,OAAO;AAAA,MACV;AAAA,MACA,CAAC,UAAgC;AAC7B,YAAI,WAAW,KAAK,KAAK,QAAQ,GAAG;AAChC,iBAAO,eAAe;AACtB,iBAAO;AACP,iBAAO;AAAA,QACX;AACA,eAAO;AAAA,MACX;AAAA,MACA;AAAA,IACJ;AAAA,EACJ,GAAG,CAAC,QAAQ,YAAY,SAAS,MAAM,CAAC;AAExC,SAAO;AACX;;;AC7EA,IAAAC,iCAA0C;AAC1C,IAAAC,mBASO;AACP,IAAAC,gBAA0B;AAanB,SAAS,iBAAiB;AAC7B,QAAM,CAAC,MAAM,QAAI,0DAA0B;AAE3C,+BAAU,MAAM;AACZ,WAAO,OAAO;AAAA,MACV;AAAA,MACA,CAAC,UAAU;AACP,cAAM,gBAAY,gCAAc;AAEhC,gBAAI,oCAAkB,SAAS,KAAK,UAAU,YAAY,GAAG;AACzD,gBAAM,SAAS,UAAU;AACzB,gBAAM,aAAa,OAAO,QAAQ;AAElC,cAAI,OAAO,WAAW,GAAG;AAGrB,gBAAI,WAAW,WAAW,mBAAmB;AAG7C,gBAAI,CAAC,UAAU;AACX,oBAAM,SAAS,WAAW,UAAU;AACpC,kBAAI,QAAQ;AACR,2BAAW,OAAO,mBAAmB;AAAA,cACzC;AAAA,YACJ;AAGA,gBAAI,CAAC,YAAY,CAAC,aAAa,QAAQ,GAAG;AACtC,oBAAM,aAAa,WAAW,mBAAmB;AACjD,kBAAI,YAAY;AACZ,sBAAM,iBAAiB,WAAW,mBAAmB;AACrD,oBAAI,kBAAkB,aAAa,cAAc,GAAG;AAChD,6BAAW;AAAA,gBACf;AAAA,cACJ;AAAA,YACJ;AAEA,gBAAI,YAAY,aAAa,QAAQ,GAAG;AACpC,oBAAM,eAAe;AACrB,uBAAS,OAAO;AAChB,qBAAO;AAAA,YACX;AAGA,kBAAM,kBAAkB,WAAW,mBAAmB;AACtD,gBAAI,iBAAiB;AACjB,oBAAM,mBACD,OAAO,SAAS,UAAU,OAAO,WAAW,KAAK,WAAW,mBAAmB,MAAM,QACrF,OAAO,SAAS,aAAa,OAAO,WAAW;AAEpD,kBAAI,kBAAkB;AAClB,sBAAM,mBAAmB,gBAAgB,mBAAmB;AAC5D,oBAAI,aAAa,gBAAgB,GAAG;AAChC,mCAAiB,OAAO;AACxB,yBAAO;AAAA,gBACX;AAAA,cACJ;AAAA,YACJ;AAAA,UACJ;AAGA,cAAI,cAAc;AAElB,kBAAI,8BAAY,UAAU,GAAG;AACzB,gBAAI,OAAO,WAAW,GAAG;AACrB,4BAAc,WAAW,mBAAmB;AAAA,YAChD;AAAA,UACJ,eAAW,iCAAe,UAAU,GAAG;AACnC,gBAAI,OAAO,SAAS,GAAG;AACnB,oBAAM,WAAW,WAAW,YAAY;AACxC,4BAAc,SAAS,OAAO,SAAS,CAAC;AAAA,YAC5C;AAAA,UACJ;AAEA,cAAI,aAAa,WAAW,KAAK,eAAe,WAAW,GAAG;AAC1D,wBAAY,OAAO;AACnB,mBAAO;AAAA,UACX;AAAA,QACJ,eAAW,mCAAiB,SAAS,GAAG;AAEpC,gBAAM,QAAQ,UAAU,SAAS;AACjC,cAAI,UAAU;AACd,qBAAW,QAAQ,OAAO;AACtB,gBAAI,aAAa,IAAI,KAAK,aAAa,IAAI,KAAK,eAAe,IAAI,KAAK,aAAa,IAAI,GAAG;AACxF,mBAAK,OAAO;AACZ,wBAAU;AAAA,YACd;AAAA,UACJ;AACA,cAAI,QAAS,QAAO;AAAA,QACxB;AAEA,eAAO;AAAA,MACX;AAAA,MACA;AAAA,IACJ;AAAA,EACJ,GAAG,CAAC,MAAM,CAAC;AAEX,SAAO;AACX;;;AC1HA,IAAAC,iCAA0C;AAC1C,IAAAC,iBAA0B;AAOnB,SAAS,2BAA2B,EAAE,eAAe,GAAoC;AAC5F,QAAM,CAAC,MAAM,QAAI,0DAA0B;AAE3C,gCAAU,MAAM;AACZ,QAAI,CAAC,eAAgB;AAErB,WAAO,OAAO,yBAAyB,WAAW,CAAC,cAAc;AAC7D,UAAI,eAAe;AACnB,UAAI,aAAa;AAEjB,iBAAW,CAAC,EAAE,QAAQ,KAAK,WAAW;AAClC,YAAI,aAAa,aAAa;AAC1B,yBAAe;AAAA,QACnB;AACA,YAAI,aAAa,WAAW;AACxB,uBAAa;AAAA,QACjB;AAAA,MACJ;AAIA,UAAI,gBAAgB,CAAC,YAAY;AAC7B,uBAAe;AAAA,MACnB;AAAA,IACJ,CAAC;AAAA,EACL,GAAG,CAAC,QAAQ,cAAc,CAAC;AAE3B,SAAO;AACX;;;ACpCA,IAAAC,iBAA0B;AAC1B,IAAAC,kCAA0C;AAC1C,IAAAC,mBAMO;AACP,IAAAC,eAAgC;AAIhC,IAAM,sBAAsB;AAErB,SAAS,qBAAqB;AACjC,QAAM,CAAC,MAAM,QAAI,2DAA0B;AAE3C,gCAAU,MAAM;AAEZ,UAAM,iBAAiB,OAAO,uBAAuB,CAAC,EAAE,aAAa,iBAAiB,KAAK,MAAM;AAE7F,UAAI,KAAK,IAAI,eAAe,KAAK,KAAK,IAAI,eAAe,GAAG;AACxD;AAAA,MACJ;AAEA,kBAAY,KAAK,MAAM;AACnB,cAAM,gBAAY,gCAAc;AAChC,YAAI,KAAC,oCAAkB,SAAS,KAAK,CAAC,UAAU,YAAY,GAAG;AAC3D;AAAA,QACJ;AAEA,cAAM,aAAa,UAAU,OAAO,QAAQ;AAC5C,YAAI,KAAC,8BAAY,UAAU,GAAG;AAC1B;AAAA,QACJ;AAEA,cAAM,cAAc,WAAW,eAAe;AAC9C,cAAM,QAAQ,YAAY,MAAM,mBAAmB;AAEnD,YAAI,CAAC,OAAO;AACR;AAAA,QACJ;AAEA,cAAM,CAAC,WAAW,UAAU,GAAG,IAAI;AAGnC,YAAI;AACA,cAAI,IAAI,GAAG;AAAA,QACf,QAAQ;AACJ;AAAA,QACJ;AAGA,eAAO,OAAO,MAAM;AAChB,gBAAM,uBAAmB,gCAAc;AACvC,cAAI,KAAC,oCAAkB,gBAAgB,KAAK,CAAC,iBAAiB,YAAY,GAAG;AACzE;AAAA,UACJ;AAEA,gBAAM,cAAc,iBAAiB,OAAO,QAAQ;AACpD,cAAI,KAAC,8BAAY,WAAW,GAAG;AAC3B;AAAA,UACJ;AAEA,gBAAM,cAAc,YAAY,eAAe;AAC/C,gBAAM,eAAe,YAAY,MAAM,mBAAmB;AAE1D,cAAI,CAAC,cAAc;AACf;AAAA,UACJ;AAEA,gBAAM,aAAa,YAAY,QAAQ,aAAa,CAAC,CAAC;AACtD,gBAAM,aAAa,YAAY,MAAM,GAAG,UAAU;AAClD,gBAAM,YAAY;AAGlB,gBAAM,eAAW,8BAAgB,aAAa,CAAC,CAAC;AAChD,gBAAM,mBAAe,kCAAgB,aAAa,CAAC,CAAC;AACpD,mBAAS,OAAO,YAAY;AAG5B,gBAAM,gBAAY,kCAAgB,GAAG;AAErC,cAAI,YAAY;AACZ,kBAAM,iBAAa,kCAAgB,UAAU;AAC7C,wBAAY,QAAQ,UAAU;AAC9B,uBAAW,YAAY,QAAQ;AAC/B,qBAAS,YAAY,SAAS;AAAA,UAClC,OAAO;AACH,wBAAY,QAAQ,QAAQ;AAC5B,qBAAS,YAAY,SAAS;AAAA,UAClC;AAGA,oBAAU,OAAO,GAAG,CAAC;AAAA,QACzB,CAAC;AAAA,MACL,CAAC;AAAA,IACL,CAAC;AAED,WAAO;AAAA,EACX,GAAG,CAAC,MAAM,CAAC;AAEX,SAAO;AACX;;;ACxGA,IAAAC,iBAAyD;AACzD,uBAA6B;AAC7B,IAAAC,kCAA0C;AAC1C,IAAAC,mBAOO;AACP,IAAAC,eAAsC;AAwMtB,IAAAC,sBAAA;AA5LhB,IAAM,cAAc;AACpB,IAAM,eAAe;AACrB,IAAM,eAAe;AAEd,SAAS,iBAAiB;AAC7B,QAAM,CAAC,MAAM,QAAI,2DAA0B;AAC3C,QAAM,SAAS,UAAU;AACzB,QAAM,CAAC,WAAW,YAAY,QAAI,yBAAwB;AAAA,IACtD,QAAQ;AAAA,IACR,SAAS;AAAA,IACT,MAAM;AAAA,IACN,KAAK;AAAA,IACL,UAAU,EAAE,KAAK,GAAG,MAAM,EAAE;AAAA,EAChC,CAAC;AACD,QAAM,eAAW,uBAAuB,IAAI;AAG5C,QAAM,wBAAoB,4BAAY,CAAC,UAAmB,eAAwB;AAE9E,QAAI,MAAM,SAAS,SAAS;AAC5B,QAAI,OAAO,SAAS;AAGpB,UAAM,WAAW,WAAW,QAAQ;AACpC,QAAI,OAAO,cAAc,UAAU;AAC/B,aAAO,KAAK,IAAI,WAAW,OAAO,cAAc,WAAW,WAAW;AAAA,IAC1E;AAGA,UAAM,UAAU,WAAW,OAAO;AAClC,QAAI,OAAO,SAAS;AAChB,aAAO;AAAA,IACX;AAGA,UAAM,YAAY,WAAW,SAAS;AACtC,QAAI,MAAM,eAAe,WAAW;AAEhC,YAAM,SAAS,MAAM,eAAe;AAAA,IACxC;AAGA,UAAM,SAAS,WAAW,MAAM;AAChC,QAAI,MAAM,QAAQ;AACd,YAAM;AAAA,IACV;AAEA,WAAO,EAAE,KAAK,KAAK;AAAA,EACvB,GAAG,CAAC,CAAC;AAGL,gCAAU,MAAM;AACZ,QAAI,CAAC,UAAU,OAAQ;AAEvB,UAAM,qBAAqB,CAAC,UAAsB;AAC9C,UAAI,SAAS,WAAW,CAAC,SAAS,QAAQ,SAAS,MAAM,MAAc,GAAG;AACtE,qBAAa,WAAS,EAAE,GAAG,MAAM,QAAQ,MAAM,EAAE;AAAA,MACrD;AAAA,IACJ;AAEA,UAAM,QAAQ,WAAW,MAAM;AAC3B,eAAS,iBAAiB,aAAa,oBAAoB,IAAI;AAAA,IACnE,GAAG,EAAE;AAEL,WAAO,MAAM;AACT,mBAAa,KAAK;AAClB,eAAS,oBAAoB,aAAa,oBAAoB,IAAI;AAAA,IACtE;AAAA,EACJ,GAAG,CAAC,UAAU,MAAM,CAAC;AAErB,gCAAU,MAAM;AACZ,WAAO,OAAO;AAAA,MACV;AAAA,MACA,CAAC,UAAsB;AACnB,cAAM,SAAS,MAAM;AACrB,cAAM,cAAc,OAAO,QAAQ,GAAG;AACtC,cAAM,gBAAgB,OAAO,eAAe;AAE5C,YAAI,eAAe,iBAAiB,cAAc,SAAS,WAAW,GAAG;AACrE,gBAAM,eAAe;AACrB,gBAAM,gBAAgB;AAGtB,gBAAM,oBAAoB,cAAc,QAAQ,cAAc,KAAK;AACnE,gBAAM,gBAAgB,kBAAkB,sBAAsB;AAC9D,gBAAM,WAAW,YAAY,sBAAsB;AACnD,gBAAM,WAAW,kBAAkB,UAAU,aAAa;AAE1D,iBAAO,eAAe,EAAE,KAAK,MAAM;AAC/B,kBAAM,gBAAY,gCAAc;AAChC,gBAAI,KAAC,oCAAkB,SAAS,EAAG;AAEnC,kBAAM,OAAO,UAAU,OAAO,QAAQ;AACtC,kBAAM,SAAS,KAAK,UAAU;AAE9B,kBAAM,eAAW,0BAAY,IAAI,IAAI,WAAQ,0BAAY,MAAM,IAAI,SAAS;AAE5E,gBAAI,gBAAY,0BAAY,QAAQ,GAAG;AACnC,2BAAa;AAAA,gBACT,QAAQ;AAAA,gBACR,SAAS,SAAS,OAAO;AAAA,gBACzB,MAAM,SAAS,eAAe;AAAA,gBAC9B,KAAK,SAAS,OAAO;AAAA,gBACrB;AAAA,cACJ,CAAC;AAAA,YACL;AAAA,UACJ,CAAC;AAED,iBAAO;AAAA,QACX;AAEA,eAAO;AAAA,MACX;AAAA,MACA;AAAA,IACJ;AAAA,EACJ,GAAG,CAAC,QAAQ,iBAAiB,CAAC;AAE9B,QAAM,iBAAa,4BAAY,MAAM;AACjC,QAAI,CAAC,UAAU,QAAS;AAExB,UAAM,MAAM,YAAY,UAAU,GAAG;AACrC,QAAI,CAAC,IAAK;AAEV,WAAO,OAAO,MAAM;AAChB,YAAM,eAAW,gCAAc,UAAU,OAAQ;AACjD,UAAI,gBAAY,0BAAY,QAAQ,GAAG;AAEnC,iBAAS,OAAO,GAAG;AAGnB,cAAM,cAAc,SAAS,eAAe;AAC5C,YAAI,gBAAgB,UAAU,QAAQ,UAAU,KAAK,KAAK,GAAG;AAEzD,gBAAM,WAAW,SAAS,YAAY;AACtC,cAAI,SAAS,SAAS,GAAG;AAErB,qBAAS,IAAI,SAAS,SAAS,GAAG,IAAI,GAAG,KAAK;AAC1C,uBAAS,CAAC,EAAE,OAAO;AAAA,YACvB;AACA,kBAAM,aAAa,SAAS,CAAC;AAC7B,gBAAI,WAAW,QAAQ,MAAM,QAAQ;AACjC,cAAC,WAAmB,eAAe,UAAU,IAAI;AAAA,YACrD,OAAO;AACH,oBAAM,kBAAc,kCAAgB,UAAU,IAAI;AAClD,yBAAW,QAAQ,WAAW;AAAA,YAClC;AAAA,UACJ,OAAO;AAEH,qBAAS,WAAO,kCAAgB,UAAU,IAAI,CAAC;AAAA,UACnD;AAAA,QACJ;AAAA,MACJ;AAAA,IACJ,CAAC;AAED,iBAAa,WAAS,EAAE,GAAG,MAAM,QAAQ,MAAM,EAAE;AAAA,EACrD,GAAG,CAAC,QAAQ,SAAS,CAAC;AAEtB,QAAM,mBAAe,4BAAY,MAAM;AACnC,iBAAa,WAAS,EAAE,GAAG,MAAM,QAAQ,MAAM,EAAE;AAAA,EACrD,GAAG,CAAC,CAAC;AAEL,QAAM,oBAAgB,4BAAY,CAAC,MAA2B;AAC1D,QAAI,EAAE,QAAQ,SAAS;AACnB,QAAE,eAAe;AACjB,iBAAW;AAAA,IACf,WAAW,EAAE,QAAQ,UAAU;AAC3B,mBAAa;AAAA,IACjB;AAAA,EACJ,GAAG,CAAC,YAAY,YAAY,CAAC;AAE7B,MAAI,CAAC,UAAU,QAAQ;AACnB,WAAO;AAAA,EACX;AAEA,aAAO;AAAA,IACH;AAAA,MAAC;AAAA;AAAA,QACG,KAAK;AAAA,QACL,WAAU;AAAA,QACV,OAAO;AAAA,UACH,UAAU;AAAA,UACV,KAAK,UAAU,SAAS;AAAA,UACxB,MAAM,UAAU,SAAS;AAAA,UACzB,OAAO;AAAA,UACP,QAAQ;AAAA,QACZ;AAAA,QACA,WAAW;AAAA,QAEX,wDAAC,SAAI,WAAU,iCACX;AAAA,wDAAC,SAAI,WAAU,+BACX;AAAA,yDAAC,WAAO,iBAAO,WAAW,WAAU;AAAA,YACpC;AAAA,cAAC;AAAA;AAAA,gBACG,MAAK;AAAA,gBACL,OAAO,UAAU;AAAA,gBACjB,UAAU,CAAC,MAAM,aAAa,WAAS,EAAE,GAAG,MAAM,MAAM,EAAE,OAAO,MAAM,EAAE;AAAA,gBACzE,WAAS;AAAA;AAAA,YACb;AAAA,aACJ;AAAA,UACA,8CAAC,SAAI,WAAU,+BACX;AAAA,yDAAC,WAAO,iBAAO,WAAW,UAAS;AAAA,YACnC;AAAA,cAAC;AAAA;AAAA,gBACG,MAAK;AAAA,gBACL,OAAO,UAAU;AAAA,gBACjB,UAAU,CAAC,MAAM,aAAa,WAAS,EAAE,GAAG,MAAM,KAAK,EAAE,OAAO,MAAM,EAAE;AAAA;AAAA,YAC5E;AAAA,aACJ;AAAA,UACA,8CAAC,SAAI,WAAU,iCACX;AAAA,yDAAC,YAAO,MAAK,UAAS,SAAS,cAAc,WAAU,UAClD,iBAAO,WAAW,cACvB;AAAA,YACA,6CAAC,YAAO,MAAK,UAAS,SAAS,YAAY,WAAU,QAChD,iBAAO,WAAW,YACvB;AAAA,aACJ;AAAA,WACJ;AAAA;AAAA,IACJ;AAAA,IACA,SAAS;AAAA,EACb;AACJ;;;ACzNwB,IAAAC,sBAAA;AAdjB,SAAS,qBAAqB;AAAA,EACjC;AAAA,EACA;AAAA,EACA,YAAY;AAChB,GAA8B;AAC1B,MAAI,YAAY,WAAW,GAAG;AAC1B,WAAO;AAAA,EACX;AAEA,SACI,6CAAC,SAAI,WAAW,mDAAmD,SAAS,IACvE,sBAAY,IAAI,CAAC,eACd,8CAAC,SAAwB,WAAU,+BAC9B;AAAA,eAAW,cAAc,YAAY,WAAW,IAAI,IACjD;AAAA,MAAC;AAAA;AAAA,QACG,KAAK,WAAW;AAAA,QAChB,KAAK,WAAW;AAAA,QAChB,WAAU;AAAA;AAAA,IACd,IAEA,6CAAC,SAAI,WAAU,+BAA8B,uBAAE;AAAA,IAEnD,8CAAC,SAAI,WAAU,+BACX;AAAA,mDAAC,UAAK,WAAU,+BAA8B,OAAO,WAAW,MAC3D,qBAAW,MAChB;AAAA,MACA,6CAAC,UAAK,WAAU,+BACX,yBAAe,WAAW,IAAI,GACnC;AAAA,OACJ;AAAA,IACA;AAAA,MAAC;AAAA;AAAA,QACG,MAAK;AAAA,QACL,WAAU;AAAA,QACV,SAAS,MAAM,SAAS,WAAW,EAAE;AAAA,QACrC,OAAM;AAAA,QACT;AAAA;AAAA,IAED;AAAA,OAzBM,WAAW,EA0BrB,CACH,GACL;AAER;;;ACnDA,IAAAC,iBAAyD;AAmBlD,SAAS,eAAe,UAAiC,CAAC,GAAyB;AACtF,QAAM;AAAA,IACF,iBAAiB;AAAA,IACjB;AAAA,IACA;AAAA,IACA;AAAA,EACJ,IAAI;AAEJ,QAAM,CAAC,aAAa,cAAc,QAAI,yBAAuB,CAAC,CAAC;AAC/D,QAAM,qBAAiB,uBAAoB,oBAAI,IAAI,CAAC;AAGpD,gCAAU,MAAM;AACZ,WAAO,MAAM;AACT,qBAAe,QAAQ,QAAQ,CAAC,QAAQ;AACpC,YAAI,gBAAgB,GAAG;AAAA,MAC3B,CAAC;AACD,qBAAe,QAAQ,MAAM;AAAA,IACjC;AAAA,EACJ,GAAG,CAAC,CAAC;AAEL,QAAM,uBAAmB,4BAAY,CAAC,SAAmC;AACrE,QAAI,YAAY,IAAI,GAAG;AACnB,YAAM,MAAM,IAAI,gBAAgB,IAAI;AACpC,qBAAe,QAAQ,IAAI,GAAG;AAC9B,aAAO;AAAA,IACX;AACA,WAAO;AAAA,EACX,GAAG,CAAC,CAAC;AAEL,QAAM,uBAAmB,4BAAY,CAAC,QAA4B;AAC9D,QAAI,OAAO,eAAe,QAAQ,IAAI,GAAG,GAAG;AACxC,UAAI,gBAAgB,GAAG;AACvB,qBAAe,QAAQ,OAAO,GAAG;AAAA,IACrC;AAAA,EACJ,GAAG,CAAC,CAAC;AAEL,QAAM,eAAW;AAAA,IACb,CAAC,UAA6B;AAC1B,YAAM,YAAY,MAAM,KAAK,KAAK;AAElC,qBAAe,CAAC,SAAS;AACrB,cAAM,iBAA+B,CAAC;AAEtC,mBAAW,QAAQ,WAAW;AAE1B,cAAI,KAAK,SAAS,eAAe,UAAU,gBAAgB;AACvD,8BAAkB,SAAS,IAAI;AAC/B;AAAA,UACJ;AAGA,cAAI,eAAe,KAAK,OAAO,aAAa;AACxC,8BAAkB,QAAQ,IAAI;AAC9B;AAAA,UACJ;AAGA,cAAI,CAAC,kBAAkB,KAAK,MAAM,gBAAgB,GAAG;AACjD,8BAAkB,QAAQ,IAAI;AAC9B;AAAA,UACJ;AAEA,gBAAM,aAAyB;AAAA,YAC3B,IAAI,WAAW;AAAA,YACf;AAAA,YACA,MAAM,KAAK;AAAA,YACX,MAAM,KAAK;AAAA,YACX,MAAM,KAAK,QAAQ;AAAA,YACnB,cAAc,KAAK;AAAA,YACnB,YAAY,iBAAiB,IAAI;AAAA,UACrC;AAEA,yBAAe,KAAK,UAAU;AAAA,QAClC;AAEA,eAAO,CAAC,GAAG,MAAM,GAAG,cAAc;AAAA,MACtC,CAAC;AAAA,IACL;AAAA,IACA,CAAC,gBAAgB,aAAa,kBAAkB,iBAAiB,gBAAgB;AAAA,EACrF;AAEA,QAAM,uBAAmB;AAAA,IACrB,CAAC,OAAe;AACZ,qBAAe,CAAC,SAAS;AACrB,cAAM,aAAa,KAAK,KAAK,CAAC,MAAM,EAAE,OAAO,EAAE;AAC/C,YAAI,YAAY;AACZ,2BAAiB,WAAW,UAAU;AAAA,QAC1C;AACA,eAAO,KAAK,OAAO,CAAC,MAAM,EAAE,OAAO,EAAE;AAAA,MACzC,CAAC;AAAA,IACL;AAAA,IACA,CAAC,gBAAgB;AAAA,EACrB;AAEA,QAAM,uBAAmB,4BAAY,MAAM;AACvC,mBAAe,CAAC,SAAS;AACrB,WAAK,QAAQ,CAAC,eAAe;AACzB,yBAAiB,WAAW,UAAU;AAAA,MAC1C,CAAC;AACD,aAAO,CAAC;AAAA,IACZ,CAAC;AAAA,EACL,GAAG,CAAC,gBAAgB,CAAC;AAErB,QAAM,6BAAyB;AAAA,IAC3B,CAAC,mBAAiC;AAE9B,kBAAY,QAAQ,CAAC,eAAe;AAChC,yBAAiB,WAAW,UAAU;AAAA,MAC1C,CAAC;AACD,qBAAe,cAAc;AAAA,IACjC;AAAA,IACA,CAAC,aAAa,gBAAgB;AAAA,EAClC;AAEA,SAAO;AAAA,IACH;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,gBAAgB;AAAA,EACpB;AACJ;;;AC3IO,IAAM,cAAkC;AAAA,EAC3C,KAAK;AAAA,EACL,KAAK;AAAA,EACL,WAAW;AAAA,EACX,OAAO;AAAA,EACP,SAAS;AAAA,IACL,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,EACR;AAAA,EACA,MAAM;AAAA,IACF,QAAQ;AAAA,MACJ,UAAU;AAAA,IACd;AAAA,IACA,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,UAAU;AAAA,EACd;AAAA,EACA,OAAO;AAAA,EACP,MAAM;AAAA,EACN,MAAM;AAAA,IACF,MAAM;AAAA,IACN,QAAQ;AAAA,IACR,YAAY;AAAA,IACZ,SAAS;AAAA,IACT,WAAW;AAAA,IACX,eAAe;AAAA,IACf,wBAAwB;AAAA,IACxB,MAAM;AAAA,EACV;AAAA,EACA,MAAM;AACV;;;AtB4HgB,IAAAC,sBAAA;AA/FhB,SAAS,YAAY;AAAA,EACjB;AAAA,EACA;AAAA,EACA,gBAAgB;AAAA,EAChB;AAAA,EACA;AAAA,EACA;AAAA,EACA,oBAAoB;AAAA,EACpB,wBAAwB;AAAA,EACxB,6BAA6B;AAAA,EAC7B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,GAAG;AACP,GAAqB;AACjB,QAAM,CAAC,MAAM,QAAI,2DAA0B;AAG3C,YAAU,UAAU;AAGpB,gCAAU,MAAM;AACZ,QAAI,CAAC,SAAU;AACf,WAAO,OAAO,uBAAuB,CAAC,EAAE,aAAa,eAAe,YAAY,MAAM;AAElF,UAAI,cAAc,OAAO,KAAK,YAAY,OAAO,GAAG;AAChD,iBAAS;AAAA,MACb;AAAA,IACJ,CAAC;AAAA,EACL,GAAG,CAAC,QAAQ,QAAQ,CAAC;AAErB,QAAM,sBAAkB,wBAAQ,MAAc;AAC1C,QAAI,OAAO,gBAAgB,SAAU,QAAO;AAC5C,QAAI,OAAO,gBAAgB,UAAU;AACjC,YAAM,OAAO,SAAS,UAAU,YAAY,QAAQ,YAAY;AAChE,UAAI,KAAM,QAAO;AAAA,IACrB;AACA,WAAO,SAAS,UAAU,sBAAsB;AAAA,EACpD,GAAG,CAAC,aAAa,IAAI,CAAC;AAEtB,QAAM,cAAU,4BAAY,MAAM;AAC9B,QAAI,YAAY,YAAa,QAAO;AAEpC,UAAM,UAAU,cAAc,MAAM;AAGpC,QAAI,SAAS,WAAW,YAAY,SAAS,GAAG;AAC5C,aAAO;AAAA,IACX;AAEA,WAAO,CAAC;AAAA,EACZ,GAAG,CAAC,QAAQ,UAAU,aAAa,MAAM,YAAY,MAAM,CAAC;AAE5D,QAAM,iBAAa,4BAAY,MAAM;AACjC,QAAI,CAAC,QAAQ,EAAG;AAEhB,QAAI,SAAS,SAAS;AAClB,YAAM,UAAU,mBAAmB,QAAQ,WAAW;AACtD,eAAS,OAAO;AAAA,IACpB,OAAO;AACH,YAAM,UAAU,sBAAsB,MAAM;AAC5C,eAAS,OAAO;AAAA,IACpB;AAAA,EACJ,GAAG,CAAC,QAAQ,MAAM,aAAa,QAAQ,OAAO,CAAC;AAE/C,QAAM,kBAAc,4BAAY,CAAC,UAAiB;AAC9C,YAAQ,MAAM,qBAAqB,KAAK;AAAA,EAC5C,GAAG,CAAC,CAAC;AAGL,QAAM,kBAAkB;AAAA,IACpB;AAAA,IACA,eAAe,IAAI;AAAA,IACnB,WAAW,yBAAyB;AAAA,IACpC;AAAA,EACJ,EAAE,OAAO,OAAO,EAAE,KAAK,GAAG;AAE1B,SACI;AAAA,IAAC;AAAA;AAAA,MACG,WAAW;AAAA,MACV,GAAG;AAAA,MAEH;AAAA,iBAAS,UACN;AAAA,UAAC;AAAA;AAAA,YACG;AAAA,YACA,eAAe,iBAAiB;AAAA,YAChC;AAAA,YACA;AAAA,YACA,SAAS;AAAA;AAAA,QACb;AAAA,QAGH,SAAS,WAAW,+BAA+B,SAAS,qBAAqB,yBAC9E;AAAA,UAAC;AAAA;AAAA,YACG;AAAA,YACA,UAAU;AAAA,YACV,WAAU;AAAA;AAAA,QACd;AAAA,QAGJ,8CAAC,SAAI,WAAU,gCACX;AAAA;AAAA,YAAC;AAAA;AAAA,cACG,iBACI;AAAA,gBAAC;AAAA;AAAA,kBACG,WAAU;AAAA,kBACV,oBAAkB;AAAA,kBAClB,aAAa,6CAAC,SAAI,WAAU,2BAA2B,2BAAgB;AAAA;AAAA,cAC3E;AAAA,cAEJ,eAAe;AAAA;AAAA,UACnB;AAAA,UACA,6CAAC,6CAAc;AAAA,UACf,6CAAC,uCAAW;AAAA,UACZ,6CAAC,uCAAW;AAAA,UAEX,SAAS,WACN,8EACI;AAAA;AAAA,cAAC;AAAA;AAAA,gBACG;AAAA,gBACA,SAAS;AAAA,gBACT;AAAA,gBACA;AAAA;AAAA,YACJ;AAAA,YACA;AAAA,cAAC;AAAA;AAAA,gBACG,aAAa,oBAAoB,cAAc;AAAA;AAAA,YACnD;AAAA,YACA,6CAAC,kBAAe;AAAA,YAChB,6CAAC,8BAA2B,gBAAgC;AAAA,aAChE;AAAA,UAGH,SAAS,UACN,8EACI;AAAA,yDAAC,+DAAuB,cAAc,+BAAc;AAAA,YACpD;AAAA,cAAC;AAAA;AAAA,gBACG;AAAA,gBACA;AAAA,gBACA;AAAA,gBACA,SAAS;AAAA;AAAA,YACb;AAAA,YACA,6CAAC,sBAAmB;AAAA,YACpB,6CAAC,kBAAe;AAAA,YAChB,6CAAC,kBAAe;AAAA,aACpB;AAAA,UAGJ;AAAA,YAAC;AAAA;AAAA,cACG,SAAS,QAAQ;AAAA,cACjB,QAAQ;AAAA,cACR;AAAA,cACA;AAAA;AAAA,UACJ;AAAA,WACJ;AAAA,QAEC,SAAS,WAAW,+BAA+B,YAAY,qBAAqB,yBACjF;AAAA,UAAC;AAAA;AAAA,YACG;AAAA,YACA,UAAU;AAAA,YACV,WAAU;AAAA;AAAA,QACd;AAAA,QAGH,eACG,6CAAC,SAAI,WAAU,yBAAwB,0BAAY;AAAA;AAAA;AAAA,EAE3D;AAER;AAEO,IAAM,iBAAa;AAAA,EACtB,SAASC,YAAW,OAAO,KAAK;AAC5B,UAAM;AAAA,MACF,MAAM;AAAA,MACN,cAAc;AAAA,MACd;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA,GAAG;AAAA,IACP,IAAI;AAEJ,UAAM,CAAC,kBAAkB,mBAAmB,QAAI,yBAAuB,WAAW;AAClF,UAAM,OAAO,kBAAkB;AAE/B,UAAM,gBAAY,uBAA6B,IAAI;AACnD,UAAM,CAAC,aAAa,cAAc,QAAI,yBAAS,CAAC;AAEhD,UAAM;AAAA,MACF;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACJ,IAAI,eAAe;AAAA,MACf;AAAA,MACA;AAAA,MACA;AAAA,MACA,iBAAiB;AAAA,IACrB,CAAC;AAED,UAAM,wBAAoB,4BAAY,MAAM;AACxC,qBAAe,CAAC,MAAM,IAAI,CAAC;AAAA,IAC/B,GAAG,CAAC,CAAC;AAEL,UAAM,sBAAkB,4BAAY,MAAM;AACtC,qBAAe,CAAC,MAAM,IAAI,CAAC;AAAA,IAC/B,GAAG,CAAC,CAAC;AAGL,kCAAU,MAAM;AACZ,sBAAgB,WAAW;AAAA,IAC/B,GAAG,CAAC,aAAa,aAAa,CAAC;AAG/B,UAAM,oBAAgB;AAAA,MAClB,OAAO;AAAA,QACH,WAAW;AAAA,QACX,OAAO;AAAA,QACP,OAAO;AAAA,UACH;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA,kBAAAC;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,QACJ;AAAA,QACA,SAAS,CAAC,UAAiB;AACvB,kBAAQ,MAAM,kBAAkB,KAAK;AAAA,QACzC;AAAA,QACA,UAAU,CAAC,MAAM;AAAA,MACrB;AAAA,MACA,CAAC,MAAM,QAAQ;AAAA,IACnB;AAGA;AAAA,MACI;AAAA,MACA,OAAO;AAAA,QACH,OAAO,MAAM;AACT,oBAAU,SAAS,MAAM;AAAA,QAC7B;AAAA,QACA,OAAO,MAAM;AACT,cAAI,UAAU,SAAS;AACnB,wBAAY,UAAU,OAAO;AAAA,UACjC;AACA,2BAAiB;AAAA,QACrB;AAAA,QACA,eAAe,MAAM;AACjB,cAAI,CAAC,UAAU,QAAS,QAAO;AAC/B,cAAI,SAAS,SAAS;AAClB,mBAAO,mBAAmB,UAAU,SAAS,WAAW;AAAA,UAC5D,OAAO;AACH,mBAAO,sBAAsB,UAAU,OAAO;AAAA,UAClD;AAAA,QACJ;AAAA,QACA,gBAAgB,CAAC,aAAqB;AAClC,cAAI,UAAU,WAAW,SAAS,QAAQ;AACtC,mCAAuB,UAAU,SAAS,QAAQ;AAAA,UACtD;AAAA,QACJ;AAAA,QACA,gBAAgB,MAAM;AAAA,QACtB;AAAA,QACA,aAAa,CAAC,OAAe,YAAoB;AAC7C,cAAI,UAAU,WAAW,SAAS,SAAS;AACvC,sBAAU,QAAQ,OAAO,MAAM;AAC3B,oBAAM,WAAO,2BAAS;AACtB,oBAAM,eAAe,iBAAiB,OAAO,OAAO;AAGpD,oBAAM,WAAW,KAAK,YAAY;AAClC,kBAAI,gBAAoC;AACxC,yBAAW,SAAS,UAAU;AAC1B,oBAAI,aAAa,KAAK,GAAG;AACrB,kCAAgB;AAChB;AAAA,gBACJ;AAAA,cACJ;AAEA,kBAAI,eAAe;AAEf,8BAAc,QAAQ,YAAY;AAAA,cACtC,OAAO;AAEH,sBAAM,aAAa,KAAK,cAAc;AACtC,oBAAI,YAAY;AACZ,6BAAW,aAAa,YAAY;AAAA,gBACxC,OAAO;AACH,uBAAK,OAAO,YAAY;AAAA,gBAC5B;AAAA,cACJ;AAAA,YACJ,CAAC;AAAA,UACL;AAAA,QACJ;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA,eAAe,CAAC,QAAgB,YAAoB;AAChD,cAAI,UAAU,WAAW,SAAS,SAAS;AACvC,sBAAU,QAAQ,OAAO,MAAM;AAC3B,oBAAM,gBAAY,gCAAc;AAChC,sBAAI,oCAAkB,SAAS,GAAG;AAC9B,sBAAM,cAAc,mBAAmB,QAAQ,OAAO;AACtD,0BAAU,YAAY,CAAC,WAAW,CAAC;AAAA,cACvC;AAAA,YACJ,CAAC;AAAA,UACL;AAAA,QACJ;AAAA,QACA,UAAU,MAAM;AACZ,cAAI,cAAc;AAClB,cAAI,OAAO;AACX,cAAI,UAAU,SAAS;AACnB,sBAAU,QAAQ,eAAe,EAAE,KAAK,MAAM;AAC1C,yBAAO,2BAAS,EAAE,eAAe,EAAE,KAAK;AAAA,YAC5C,CAAC;AAED,gBAAI,MAAM;AACN,4BAAc,KAAK,UAAU,UAAU,QAAQ,eAAe,EAAE,OAAO,CAAC;AAAA,YAC5E;AAAA,UACJ;AACA,iBAAO;AAAA,YACH;AAAA,YACA;AAAA,YACA,aAAa,YAAY,IAAI,QAAM;AAAA,cAC/B,GAAG;AAAA,cACH,MAAM,EAAE;AAAA;AAAA,YACZ,EAAE;AAAA,UACN;AAAA,QACJ;AAAA,QACA,UAAU,CAAC,UAA+D;AACtE,cAAI,UAAU,WAAW,MAAM,aAAa;AACxC,gBAAI;AACA,oBAAM,cAAc,UAAU,QAAQ,iBAAiB,MAAM,WAAW;AACxE,wBAAU,QAAQ,eAAe,WAAW;AAAA,YAChD,SAAS,GAAG;AACR,sBAAQ,MAAM,mCAAmC,CAAC;AAAA,YACtD;AAAA,UACJ;AACA,cAAI,MAAM,aAAa;AACnB,2BAAe,MAAM,WAAW;AAAA,UACpC;AAAA,QACJ;AAAA,QACA,SAAS,CAAC,MAAc,aAAwB;AAC5C,gBAAM,SAAS,UAAU;AACzB,cAAI,CAAC,OAAQ;AAEb,iBAAO,OAAO,MAAM;AAChB,kBAAM,WAAO,2BAAS;AACtB,iBAAK,MAAM;AACX,kBAAM,gBAAY,uCAAqB;AAEvC,gBAAI,CAAC,MAAM;AACP,mBAAK,OAAO,SAAS;AACrB;AAAA,YACJ;AAEA,gBAAI,CAAC,YAAY,SAAS,WAAW,GAAG;AACpC,wBAAU,WAAO,kCAAgB,IAAI,CAAC;AACtC,mBAAK,OAAO,SAAS;AACrB;AAAA,YACJ;AAEA,kBAAM,UAAU;AAChB,gBAAI,YAAY;AAChB,gBAAI;AAEJ,oBAAQ,QAAQ,QAAQ,KAAK,IAAI,OAAO,MAAM;AAC1C,oBAAM,CAAC,WAAW,MAAM,IAAI;AAC5B,oBAAM,aAAa,MAAM;AAEzB,kBAAI,aAAa,WAAW;AACxB,0BAAU,WAAO,kCAAgB,KAAK,MAAM,WAAW,UAAU,CAAC,CAAC;AAAA,cACvE;AAEA,oBAAM,SAAS,SAAS,KAAK,CAAC,MAAM,EAAE,WAAW,MAAM;AAEvD,kBAAI,QAAQ;AACR,sBAAM,cAAc,mBAAmB,OAAO,QAAQ,OAAO,OAAO;AACpE,0BAAU,OAAO,WAAW;AAAA,cAChC,OAAO;AACH,0BAAU,WAAO,kCAAgB,SAAS,CAAC;AAAA,cAC/C;AAEA,0BAAY,aAAa,UAAU;AAAA,YACvC;AAEA,gBAAI,YAAY,KAAK,QAAQ;AACzB,wBAAU,WAAO,kCAAgB,KAAK,MAAM,SAAS,CAAC,CAAC;AAAA,YAC3D;AAEA,iBAAK,OAAO,SAAS;AAAA,UACzB,CAAC;AAAA,QACL;AAAA,QACA,YAAY,CAAC,SAAiB;AAC1B,gBAAM,SAAS,UAAU;AACzB,cAAI,CAAC,OAAQ;AAEb,iBAAO,OAAO,MAAM;AAChB,kBAAM,gBAAY,gCAAc;AAChC,oBAAI,oCAAkB,SAAS,GAAG;AAC9B,wBAAU,WAAW,IAAI;AAAA,YAC7B,OAAO;AAEH,oBAAM,WAAO,2BAAS;AACtB,oBAAM,YAAY,KAAK,aAAa;AACpC,kBAAI,WAAW;AACX,0BAAU,UAAU;AACpB,sBAAM,mBAAe,gCAAc;AACnC,wBAAI,oCAAkB,YAAY,GAAG;AACjC,+BAAa,WAAW,IAAI;AAAA,gBAChC;AAAA,cACJ;AAAA,YACJ;AAAA,UACJ,CAAC;AAAA,QACL;AAAA,MACJ;AAAA,MACA,CAAC,MAAM,aAAa,kBAAkB,gBAAgB,UAAU,gBAAgB;AAAA,IACpF;AAEA,UAAM,mBAAe,wBAAQ,MAAM,YAAY,UAAU,MAAM,GAAG,CAAC,UAAU,MAAM,CAAC;AAEpF,WACI,6CAAC,cAAc,UAAd,EAAuB,OAAO,cAC3B,uDAAC,0CAAgB,eACb;AAAA,MAAC;AAAA;AAAA,QACI,GAAG;AAAA,QACJ;AAAA,QACA;AAAA,QACA,aAAa;AAAA,QACb,oBAAoB;AAAA,QACpB,aAAa,cAAc;AAAA,QAC3B,eAAe;AAAA,QACf,aAAa;AAAA,QACb;AAAA;AAAA,IACJ,GACJ,GACJ;AAAA,EAER;AACJ;","names":["import_react","import_LexicalComposerContext","import_markdown","import_rich_text","import_list","import_code","import_link","import_lexical","import_lexical","import_lexical","import_lexical","import_LexicalComposerContext","import_jsx_runtime","import_react","import_LexicalComposerContext","import_lexical","import_jsx_runtime","import_react","import_LexicalComposerContext","import_lexical","import_react","import_LexicalComposerContext","import_lexical","import_lexical","import_lexical","import_markdown","import_react","import_lexical","import_react","import_LexicalComposerContext","import_lexical","import_jsx_runtime","import_react","import_jsx_runtime","$insertNodes","import_react","import_LexicalComposerContext","import_lexical","import_LexicalComposerContext","import_lexical","import_react","import_LexicalComposerContext","import_react","import_react","import_LexicalComposerContext","import_lexical","import_link","import_react","import_LexicalComposerContext","import_lexical","import_link","import_jsx_runtime","import_jsx_runtime","import_react","import_jsx_runtime","IMComposer","MarkdownQuoteNode"]}
|
package/dist/index.css.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/IMComposer.css"],"sourcesContent":["/* IMComposer Base Styles */\n.im-composer {\n display: flex;\n flex-direction: column;\n background: #ffffff;\n height: 100%;\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;\n position: relative;\n}\n\n.im-composer-disabled {\n opacity: 0.6;\n pointer-events: none;\n}\n\n/* Editor Container */\n.im-composer-editor-container {\n position: relative;\n min-height: 80px;\n height: 100%;\n overflow-y: auto;\n}\n\n.im-composer-editor {\n font-family: system-ui, -apple-system, BlinkMacSystemFont, \"MozillaTwemojiColr\", \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Noto Color Emoji\", sans-serif;\n height: 100%;\n min-height: 80px;\n padding: 6px 10px;\n outline: none;\n font-size: 14px;\n line-height: 1.5;\n}\n\n.im-composer-editor:focus {\n outline: none;\n}\n\n.im-composer-placeholder {\n position: absolute;\n top: 6px;\n left: 12px;\n color: #999;\n pointer-events: none;\n font-size: 14px;\n}\n\n/* Toolbar */\n.im-composer-toolbar {\n display: flex;\n align-items: center;\n gap: 2px;\n padding: 8px;\n border-bottom: 1px solid #e0e0e0;\n background: #f9f9f9;\n flex-wrap: wrap;\n}\n\n.im-composer-toolbar-btn {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 28px;\n height: 28px;\n border: 1px solid transparent;\n background: transparent;\n border-radius: 4px;\n cursor: pointer;\n font-size: 14px;\n color: #555;\n transition: all 0.2s;\n padding: 0;\n margin-right: 2px;\n}\n\n.im-composer-toolbar-btn svg {\n width: 16px;\n height: 16px;\n pointer-events: none;\n}\n\n.im-composer-toolbar-btn:hover {\n background: #e0e0e0;\n}\n\n.im-composer-toolbar-btn:active {\n background: #d0d0d0;\n}\n\n.im-composer-toolbar-divider {\n width: 1px;\n height: 24px;\n background: #e0e0e0;\n margin: 0 4px;\n}\n\n/* Link Dialog */\n.im-composer-link-dialog {\n position: fixed;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%);\n width: 320px;\n z-index: 1000;\n background: #fff;\n border: 1px solid #e0e0e0;\n border-radius: 8px;\n box-shadow: 0 4px 16px rgba(0, 0, 0, 0.2);\n padding: 12px;\n}\n\n.im-composer-link-dialog-content {\n display: flex;\n flex-direction: column;\n gap: 8px;\n}\n\n.im-composer-link-input {\n padding: 8px 12px;\n border: 1px solid #e0e0e0;\n border-radius: 4px;\n font-size: 14px;\n}\n\n.im-composer-link-input:focus {\n outline: none;\n border-color: #007bff;\n}\n\n.im-composer-link-dialog-buttons {\n display: flex;\n justify-content: flex-end;\n gap: 8px;\n margin-top: 8px;\n}\n\n.im-composer-link-dialog-buttons button {\n padding: 8px 16px;\n border: none;\n border-radius: 4px;\n cursor: pointer;\n font-size: 14px;\n}\n\n.im-composer-link-dialog-buttons button:first-child {\n background: #f0f0f0;\n color: #333;\n}\n\n.im-composer-link-dialog-buttons button:last-child {\n background: #007bff;\n color: #fff;\n}\n\n/* Link Edit Popup */\n.im-composer-link-edit-popup {\n z-index: 1001;\n background: #fff;\n border: 1px solid #e0e0e0;\n border-radius: 6px;\n box-shadow: 0 2px 12px rgba(0, 0, 0, 0.15);\n padding: 8px;\n}\n\n.im-composer-link-edit-content {\n display: flex;\n flex-direction: column;\n gap: 6px;\n}\n\n.im-composer-link-edit-field {\n display: flex;\n flex-direction: column;\n gap: 2px;\n}\n\n.im-composer-link-edit-field label {\n font-size: 11px;\n color: #666;\n font-weight: 500;\n}\n\n.im-composer-link-edit-field input {\n padding: 5px 8px;\n border: 1px solid #e0e0e0;\n border-radius: 4px;\n font-size: 12px;\n}\n\n.im-composer-link-edit-field input:focus {\n outline: none;\n border-color: #007bff;\n}\n\n.im-composer-link-edit-buttons {\n display: flex;\n justify-content: flex-end;\n gap: 6px;\n margin-top: 2px;\n}\n\n.im-composer-link-edit-buttons button {\n padding: 4px 10px;\n border: none;\n border-radius: 4px;\n cursor: pointer;\n font-size: 12px;\n}\n\n.im-composer-link-edit-buttons button.remove {\n background: #f5f5f5;\n color: #e53935;\n}\n\n.im-composer-link-edit-buttons button.remove:hover {\n background: #ffebee;\n}\n\n.im-composer-link-edit-buttons button.save {\n background: #007bff;\n color: #fff;\n}\n\n.im-composer-link-edit-buttons button.save:hover {\n background: #0056b3;\n}\n\n/* Mention */\n.im-composer-mention {\n background: #e8f0fe;\n color: #1a73e8;\n padding: 1px 4px;\n border-radius: 3px;\n font-weight: 500;\n}\n\n.im-composer-mention-menu {\n background: #fff;\n border-radius: 8px;\n box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);\n max-height: 200px;\n overflow-y: auto;\n z-index: 1000;\n min-width: 200px;\n}\n\n.im-composer-mention-item {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 8px 12px;\n cursor: pointer;\n transition: background 0.15s;\n}\n\n.im-composer-mention-item:hover,\n.im-composer-mention-item.selected {\n background: #f3f8ff;\n}\n\n.im-composer-mention-avatar {\n width: 24px;\n height: 24px;\n border-radius: 50%;\n object-fit: cover;\n}\n\n.im-composer-mention-name {\n font-size: 14px;\n color: #333;\n}\n\n/* Attachments */\n.im-composer-attachments {\n display: flex;\n flex-wrap: wrap;\n gap: 8px;\n padding: 8px 12px;\n background: #f9f9f9;\n}\n\n.im-composer-attachments-top {\n border-bottom: 1px solid #e0e0e0;\n}\n\n.im-composer-attachments-bottom {\n border-top: 1px solid #e0e0e0;\n}\n\n.im-composer-attachment-item {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 8px;\n background: #fff;\n border: 1px solid #e0e0e0;\n border-radius: 6px;\n max-width: 200px;\n}\n\n.im-composer-attachment-preview {\n width: 40px;\n height: 40px;\n object-fit: cover;\n border-radius: 4px;\n}\n\n.im-composer-attachment-icon {\n width: 40px;\n height: 40px;\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: 24px;\n background: #f0f0f0;\n border-radius: 4px;\n}\n\n.im-composer-attachment-info {\n flex: 1;\n min-width: 0;\n display: flex;\n flex-direction: column;\n}\n\n.im-composer-attachment-name {\n font-size: 12px;\n color: #333;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.im-composer-attachment-size {\n font-size: 11px;\n color: #999;\n}\n\n.im-composer-attachment-remove {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 20px;\n height: 20px;\n border: none;\n background: #f0f0f0;\n border-radius: 50%;\n cursor: pointer;\n font-size: 14px;\n color: #666;\n flex-shrink: 0;\n}\n\n.im-composer-attachment-remove:hover {\n background: #e0e0e0;\n color: #333;\n}\n\n/* Image */\n.im-composer-image-container {\n display: block;\n margin: 8px 0;\n text-align: center;\n}\n\n.im-composer-image-wrapper {\n display: inline-block;\n position: relative;\n cursor: pointer;\n border: 2px solid transparent;\n border-radius: 6px;\n transition: border-color 0.15s ease;\n}\n\n.im-composer-image-wrapper.selected {\n border-color: #1890ff;\n outline: 2px solid rgba(24, 144, 255, 0.3);\n}\n\n.im-composer-image-wrapper:hover {\n border-color: #91d5ff;\n}\n\n.im-composer-image {\n display: block;\n max-width: 100%;\n max-height: 300px;\n border-radius: 4px;\n user-select: none;\n}\n\n/* Uploading indicator */\n.im-composer-uploading {\n position: absolute;\n bottom: 8px;\n right: 8px;\n padding: 4px 8px;\n background: rgba(0, 0, 0, 0.7);\n color: #fff;\n border-radius: 4px;\n font-size: 12px;\n}\n\n/* Rich text formatting */\n.im-composer-editor h1 {\n font-size: 24px;\n font-weight: 700;\n margin: 16px 0 8px;\n}\n\n.im-composer-editor h2 {\n font-size: 20px;\n font-weight: 600;\n margin: 14px 0 6px;\n}\n\n.im-composer-editor h3 {\n font-size: 16px;\n font-weight: 600;\n margin: 12px 0 4px;\n}\n\n.im-composer-editor blockquote {\n border-left: 3px solid #e0e0e0;\n margin: 8px 0;\n padding-left: 12px;\n color: #666;\n}\n\n.im-composer-editor code {\n background: #f5f5f5;\n padding: 2px 4px;\n border-radius: 3px;\n font-family: 'SF Mono', Monaco, monospace;\n font-size: 13px;\n}\n\n.im-composer-editor pre {\n background: #f5f5f5;\n padding: 12px;\n border-radius: 6px;\n overflow-x: auto;\n margin: 8px 0;\n}\n\n.im-composer-editor pre code {\n background: transparent;\n padding: 0;\n}\n\n.im-composer-editor ul,\n.im-composer-editor ol {\n margin: 8px 0;\n padding-left: 24px;\n}\n\n.im-composer-editor a {\n color: #007bff;\n text-decoration: none;\n}\n\n.im-composer-editor a:hover {\n text-decoration: underline;\n}\n\n.im-composer-editor p,\n.im-composer-paragraph {\n margin: 0;\n}\n\n.im-composer-editor p:last-child {\n margin-bottom: 0;\n}\n\n/* Emoji */\n.im-composer-emoji {\n display: inline;\n vertical-align: middle;\n}\n\n.im-composer-emoji-img {\n width: 1.2em;\n height: 1.2em;\n vertical-align: -0.2em;\n margin: 0 1px;\n display: inline-block;\n}\n\n/* Quote Message */\n.im-composer-quote-wrapper {\n display: block;\n margin-bottom: 8px;\n user-select: none;\n}\n\n.im-composer-quote {\n display: inline-flex;\n align-items: center;\n background-color: #f0f2f5;\n color: #666;\n padding: 4px 8px;\n border-radius: 4px;\n font-size: 12px;\n max-width: 100%;\n box-sizing: border-box;\n gap: 6px;\n}\n\n.im-composer-quote-close {\n order: -1;\n background: none;\n border: none;\n cursor: pointer;\n padding: 0;\n margin: 0;\n color: #999;\n font-size: 14px;\n line-height: 1;\n display: flex;\n align-items: center;\n justify-content: center;\n width: 16px;\n height: 16px;\n}\n\n.im-composer-quote-close:hover {\n color: #666;\n background-color: rgba(0, 0, 0, 0.05);\n border-radius: 50%;\n}\n\n.im-composer-quote-text {\n font-family: system-ui, -apple-system, BlinkMacSystemFont, \"MozillaTwemojiColr\", \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Noto Color Emoji\", sans-serif;\n display: flex;\n align-items: center;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n gap: 4px;\n color: #8e9ab0;\n}\n\n.im-composer-quote-title {\n font-weight: 500;\n}\n\n.im-composer-quote-content {\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n/* Theme Classes */\n.im-composer-text-bold {\n font-weight: bold;\n}\n\n.im-composer-text-italic {\n font-style: italic;\n}\n\n.im-composer-text-underline {\n text-decoration: underline;\n}\n\n.im-composer-text-strikethrough {\n text-decoration: line-through;\n}\n\n.im-composer-text-underline-strikethrough {\n text-decoration: underline line-through;\n}\n\n.im-composer-text-code {\n background-color: #f0f2f5;\n padding: 1px 0.25rem;\n font-family: Menlo, Consolas, Monaco, monospace;\n font-size: 94%;\n border-radius: 3px;\n}\n\n.im-composer-toolbar-btn.active {\n background-color: #e8e8e8;\n color: #000;\n}"],"mappings":"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","names":[]}
|