@blokhaus/core 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +191 -0
- package/dist/index.cjs +11541 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +834 -0
- package/dist/index.d.ts +834 -0
- package/dist/index.js +11725 -0
- package/dist/index.js.map +1 -0
- package/package.json +91 -0
- package/src/styles/tokens.css +183 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/components/EditorRoot.tsx","../src/nodes/index.ts","../src/nodes/ImageNode.tsx","../src/nodes/LoadingImageNode.tsx","../src/nodes/AIPreviewNode.tsx","../src/plugins/aiProviderRegistry.ts","../src/utils/markdown.ts","../src/nodes/VideoNode.tsx","../src/nodes/CalloutNode.tsx","../src/nodes/HorizontalRuleNode.tsx","../src/nodes/ToggleContainerNode.tsx","../src/nodes/ToggleTitleNode.tsx","../src/nodes/ToggleContentNode.tsx","../src/nodes/MentionNode.tsx","../src/nodes/CodeBlockNode.tsx","../src/nodes/LoadingVideoNode.tsx","../src/theme.ts","../src/index.ts","../src/components/FloatingToolbar.tsx","../src/commands.ts","../src/utils/style.ts","../src/components/ColorPicker.tsx","../src/data/color-palette.ts","../src/components/FontPicker.tsx","../src/data/font-families.ts","../src/components/SlashMenu.tsx","../src/components/OverlayPortal.tsx","../src/components/TurnIntoMenu.tsx","../src/plugins/InputRulePlugin.tsx","../src/plugins/ImagePlugin.tsx","../src/plugins/AIPlugin.tsx","../src/plugins/MentionPlugin.tsx","../src/plugins/PastePlugin.tsx","../src/utils/sanitize.ts","../src/plugins/EmojiPickerPlugin.tsx","../src/data/emoji-list.ts","../src/plugins/LinkPlugin.tsx","../src/hooks/useEditorState.ts","../src/hooks/useWordCount.ts","../src/components/MobileToolbar.tsx","../src/plugins/ColorPlugin.tsx","../src/plugins/ListPlugin.tsx","../src/plugins/TablePlugin.tsx","../src/components/TableActionMenu.tsx","../src/components/TableHoverActions.tsx","../src/plugins/DirectionPlugin.tsx","../src/plugins/CalloutPlugin.tsx","../src/data/callout-presets.ts","../src/plugins/VideoPlugin.tsx","../src/utils/video-embeds.ts","../src/plugins/TogglePlugin.tsx","../src/plugins/BlockSelectionPlugin.tsx","../src/hooks/useBlockHighlight.ts","../src/utils/block-selection.ts","../src/hooks/useMarqueeSelect.ts","../src/hooks/useBlockSelectionActions.ts"],"sourcesContent":["\"use client\";\n\n// REACT\nimport { useEffect } from \"react\";\n\n// LEXICAL\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 { AutoFocusPlugin } from \"@lexical/react/LexicalAutoFocusPlugin\";\nimport { LexicalErrorBoundary } from \"@lexical/react/LexicalErrorBoundary\";\nimport { useLexicalComposerContext } from \"@lexical/react/LexicalComposerContext\";\nimport { $getRoot } from \"lexical\";\n\n// NODES\nimport { ALL_NODES } from \"../nodes\";\n\n// THEME\nimport { blokhausTheme } from \"../theme\";\n\ninterface EditorRootProps {\n /** Unique namespace — required for multi-editor isolation. See Section 8. */\n namespace: string;\n /** Initial serialized Lexical JSON state. Pass null for a blank editor. */\n initialState?: string | null;\n children?: React.ReactNode;\n className?: string;\n /** Document-level text direction. Omit for per-paragraph auto-detection (default). */\n dir?: \"ltr\" | \"rtl\" | \"auto\";\n /** Customizable placeholder text. Default: \"Start writing...\" */\n placeholder?: string;\n /** Read-only mode. Default: true (editable). */\n editable?: boolean;\n /** Whether the editor auto-focuses on mount. Default: true. */\n autoFocus?: boolean;\n /** Custom error handler for Lexical errors. Default: console.error + throw. */\n onError?: (error: Error) => void;\n}\n\n/** Sets the root node direction on mount when an explicit dir is provided. */\nfunction SetInitialDirection({ dir }: { dir: \"ltr\" | \"rtl\" }) {\n const [editor] = useLexicalComposerContext();\n useEffect(() => {\n editor.update(() => {\n $getRoot().setDirection(dir);\n });\n // Only on mount — do not override per-block directions on re-render\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n return null;\n}\n\nconst defaultOnError = (error: Error) => {\n console.error(\"[Blokhaus] Lexical error:\", error);\n throw error;\n};\n\nexport function EditorRoot({\n namespace,\n initialState,\n children,\n className,\n dir,\n placeholder = \"Start writing...\",\n editable = true,\n autoFocus = true,\n onError = defaultOnError,\n}: EditorRootProps) {\n const initialConfig = {\n namespace,\n nodes: ALL_NODES,\n theme: blokhausTheme,\n editorState: initialState ?? undefined,\n editable,\n onError,\n };\n\n return (\n <LexicalComposer initialConfig={initialConfig}>\n <div className={className} dir={dir} data-blokhaus-root data-namespace={namespace}>\n <RichTextPlugin\n contentEditable={\n <ContentEditable\n aria-label=\"Editor content\"\n aria-placeholder={placeholder}\n className=\"blokhaus-content-editable focus:outline-none\"\n placeholder={\n <div className=\"blokhaus-placeholder\">\n {placeholder}\n </div>\n }\n />\n }\n placeholder={null}\n ErrorBoundary={LexicalErrorBoundary}\n />\n <HistoryPlugin />\n {autoFocus && <AutoFocusPlugin />}\n {dir && dir !== \"auto\" && <SetInitialDirection dir={dir} />}\n {children}\n </div>\n </LexicalComposer>\n );\n}\n","import type { Klass, LexicalNode } from 'lexical';\nimport { HeadingNode, QuoteNode } from '@lexical/rich-text';\nimport { ListNode, ListItemNode } from '@lexical/list';\nimport { LinkNode, AutoLinkNode } from '@lexical/link';\nimport { TableNode, TableRowNode, TableCellNode } from '@lexical/table';\nimport { ImageNode } from './ImageNode';\nimport { LoadingImageNode } from './LoadingImageNode';\nimport { AIPreviewNode } from './AIPreviewNode';\nimport { MentionNode } from './MentionNode';\nimport { CodeBlockNode } from './CodeBlockNode';\nimport { CalloutNode } from './CalloutNode';\nimport { VideoNode } from './VideoNode';\nimport { LoadingVideoNode } from './LoadingVideoNode';\nimport { HorizontalRuleNode } from './HorizontalRuleNode';\nimport { ToggleContainerNode } from './ToggleContainerNode';\nimport { ToggleTitleNode } from './ToggleTitleNode';\nimport { ToggleContentNode } from './ToggleContentNode';\n\nexport const ALL_NODES: Array<Klass<LexicalNode>> = [\n HeadingNode,\n QuoteNode,\n ListNode,\n ListItemNode,\n LinkNode,\n AutoLinkNode,\n TableNode,\n TableRowNode,\n TableCellNode,\n ImageNode,\n LoadingImageNode,\n AIPreviewNode,\n MentionNode,\n CodeBlockNode,\n CalloutNode,\n VideoNode,\n LoadingVideoNode,\n HorizontalRuleNode,\n ToggleContainerNode,\n ToggleTitleNode,\n ToggleContentNode,\n];\n","\"use client\";\n\nimport { useCallback, useEffect, useRef } from \"react\";\nimport type { ReactElement } from \"react\";\n\nimport type {\n DOMConversionMap,\n DOMConversionOutput,\n DOMExportOutput,\n EditorConfig,\n LexicalNode,\n NodeKey,\n SerializedLexicalNode,\n Spread,\n} from \"lexical\";\nimport {\n $getNodeByKey,\n $getSelection,\n $isNodeSelection,\n CLICK_COMMAND,\n COMMAND_PRIORITY_LOW,\n DecoratorNode,\n KEY_BACKSPACE_COMMAND,\n KEY_DELETE_COMMAND,\n} from \"lexical\";\nimport { useLexicalComposerContext } from \"@lexical/react/LexicalComposerContext\";\nimport { useLexicalNodeSelection } from \"@lexical/react/useLexicalNodeSelection\";\n\nexport interface ImagePayload {\n src: string;\n altText: string;\n width?: number;\n height?: number;\n key?: NodeKey;\n}\n\nexport type SerializedImageNode = Spread<\n {\n src: string;\n altText: string;\n width?: number;\n height?: number;\n },\n SerializedLexicalNode\n>;\n\nexport class ImageNode extends DecoratorNode<ReactElement> {\n __src: string;\n __altText: string;\n __width: number | undefined;\n __height: number | undefined;\n\n static getType(): string {\n return \"image\";\n }\n\n static clone(node: ImageNode): ImageNode {\n return new ImageNode(\n node.__src,\n node.__altText,\n node.__width,\n node.__height,\n node.__key,\n );\n }\n\n constructor(\n src: string,\n altText: string,\n width?: number,\n height?: number,\n key?: NodeKey,\n ) {\n super(key);\n this.__src = src;\n this.__altText = altText;\n this.__width = width;\n this.__height = height;\n }\n\n createDOM(_config: EditorConfig): HTMLElement {\n const div = document.createElement(\"div\");\n div.style.display = \"inline-block\";\n div.style.maxWidth = \"100%\";\n return div;\n }\n\n updateDOM(): false {\n return false;\n }\n\n exportDOM(): DOMExportOutput {\n const img = document.createElement(\"img\");\n img.setAttribute(\"src\", this.__src);\n img.setAttribute(\"alt\", this.__altText);\n if (this.__width) img.setAttribute(\"width\", String(this.__width));\n if (this.__height) img.setAttribute(\"height\", String(this.__height));\n return { element: img };\n }\n\n static importDOM(): DOMConversionMap | null {\n return {\n img: () => ({\n conversion: convertImageElement,\n priority: 0,\n }),\n };\n }\n\n static importJSON(serializedNode: SerializedImageNode): ImageNode {\n return $createImageNode({\n src: serializedNode.src,\n altText: serializedNode.altText,\n width: serializedNode.width,\n height: serializedNode.height,\n });\n }\n\n exportJSON(): SerializedImageNode {\n return {\n ...super.exportJSON(),\n src: this.__src,\n altText: this.__altText,\n width: this.__width,\n height: this.__height,\n type: \"image\",\n version: 1,\n };\n }\n\n getSrc(): string {\n return this.__src;\n }\n\n getAltText(): string {\n return this.__altText;\n }\n\n decorate(): ReactElement {\n return (\n <ImageComponent\n src={this.__src}\n altText={this.__altText}\n width={this.__width}\n height={this.__height}\n nodeKey={this.getKey()}\n />\n );\n }\n}\n\nfunction convertImageElement(domNode: Node): DOMConversionOutput | null {\n if (domNode instanceof HTMLImageElement) {\n const src = domNode.getAttribute(\"src\");\n const alt = domNode.getAttribute(\"alt\") || \"\";\n if (src) {\n const node = $createImageNode({ src, altText: alt });\n return { node };\n }\n }\n return null;\n}\n\nfunction ImageComponent({\n src,\n altText,\n width,\n height,\n nodeKey,\n}: {\n src: string;\n altText: string;\n width?: number;\n height?: number;\n nodeKey: NodeKey;\n}) {\n const [editor] = useLexicalComposerContext();\n const [isSelected, setSelected, clearSelection] =\n useLexicalNodeSelection(nodeKey);\n const imgRef = useRef<HTMLDivElement>(null);\n\n useEffect(() => {\n return editor.registerCommand(\n CLICK_COMMAND,\n (event: MouseEvent) => {\n if (imgRef.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, clearSelection, setSelected]);\n\n const onDelete = useCallback(\n (event: KeyboardEvent) => {\n if (isSelected) {\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 const unregisterBackspace = editor.registerCommand(\n KEY_BACKSPACE_COMMAND,\n onDelete,\n COMMAND_PRIORITY_LOW,\n );\n const unregisterDelete = editor.registerCommand(\n KEY_DELETE_COMMAND,\n onDelete,\n COMMAND_PRIORITY_LOW,\n );\n return () => {\n unregisterBackspace();\n unregisterDelete();\n };\n }, [editor, onDelete]);\n\n return (\n <div\n ref={imgRef}\n data-testid=\"image-node\"\n style={{\n display: \"inline-block\",\n maxWidth: \"100%\",\n position: \"relative\",\n cursor: \"pointer\",\n }}\n role=\"img\"\n aria-label={altText}\n >\n <img\n src={src}\n alt={altText}\n width={width}\n height={height}\n style={{\n maxWidth: \"100%\",\n borderRadius: \"var(--blokhaus-radius, 0.5rem)\",\n outline: isSelected\n ? \"2px solid var(--blokhaus-ring, #3b82f6)\"\n : \"none\",\n outlineOffset: \"2px\",\n }}\n draggable={false}\n />\n </div>\n );\n}\n\nexport function $createImageNode(payload: ImagePayload): ImageNode {\n return new ImageNode(\n payload.src,\n payload.altText,\n payload.width,\n payload.height,\n payload.key,\n );\n}\n\nexport function $isImageNode(\n node: LexicalNode | null | undefined,\n): node is ImageNode {\n return node instanceof ImageNode;\n}\n","\"use client\";\n\nimport type { ReactElement } from \"react\";\nimport type {\n DOMConversionMap,\n DOMExportOutput,\n EditorConfig,\n LexicalNode,\n NodeKey,\n SerializedLexicalNode,\n Spread,\n} from \"lexical\";\nimport { DecoratorNode } from \"lexical\";\n\nexport type SerializedLoadingImageNode = Spread<\n { objectURL: string },\n SerializedLexicalNode\n>;\n\nexport class LoadingImageNode extends DecoratorNode<ReactElement> {\n __objectURL: string;\n\n static getType(): string {\n return \"loading-image\";\n }\n\n static clone(node: LoadingImageNode): LoadingImageNode {\n return new LoadingImageNode(node.__objectURL, node.__key);\n }\n\n constructor(objectURL: string, key?: NodeKey) {\n super(key);\n this.__objectURL = objectURL;\n }\n\n createDOM(_config: EditorConfig): HTMLElement {\n const div = document.createElement(\"div\");\n div.style.position = \"relative\";\n div.style.display = \"inline-block\";\n div.style.maxWidth = \"100%\";\n return div;\n }\n\n updateDOM(): false {\n return false;\n }\n\n exportDOM(): DOMExportOutput {\n const element = document.createElement(\"div\");\n element.setAttribute(\"data-loading-image\", \"true\");\n return { element };\n }\n\n static importDOM(): DOMConversionMap | null {\n return null;\n }\n\n static importJSON(\n serializedNode: SerializedLoadingImageNode,\n ): LoadingImageNode {\n return $createLoadingImageNode(serializedNode.objectURL);\n }\n\n exportJSON(): SerializedLoadingImageNode {\n return {\n ...super.exportJSON(),\n objectURL: this.__objectURL,\n type: \"loading-image\",\n version: 1,\n };\n }\n\n getObjectURL(): string {\n return this.__objectURL;\n }\n\n decorate(): ReactElement {\n return <LoadingImageComponent objectURL={this.__objectURL} />;\n }\n}\n\nfunction LoadingImageComponent({ objectURL }: { objectURL: string }) {\n return (\n <div\n data-testid=\"loading-image-node\"\n style={{\n position: \"relative\",\n display: \"inline-block\",\n maxWidth: \"100%\",\n }}\n >\n <img\n src={objectURL}\n alt=\"Uploading...\"\n style={{\n maxWidth: \"100%\",\n borderRadius: \"var(--blokhaus-radius, 0.5rem)\",\n opacity: 0.6,\n }}\n />\n {/* Spinner overlay */}\n <div\n data-testid=\"loading-image-spinner\"\n style={{\n position: \"absolute\",\n inset: 0,\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n backgroundColor: \"var(--blokhaus-loading-overlay, rgba(0, 0, 0, 0.1))\",\n borderRadius: \"var(--blokhaus-radius, 0.5rem)\",\n }}\n >\n <div\n style={{\n width: \"32px\",\n height: \"32px\",\n border: \"3px solid var(--blokhaus-muted, #e2e8f0)\",\n borderTopColor: \"var(--blokhaus-accent, #3b82f6)\",\n borderRadius: \"50%\",\n animation: \"blokhaus-spin 0.8s linear infinite\",\n }}\n />\n </div>\n <style>{`@keyframes blokhaus-spin { to { transform: rotate(360deg); } }`}</style>\n </div>\n );\n}\n\nexport function $createLoadingImageNode(objectURL: string): LoadingImageNode {\n return new LoadingImageNode(objectURL);\n}\n\nexport function $isLoadingImageNode(\n node: LexicalNode | null | undefined,\n): node is LoadingImageNode {\n return node instanceof LoadingImageNode;\n}\n","\"use client\";\n\nimport { useCallback, useEffect, useRef, useState } from \"react\";\nimport type { ReactElement } from \"react\";\n\nimport type {\n DOMConversionMap,\n DOMExportOutput,\n EditorConfig,\n LexicalNode,\n NodeKey,\n SerializedLexicalNode,\n Spread,\n} from \"lexical\";\nimport { $getNodeByKey, DecoratorNode } from \"lexical\";\nimport { useLexicalComposerContext } from \"@lexical/react/LexicalComposerContext\";\n\nimport { getAIProvider, getAIConfig } from \"../plugins/aiProviderRegistry\";\nimport { $parseMarkdownToLexicalNodes } from \"../utils/markdown\";\nimport type { AIPluginConfig } from \"../types\";\n\nimport { SparkleIcon, CheckIcon, XIcon, ArrowClockwiseIcon } from \"@phosphor-icons/react\";\n\nexport interface AIPreviewPayload {\n prompt: string;\n context: string;\n key?: NodeKey;\n}\n\nexport type SerializedAIPreviewNode = Spread<\n {\n prompt: string;\n context: string;\n },\n SerializedLexicalNode\n>;\n\ntype StreamStatus = \"streaming\" | \"complete\" | \"error\";\n\nexport class AIPreviewNode extends DecoratorNode<ReactElement> {\n __prompt: string;\n __context: string;\n\n static getType(): string {\n return \"ai-preview\";\n }\n\n static clone(node: AIPreviewNode): AIPreviewNode {\n return new AIPreviewNode(node.__prompt, node.__context, node.__key);\n }\n\n constructor(prompt: string, context: string, key?: NodeKey) {\n super(key);\n this.__prompt = prompt;\n this.__context = context;\n }\n\n createDOM(_config: EditorConfig): HTMLElement {\n const div = document.createElement(\"div\");\n div.style.display = \"block\";\n div.style.width = \"100%\";\n return div;\n }\n\n updateDOM(): false {\n return false;\n }\n\n exportDOM(): DOMExportOutput {\n // Transient node — should not persist in exported HTML\n const div = document.createElement(\"div\");\n div.textContent = \"[AI Preview]\";\n return { element: div };\n }\n\n static importDOM(): DOMConversionMap | null {\n // Transient node — never imported from HTML\n return null;\n }\n\n static importJSON(serialized: SerializedAIPreviewNode): AIPreviewNode {\n return $createAIPreviewNode({\n prompt: serialized.prompt,\n context: serialized.context,\n });\n }\n\n exportJSON(): SerializedAIPreviewNode {\n return {\n ...super.exportJSON(),\n prompt: this.__prompt,\n context: this.__context,\n type: \"ai-preview\",\n version: 1,\n };\n }\n\n decorate(): ReactElement {\n return (\n <AIPreviewComponent\n nodeKey={this.getKey()}\n prompt={this.__prompt}\n context={this.__context}\n />\n );\n }\n}\n\nfunction AIPreviewComponent({\n nodeKey,\n prompt,\n context,\n}: {\n nodeKey: NodeKey;\n prompt: string;\n context: string;\n}) {\n const [editor] = useLexicalComposerContext();\n const [content, setContent] = useState(\"\");\n const [status, setStatus] = useState<StreamStatus>(\"streaming\");\n const [errorMessage, setErrorMessage] = useState<string>(\"\");\n const [retryCount, setRetryCount] = useState(0);\n const cancelledRef = useRef(false);\n const readerRef = useRef<ReadableStreamDefaultReader<string> | null>(null);\n const configRef = useRef<AIPluginConfig>({});\n\n // Read config from registry once (stable across renders)\n useEffect(() => {\n configRef.current = getAIConfig(editor);\n }, [editor]);\n\n // Resolved labels with defaults\n const labels = configRef.current.labels ?? {};\n const headerLabel = labels.header ?? \"AI\";\n const streamingLabel = labels.streaming ?? \"generating...\";\n const acceptLabel = labels.accept ?? \"Accept\";\n const discardLabel = labels.discard ?? \"Discard\";\n const retryLabel = labels.retry ?? \"Retry\";\n const dismissLabel = labels.dismiss ?? \"Dismiss\";\n const defaultErrorLabel = labels.defaultError ?? \"An error occurred\";\n\n // Retry limits\n const maxRetries = configRef.current.retry?.maxRetries ?? Infinity;\n\n // Stream on mount (and on retry) — local React state only, NO editor.update() during streaming\n useEffect(() => {\n cancelledRef.current = false;\n setContent(\"\");\n setStatus(\"streaming\");\n setErrorMessage(\"\");\n\n const provider = getAIProvider(editor);\n const config = getAIConfig(editor);\n configRef.current = config;\n\n if (!provider) {\n setStatus(\"error\");\n setErrorMessage(\"No AI provider configured\");\n return;\n }\n\n let accumulated = \"\";\n\n provider\n .generate({ prompt, context, config: config.generate })\n .then(async (stream) => {\n const reader = stream.getReader();\n readerRef.current = reader;\n\n while (true) {\n if (cancelledRef.current) {\n reader.cancel();\n break;\n }\n\n const { done, value } = await reader.read();\n if (done) break;\n\n accumulated += value;\n setContent(accumulated);\n }\n\n if (!cancelledRef.current) {\n setStatus(\"complete\");\n }\n })\n .catch((err: unknown) => {\n if (!cancelledRef.current) {\n const error = err instanceof Error ? err : new Error(\"Stream failed\");\n setStatus(\"error\");\n setErrorMessage(error.message);\n config.onError?.(error);\n }\n });\n\n return () => {\n cancelledRef.current = true;\n readerRef.current?.cancel();\n };\n }, [editor, prompt, context, retryCount]);\n\n // Retry: bump the counter to re-trigger the stream effect\n const handleRetry = useCallback(() => {\n setRetryCount((c) => c + 1);\n }, []);\n\n // Accept: parse Markdown → replace this node (single editor.update())\n const handleAccept = useCallback(() => {\n configRef.current.onAccept?.(content);\n editor.update(() => {\n const node = $getNodeByKey(nodeKey);\n if (!node) return;\n\n const lexicalNodes = $parseMarkdownToLexicalNodes(content);\n\n if (lexicalNodes.length === 0) {\n node.remove();\n return;\n }\n\n // Replace the AIPreviewNode with the parsed nodes\n // Insert first node in place, then insert remaining after it\n const firstNode = lexicalNodes[0]!;\n node.replace(firstNode);\n\n let current = firstNode;\n for (let i = 1; i < lexicalNodes.length; i++) {\n current.insertAfter(lexicalNodes[i]!);\n current = lexicalNodes[i]!;\n }\n });\n }, [editor, nodeKey, content]);\n\n // Discard: remove this node (single editor.update())\n const handleDiscard = useCallback(() => {\n if (status !== \"error\") {\n configRef.current.onDiscard?.();\n }\n editor.update(() => {\n const node = $getNodeByKey(nodeKey);\n if (node) {\n node.remove();\n }\n });\n }, [editor, nodeKey, status]);\n\n return (\n <div\n data-testid=\"ai-preview-node\"\n style={{\n position: \"relative\",\n borderInlineStart: \"3px solid var(--blokhaus-ai-stream, #3366cc)\",\n borderRadius: \"8px\",\n padding: \"16px 20px\",\n margin: \"8px 0\",\n backgroundColor: \"var(--blokhaus-ai-stream-bg, rgba(51, 102, 204, 0.05))\",\n fontFamily: \"var(--blokhaus-font-sans, system-ui, sans-serif)\",\n }}\n >\n <div\n style={{\n display: \"flex\",\n alignItems: \"center\",\n gap: \"6px\",\n marginBottom: \"12px\",\n fontSize: \"12px\",\n fontWeight: 500,\n color: \"var(--blokhaus-ai-stream, #3366cc)\",\n letterSpacing: \"0.02em\",\n textTransform: \"uppercase\",\n }}\n >\n <SparkleIcon size={14} weight=\"fill\" />\n <span>{headerLabel}</span>\n {status === \"streaming\" && (\n <span\n style={{\n fontSize: \"11px\",\n fontWeight: 400,\n color: \"var(--blokhaus-muted-foreground, #94a3b8)\",\n textTransform: \"none\",\n letterSpacing: \"0\",\n }}\n >\n {streamingLabel}\n </span>\n )}\n </div>\n\n {status === \"error\" ? (\n <div\n data-testid=\"ai-preview-error\"\n style={{\n color: \"var(--blokhaus-destructive, #ef4444)\",\n fontSize: \"14px\",\n }}\n >\n {errorMessage || defaultErrorLabel}\n </div>\n ) : (\n <div\n data-testid=\"ai-preview-content\"\n style={{\n fontSize: \"15px\",\n lineHeight: 1.7,\n color: \"var(--blokhaus-foreground, #0f172a)\",\n whiteSpace: \"pre-wrap\",\n }}\n >\n {content}\n {status === \"streaming\" && (\n <span\n style={{\n display: \"inline-block\",\n width: \"2px\",\n height: \"1em\",\n marginInlineStart: \"1px\",\n backgroundColor: \"var(--blokhaus-ai-stream, #3366cc)\",\n animation: \"blokhaus-cursor-blink 1s step-end infinite\",\n verticalAlign: \"text-bottom\",\n }}\n />\n )}\n </div>\n )}\n\n {(status === \"complete\" || status === \"error\") && (\n <div\n style={{\n display: \"flex\",\n gap: \"8px\",\n marginTop: \"14px\",\n }}\n >\n {status === \"complete\" && (\n <button\n type=\"button\"\n data-testid=\"ai-preview-accept\"\n onClick={handleAccept}\n style={{\n display: \"flex\",\n alignItems: \"center\",\n gap: \"5px\",\n padding: \"6px 14px\",\n borderRadius: \"8px\",\n border: \"none\",\n fontSize: \"13px\",\n fontWeight: 500,\n cursor: \"pointer\",\n backgroundColor: \"var(--blokhaus-ai-stream, #3366cc)\",\n color: \"#fff\",\n transition: \"opacity 0.15s\",\n }}\n >\n <CheckIcon size={14} weight=\"bold\" />\n {acceptLabel}\n </button>\n )}\n {status === \"error\" && retryCount < maxRetries && (\n <button\n type=\"button\"\n data-testid=\"ai-preview-retry\"\n onClick={handleRetry}\n style={{\n display: \"flex\",\n alignItems: \"center\",\n gap: \"5px\",\n padding: \"6px 14px\",\n borderRadius: \"8px\",\n border: \"none\",\n fontSize: \"13px\",\n fontWeight: 500,\n cursor: \"pointer\",\n backgroundColor: \"var(--blokhaus-ai-stream, #3366cc)\",\n color: \"#fff\",\n transition: \"opacity 0.15s\",\n }}\n >\n <span\n style={{\n display: \"inline-flex\",\n animation: \"blokhaus-retry-spin 0.5s ease-in-out\",\n }}\n key={retryCount}\n >\n <ArrowClockwiseIcon size={14} weight=\"bold\" />\n </span>\n {retryLabel}\n </button>\n )}\n <button\n type=\"button\"\n data-testid={\n status === \"error\" ? \"ai-preview-dismiss\" : \"ai-preview-discard\"\n }\n onClick={handleDiscard}\n style={{\n display: \"flex\",\n alignItems: \"center\",\n gap: \"5px\",\n padding: \"6px 14px\",\n borderRadius: \"8px\",\n border: \"1px solid var(--blokhaus-border, #e2e8f0)\",\n fontSize: \"13px\",\n fontWeight: 500,\n cursor: \"pointer\",\n backgroundColor: \"transparent\",\n color: \"var(--blokhaus-muted-foreground, #64748b)\",\n transition: \"opacity 0.15s\",\n }}\n >\n <XIcon size={14} weight=\"bold\" />\n {status === \"error\" ? dismissLabel : discardLabel}\n </button>\n </div>\n )}\n\n <style\n dangerouslySetInnerHTML={{\n __html: `\n @keyframes blokhaus-cursor-blink {\n 0%, 100% { opacity: 1; }\n 50% { opacity: 0; }\n }\n @keyframes blokhaus-retry-spin {\n from { transform: rotate(0deg); }\n to { transform: rotate(360deg); }\n }\n `,\n }}\n />\n </div>\n );\n}\n\nexport function $createAIPreviewNode(\n payload: AIPreviewPayload,\n): AIPreviewNode {\n return new AIPreviewNode(payload.prompt, payload.context, payload.key);\n}\n\nexport function $isAIPreviewNode(\n node: LexicalNode | null | undefined,\n): node is AIPreviewNode {\n return node instanceof AIPreviewNode;\n}\n","import type { LexicalEditor } from \"lexical\";\nimport type { AIProvider, AIPluginConfig } from \"../types\";\n\n/** Internal entry stored for each editor instance. */\ninterface AIRegistryEntry {\n provider: AIProvider;\n config: AIPluginConfig;\n}\n\n/**\n * WeakMap-based registry that maps each Lexical editor instance to its AIProvider + config.\n * Using WeakMap ensures:\n * 1. Multi-editor isolation — each editor has its own provider\n * 2. No memory leaks — when the editor is garbage collected, the entry is removed\n * 3. No module-level mutable singletons — the WeakMap is keyed by instance\n */\nconst registry = new WeakMap<LexicalEditor, AIRegistryEntry>();\n\nexport function registerAIProvider(\n editor: LexicalEditor,\n provider: AIProvider,\n config: AIPluginConfig = {},\n): void {\n registry.set(editor, { provider, config });\n}\n\nexport function getAIProvider(\n editor: LexicalEditor,\n): AIProvider | null {\n return registry.get(editor)?.provider ?? null;\n}\n\nexport function getAIConfig(\n editor: LexicalEditor,\n): AIPluginConfig {\n return registry.get(editor)?.config ?? {};\n}\n\nexport function unregisterAIProvider(editor: LexicalEditor): void {\n registry.delete(editor);\n}\n","import type { LexicalNode, ElementNode } from \"lexical\";\nimport {\n $createParagraphNode,\n $createTextNode,\n $isElementNode,\n $isTextNode,\n} from \"lexical\";\nimport { $createHeadingNode, $isHeadingNode, $isQuoteNode } from \"@lexical/rich-text\";\nimport { $createQuoteNode } from \"@lexical/rich-text\";\nimport {\n $createListItemNode,\n $createListNode,\n $isListNode,\n $isListItemNode,\n} from \"@lexical/list\";\nimport { $isImageNode } from \"../nodes/ImageNode\";\nimport { $isVideoNode } from \"../nodes/VideoNode\";\nimport { $isLinkNode } from \"@lexical/link\";\nimport {\n $isTableNode,\n $isTableRowNode,\n $isTableCellNode,\n} from \"@lexical/table\";\nimport { $isCalloutNode } from \"../nodes/CalloutNode\";\nimport { $isHorizontalRuleNode } from \"../nodes/HorizontalRuleNode\";\nimport { $isToggleContainerNode } from \"../nodes/ToggleContainerNode\";\nimport { $isToggleTitleNode } from \"../nodes/ToggleTitleNode\";\nimport { $isToggleContentNode } from \"../nodes/ToggleContentNode\";\n\n/**\n * Serializes an array of Lexical nodes to Markdown.\n * Pure function — call inside editor.read().\n */\nexport function serializeNodesToMarkdown(nodes: LexicalNode[]): string {\n const lines: string[] = [];\n\n for (const node of nodes) {\n lines.push(serializeNode(node));\n }\n\n return lines.join(\"\\n\\n\");\n}\n\nfunction serializeNode(node: LexicalNode): string {\n if ($isHeadingNode(node)) {\n const tag = node.getTag();\n const level = parseInt(tag.replace(\"h\", \"\"), 10);\n const prefix = \"#\".repeat(level);\n return `${prefix} ${serializeChildren(node)}`;\n }\n\n if ($isQuoteNode(node)) {\n return `> ${serializeChildren(node)}`;\n }\n\n if ($isListNode(node)) {\n const listType = node.getListType();\n const items = node.getChildren();\n return items\n .map((item, i) => {\n const content = $isElementNode(item)\n ? serializeChildren(item)\n : item.getTextContent();\n let prefix: string;\n if (listType === \"number\") {\n prefix = `${i + 1}. `;\n } else if (listType === \"check\" && $isListItemNode(item)) {\n prefix = item.getChecked() ? \"- [x] \" : \"- [ ] \";\n } else {\n prefix = \"- \";\n }\n return `${prefix}${content}`;\n })\n .join(\"\\n\");\n }\n\n if ($isImageNode(node)) {\n return `})`;\n }\n\n if ($isVideoNode(node)) {\n const title = node.getTitle() || \"Video\";\n return `[${title}](${node.getSrc()})`;\n }\n\n if ($isHorizontalRuleNode(node)) {\n return \"---\";\n }\n\n if ($isTableNode(node)) {\n const rows = node.getChildren();\n const lines: string[] = [];\n\n for (let rowIdx = 0; rowIdx < rows.length; rowIdx++) {\n const row = rows[rowIdx];\n if (!row || !$isTableRowNode(row)) continue;\n\n const cells = row.getChildren();\n const cellTexts: string[] = [];\n\n for (const cell of cells) {\n if ($isTableCellNode(cell)) {\n cellTexts.push(serializeChildren(cell).replace(/\\|/g, \"\\\\|\"));\n }\n }\n\n lines.push(`| ${cellTexts.join(\" | \")} |`);\n\n if (rowIdx === 0) {\n lines.push(`| ${cellTexts.map(() => \"---\").join(\" | \")} |`);\n }\n }\n\n return lines.join(\"\\n\");\n }\n\n if ($isToggleContainerNode(node)) {\n const children = node.getChildren();\n let titleText = \"\";\n let contentText = \"\";\n\n for (const child of children) {\n if ($isToggleTitleNode(child)) {\n titleText = serializeChildren(child);\n } else if ($isToggleContentNode(child)) {\n contentText = child\n .getChildren()\n .map((contentChild) => {\n if ($isElementNode(contentChild)) {\n return serializeChildren(contentChild);\n }\n return contentChild.getTextContent();\n })\n .join(\"\\n\");\n }\n }\n\n return `<details>\\n<summary>${titleText}</summary>\\n\\n${contentText}\\n\\n</details>`;\n }\n\n if ($isCalloutNode(node)) {\n const emoji = node.getEmoji();\n const childContent = node\n .getChildren()\n .map((child) => {\n if ($isElementNode(child)) {\n return serializeChildren(child);\n }\n return child.getTextContent();\n })\n .join(\"\\n> \");\n return `> [!${emoji}] ${childContent}`;\n }\n\n if ($isElementNode(node)) {\n return serializeChildren(node);\n }\n\n return node.getTextContent();\n}\n\nfunction serializeChildren(node: ElementNode): string {\n const children = node.getChildren();\n let result = \"\";\n\n for (const child of children) {\n if ($isTextNode(child)) {\n let text = child.getTextContent();\n const format = child.getFormat();\n\n // Bold (bit 0)\n if (format & 1) text = `**${text}**`;\n // Italic (bit 1)\n if (format & 2) text = `*${text}*`;\n // Strikethrough (bit 2)\n if (format & 4) text = `~~${text}~~`;\n // Underline (bit 3) — no Markdown equivalent, skip\n // Code (bit 4)\n if (format & 16) text = `\\`${text}\\``;\n\n result += text;\n } else if ($isLinkNode(child)) {\n const linkText = serializeChildren(child);\n const url = child.getURL();\n result += `[${linkText}](${url})`;\n } else if ($isElementNode(child)) {\n result += serializeChildren(child);\n } else {\n result += child.getTextContent();\n }\n }\n\n return result;\n}\n\n/**\n * Parses a Markdown string into Lexical nodes.\n * Must be called inside editor.update() — creates Lexical nodes that require\n * an active editor context.\n */\nexport function $parseMarkdownToLexicalNodes(\n markdown: string,\n): LexicalNode[] {\n const blocks = markdown.split(/\\n\\n+/);\n const nodes: LexicalNode[] = [];\n\n for (const block of blocks) {\n const trimmed = block.trim();\n if (!trimmed) continue;\n\n const headingMatch = trimmed.match(/^(#{1,6})\\s+(.*)$/);\n if (headingMatch) {\n const level = headingMatch[1]!.length;\n const tag = `h${Math.min(level, 6)}` as\n | \"h1\"\n | \"h2\"\n | \"h3\"\n | \"h4\"\n | \"h5\"\n | \"h6\";\n const heading = $createHeadingNode(tag);\n heading.append(...$parseInlineMarkdown(headingMatch[2]!));\n nodes.push(heading);\n continue;\n }\n\n if (trimmed.startsWith(\"> \")) {\n const quote = $createQuoteNode();\n const content = trimmed\n .split(\"\\n\")\n .map((l) => l.replace(/^>\\s?/, \"\"))\n .join(\" \");\n quote.append(...$parseInlineMarkdown(content));\n nodes.push(quote);\n continue;\n }\n\n const lines = trimmed.split(\"\\n\");\n const isChecklist = lines.every((l) => /^- \\[([ x])\\] /.test(l));\n const isBullet = lines.every((l) => /^[-*]\\s/.test(l));\n const isNumbered = lines.every((l) => /^\\d+\\.\\s/.test(l));\n\n if (isChecklist) {\n const list = $createListNode(\"check\");\n for (const line of lines) {\n const match = line.match(/^- \\[([ x])\\] (.*)$/);\n if (!match) continue;\n const checked = match[1] === \"x\";\n const content = match[2] ?? \"\";\n const item = $createListItemNode(checked);\n item.append(...$parseInlineMarkdown(content));\n list.append(item);\n }\n nodes.push(list);\n continue;\n }\n\n if (isBullet || isNumbered) {\n const list = $createListNode(isBullet ? \"bullet\" : \"number\");\n for (const line of lines) {\n const content = line.replace(/^[-*]\\s|^\\d+\\.\\s/, \"\");\n const item = $createListItemNode();\n item.append(...$parseInlineMarkdown(content));\n list.append(item);\n }\n nodes.push(list);\n continue;\n }\n\n const paragraph = $createParagraphNode();\n paragraph.append(...$parseInlineMarkdown(trimmed));\n nodes.push(paragraph);\n }\n\n return nodes;\n}\n\n/**\n * Parses inline Markdown formatting into TextNode instances with format bitmasks.\n * Handles: **bold**, *italic*, `code`, ~~strikethrough~~\n */\nfunction $parseInlineMarkdown(text: string): LexicalNode[] {\n const nodes: LexicalNode[] = [];\n\n // Regex that matches inline formatting tokens\n // Order matters: ** before *, ~~ before ~\n const pattern =\n /(\\*\\*(.+?)\\*\\*|\\*(.+?)\\*|`(.+?)`|~~(.+?)~~)/g;\n\n let lastIndex = 0;\n let match: RegExpExecArray | null;\n\n while ((match = pattern.exec(text)) !== null) {\n // Add plain text before the match\n if (match.index > lastIndex) {\n const plain = text.slice(lastIndex, match.index);\n if (plain) {\n nodes.push($createTextNode(plain));\n }\n }\n\n if (match[2] != null) {\n // **bold**\n const node = $createTextNode(match[2]);\n node.setFormat(1); // bold\n nodes.push(node);\n } else if (match[3] != null) {\n // *italic*\n const node = $createTextNode(match[3]);\n node.setFormat(2); // italic\n nodes.push(node);\n } else if (match[4] != null) {\n // `code`\n const node = $createTextNode(match[4]);\n node.setFormat(16); // code\n nodes.push(node);\n } else if (match[5] != null) {\n // ~~strikethrough~~\n const node = $createTextNode(match[5]);\n node.setFormat(4); // strikethrough\n nodes.push(node);\n }\n\n lastIndex = match.index + match[0].length;\n }\n\n // Add remaining plain text\n if (lastIndex < text.length) {\n const remaining = text.slice(lastIndex);\n if (remaining) {\n nodes.push($createTextNode(remaining));\n }\n }\n\n // If no nodes were created, create a single text node\n if (nodes.length === 0) {\n nodes.push($createTextNode(text));\n }\n\n return nodes;\n}\n","\"use client\";\n\nimport { useCallback, useEffect, useRef } from \"react\";\nimport type { ReactElement } from \"react\";\n\nimport type {\n DOMConversionMap,\n DOMConversionOutput,\n DOMExportOutput,\n EditorConfig,\n LexicalNode,\n NodeKey,\n SerializedLexicalNode,\n Spread,\n} from \"lexical\";\nimport {\n $getNodeByKey,\n CLICK_COMMAND,\n COMMAND_PRIORITY_LOW,\n DecoratorNode,\n KEY_BACKSPACE_COMMAND,\n KEY_DELETE_COMMAND,\n} from \"lexical\";\nimport { useLexicalComposerContext } from \"@lexical/react/LexicalComposerContext\";\nimport { useLexicalNodeSelection } from \"@lexical/react/useLexicalNodeSelection\";\n\nexport interface VideoPayload {\n src: string;\n videoType: \"embed\" | \"file\";\n provider: string;\n title?: string;\n key?: NodeKey;\n}\n\nexport type SerializedVideoNode = Spread<\n {\n src: string;\n videoType: \"embed\" | \"file\";\n provider: string;\n title: string;\n },\n SerializedLexicalNode\n>;\n\nexport class VideoNode extends DecoratorNode<ReactElement> {\n __src: string;\n __videoType: \"embed\" | \"file\";\n __provider: string;\n __title: string;\n\n static getType(): string {\n return \"video\";\n }\n\n static clone(node: VideoNode): VideoNode {\n return new VideoNode(\n node.__src,\n node.__videoType,\n node.__provider,\n node.__title,\n node.__key,\n );\n }\n\n constructor(\n src: string,\n videoType: \"embed\" | \"file\",\n provider: string,\n title?: string,\n key?: NodeKey,\n ) {\n super(key);\n this.__src = src;\n this.__videoType = videoType;\n this.__provider = provider;\n this.__title = title ?? \"\";\n }\n\n createDOM(_config: EditorConfig): HTMLElement {\n const div = document.createElement(\"div\");\n div.style.display = \"block\";\n div.style.maxWidth = \"100%\";\n return div;\n }\n\n updateDOM(): false {\n return false;\n }\n\n exportDOM(): DOMExportOutput {\n const div = document.createElement(\"div\");\n div.setAttribute(\"data-video-src\", this.__src);\n div.setAttribute(\"data-video-type\", this.__videoType);\n div.setAttribute(\"data-video-provider\", this.__provider);\n if (this.__title) {\n div.setAttribute(\"data-video-title\", this.__title);\n }\n return { element: div };\n }\n\n static importDOM(): DOMConversionMap | null {\n return {\n div: (domNode: HTMLElement) => {\n if (!domNode.hasAttribute(\"data-video-src\")) return null;\n return {\n conversion: convertVideoElement,\n priority: 1,\n };\n },\n iframe: (domNode: HTMLElement) => {\n const src = domNode.getAttribute(\"src\") ?? \"\";\n if (\n src.includes(\"youtube.com\") ||\n src.includes(\"vimeo.com\") ||\n src.includes(\"loom.com\")\n ) {\n return {\n conversion: convertIframeElement,\n priority: 1,\n };\n }\n return null;\n },\n };\n }\n\n static importJSON(serializedNode: SerializedVideoNode): VideoNode {\n return $createVideoNode({\n src: serializedNode.src,\n videoType: serializedNode.videoType,\n provider: serializedNode.provider,\n title: serializedNode.title,\n });\n }\n\n exportJSON(): SerializedVideoNode {\n return {\n ...super.exportJSON(),\n src: this.__src,\n videoType: this.__videoType,\n provider: this.__provider,\n title: this.__title,\n type: \"video\",\n version: 1,\n };\n }\n\n getSrc(): string {\n return this.__src;\n }\n\n getVideoType(): \"embed\" | \"file\" {\n return this.__videoType;\n }\n\n getProvider(): string {\n return this.__provider;\n }\n\n getTitle(): string {\n return this.__title;\n }\n\n decorate(): ReactElement {\n return (\n <VideoComponent\n src={this.__src}\n videoType={this.__videoType}\n provider={this.__provider}\n title={this.__title}\n nodeKey={this.getKey()}\n />\n );\n }\n}\n\nfunction convertVideoElement(domNode: Node): DOMConversionOutput | null {\n if (domNode instanceof HTMLElement) {\n const src = domNode.getAttribute(\"data-video-src\");\n if (!src) return null;\n const node = $createVideoNode({\n src,\n videoType:\n (domNode.getAttribute(\"data-video-type\") as \"embed\" | \"file\") ??\n \"embed\",\n provider: domNode.getAttribute(\"data-video-provider\") ?? \"generic\",\n title: domNode.getAttribute(\"data-video-title\") ?? \"\",\n });\n return { node };\n }\n return null;\n}\n\nfunction convertIframeElement(domNode: Node): DOMConversionOutput | null {\n if (domNode instanceof HTMLIFrameElement) {\n const src = domNode.getAttribute(\"src\");\n if (!src) return null;\n\n let provider = \"generic\";\n if (src.includes(\"youtube.com\")) provider = \"youtube\";\n else if (src.includes(\"vimeo.com\")) provider = \"vimeo\";\n else if (src.includes(\"loom.com\")) provider = \"loom\";\n\n const node = $createVideoNode({\n src,\n videoType: \"embed\",\n provider,\n title: domNode.getAttribute(\"title\") ?? \"\",\n });\n return { node };\n }\n return null;\n}\n\nfunction VideoComponent({\n src,\n videoType,\n provider,\n title,\n nodeKey,\n}: {\n src: string;\n videoType: \"embed\" | \"file\";\n provider: string;\n title: string;\n nodeKey: NodeKey;\n}) {\n const [editor] = useLexicalComposerContext();\n const [isSelected, setSelected, clearSelection] =\n useLexicalNodeSelection(nodeKey);\n const containerRef = useRef<HTMLDivElement>(null);\n\n useEffect(() => {\n return editor.registerCommand(\n CLICK_COMMAND,\n (event: MouseEvent) => {\n if (containerRef.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, clearSelection, setSelected]);\n\n const onDelete = useCallback(\n (event: KeyboardEvent) => {\n if (isSelected) {\n event.preventDefault();\n editor.update(() => {\n const node = $getNodeByKey(nodeKey);\n if (node) node.remove();\n });\n return true;\n }\n return false;\n },\n [editor, isSelected, nodeKey],\n );\n\n useEffect(() => {\n const unregisterBackspace = editor.registerCommand(\n KEY_BACKSPACE_COMMAND,\n onDelete,\n COMMAND_PRIORITY_LOW,\n );\n const unregisterDelete = editor.registerCommand(\n KEY_DELETE_COMMAND,\n onDelete,\n COMMAND_PRIORITY_LOW,\n );\n return () => {\n unregisterBackspace();\n unregisterDelete();\n };\n }, [editor, onDelete]);\n\n return (\n <div\n ref={containerRef}\n data-testid=\"video-node\"\n data-video-provider={provider}\n style={{\n position: \"relative\",\n maxWidth: \"100%\",\n cursor: \"pointer\",\n borderRadius: \"var(--blokhaus-radius, 0.5rem)\",\n outline: isSelected\n ? \"2px solid var(--blokhaus-ring, #3b82f6)\"\n : \"none\",\n outlineOffset: \"2px\",\n }}\n >\n {videoType === \"embed\" ? (\n <iframe\n src={src}\n title={title || \"Embedded video\"}\n allow=\"autoplay; encrypted-media; picture-in-picture\"\n allowFullScreen\n style={{\n display: \"block\",\n width: \"100%\",\n aspectRatio: \"16 / 9\",\n border: \"none\",\n borderRadius: \"var(--blokhaus-radius, 0.5rem)\",\n }}\n draggable={false}\n />\n ) : (\n <video\n src={src}\n controls\n style={{\n display: \"block\",\n width: \"100%\",\n maxHeight: \"500px\",\n borderRadius: \"var(--blokhaus-radius, 0.5rem)\",\n }}\n draggable={false}\n >\n <track kind=\"captions\" />\n </video>\n )}\n\n {/* Transparent click overlay — captures clicks that iframes/videos swallow.\n Hidden when selected so the user can interact with the player. */}\n {!isSelected && (\n <div\n data-testid=\"video-click-overlay\"\n style={{\n position: \"absolute\",\n inset: 0,\n cursor: \"pointer\",\n borderRadius: \"var(--blokhaus-radius, 0.5rem)\",\n }}\n />\n )}\n </div>\n );\n}\n\nexport function $createVideoNode(payload: VideoPayload): VideoNode {\n return new VideoNode(\n payload.src,\n payload.videoType,\n payload.provider,\n payload.title,\n payload.key,\n );\n}\n\nexport function $isVideoNode(\n node: LexicalNode | null | undefined,\n): node is VideoNode {\n return node instanceof VideoNode;\n}\n","\"use client\";\n\nimport type {\n DOMConversionMap,\n DOMConversionOutput,\n DOMExportOutput,\n EditorConfig,\n ElementDOMSlot,\n LexicalNode,\n NodeKey,\n SerializedElementNode,\n Spread,\n} from \"lexical\";\nimport { ElementNode } from \"lexical\";\n\n// ─── Types ──────────────────────────────────────────────────────────────────\n\nexport interface CalloutPayload {\n emoji?: string;\n colorPreset?: string;\n key?: NodeKey;\n}\n\nexport type SerializedCalloutNode = Spread<\n {\n emoji: string;\n colorPreset: string;\n },\n SerializedElementNode\n>;\n\n// ─── Node Class ─────────────────────────────────────────────────────────────\n\nexport class CalloutNode extends ElementNode {\n __emoji: string;\n __colorPreset: string;\n\n static getType(): string {\n return \"callout\";\n }\n\n static clone(node: CalloutNode): CalloutNode {\n return new CalloutNode(node.__emoji, node.__colorPreset, node.__key);\n }\n\n constructor(emoji: string = \"\\u{1F4A1}\", colorPreset: string = \"default\", key?: NodeKey) {\n super(key);\n this.__emoji = emoji;\n this.__colorPreset = colorPreset;\n }\n\n // ── DOM ─────────────────────────────────────────────────────────────────\n\n createDOM(config: EditorConfig): HTMLElement {\n const div = document.createElement(\"div\");\n const themeClass = config.theme.callout as string | undefined;\n if (themeClass) {\n div.className = themeClass;\n }\n if (this.__colorPreset !== \"default\") {\n div.classList.add(`blokhaus-callout--${this.__colorPreset}`);\n }\n div.dataset.calloutEmoji = this.__emoji;\n div.dataset.calloutColor = this.__colorPreset;\n\n // Non-editable emoji element — Lexical children are placed after it\n const emojiSpan = document.createElement(\"span\");\n emojiSpan.textContent = this.__emoji;\n emojiSpan.contentEditable = \"false\";\n emojiSpan.setAttribute(\"data-callout-emoji-display\", \"true\");\n div.appendChild(emojiSpan);\n\n return div;\n }\n\n /**\n * Tell Lexical's reconciler to insert children after the emoji span.\n * This is the correct API (Lexical 0.40+) for nodes whose createDOM()\n * includes accessory elements that aren't Lexical children.\n */\n getDOMSlot(element: HTMLElement): ElementDOMSlot {\n const emojiSpan = element.querySelector(\"[data-callout-emoji-display]\");\n return super.getDOMSlot(element).withAfter(emojiSpan);\n }\n\n updateDOM(prevNode: CalloutNode, dom: HTMLElement): boolean {\n // Update emoji in place\n if (prevNode.__emoji !== this.__emoji) {\n dom.dataset.calloutEmoji = this.__emoji;\n const emojiSpan = dom.querySelector(\"[data-callout-emoji-display]\");\n if (emojiSpan) {\n emojiSpan.textContent = this.__emoji;\n }\n }\n\n // Update color preset in place\n if (prevNode.__colorPreset !== this.__colorPreset) {\n dom.dataset.calloutColor = this.__colorPreset;\n // Remove old preset class\n if (prevNode.__colorPreset !== \"default\") {\n dom.classList.remove(`blokhaus-callout--${prevNode.__colorPreset}`);\n }\n // Add new preset class\n if (this.__colorPreset !== \"default\") {\n dom.classList.add(`blokhaus-callout--${this.__colorPreset}`);\n }\n }\n\n // Return false — we handled updates in place, no full re-create needed\n return false;\n }\n\n // ── DOM Import/Export ───────────────────────────────────────────────────\n\n exportDOM(): DOMExportOutput {\n const div = document.createElement(\"div\");\n div.dataset.calloutEmoji = this.__emoji;\n div.dataset.calloutColor = this.__colorPreset;\n return { element: div };\n }\n\n static importDOM(): DOMConversionMap | null {\n return {\n div: (domNode: Node) => {\n if (domNode instanceof HTMLElement && domNode.dataset.calloutEmoji) {\n return {\n conversion: convertCalloutElement,\n priority: 1,\n };\n }\n return null;\n },\n };\n }\n\n // ── JSON Serialization ─────────────────────────────────────────────────\n\n static importJSON(serialized: SerializedCalloutNode): CalloutNode {\n return $createCalloutNode({\n emoji: serialized.emoji,\n colorPreset: serialized.colorPreset,\n });\n }\n\n exportJSON(): SerializedCalloutNode {\n return {\n ...super.exportJSON(),\n emoji: this.__emoji,\n colorPreset: this.__colorPreset,\n type: \"callout\",\n version: 1,\n };\n }\n\n // ── Getters & Setters ──────────────────────────────────────────────────\n\n getEmoji(): string {\n return this.getLatest().__emoji;\n }\n\n setEmoji(emoji: string): this {\n const writable = this.getWritable();\n writable.__emoji = emoji;\n return this;\n }\n\n getColorPreset(): string {\n return this.getLatest().__colorPreset;\n }\n\n setColorPreset(preset: string): this {\n const writable = this.getWritable();\n writable.__colorPreset = preset;\n return this;\n }\n}\n\n// ─── DOM Conversion ─────────────────────────────────────────────────────────\n\nfunction convertCalloutElement(domNode: Node): DOMConversionOutput | null {\n if (domNode instanceof HTMLElement) {\n const emoji = domNode.dataset.calloutEmoji ?? \"\\u{1F4A1}\";\n const colorPreset = domNode.dataset.calloutColor ?? \"default\";\n const node = $createCalloutNode({ emoji, colorPreset });\n return { node };\n }\n return null;\n}\n\n// ─── Factory Functions ──────────────────────────────────────────────────────\n\nexport function $createCalloutNode(payload?: CalloutPayload): CalloutNode {\n return new CalloutNode(\n payload?.emoji ?? \"\\u{1F4A1}\",\n payload?.colorPreset ?? \"default\",\n payload?.key,\n );\n}\n\nexport function $isCalloutNode(node: LexicalNode | null | undefined): node is CalloutNode {\n return node instanceof CalloutNode;\n}\n","\"use client\";\n\n// REACT\nimport { useCallback, useEffect, useRef } from \"react\";\nimport type { ReactElement } from \"react\";\n\n// LEXICAL\nimport type {\n DOMConversionMap,\n DOMConversionOutput,\n DOMExportOutput,\n EditorConfig,\n LexicalNode,\n NodeKey,\n SerializedLexicalNode,\n} from \"lexical\";\nimport {\n $getNodeByKey,\n CLICK_COMMAND,\n COMMAND_PRIORITY_LOW,\n DecoratorNode,\n KEY_BACKSPACE_COMMAND,\n KEY_DELETE_COMMAND,\n} from \"lexical\";\nimport { useLexicalComposerContext } from \"@lexical/react/LexicalComposerContext\";\nimport { useLexicalNodeSelection } from \"@lexical/react/useLexicalNodeSelection\";\n\n// ─── Node ───────────────────────────────────────────────────────────────────\n\nexport class HorizontalRuleNode extends DecoratorNode<ReactElement> {\n static getType(): string {\n return \"horizontal-rule\";\n }\n\n static clone(node: HorizontalRuleNode): HorizontalRuleNode {\n return new HorizontalRuleNode(node.__key);\n }\n\n constructor(key?: NodeKey) {\n super(key);\n }\n\n createDOM(_config: EditorConfig): HTMLElement {\n const div = document.createElement(\"div\");\n div.style.display = \"block\";\n div.style.width = \"100%\";\n return div;\n }\n\n updateDOM(): false {\n return false;\n }\n\n exportDOM(): DOMExportOutput {\n return { element: document.createElement(\"hr\") };\n }\n\n static importDOM(): DOMConversionMap | null {\n return {\n hr: () => ({\n conversion: convertHorizontalRuleElement,\n priority: 0,\n }),\n };\n }\n\n static importJSON(_serializedNode: SerializedLexicalNode): HorizontalRuleNode {\n return $createHorizontalRuleNode();\n }\n\n exportJSON(): SerializedLexicalNode {\n return {\n ...super.exportJSON(),\n type: \"horizontal-rule\",\n version: 1,\n };\n }\n\n decorate(): ReactElement {\n return <HorizontalRuleComponent nodeKey={this.getKey()} />;\n }\n}\n\n// ─── DOM Converter ──────────────────────────────────────────────────────────\n\nfunction convertHorizontalRuleElement(): DOMConversionOutput {\n return { node: $createHorizontalRuleNode() };\n}\n\n// ─── React Component ────────────────────────────────────────────────────────\n\nfunction HorizontalRuleComponent({ nodeKey }: { nodeKey: NodeKey }) {\n const [editor] = useLexicalComposerContext();\n const [isSelected, setSelected, clearSelection] =\n useLexicalNodeSelection(nodeKey);\n const containerRef = useRef<HTMLDivElement>(null);\n\n // Click to select\n useEffect(() => {\n return editor.registerCommand(\n CLICK_COMMAND,\n (event: MouseEvent) => {\n if (containerRef.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, clearSelection, setSelected]);\n\n // Delete/Backspace to remove\n const onDelete = useCallback(\n (event: KeyboardEvent) => {\n if (isSelected) {\n event.preventDefault();\n editor.update(() => {\n const node = $getNodeByKey(nodeKey);\n if (node) node.remove();\n });\n return true;\n }\n return false;\n },\n [editor, isSelected, nodeKey],\n );\n\n useEffect(() => {\n const unregisterBackspace = editor.registerCommand(\n KEY_BACKSPACE_COMMAND,\n onDelete,\n COMMAND_PRIORITY_LOW,\n );\n const unregisterDelete = editor.registerCommand(\n KEY_DELETE_COMMAND,\n onDelete,\n COMMAND_PRIORITY_LOW,\n );\n return () => {\n unregisterBackspace();\n unregisterDelete();\n };\n }, [editor, onDelete]);\n\n return (\n <div\n ref={containerRef}\n data-testid=\"horizontal-rule\"\n style={{\n cursor: \"pointer\",\n padding: \"12px 0\",\n }}\n >\n <hr\n style={{\n border: \"none\",\n borderTop: isSelected\n ? \"2px solid var(--blokhaus-ring, #3b82f6)\"\n : \"1px solid var(--blokhaus-border, #e2e8f0)\",\n margin: 0,\n transition: \"border-color 0.15s\",\n }}\n />\n </div>\n );\n}\n\n// ─── Factories ──────────────────────────────────────────────────────────────\n\nexport function $createHorizontalRuleNode(): HorizontalRuleNode {\n return new HorizontalRuleNode();\n}\n\nexport function $isHorizontalRuleNode(\n node: LexicalNode | null | undefined,\n): node is HorizontalRuleNode {\n return node instanceof HorizontalRuleNode;\n}\n","\"use client\";\n\nimport type {\n DOMConversionMap,\n DOMConversionOutput,\n DOMExportOutput,\n EditorConfig,\n LexicalEditor,\n LexicalNode,\n NodeKey,\n RangeSelection,\n SerializedElementNode,\n Spread,\n} from \"lexical\";\nimport { $createParagraphNode, $isElementNode, ElementNode } from \"lexical\";\nimport { IS_CHROME } from \"@lexical/utils\";\n\nexport interface ToggleContainerPayload {\n open?: boolean;\n key?: NodeKey;\n}\n\nexport type SerializedToggleContainerNode = Spread<\n { open: boolean },\n SerializedElementNode\n>;\n\nexport class ToggleContainerNode extends ElementNode {\n __open: boolean;\n\n static getType(): string {\n return \"toggle-container\";\n }\n\n static clone(node: ToggleContainerNode): ToggleContainerNode {\n return new ToggleContainerNode(node.__open, node.__key);\n }\n\n constructor(open: boolean = true, key?: NodeKey) {\n super(key);\n this.__open = open;\n }\n\n // Container acts as a structural boundary in the AST\n isShadowRoot(): boolean {\n return true;\n }\n\n createDOM(config: EditorConfig, editor: LexicalEditor): HTMLElement {\n const themeClass = config.theme.toggleContainer as string | undefined;\n let dom: HTMLElement;\n\n if (IS_CHROME) {\n // Chrome has issues with <details> in contenteditable contexts\n dom = document.createElement(\"div\");\n dom.setAttribute(\"data-toggle-container\", \"true\");\n dom.setAttribute(\"data-open\", this.__open ? \"true\" : \"false\");\n } else {\n const details = document.createElement(\"details\");\n details.open = this.__open;\n details.addEventListener(\"toggle\", () => {\n const open = editor.getEditorState().read(() => this.getOpen());\n if (open !== details.open) {\n editor.update(() => this.toggleOpen());\n }\n });\n dom = details;\n }\n\n if (themeClass) {\n dom.className = themeClass;\n }\n\n return dom;\n }\n\n updateDOM(prevNode: ToggleContainerNode, dom: HTMLElement): boolean {\n if (prevNode.__open !== this.__open) {\n if (IS_CHROME) {\n dom.setAttribute(\"data-open\", this.__open ? \"true\" : \"false\");\n } else {\n (dom as HTMLDetailsElement).open = this.__open;\n }\n }\n return false;\n }\n\n // Backspace at start of first child → unwrap the entire container\n collapseAtStart(_selection: RangeSelection): boolean {\n const children = this.getChildren();\n const nodesToInsert: LexicalNode[] = [];\n for (const child of children) {\n if ($isElementNode(child)) {\n nodesToInsert.push(...child.getChildren());\n }\n }\n for (const node of nodesToInsert) {\n this.insertBefore(node);\n }\n this.remove();\n if (nodesToInsert.length > 0) {\n const first = nodesToInsert[0]!;\n if ($isElementNode(first)) {\n first.selectStart();\n }\n }\n return true;\n }\n\n static importDOM(): DOMConversionMap | null {\n return {\n details: (_domNode: Node) => ({\n conversion: convertDetailsElement,\n priority: 1,\n }),\n };\n }\n\n exportDOM(): DOMExportOutput {\n const element = document.createElement(\"details\");\n if (this.__open) {\n element.setAttribute(\"open\", \"\");\n }\n return { element };\n }\n\n static importJSON(\n serialized: SerializedToggleContainerNode,\n ): ToggleContainerNode {\n return $createToggleContainerNode({ open: serialized.open });\n }\n\n exportJSON(): SerializedToggleContainerNode {\n return {\n ...super.exportJSON(),\n open: this.__open,\n type: \"toggle-container\",\n version: 1,\n };\n }\n\n getOpen(): boolean {\n return this.getLatest().__open;\n }\n\n setOpen(open: boolean): void {\n const writable = this.getWritable();\n writable.__open = open;\n }\n\n toggleOpen(): void {\n this.setOpen(!this.getOpen());\n }\n}\n\nfunction convertDetailsElement(domNode: Node): DOMConversionOutput | null {\n if (domNode instanceof HTMLElement) {\n const isOpen = (domNode as HTMLDetailsElement).open !== false;\n return { node: $createToggleContainerNode({ open: isOpen }) };\n }\n return null;\n}\n\nexport function $createToggleContainerNode(\n payload?: ToggleContainerPayload,\n): ToggleContainerNode {\n return new ToggleContainerNode(payload?.open ?? true, payload?.key);\n}\n\nexport function $isToggleContainerNode(\n node: LexicalNode | null | undefined,\n): node is ToggleContainerNode {\n return node instanceof ToggleContainerNode;\n}\n","\"use client\";\n\nimport type {\n DOMConversionMap,\n DOMConversionOutput,\n EditorConfig,\n LexicalEditor,\n LexicalNode,\n RangeSelection,\n SerializedElementNode,\n} from \"lexical\";\nimport { $createParagraphNode, $isElementNode, ElementNode } from \"lexical\";\nimport { IS_CHROME } from \"@lexical/utils\";\nimport { $isToggleContainerNode } from \"./ToggleContainerNode\";\nimport { $isToggleContentNode } from \"./ToggleContentNode\";\n\nexport class ToggleTitleNode extends ElementNode {\n static getType(): string {\n return \"toggle-title\";\n }\n\n static clone(node: ToggleTitleNode): ToggleTitleNode {\n return new ToggleTitleNode(node.__key);\n }\n\n createDOM(config: EditorConfig, editor: LexicalEditor): HTMLElement {\n const dom = document.createElement(\"summary\");\n const themeClass = config.theme.toggleTitle as string | undefined;\n if (themeClass) {\n dom.className = themeClass;\n }\n dom.setAttribute(\"data-placeholder\", \"Toggle heading\");\n\n if (IS_CHROME) {\n // On Chrome we use <div> parent, so <summary> has no native toggle.\n // Toggle when clicking the disclosure triangle area (~28px from inline-start).\n dom.addEventListener(\"click\", (e: MouseEvent) => {\n const isRtl = getComputedStyle(dom).direction === \"rtl\";\n const clickedOnTriangle = isRtl\n ? e.offsetX > dom.offsetWidth - 28\n : e.offsetX < 28;\n\n if (clickedOnTriangle) {\n e.preventDefault();\n editor.update(() => {\n const container = this.getLatest().getParent();\n if ($isToggleContainerNode(container)) {\n container.toggleOpen();\n }\n });\n }\n });\n }\n\n return dom;\n }\n\n updateDOM(): boolean {\n return false;\n }\n\n // ── Enter key: move cursor from title to content ────────────────────────\n\n insertNewAfter(\n _selection: RangeSelection,\n restoreSelection?: boolean,\n ): ElementNode | null {\n const container = this.getParent();\n\n if (!$isToggleContainerNode(container)) {\n return null;\n }\n\n if (container.getOpen()) {\n // Open → navigate into the content node\n const content = this.getNextSibling();\n if ($isToggleContentNode(content)) {\n const firstChild = content.getFirstChild();\n if ($isElementNode(firstChild)) {\n return firstChild;\n }\n // Content is empty — add a paragraph\n const paragraph = $createParagraphNode();\n content.append(paragraph);\n return paragraph;\n }\n }\n\n // Closed → insert paragraph after the container\n const paragraph = $createParagraphNode();\n container.insertAfter(paragraph, restoreSelection);\n return paragraph;\n }\n\n // ── Backspace at start: unwrap entire toggle ────────────────────────────\n\n collapseAtStart(_selection: RangeSelection): boolean {\n const container = this.getParent();\n if ($isToggleContainerNode(container)) {\n return container.collapseAtStart(_selection);\n }\n return false;\n }\n\n static importDOM(): DOMConversionMap | null {\n return {\n summary: (_domNode: Node) => ({\n conversion: convertSummaryElement,\n priority: 1,\n }),\n };\n }\n\n static importJSON(_serialized: SerializedElementNode): ToggleTitleNode {\n return $createToggleTitleNode();\n }\n\n exportJSON(): SerializedElementNode {\n return {\n ...super.exportJSON(),\n type: \"toggle-title\",\n version: 1,\n };\n }\n\n // Title is NOT a shadow root — it's editable inline text\n}\n\nfunction convertSummaryElement(_domNode: Node): DOMConversionOutput | null {\n return { node: $createToggleTitleNode() };\n}\n\nexport function $createToggleTitleNode(): ToggleTitleNode {\n return new ToggleTitleNode();\n}\n\nexport function $isToggleTitleNode(\n node: LexicalNode | null | undefined,\n): node is ToggleTitleNode {\n return node instanceof ToggleTitleNode;\n}\n","\"use client\";\n\nimport type {\n DOMConversionMap,\n DOMConversionOutput,\n DOMExportOutput,\n EditorConfig,\n LexicalNode,\n SerializedElementNode,\n} from \"lexical\";\nimport { ElementNode } from \"lexical\";\n\n// ─── Node Class ─────────────────────────────────────────────────────────────\n\nexport class ToggleContentNode extends ElementNode {\n static getType(): string {\n return \"toggle-content\";\n }\n\n static clone(node: ToggleContentNode): ToggleContentNode {\n return new ToggleContentNode(node.__key);\n }\n\n // ── DOM ─────────────────────────────────────────────────────────────────\n\n createDOM(config: EditorConfig): HTMLElement {\n const dom = document.createElement(\"div\");\n const themeClass = config.theme.toggleContent as string | undefined;\n if (themeClass) {\n dom.className = themeClass;\n }\n dom.setAttribute(\"data-toggle-content\", \"true\");\n return dom;\n }\n\n updateDOM(): boolean {\n return false;\n }\n\n // Content area is a shadow root — block-level operations stay contained\n isShadowRoot(): boolean {\n return true;\n }\n\n // ── DOM Import/Export ───────────────────────────────────────────────────\n\n static importDOM(): DOMConversionMap | null {\n return {\n div: (domNode: Node) => {\n if (\n domNode instanceof HTMLElement &&\n domNode.hasAttribute(\"data-toggle-content\")\n ) {\n return {\n conversion: convertToggleContentElement,\n priority: 2,\n };\n }\n return null;\n },\n };\n }\n\n exportDOM(): DOMExportOutput {\n const element = document.createElement(\"div\");\n element.setAttribute(\"data-toggle-content\", \"true\");\n return { element };\n }\n\n // ── JSON Serialization ─────────────────────────────────────────────────\n\n static importJSON(_serialized: SerializedElementNode): ToggleContentNode {\n return $createToggleContentNode();\n }\n\n exportJSON(): SerializedElementNode {\n return {\n ...super.exportJSON(),\n type: \"toggle-content\",\n version: 1,\n };\n }\n}\n\n// ─── DOM Conversion ─────────────────────────────────────────────────────────\n\nfunction convertToggleContentElement(\n _domNode: Node,\n): DOMConversionOutput | null {\n return { node: $createToggleContentNode() };\n}\n\n// ─── Factory Functions ──────────────────────────────────────────────────────\n\nexport function $createToggleContentNode(): ToggleContentNode {\n return new ToggleContentNode();\n}\n\nexport function $isToggleContentNode(\n node: LexicalNode | null | undefined,\n): node is ToggleContentNode {\n return node instanceof ToggleContentNode;\n}\n","\"use client\";\n\nimport { useCallback } from \"react\";\nimport type { ReactElement } from \"react\";\n\nimport type {\n DOMConversionMap,\n DOMConversionOutput,\n DOMExportOutput,\n EditorConfig,\n LexicalNode,\n NodeKey,\n SerializedLexicalNode,\n Spread,\n} from \"lexical\";\nimport {\n $getNodeByKey,\n $getSelection,\n $isNodeSelection,\n DecoratorNode,\n KEY_BACKSPACE_COMMAND,\n KEY_DELETE_COMMAND,\n COMMAND_PRIORITY_LOW,\n} from \"lexical\";\nimport { useLexicalComposerContext } from \"@lexical/react/LexicalComposerContext\";\nimport { useEffect } from \"react\";\n\nexport interface MentionPayload {\n id: string;\n label: string;\n trigger: string;\n key?: NodeKey;\n}\n\nexport type SerializedMentionNode = Spread<\n {\n mentionId: string;\n label: string;\n trigger: string;\n },\n SerializedLexicalNode\n>;\n\nexport class MentionNode extends DecoratorNode<ReactElement> {\n __mentionId: string;\n __label: string;\n __trigger: string;\n\n static getType(): string {\n return \"mention\";\n }\n\n static clone(node: MentionNode): MentionNode {\n return new MentionNode(\n node.__mentionId,\n node.__label,\n node.__trigger,\n node.__key,\n );\n }\n\n constructor(\n mentionId: string,\n label: string,\n trigger: string,\n key?: NodeKey,\n ) {\n super(key);\n this.__mentionId = mentionId;\n this.__label = label;\n this.__trigger = trigger;\n }\n\n createDOM(config: EditorConfig): HTMLElement {\n const span = document.createElement(\"span\");\n span.style.display = \"inline\";\n return span;\n }\n\n updateDOM(): false {\n return false;\n }\n\n exportDOM(): DOMExportOutput {\n const span = document.createElement(\"span\");\n span.setAttribute(\"data-mention-id\", this.__mentionId);\n span.setAttribute(\"data-mention-trigger\", this.__trigger);\n span.textContent = `${this.__trigger}${this.__label}`;\n return { element: span };\n }\n\n static importDOM(): DOMConversionMap | null {\n return {\n span: (domNode: HTMLElement) => {\n if (!domNode.hasAttribute(\"data-mention-id\")) return null;\n return {\n conversion: (element: HTMLElement): DOMConversionOutput | null => {\n const mentionId = element.getAttribute(\"data-mention-id\");\n const trigger =\n element.getAttribute(\"data-mention-trigger\") ?? \"@\";\n const label = element.textContent?.replace(trigger, \"\") ?? \"\";\n if (!mentionId) return null;\n return {\n node: $createMentionNode({\n id: mentionId,\n label,\n trigger,\n }),\n };\n },\n priority: 1,\n };\n },\n };\n }\n\n static importJSON(serialized: SerializedMentionNode): MentionNode {\n return $createMentionNode({\n id: serialized.mentionId,\n label: serialized.label,\n trigger: serialized.trigger,\n });\n }\n\n exportJSON(): SerializedMentionNode {\n return {\n ...super.exportJSON(),\n mentionId: this.__mentionId,\n label: this.__label,\n trigger: this.__trigger,\n type: \"mention\",\n version: 1,\n };\n }\n\n isInline(): true {\n return true;\n }\n\n getTextContent(): string {\n return `${this.__trigger}${this.__label}`;\n }\n\n decorate(): ReactElement {\n return (\n <MentionComponent\n nodeKey={this.getKey()}\n mentionId={this.__mentionId}\n label={this.__label}\n trigger={this.__trigger}\n />\n );\n }\n}\n\nfunction MentionComponent({\n nodeKey,\n mentionId,\n label,\n trigger,\n}: {\n nodeKey: NodeKey;\n mentionId: string;\n label: string;\n trigger: string;\n}) {\n const [editor] = useLexicalComposerContext();\n\n useEffect(() => {\n const removeNode = () => {\n editor.update(() => {\n const selection = $getSelection();\n if (!$isNodeSelection(selection)) return false;\n const nodes = selection.getNodes();\n for (const node of nodes) {\n if (node.getKey() === nodeKey) {\n node.remove();\n return true;\n }\n }\n return false;\n });\n return true;\n };\n\n const unregisterBackspace = editor.registerCommand(\n KEY_BACKSPACE_COMMAND,\n (event) => {\n const selection = $getSelection();\n if (!$isNodeSelection(selection)) return false;\n const nodes = selection.getNodes();\n const isSelected = nodes.some((n) => n.getKey() === nodeKey);\n if (isSelected) {\n event?.preventDefault();\n removeNode();\n return true;\n }\n return false;\n },\n COMMAND_PRIORITY_LOW,\n );\n\n const unregisterDelete = editor.registerCommand(\n KEY_DELETE_COMMAND,\n (event) => {\n const selection = $getSelection();\n if (!$isNodeSelection(selection)) return false;\n const nodes = selection.getNodes();\n const isSelected = nodes.some((n) => n.getKey() === nodeKey);\n if (isSelected) {\n event?.preventDefault();\n removeNode();\n return true;\n }\n return false;\n },\n COMMAND_PRIORITY_LOW,\n );\n\n return () => {\n unregisterBackspace();\n unregisterDelete();\n };\n }, [editor, nodeKey]);\n\n const chipColor =\n trigger === \"#\"\n ? \"var(--blokhaus-accent, #3b82f6)\"\n : \"var(--blokhaus-ai-stream, #3366cc)\";\n\n return (\n <span\n data-testid=\"mention-node\"\n data-mention-id={mentionId}\n data-mention-trigger={trigger}\n style={{\n display: \"inline-flex\",\n alignItems: \"center\",\n gap: \"2px\",\n padding: \"1px 6px\",\n borderRadius: \"4px\",\n backgroundColor: `color-mix(in srgb, ${chipColor} 12%, transparent)`,\n color: chipColor,\n fontSize: \"inherit\",\n lineHeight: \"inherit\",\n fontWeight: 500,\n cursor: \"default\",\n userSelect: \"none\",\n whiteSpace: \"nowrap\",\n verticalAlign: \"baseline\",\n }}\n >\n <span style={{ opacity: 0.6 }}>{trigger}</span>\n {label}\n </span>\n );\n}\n\nexport function $createMentionNode(\n payload: MentionPayload,\n): MentionNode {\n return new MentionNode(\n payload.id,\n payload.label,\n payload.trigger,\n payload.key,\n );\n}\n\nexport function $isMentionNode(\n node: LexicalNode | null | undefined,\n): node is MentionNode {\n return node instanceof MentionNode;\n}\n","\"use client\";\n\nimport { useCallback, useEffect, useRef, useState } from \"react\";\nimport type { ReactElement } from \"react\";\n\nimport type {\n DOMConversionMap,\n DOMConversionOutput,\n DOMExportOutput,\n EditorConfig,\n LexicalNode,\n NodeKey,\n SerializedLexicalNode,\n Spread,\n} from \"lexical\";\nimport {\n $getNodeByKey,\n CLICK_COMMAND,\n COMMAND_PRIORITY_LOW,\n DecoratorNode,\n KEY_BACKSPACE_COMMAND,\n KEY_DELETE_COMMAND,\n} from \"lexical\";\nimport { useLexicalComposerContext } from \"@lexical/react/LexicalComposerContext\";\nimport { useLexicalNodeSelection } from \"@lexical/react/useLexicalNodeSelection\";\n\nimport { CopyIcon, CheckIcon } from \"@phosphor-icons/react\";\n\nconst SUPPORTED_LANGUAGES = [\n \"javascript\",\n \"typescript\",\n \"python\",\n \"css\",\n \"html\",\n \"json\",\n \"bash\",\n \"go\",\n \"rust\",\n \"java\",\n \"c\",\n \"cpp\",\n \"sql\",\n \"markdown\",\n \"yaml\",\n \"text\",\n] as const;\n\nexport interface CodeBlockPayload {\n code: string;\n language: string;\n key?: NodeKey;\n autoFocus?: boolean;\n}\n\nexport type SerializedCodeBlockNode = Spread<\n {\n code: string;\n language: string;\n },\n SerializedLexicalNode\n>;\n\nexport class CodeBlockNode extends DecoratorNode<ReactElement> {\n __code: string;\n __language: string;\n __autoFocus: boolean;\n\n static getType(): string {\n return \"code-block\";\n }\n\n static clone(node: CodeBlockNode): CodeBlockNode {\n const clone = new CodeBlockNode(node.__code, node.__language, node.__key);\n clone.__autoFocus = node.__autoFocus;\n return clone;\n }\n\n constructor(code: string, language: string, key?: NodeKey) {\n super(key);\n this.__code = code;\n this.__language = language;\n this.__autoFocus = false;\n }\n\n createDOM(_config: EditorConfig): HTMLElement {\n const div = document.createElement(\"div\");\n div.style.display = \"block\";\n div.style.width = \"100%\";\n return div;\n }\n\n updateDOM(): false {\n return false;\n }\n\n exportDOM(): DOMExportOutput {\n const pre = document.createElement(\"pre\");\n const code = document.createElement(\"code\");\n code.textContent = this.__code;\n if (this.__language && this.__language !== \"text\") {\n code.className = `language-${this.__language}`;\n }\n pre.appendChild(code);\n return { element: pre };\n }\n\n static importDOM(): DOMConversionMap | null {\n return {\n pre: () => ({\n conversion: convertPreElement,\n priority: 0,\n }),\n };\n }\n\n static importJSON(serialized: SerializedCodeBlockNode): CodeBlockNode {\n return $createCodeBlockNode({\n code: serialized.code,\n language: serialized.language,\n });\n }\n\n exportJSON(): SerializedCodeBlockNode {\n return {\n ...super.exportJSON(),\n code: this.__code,\n language: this.__language,\n type: \"code-block\",\n version: 1,\n };\n }\n\n getCode(): string {\n return this.__code;\n }\n\n getLanguage(): string {\n return this.__language;\n }\n\n decorate(): ReactElement {\n return (\n <CodeBlockComponent\n code={this.__code}\n language={this.__language}\n nodeKey={this.getKey()}\n autoFocus={this.__autoFocus}\n />\n );\n }\n}\n\nfunction convertPreElement(domNode: Node): DOMConversionOutput | null {\n if (domNode instanceof HTMLPreElement) {\n const codeEl = domNode.querySelector(\"code\");\n const code = codeEl?.textContent ?? domNode.textContent ?? \"\";\n let language = \"text\";\n const className = codeEl?.className ?? \"\";\n const langMatch = className.match(/language-(\\w+)/);\n if (langMatch?.[1]) {\n language = langMatch[1];\n }\n const node = $createCodeBlockNode({ code, language });\n return { node };\n }\n return null;\n}\n\nfunction CodeBlockComponent({\n code,\n language,\n nodeKey,\n autoFocus,\n}: {\n code: string;\n language: string;\n nodeKey: NodeKey;\n autoFocus: boolean;\n}) {\n const [editor] = useLexicalComposerContext();\n const [isSelected, setSelected, clearSelection] =\n useLexicalNodeSelection(nodeKey);\n const containerRef = useRef<HTMLDivElement>(null);\n const textareaRef = useRef<HTMLTextAreaElement>(null);\n const [localCode, setLocalCode] = useState(code);\n const [localLanguage, setLocalLanguage] = useState(language);\n const [highlightedHtml, setHighlightedHtml] = useState<string | null>(null);\n const [copied, setCopied] = useState(false);\n const [isEditing, setIsEditing] = useState(autoFocus);\n const debounceTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n const highlightTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n const didAutoFocusRef = useRef(false);\n\n // Auto-focus the textarea when the node is freshly created\n useEffect(() => {\n if (autoFocus && !didAutoFocusRef.current && textareaRef.current) {\n didAutoFocusRef.current = true;\n textareaRef.current.focus();\n // Clear the autoFocus flag on the node so it doesn't re-focus on re-render\n editor.update(() => {\n const node = $getNodeByKey(nodeKey);\n if (node && node instanceof CodeBlockNode) {\n const writable = node.getWritable();\n writable.__autoFocus = false;\n }\n });\n }\n }, [autoFocus, editor, nodeKey]);\n\n // Sync from node props when they change externally\n useEffect(() => {\n setLocalCode(code);\n }, [code]);\n\n useEffect(() => {\n setLocalLanguage(language);\n }, [language]);\n\n useEffect(() => {\n return editor.registerCommand(\n CLICK_COMMAND,\n (event: MouseEvent) => {\n if (containerRef.current?.contains(event.target as Node)) {\n // If clicking inside the textarea or controls, don't select the node\n const target = event.target as HTMLElement;\n if (\n target.tagName === \"TEXTAREA\" ||\n target.tagName === \"SELECT\" ||\n target.tagName === \"BUTTON\" ||\n target.closest(\"select\") ||\n target.closest(\"button\")\n ) {\n return false;\n }\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, clearSelection, setSelected]);\n\n const onDelete = useCallback(\n (event: KeyboardEvent) => {\n if (isSelected && !isEditing) {\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, isEditing, nodeKey],\n );\n\n useEffect(() => {\n const unregisterBackspace = editor.registerCommand(\n KEY_BACKSPACE_COMMAND,\n onDelete,\n COMMAND_PRIORITY_LOW,\n );\n const unregisterDelete = editor.registerCommand(\n KEY_DELETE_COMMAND,\n onDelete,\n COMMAND_PRIORITY_LOW,\n );\n return () => {\n unregisterBackspace();\n unregisterDelete();\n };\n }, [editor, onDelete]);\n\n const updateNodeCode = useCallback(\n (newCode: string) => {\n if (debounceTimerRef.current) {\n clearTimeout(debounceTimerRef.current);\n }\n debounceTimerRef.current = setTimeout(() => {\n editor.update(() => {\n const node = $getNodeByKey(nodeKey);\n if (node && node instanceof CodeBlockNode) {\n const writable = node.getWritable();\n writable.__code = newCode;\n }\n });\n }, 300);\n },\n [editor, nodeKey],\n );\n\n const handleCodeChange = useCallback(\n (e: React.ChangeEvent<HTMLTextAreaElement>) => {\n const newCode = e.target.value;\n setLocalCode(newCode);\n updateNodeCode(newCode);\n },\n [updateNodeCode],\n );\n\n const handleLanguageChange = useCallback(\n (e: React.ChangeEvent<HTMLSelectElement>) => {\n const newLanguage = e.target.value;\n setLocalLanguage(newLanguage);\n editor.update(() => {\n const node = $getNodeByKey(nodeKey);\n if (node && node instanceof CodeBlockNode) {\n const writable = node.getWritable();\n writable.__language = newLanguage;\n }\n });\n },\n [editor, nodeKey],\n );\n\n // Build HTML for clipboard — preserves formatting when pasted into another editor\n const buildClipboardHtml = useCallback(\n (text: string) => {\n const escaped = text\n .replace(/&/g, \"&\")\n .replace(/</g, \"<\")\n .replace(/>/g, \">\");\n const langClass =\n localLanguage && localLanguage !== \"text\"\n ? ` class=\"language-${localLanguage}\"`\n : \"\";\n return `<pre><code${langClass}>${escaped}</code></pre>`;\n },\n [localLanguage],\n );\n\n const handleCopy = useCallback(() => {\n const html = buildClipboardHtml(localCode);\n const htmlBlob = new Blob([html], { type: \"text/html\" });\n const textBlob = new Blob([localCode], { type: \"text/plain\" });\n navigator.clipboard\n .write([new ClipboardItem({ \"text/html\": htmlBlob, \"text/plain\": textBlob })])\n .then(() => {\n setCopied(true);\n setTimeout(() => setCopied(false), 2000);\n });\n }, [localCode, buildClipboardHtml]);\n\n // Textarea copy/cut — write HTML alongside plain text so paste recreates a code block\n const handleTextareaCopy = useCallback(\n (e: React.ClipboardEvent<HTMLTextAreaElement>) => {\n const ta = e.currentTarget;\n const selected = ta.value.substring(ta.selectionStart, ta.selectionEnd);\n const text = selected || localCode;\n\n e.preventDefault();\n e.clipboardData.setData(\"text/plain\", text);\n e.clipboardData.setData(\"text/html\", buildClipboardHtml(text));\n },\n [localCode, buildClipboardHtml],\n );\n\n const handleTextareaCut = useCallback(\n (e: React.ClipboardEvent<HTMLTextAreaElement>) => {\n const ta = e.currentTarget;\n const selected = ta.value.substring(ta.selectionStart, ta.selectionEnd);\n const text = selected || localCode;\n\n e.preventDefault();\n e.clipboardData.setData(\"text/plain\", text);\n e.clipboardData.setData(\"text/html\", buildClipboardHtml(text));\n\n // Remove the selected text\n if (selected) {\n const before = ta.value.substring(0, ta.selectionStart);\n const after = ta.value.substring(ta.selectionEnd);\n const newCode = before + after;\n setLocalCode(newCode);\n updateNodeCode(newCode);\n } else {\n setLocalCode(\"\");\n updateNodeCode(\"\");\n }\n },\n [localCode, buildClipboardHtml, updateNodeCode],\n );\n\n // Fetch Shiki highlighting (debounced)\n useEffect(() => {\n if (!localCode.trim()) {\n setHighlightedHtml(null);\n return;\n }\n\n if (highlightTimerRef.current) {\n clearTimeout(highlightTimerRef.current);\n }\n\n highlightTimerRef.current = setTimeout(() => {\n fetch(\"/api/editor/highlight\", {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({ code: localCode, language: localLanguage }),\n })\n .then((res) => {\n if (!res.ok) throw new Error(\"Highlight failed\");\n return res.json();\n })\n .then((data: { html: string }) => {\n setHighlightedHtml(data.html);\n })\n .catch(() => {\n // Silently fall back to raw code display\n setHighlightedHtml(null);\n });\n }, 500);\n\n return () => {\n if (highlightTimerRef.current) {\n clearTimeout(highlightTimerRef.current);\n }\n };\n }, [localCode, localLanguage]);\n\n useEffect(() => {\n if (textareaRef.current && isEditing) {\n const ta = textareaRef.current;\n ta.style.height = \"auto\";\n ta.style.height = `${ta.scrollHeight}px`;\n }\n }, [localCode, isEditing]);\n\n return (\n <div\n ref={containerRef}\n data-testid=\"code-block-node\"\n style={{\n position: \"relative\",\n borderRadius: \"var(--blokhaus-radius, 0.5rem)\",\n backgroundColor: \"var(--blokhaus-muted, #f1f5f9)\",\n margin: \"0.5em 0\",\n overflow: \"hidden\",\n outline: isSelected\n ? \"2px solid var(--blokhaus-ring, #3b82f6)\"\n : \"none\",\n outlineOffset: \"2px\",\n }}\n >\n <div\n style={{\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"space-between\",\n padding: \"6px 12px\",\n borderBottom: \"1px solid var(--blokhaus-border, #e2e8f0)\",\n fontSize: \"12px\",\n }}\n >\n <select\n data-testid=\"code-block-language\"\n value={localLanguage}\n onChange={handleLanguageChange}\n style={{\n backgroundColor: \"transparent\",\n border: \"none\",\n fontSize: \"12px\",\n fontWeight: 500,\n color: \"var(--blokhaus-muted-foreground, #64748b)\",\n cursor: \"pointer\",\n outline: \"none\",\n padding: \"2px 4px\",\n }}\n >\n {SUPPORTED_LANGUAGES.map((lang) => (\n <option key={lang} value={lang}>\n {lang}\n </option>\n ))}\n </select>\n\n <button\n type=\"button\"\n data-testid=\"code-block-copy\"\n onClick={handleCopy}\n style={{\n display: \"flex\",\n alignItems: \"center\",\n gap: \"4px\",\n padding: \"3px 8px\",\n borderRadius: \"6px\",\n border: \"none\",\n fontSize: \"11px\",\n fontWeight: 500,\n cursor: \"pointer\",\n backgroundColor: \"transparent\",\n color: \"var(--blokhaus-muted-foreground, #64748b)\",\n transition: \"background-color 80ms ease\",\n }}\n >\n {copied ? (\n <>\n <CheckIcon size={12} weight=\"bold\" />\n Copied\n </>\n ) : (\n <>\n <CopyIcon size={12} />\n Copy\n </>\n )}\n </button>\n </div>\n\n <div\n style={{\n position: \"relative\",\n minHeight: \"40px\",\n }}\n >\n {!isEditing && highlightedHtml ? (\n <div\n data-testid=\"code-block-highlighted\"\n onClick={() => {\n setIsEditing(true);\n // Focus textarea after it renders\n setTimeout(() => textareaRef.current?.focus(), 0);\n }}\n style={{\n padding: \"12px 16px\",\n cursor: \"text\",\n overflow: \"auto\",\n }}\n dangerouslySetInnerHTML={{ __html: highlightedHtml }}\n />\n ) : null}\n\n {isEditing || !highlightedHtml ? (\n <textarea\n ref={textareaRef}\n data-testid=\"code-block-textarea\"\n value={localCode}\n onChange={handleCodeChange}\n onCopy={handleTextareaCopy}\n onCut={handleTextareaCut}\n onFocus={() => setIsEditing(true)}\n onBlur={() => setIsEditing(false)}\n placeholder=\"Enter code...\"\n spellCheck={false}\n autoComplete=\"off\"\n autoCorrect=\"off\"\n autoCapitalize=\"off\"\n style={{\n display: \"block\",\n width: \"100%\",\n padding: \"12px 16px\",\n fontFamily:\n 'var(--blokhaus-font-mono, ui-monospace, \"SFMono-Regular\", monospace)',\n fontSize: \"13px\",\n lineHeight: 1.6,\n color: \"var(--blokhaus-foreground, #0f172a)\",\n backgroundColor: \"transparent\",\n border: \"none\",\n outline: \"none\",\n resize: \"none\",\n overflow: \"hidden\",\n whiteSpace: \"pre\",\n tabSize: 2,\n minHeight: \"40px\",\n }}\n />\n ) : null}\n </div>\n </div>\n );\n}\n\nexport function $createCodeBlockNode(payload: CodeBlockPayload): CodeBlockNode {\n const node = new CodeBlockNode(payload.code, payload.language, payload.key);\n if (payload.autoFocus) {\n node.__autoFocus = true;\n }\n return node;\n}\n\nexport function $isCodeBlockNode(\n node: LexicalNode | null | undefined,\n): node is CodeBlockNode {\n return node instanceof CodeBlockNode;\n}\n","\"use client\";\n\nimport type { ReactElement } from \"react\";\nimport type {\n DOMConversionMap,\n DOMExportOutput,\n EditorConfig,\n LexicalNode,\n NodeKey,\n SerializedLexicalNode,\n Spread,\n} from \"lexical\";\nimport { DecoratorNode } from \"lexical\";\n\nexport type SerializedLoadingVideoNode = Spread<\n { objectURL: string; fileName: string },\n SerializedLexicalNode\n>;\n\nexport class LoadingVideoNode extends DecoratorNode<ReactElement> {\n __objectURL: string;\n __fileName: string;\n\n static getType(): string {\n return \"loading-video\";\n }\n\n static clone(node: LoadingVideoNode): LoadingVideoNode {\n return new LoadingVideoNode(\n node.__objectURL,\n node.__fileName,\n node.__key,\n );\n }\n\n constructor(objectURL: string, fileName: string, key?: NodeKey) {\n super(key);\n this.__objectURL = objectURL;\n this.__fileName = fileName;\n }\n\n createDOM(_config: EditorConfig): HTMLElement {\n const div = document.createElement(\"div\");\n div.style.position = \"relative\";\n div.style.display = \"block\";\n div.style.maxWidth = \"100%\";\n return div;\n }\n\n updateDOM(): false {\n return false;\n }\n\n exportDOM(): DOMExportOutput {\n const element = document.createElement(\"div\");\n element.setAttribute(\"data-loading-video\", \"true\");\n return { element };\n }\n\n static importDOM(): DOMConversionMap | null {\n return null;\n }\n\n static importJSON(\n serializedNode: SerializedLoadingVideoNode,\n ): LoadingVideoNode {\n return $createLoadingVideoNode(\n serializedNode.objectURL,\n serializedNode.fileName,\n );\n }\n\n exportJSON(): SerializedLoadingVideoNode {\n return {\n ...super.exportJSON(),\n objectURL: this.__objectURL,\n fileName: this.__fileName,\n type: \"loading-video\",\n version: 1,\n };\n }\n\n getObjectURL(): string {\n return this.__objectURL;\n }\n\n getFileName(): string {\n return this.__fileName;\n }\n\n decorate(): ReactElement {\n return (\n <LoadingVideoComponent\n objectURL={this.__objectURL}\n fileName={this.__fileName}\n />\n );\n }\n}\n\nfunction LoadingVideoComponent({\n fileName,\n}: {\n objectURL: string;\n fileName: string;\n}) {\n return (\n <div\n data-testid=\"loading-video-node\"\n style={{\n position: \"relative\",\n width: \"100%\",\n aspectRatio: \"16 / 9\",\n maxHeight: \"400px\",\n backgroundColor: \"var(--blokhaus-muted)\",\n borderRadius: \"var(--blokhaus-radius, 0.5rem)\",\n overflow: \"hidden\",\n opacity: 0.6,\n }}\n >\n {/* File name label */}\n <div\n style={{\n position: \"absolute\",\n bottom: \"12px\",\n left: \"12px\",\n right: \"12px\",\n fontSize: \"13px\",\n color: \"var(--blokhaus-muted-foreground)\",\n fontFamily: \"var(--blokhaus-font-sans, system-ui, sans-serif)\",\n overflow: \"hidden\",\n textOverflow: \"ellipsis\",\n whiteSpace: \"nowrap\",\n }}\n >\n {fileName}\n </div>\n\n {/* Spinner overlay */}\n <div\n data-testid=\"loading-video-spinner\"\n style={{\n position: \"absolute\",\n inset: 0,\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n }}\n >\n <div\n style={{\n width: \"32px\",\n height: \"32px\",\n border: \"3px solid var(--blokhaus-muted)\",\n borderTopColor: \"var(--blokhaus-accent)\",\n borderRadius: \"50%\",\n animation: \"blokhaus-spin 0.8s linear infinite\",\n }}\n />\n </div>\n <style>{`@keyframes blokhaus-spin { to { transform: rotate(360deg); } }`}</style>\n </div>\n );\n}\n\nexport function $createLoadingVideoNode(\n objectURL: string,\n fileName: string,\n): LoadingVideoNode {\n return new LoadingVideoNode(objectURL, fileName);\n}\n\nexport function $isLoadingVideoNode(\n node: LexicalNode | null | undefined,\n): node is LoadingVideoNode {\n return node instanceof LoadingVideoNode;\n}\n","// LEXICAL\nimport type { EditorThemeClasses } from 'lexical';\n\nexport const blokhausTheme: EditorThemeClasses = {\n paragraph: 'blokhaus-paragraph',\n heading: {\n h1: 'blokhaus-h1',\n h2: 'blokhaus-h2',\n h3: 'blokhaus-h3',\n h4: 'blokhaus-h3',\n h5: 'blokhaus-h3',\n h6: 'blokhaus-h3',\n },\n quote: 'blokhaus-quote',\n list: {\n ul: 'blokhaus-ul',\n ol: 'blokhaus-ol',\n listitem: 'blokhaus-listitem',\n checklist: 'blokhaus-checklist',\n listitemChecked: 'blokhaus-listitem-checked',\n listitemUnchecked: 'blokhaus-listitem-unchecked',\n nested: {\n listitem: 'blokhaus-nested-listitem',\n },\n },\n text: {\n bold: 'blokhaus-bold',\n italic: 'blokhaus-italic',\n underline: 'blokhaus-underline',\n strikethrough: 'blokhaus-strikethrough',\n code: 'blokhaus-code',\n },\n link: 'blokhaus-link',\n code: 'blokhaus-code-block',\n table: 'blokhaus-table',\n tableRow: 'blokhaus-table-row',\n tableCell: 'blokhaus-table-cell',\n tableCellHeader: 'blokhaus-table-cell-header',\n tableSelection: 'blokhaus-table-selection',\n callout: 'blokhaus-callout',\n toggleContainer: 'blokhaus-toggle-container',\n toggleTitle: 'blokhaus-toggle-title',\n toggleContent: 'blokhaus-toggle-content',\n};\n","export { EditorRoot } from './components/EditorRoot';\nexport { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext';\nexport { $getSelection, $isRangeSelection, TextNode } from 'lexical';\nexport type { LexicalEditor } from 'lexical';\nexport { FloatingToolbar } from './components/FloatingToolbar';\nexport { SlashMenu } from './components/SlashMenu';\nexport { OverlayPortal } from './components/OverlayPortal';\nexport { InputRulePlugin } from './plugins/InputRulePlugin';\nexport { ImagePlugin } from './plugins/ImagePlugin';\nexport { AIPlugin } from './plugins/AIPlugin';\nexport { MentionPlugin } from './plugins/MentionPlugin';\nexport { PastePlugin } from './plugins/PastePlugin';\nexport { EmojiPickerPlugin } from './plugins/EmojiPickerPlugin';\nexport { LinkPlugin } from './plugins/LinkPlugin';\nexport { useEditorState } from './hooks/useEditorState';\nexport { useWordCount } from './hooks/useWordCount';\nexport { MobileToolbar } from './components/MobileToolbar';\nexport { sanitizePastedHTML } from './utils/sanitize';\nexport { ColorPlugin } from './plugins/ColorPlugin';\nexport { ColorPicker } from './components/ColorPicker';\nexport { DEFAULT_COLOR_PALETTE } from './data/color-palette';\nexport type { ColorEntry, ColorPalette } from './data/color-palette';\nexport { ListPlugin } from './plugins/ListPlugin';\nexport { TablePlugin } from './plugins/TablePlugin';\nexport { TableActionMenu } from './components/TableActionMenu';\nexport { TableHoverActions } from './components/TableHoverActions';\nexport { OPEN_SLASH_MENU_COMMAND, INSERT_IMAGE_COMMAND, OPEN_AI_PROMPT_COMMAND, INSERT_AI_PREVIEW_COMMAND, OPEN_EMOJI_PICKER_COMMAND, OPEN_LINK_INPUT_COMMAND, SET_TEXT_COLOR_COMMAND, SET_HIGHLIGHT_COLOR_COMMAND, INSERT_TABLE_COMMAND_BLOKHAUS, INSERT_CALLOUT_COMMAND, INSERT_VIDEO_COMMAND, OPEN_VIDEO_INPUT_COMMAND, INSERT_TOGGLE_COMMAND, SET_FONT_FAMILY_COMMAND, SET_BLOCK_DIRECTION_COMMAND } from './commands';\nexport { DirectionPlugin } from './plugins/DirectionPlugin';\nexport { FontPicker } from './components/FontPicker';\nexport { DEFAULT_FONT_FAMILIES } from './data/font-families';\nexport type { FontFamilyEntry } from './data/font-families';\nexport { ImageNode, $createImageNode, $isImageNode } from './nodes/ImageNode';\nexport { LoadingImageNode, $createLoadingImageNode, $isLoadingImageNode } from './nodes/LoadingImageNode';\nexport { AIPreviewNode, $createAIPreviewNode, $isAIPreviewNode } from './nodes/AIPreviewNode';\nexport { MentionNode, $createMentionNode, $isMentionNode } from './nodes/MentionNode';\nexport { CodeBlockNode, $createCodeBlockNode, $isCodeBlockNode } from './nodes/CodeBlockNode';\nexport { CalloutNode, $createCalloutNode, $isCalloutNode } from './nodes/CalloutNode';\nexport { CalloutPlugin } from './plugins/CalloutPlugin';\nexport { DEFAULT_CALLOUT_PRESETS } from './data/callout-presets';\nexport { serializeNodesToMarkdown, $parseMarkdownToLexicalNodes } from './utils/markdown';\nexport type {\n UploadHandler,\n MentionProvider,\n MentionItem,\n InputRule,\n AIProvider,\n AIGenerateConfig,\n AIGenerateParams,\n AIPluginConfig,\n AIPreviewLabels,\n AIRetryConfig,\n AIPromptInputRenderProps,\n} from './types';\nexport type { SlashMenuItem } from './components/SlashMenu';\nexport type { ImagePayload } from './nodes/ImageNode';\nexport type { AIPreviewPayload } from './nodes/AIPreviewNode';\nexport type { MentionPayload } from './nodes/MentionNode';\nexport type { CodeBlockPayload } from './nodes/CodeBlockNode';\nexport type { EmojiItem } from './data/emoji-list';\nexport { DEFAULT_EMOJIS } from './data/emoji-list';\nexport type { EmojiPickerPluginProps } from './plugins/EmojiPickerPlugin';\nexport type { LinkPluginConfig, LinkInputRenderProps, LinkPreviewRenderProps } from './plugins/LinkPlugin';\nexport type { CalloutPayload } from './nodes/CalloutNode';\nexport type { CalloutPreset } from './data/callout-presets';\nexport { VideoPlugin } from './plugins/VideoPlugin';\nexport { VideoNode, $createVideoNode, $isVideoNode } from './nodes/VideoNode';\nexport { HorizontalRuleNode, $createHorizontalRuleNode, $isHorizontalRuleNode } from './nodes/HorizontalRuleNode';\nexport { LoadingVideoNode, $createLoadingVideoNode, $isLoadingVideoNode } from './nodes/LoadingVideoNode';\nexport { parseVideoEmbed } from './utils/video-embeds';\nexport type { VideoPayload } from './nodes/VideoNode';\nexport type { VideoEmbedInfo } from './utils/video-embeds';\nexport type { VideoEmbedRenderProps, VideoFileRenderProps } from './plugins/VideoPlugin';\nexport { ToggleContainerNode, $createToggleContainerNode, $isToggleContainerNode } from './nodes/ToggleContainerNode';\nexport { ToggleTitleNode, $createToggleTitleNode, $isToggleTitleNode } from './nodes/ToggleTitleNode';\nexport { ToggleContentNode, $createToggleContentNode, $isToggleContentNode } from './nodes/ToggleContentNode';\nexport { TogglePlugin } from './plugins/TogglePlugin';\nexport { BlockSelectionPlugin } from './plugins/BlockSelectionPlugin';\nexport type { ToggleContainerPayload } from './nodes/ToggleContainerNode';\n","\"use client\";\n\n// REACT\nimport { useCallback, useEffect, useRef, useState } from \"react\";\n\n// LEXICAL\nimport { useLexicalComposerContext } from \"@lexical/react/LexicalComposerContext\";\nimport {\n $getSelection,\n $isRangeSelection,\n $isTextNode,\n $isElementNode,\n $isRootNode,\n CAN_REDO_COMMAND,\n CAN_UNDO_COMMAND,\n COMMAND_PRIORITY_LOW,\n FORMAT_TEXT_COMMAND,\n KEY_ESCAPE_COMMAND,\n REDO_COMMAND,\n SELECTION_CHANGE_COMMAND,\n UNDO_COMMAND,\n} from \"lexical\";\nimport { $isTableSelection } from \"@lexical/table\";\n\n// REACT DOM\nimport { createPortal } from \"react-dom\";\n\n// PHOSPHOR ICONS\nimport {\n TextBIcon,\n TextItalicIcon,\n TextUnderlineIcon,\n TextStrikethroughIcon,\n CodeIcon,\n LinkIcon,\n TextAaIcon,\n TextAlignLeftIcon,\n TextAlignRightIcon,\n ArrowCounterClockwiseIcon,\n ArrowClockwiseIcon,\n} from \"@phosphor-icons/react\";\nimport type { IconWeight } from \"@phosphor-icons/react\";\n\n// LEXICAL LINK\nimport { $isLinkNode } from \"@lexical/link\";\n\n// INTERNAL\nimport { OPEN_LINK_INPUT_COMMAND, SET_BLOCK_DIRECTION_COMMAND } from \"../commands\";\nimport { getInlineStyleProperty } from \"../utils/style\";\nimport { ColorPicker } from \"./ColorPicker\";\nimport { FontPicker } from \"./FontPicker\";\nimport type { ColorPalette } from \"../data/color-palette\";\nimport type { FontFamilyEntry } from \"../data/font-families\";\n\ntype TextFormat = \"bold\" | \"italic\" | \"underline\" | \"strikethrough\" | \"code\";\n\nconst MOD =\n typeof navigator !== \"undefined\" && /Mac|iPhone|iPad|iPod/.test(navigator.platform)\n ? \"Cmd\"\n : \"Ctrl\";\n\ninterface ToolbarButton {\n icon: React.ComponentType<{ size?: number; weight?: IconWeight }>;\n format: TextFormat;\n label: string;\n shortcut: string;\n}\n\nconst TOOLBAR_BUTTONS: ToolbarButton[] = [\n { icon: TextBIcon, format: \"bold\", label: \"Bold\", shortcut: `${MOD}+B` },\n { icon: TextItalicIcon, format: \"italic\", label: \"Italic\", shortcut: `${MOD}+I` },\n { icon: TextUnderlineIcon, format: \"underline\", label: \"Underline\", shortcut: `${MOD}+U` },\n { icon: TextStrikethroughIcon, format: \"strikethrough\", label: \"Strikethrough\", shortcut: `${MOD}+Shift+S` },\n { icon: CodeIcon, format: \"code\", label: \"Inline Code\", shortcut: `${MOD}+E` },\n];\n\ninterface FloatingToolbarProps {\n colorPalette?: ColorPalette;\n fontFamilies?: FontFamilyEntry[];\n}\n\nexport function FloatingToolbar({ colorPalette, fontFamilies }: FloatingToolbarProps = {}) {\n // Hook - Lexical Editor Context\n const [editor] = useLexicalComposerContext();\n\n // States\n const [isVisible, setIsVisible] = useState<boolean>(false);\n const [position, setPosition] = useState<{ top: number; left: number }>({\n top: 0,\n left: 0,\n });\n const [activeFormats, setActiveFormats] = useState<Set<string>>(new Set());\n const [activeTextColor, setActiveTextColor] = useState<string | null>(null);\n const [activeHighlightColor, setActiveHighlightColor] = useState<string | null>(null);\n const [activeFont, setActiveFont] = useState<string | null>(null);\n const [blockDirection, setBlockDirection] = useState<\"ltr\" | \"rtl\" | null>(null);\n const [showColorPicker, setShowColorPicker] = useState(false);\n const [showFontPicker, setShowFontPicker] = useState(false);\n const [canUndo, setCanUndo] = useState(false);\n const [canRedo, setCanRedo] = useState(false);\n const toolbarRef = useRef<HTMLDivElement>(null);\n const [portalContainer, setPortalContainer] = useState<HTMLElement | null>(\n null,\n );\n\n // Effect - Set Portal Container on Mount\n useEffect(() => {\n if (typeof window === \"undefined\") return;\n setPortalContainer(document.body);\n }, []);\n\n // Track undo/redo availability\n useEffect(() => {\n const unregisterUndo = editor.registerCommand(\n CAN_UNDO_COMMAND,\n (payload) => {\n setCanUndo(payload);\n return false;\n },\n COMMAND_PRIORITY_LOW,\n );\n const unregisterRedo = editor.registerCommand(\n CAN_REDO_COMMAND,\n (payload) => {\n setCanRedo(payload);\n return false;\n },\n COMMAND_PRIORITY_LOW,\n );\n return () => {\n unregisterUndo();\n unregisterRedo();\n };\n }, [editor]);\n\n // Callback - Update Toolbar Position and Active Formats\n const updateToolbar = useCallback(() => {\n // Read DOM selection OUTSIDE editor.read() — the DOM is already up to date\n // when SELECTION_CHANGE_COMMAND fires\n const domSelection = window.getSelection();\n if (\n !domSelection ||\n domSelection.rangeCount === 0 ||\n domSelection.isCollapsed\n ) {\n // Fast path: collapsed selection (normal typing) — hide if visible, skip everything else\n if (isVisibleRef.current) {\n setIsVisible(false);\n isVisibleRef.current = false;\n }\n return;\n }\n\n const range = domSelection.getRangeAt(0);\n const rect = range.getBoundingClientRect();\n\n if (rect.width === 0 && rect.height === 0) {\n if (isVisibleRef.current) {\n setIsVisible(false);\n isVisibleRef.current = false;\n }\n return;\n }\n\n // Read Lexical state for active formats\n editor.read(() => {\n const selection = $getSelection();\n\n // Hide toolbar when table selection is active (table has its own action menu)\n if ($isTableSelection(selection)) {\n setIsVisible(false);\n isVisibleRef.current = false;\n return;\n }\n\n if (!$isRangeSelection(selection) || selection.isCollapsed()) {\n setIsVisible(false);\n isVisibleRef.current = false;\n return;\n }\n\n const formats = new Set<string>();\n if (selection.hasFormat(\"bold\")) formats.add(\"bold\");\n if (selection.hasFormat(\"italic\")) formats.add(\"italic\");\n if (selection.hasFormat(\"underline\")) formats.add(\"underline\");\n if (selection.hasFormat(\"strikethrough\")) formats.add(\"strikethrough\");\n if (selection.hasFormat(\"code\")) formats.add(\"code\");\n\n // Check if cursor is inside a link\n const node = selection.anchor.getNode();\n const parent = node.getParent();\n if ($isLinkNode(parent) || $isLinkNode(node)) {\n formats.add(\"link\");\n }\n\n // Read active text color and highlight from the anchor node's style\n const anchorNode = selection.anchor.getNode();\n if ($isTextNode(anchorNode)) {\n const style = anchorNode.getStyle();\n setActiveTextColor(getInlineStyleProperty(style, \"color\"));\n setActiveHighlightColor(getInlineStyleProperty(style, \"background-color\"));\n setActiveFont(getInlineStyleProperty(style, \"font-family\"));\n } else {\n setActiveTextColor(null);\n setActiveHighlightColor(null);\n setActiveFont(null);\n }\n\n // Read block direction from the top-level element\n let block = $isElementNode(anchorNode) ? anchorNode : anchorNode.getParent();\n while (block && block.getParent() && !$isRootNode(block.getParent())) {\n block = block.getParent();\n }\n if (block && $isElementNode(block) && !$isRootNode(block)) {\n setBlockDirection(block.getDirection());\n } else {\n setBlockDirection(null);\n }\n\n setActiveFormats(formats);\n });\n\n // Position above the selection, or below if too close to top\n const toolbarHeight = 40;\n const gap = 8;\n const showBelow = rect.top < toolbarHeight + gap;\n\n setPosition({\n top: showBelow ? rect.bottom + gap : rect.top - gap,\n left: rect.left + rect.width / 2,\n });\n setIsVisible(true);\n isVisibleRef.current = true;\n }, [editor]);\n\n // RAF ref to throttle selection change updates\n const selectionRafRef = useRef(0);\n const isVisibleRef = useRef(false);\n\n useEffect(() => {\n return editor.registerCommand(\n SELECTION_CHANGE_COMMAND,\n () => {\n // Throttle: coalesce rapid selection changes into one RAF\n if (selectionRafRef.current === 0) {\n selectionRafRef.current = requestAnimationFrame(() => {\n selectionRafRef.current = 0;\n updateToolbar();\n });\n }\n return false;\n },\n COMMAND_PRIORITY_LOW,\n );\n }, [editor, updateToolbar]);\n\n // Close toolbar on Escape — handled via Lexical command since focus stays in editor\n useEffect(() => {\n if (!isVisible) return;\n\n return editor.registerCommand(\n KEY_ESCAPE_COMMAND,\n () => {\n setIsVisible(false);\n return true;\n },\n COMMAND_PRIORITY_LOW,\n );\n }, [editor, isVisible]);\n\n const handleFormat = useCallback(\n (format: TextFormat) => {\n editor.dispatchCommand(FORMAT_TEXT_COMMAND, format);\n // Re-focus editor after button click\n editor.focus();\n },\n [editor],\n );\n\n // Keyboard shortcuts: Cmd+E (code), Cmd+Shift+S (strikethrough)\n useEffect(() => {\n const rootElement = editor.getRootElement();\n if (!rootElement) return;\n\n const handleKeyDown = (e: KeyboardEvent) => {\n const isMod = e.metaKey || e.ctrlKey;\n\n // Cmd+E → inline code\n if (isMod && e.key === \"e\" && !e.shiftKey) {\n e.preventDefault();\n editor.dispatchCommand(FORMAT_TEXT_COMMAND, \"code\");\n }\n\n // Cmd+Shift+S → strikethrough\n if (isMod && e.shiftKey && e.key === \"s\") {\n e.preventDefault();\n editor.dispatchCommand(FORMAT_TEXT_COMMAND, \"strikethrough\");\n }\n };\n\n rootElement.addEventListener(\"keydown\", handleKeyDown);\n return () => rootElement.removeEventListener(\"keydown\", handleKeyDown);\n }, [editor]);\n\n // Close pickers when toolbar hides\n useEffect(() => {\n if (!isVisible) {\n setShowColorPicker(false);\n setShowFontPicker(false);\n }\n }, [isVisible]);\n\n if (!isVisible || !portalContainer) return null;\n\n // Use inline styles for the portal — Tailwind may not scan portalled elements\n const showBelow = position.top > 100; // rough heuristic\n const transformValue =\n position.top < 50 ? \"translateX(-50%)\" : \"translate(-50%, -100%)\";\n\n return createPortal(\n <div\n ref={toolbarRef}\n role=\"toolbar\"\n aria-label=\"Text formatting\"\n data-testid=\"floating-toolbar\"\n style={{\n position: \"fixed\",\n zIndex: 50,\n display: \"flex\",\n alignItems: \"center\",\n gap: \"1px\",\n padding: \"3px\",\n borderRadius: \"10px\",\n border: \"1px solid var(--blokhaus-popover-border, rgba(0, 0, 0, 0.12))\",\n backgroundColor: \"var(--blokhaus-popover-bg, rgba(255, 255, 255, 0.96))\",\n backdropFilter: \"blur(20px) saturate(180%)\",\n WebkitBackdropFilter: \"blur(20px) saturate(180%)\",\n boxShadow: \"var(--blokhaus-popover-shadow, 0 0 0 0.5px rgba(0,0,0,0.06), 0 8px 40px rgba(0,0,0,0.16), 0 2px 8px rgba(0,0,0,0.06))\",\n top: `${position.top}px`,\n left: `${position.left}px`,\n transform: transformValue,\n fontFamily:\n '-apple-system, BlinkMacSystemFont, \"SF Pro Text\", system-ui, sans-serif',\n }}\n >\n {/* Undo button */}\n <button\n type=\"button\"\n title={`Undo (${MOD}+Z)`}\n aria-label=\"Undo\"\n disabled={!canUndo}\n data-testid=\"toolbar-undo\"\n onMouseDown={(e) => {\n e.preventDefault();\n editor.dispatchCommand(UNDO_COMMAND, undefined);\n editor.focus();\n }}\n style={{\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n width: \"30px\",\n height: \"30px\",\n borderRadius: \"7px\",\n border: \"none\",\n cursor: \"default\",\n backgroundColor: \"transparent\",\n color: \"var(--blokhaus-icon-secondary)\",\n opacity: canUndo ? 1 : 0.3,\n pointerEvents: canUndo ? \"auto\" : \"none\",\n transition: \"opacity 80ms ease\",\n }}\n >\n <ArrowCounterClockwiseIcon size={15} weight=\"regular\" />\n </button>\n\n {/* Redo button */}\n <button\n type=\"button\"\n title={`Redo (${MOD}+Shift+Z)`}\n aria-label=\"Redo\"\n disabled={!canRedo}\n data-testid=\"toolbar-redo\"\n onMouseDown={(e) => {\n e.preventDefault();\n editor.dispatchCommand(REDO_COMMAND, undefined);\n editor.focus();\n }}\n style={{\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n width: \"30px\",\n height: \"30px\",\n borderRadius: \"7px\",\n border: \"none\",\n cursor: \"default\",\n backgroundColor: \"transparent\",\n color: \"var(--blokhaus-icon-secondary)\",\n opacity: canRedo ? 1 : 0.3,\n pointerEvents: canRedo ? \"auto\" : \"none\",\n transition: \"opacity 80ms ease\",\n }}\n >\n <ArrowClockwiseIcon size={15} weight=\"regular\" />\n </button>\n\n {/* Separator */}\n <div\n style={{\n width: \"1px\",\n height: \"18px\",\n backgroundColor: \"var(--blokhaus-separator)\",\n margin: \"0 2px\",\n }}\n />\n\n {TOOLBAR_BUTTONS.map(({ icon: Icon, format, label, shortcut }) => (\n <button\n key={format}\n type=\"button\"\n title={`${label} (${shortcut})`}\n aria-label={label}\n aria-pressed={activeFormats.has(format)}\n data-testid={`toolbar-${format}`}\n onMouseDown={(e) => {\n e.preventDefault();\n handleFormat(format);\n }}\n style={{\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n width: \"30px\",\n height: \"30px\",\n borderRadius: \"7px\",\n border: \"none\",\n cursor: \"default\",\n backgroundColor: activeFormats.has(format)\n ? \"var(--blokhaus-accent, #007AFF)\"\n : \"transparent\",\n color: activeFormats.has(format)\n ? \"var(--blokhaus-accent-foreground, #fff)\"\n : \"var(--blokhaus-icon-secondary)\",\n transition: \"background-color 80ms ease, color 80ms ease\",\n }}\n >\n <Icon\n size={15}\n weight={activeFormats.has(format) ? \"bold\" : \"regular\"}\n />\n </button>\n ))}\n\n {/* Separator */}\n <div\n style={{\n width: \"1px\",\n height: \"18px\",\n backgroundColor: \"var(--blokhaus-separator)\",\n margin: \"0 2px\",\n }}\n />\n\n {/* Link button */}\n <button\n type=\"button\"\n title=\"Link (Cmd+K)\"\n aria-label=\"Link\"\n aria-pressed={activeFormats.has(\"link\")}\n data-testid=\"toolbar-link\"\n onMouseDown={(e) => {\n e.preventDefault();\n editor.dispatchCommand(OPEN_LINK_INPUT_COMMAND, undefined);\n }}\n style={{\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n width: \"30px\",\n height: \"30px\",\n borderRadius: \"7px\",\n border: \"none\",\n cursor: \"default\",\n backgroundColor: activeFormats.has(\"link\")\n ? \"var(--blokhaus-accent, #007AFF)\"\n : \"transparent\",\n color: activeFormats.has(\"link\")\n ? \"var(--blokhaus-accent-foreground, #fff)\"\n : \"var(--blokhaus-icon-secondary)\",\n transition: \"background-color 80ms ease, color 80ms ease\",\n }}\n >\n <LinkIcon\n size={15}\n weight={activeFormats.has(\"link\") ? \"bold\" : \"regular\"}\n />\n </button>\n\n {/* Separator */}\n <div\n style={{\n width: \"1px\",\n height: \"18px\",\n backgroundColor: \"var(--blokhaus-separator)\",\n margin: \"0 2px\",\n }}\n />\n\n {/* Color button */}\n <div style={{ position: \"relative\" }}>\n <button\n type=\"button\"\n title=\"Text color\"\n aria-label=\"Text color\"\n aria-expanded={showColorPicker}\n data-testid=\"toolbar-color\"\n onMouseDown={(e) => {\n e.preventDefault();\n setShowColorPicker((prev) => {\n if (!prev) setShowFontPicker(false);\n return !prev;\n });\n }}\n style={{\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n flexDirection: \"column\",\n width: \"30px\",\n height: \"30px\",\n borderRadius: \"7px\",\n border: \"none\",\n cursor: \"default\",\n backgroundColor: showColorPicker\n ? \"var(--blokhaus-hover-bg)\"\n : \"transparent\",\n color: \"var(--blokhaus-icon-secondary)\",\n transition: \"background-color 80ms ease\",\n gap: \"1px\",\n }}\n >\n <span\n style={{\n fontSize: \"13px\",\n fontWeight: 700,\n lineHeight: 1,\n color: activeTextColor || \"var(--blokhaus-icon-secondary)\",\n }}\n >\n A\n </span>\n <div\n style={{\n width: \"12px\",\n height: \"2.5px\",\n borderRadius: \"1px\",\n backgroundColor: activeHighlightColor || \"var(--blokhaus-accent, #007AFF)\",\n }}\n />\n </button>\n\n {/* Color picker dropdown */}\n {showColorPicker && (\n <div\n data-testid=\"color-picker-dropdown\"\n style={{\n position: \"absolute\",\n top: \"calc(100% + 6px)\",\n left: \"50%\",\n transform: \"translateX(-50%)\",\n borderRadius: \"12px\",\n border: \"1px solid var(--blokhaus-popover-border, rgba(0, 0, 0, 0.12))\",\n backgroundColor: \"var(--blokhaus-popover-bg, rgba(255, 255, 255, 0.96))\",\n backdropFilter: \"blur(20px) saturate(180%)\",\n WebkitBackdropFilter: \"blur(20px) saturate(180%)\",\n boxShadow: \"var(--blokhaus-popover-shadow, 0 0 0 0.5px rgba(0,0,0,0.06), 0 8px 40px rgba(0,0,0,0.16), 0 2px 8px rgba(0,0,0,0.06))\",\n zIndex: 60,\n }}\n >\n <ColorPicker\n palette={colorPalette}\n activeTextColor={activeTextColor}\n activeHighlightColor={activeHighlightColor}\n onClose={() => setShowColorPicker(false)}\n />\n </div>\n )}\n </div>\n\n {/* Font picker button */}\n <div style={{ position: \"relative\" }}>\n <button\n type=\"button\"\n title=\"Font family\"\n aria-label=\"Font family\"\n aria-expanded={showFontPicker}\n data-testid=\"toolbar-font\"\n onMouseDown={(e) => {\n e.preventDefault();\n setShowFontPicker((prev) => {\n if (!prev) setShowColorPicker(false);\n return !prev;\n });\n }}\n style={{\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n width: \"30px\",\n height: \"30px\",\n borderRadius: \"7px\",\n border: \"none\",\n cursor: \"default\",\n backgroundColor: showFontPicker\n ? \"var(--blokhaus-hover-bg)\"\n : \"transparent\",\n color: \"var(--blokhaus-icon-secondary)\",\n transition: \"background-color 80ms ease\",\n }}\n >\n <TextAaIcon size={15} weight=\"regular\" />\n </button>\n\n {/* Font picker dropdown */}\n {showFontPicker && (\n <div\n data-testid=\"font-picker-dropdown\"\n style={{\n position: \"absolute\",\n top: \"calc(100% + 6px)\",\n left: \"50%\",\n transform: \"translateX(-50%)\",\n borderRadius: \"12px\",\n border: \"1px solid var(--blokhaus-popover-border, rgba(0, 0, 0, 0.12))\",\n backgroundColor: \"var(--blokhaus-popover-bg, rgba(255, 255, 255, 0.96))\",\n backdropFilter: \"blur(20px) saturate(180%)\",\n WebkitBackdropFilter: \"blur(20px) saturate(180%)\",\n boxShadow: \"var(--blokhaus-popover-shadow, 0 0 0 0.5px rgba(0,0,0,0.06), 0 8px 40px rgba(0,0,0,0.16), 0 2px 8px rgba(0,0,0,0.06))\",\n zIndex: 60,\n }}\n >\n <FontPicker\n fonts={fontFamilies}\n activeFont={activeFont}\n onClose={() => setShowFontPicker(false)}\n />\n </div>\n )}\n </div>\n\n {/* Separator */}\n <div\n style={{\n width: \"1px\",\n height: \"18px\",\n backgroundColor: \"var(--blokhaus-separator)\",\n margin: \"0 2px\",\n }}\n />\n\n {/* Direction toggle button */}\n <button\n type=\"button\"\n title={blockDirection === \"rtl\" ? \"Switch to LTR\" : \"Switch to RTL\"}\n aria-label={blockDirection === \"rtl\" ? \"Switch to left-to-right\" : \"Switch to right-to-left\"}\n data-testid=\"toolbar-direction\"\n onMouseDown={(e) => {\n e.preventDefault();\n const newDir = blockDirection === \"rtl\" ? \"ltr\" : \"rtl\";\n editor.dispatchCommand(SET_BLOCK_DIRECTION_COMMAND, newDir);\n setBlockDirection(newDir);\n editor.focus();\n }}\n style={{\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n width: \"30px\",\n height: \"30px\",\n borderRadius: \"7px\",\n border: \"none\",\n cursor: \"default\",\n backgroundColor: \"transparent\",\n color: \"var(--blokhaus-icon-secondary)\",\n transition: \"background-color 80ms ease, color 80ms ease\",\n }}\n >\n {blockDirection === \"rtl\" ? (\n <TextAlignLeftIcon size={15} weight=\"regular\" />\n ) : (\n <TextAlignRightIcon size={15} weight=\"regular\" />\n )}\n </button>\n </div>,\n portalContainer,\n );\n}\n","// LEXICAL\nimport { createCommand } from 'lexical';\n\nexport const OPEN_SLASH_MENU_COMMAND = createCommand<void>('OPEN_SLASH_MENU_COMMAND');\nexport const INSERT_IMAGE_COMMAND = createCommand<File>('INSERT_IMAGE_COMMAND');\nexport const OPEN_AI_PROMPT_COMMAND = createCommand<void>('OPEN_AI_PROMPT_COMMAND');\nexport const INSERT_AI_PREVIEW_COMMAND = createCommand<{ prompt: string }>('INSERT_AI_PREVIEW_COMMAND');\nexport const OPEN_EMOJI_PICKER_COMMAND = createCommand<void>('OPEN_EMOJI_PICKER_COMMAND');\nexport const OPEN_LINK_INPUT_COMMAND = createCommand<void>('OPEN_LINK_INPUT_COMMAND');\nexport const SET_TEXT_COLOR_COMMAND = createCommand<string>('SET_TEXT_COLOR_COMMAND');\nexport const SET_HIGHLIGHT_COLOR_COMMAND = createCommand<string>('SET_HIGHLIGHT_COLOR_COMMAND');\nexport const INSERT_TABLE_COMMAND_BLOKHAUS = createCommand<{ rows: number; columns: number }>('INSERT_TABLE_COMMAND_BLOKHAUS');\nexport const INSERT_CALLOUT_COMMAND = createCommand<{ emoji?: string; colorPreset?: string }>('INSERT_CALLOUT_COMMAND');\nexport const INSERT_VIDEO_COMMAND = createCommand<{ file: File } | { url: string }>('INSERT_VIDEO_COMMAND');\nexport const OPEN_VIDEO_INPUT_COMMAND = createCommand<void>('OPEN_VIDEO_INPUT_COMMAND');\nexport const INSERT_TOGGLE_COMMAND = createCommand<{ isOpen?: boolean } | undefined>('INSERT_TOGGLE_COMMAND');\nexport const SET_FONT_FAMILY_COMMAND = createCommand<string>('SET_FONT_FAMILY_COMMAND');\nexport const SET_BLOCK_DIRECTION_COMMAND = createCommand<'ltr' | 'rtl'>('SET_BLOCK_DIRECTION_COMMAND');\n","/**\n * Pure CSS inline style string utilities.\n *\n * Lexical's `selection.setStyle()` replaces the entire style string,\n * so we need helpers to merge properties without clobbering existing ones.\n */\n\n/**\n * Parse a CSS inline style string into a Map of property → value.\n */\nfunction parseStyle(style: string): Map<string, string> {\n const map = new Map<string, string>();\n if (!style.trim()) return map;\n\n for (const declaration of style.split(\";\")) {\n const colonIndex = declaration.indexOf(\":\");\n if (colonIndex === -1) continue;\n const prop = declaration.slice(0, colonIndex).trim();\n const val = declaration.slice(colonIndex + 1).trim();\n if (prop && val) {\n map.set(prop, val);\n }\n }\n return map;\n}\n\n/**\n * Serialize a Map of style properties back to an inline style string.\n */\nfunction serializeStyle(map: Map<string, string>): string {\n const parts: string[] = [];\n for (const [prop, val] of map) {\n parts.push(`${prop}: ${val}`);\n }\n return parts.join(\"; \");\n}\n\n/**\n * Merge a single CSS property into an existing inline style string.\n * If `value` is `null`, the property is removed.\n * Returns the new style string.\n */\nexport function mergeInlineStyle(\n existing: string,\n property: string,\n value: string | null,\n): string {\n const map = parseStyle(existing);\n if (value === null) {\n map.delete(property);\n } else {\n map.set(property, value);\n }\n return serializeStyle(map);\n}\n\n/**\n * Read a single CSS property value from an inline style string.\n * Returns the value or `null` if not present.\n */\nexport function getInlineStyleProperty(\n style: string,\n property: string,\n): string | null {\n const map = parseStyle(style);\n return map.get(property) ?? null;\n}\n","\"use client\";\n\nimport { useCallback } from \"react\";\nimport { useLexicalComposerContext } from \"@lexical/react/LexicalComposerContext\";\nimport { CheckIcon } from \"@phosphor-icons/react\";\n\nimport { SET_TEXT_COLOR_COMMAND, SET_HIGHLIGHT_COLOR_COMMAND } from \"../commands\";\nimport type { ColorPalette } from \"../data/color-palette\";\nimport { DEFAULT_COLOR_PALETTE } from \"../data/color-palette\";\n\ninterface ColorPickerProps {\n palette?: ColorPalette;\n activeTextColor: string | null;\n activeHighlightColor: string | null;\n onClose: () => void;\n}\n\nexport function ColorPicker({\n palette = DEFAULT_COLOR_PALETTE,\n activeTextColor,\n activeHighlightColor,\n onClose,\n}: ColorPickerProps) {\n const [editor] = useLexicalComposerContext();\n\n const handleTextColor = useCallback(\n (value: string) => {\n editor.dispatchCommand(SET_TEXT_COLOR_COMMAND, value);\n editor.focus();\n onClose();\n },\n [editor, onClose],\n );\n\n const handleHighlightColor = useCallback(\n (value: string) => {\n editor.dispatchCommand(SET_HIGHLIGHT_COLOR_COMMAND, value);\n editor.focus();\n onClose();\n },\n [editor, onClose],\n );\n\n return (\n <div\n data-testid=\"color-picker\"\n onMouseDown={(e) => e.preventDefault()}\n style={{\n padding: \"8px\",\n minWidth: \"200px\",\n fontFamily:\n '-apple-system, BlinkMacSystemFont, \"SF Pro Text\", system-ui, sans-serif',\n }}\n >\n {/* Text color section */}\n <div\n style={{\n fontSize: \"10.5px\",\n fontWeight: 600,\n color: \"var(--blokhaus-text-tertiary)\",\n textTransform: \"uppercase\",\n letterSpacing: \"0.05em\",\n padding: \"2px 4px 6px\",\n userSelect: \"none\",\n }}\n >\n Text color\n </div>\n <div style={{ display: \"flex\", flexWrap: \"wrap\", gap: \"2px\", marginBottom: \"8px\" }}>\n {palette.text.map((entry) => {\n const isActive =\n entry.value === \"\" ? !activeTextColor : activeTextColor === entry.value;\n\n return (\n <button\n key={`text-${entry.label}`}\n type=\"button\"\n title={entry.label}\n aria-label={entry.label}\n data-testid={`color-text-${entry.label.toLowerCase()}`}\n onMouseDown={(e) => {\n e.preventDefault();\n handleTextColor(entry.value);\n }}\n style={{\n width: \"24px\",\n height: \"24px\",\n borderRadius: \"4px\",\n border: \"1px solid var(--blokhaus-popover-border)\",\n cursor: \"pointer\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n backgroundColor: \"transparent\",\n position: \"relative\",\n }}\n >\n <span\n style={{\n fontSize: \"14px\",\n fontWeight: 700,\n color:\n entry.swatch === \"currentColor\"\n ? \"var(--blokhaus-foreground, #1d1d1f)\"\n : entry.swatch,\n lineHeight: 1,\n }}\n >\n A\n </span>\n {isActive && (\n <CheckIcon\n size={8}\n weight=\"bold\"\n style={{\n position: \"absolute\",\n bottom: \"1px\",\n insetInlineEnd: \"1px\",\n color: \"var(--blokhaus-accent, #007AFF)\",\n }}\n />\n )}\n </button>\n );\n })}\n </div>\n\n {/* Separator */}\n <div\n style={{\n height: \"0.5px\",\n backgroundColor: \"var(--blokhaus-separator)\",\n margin: \"4px 0\",\n }}\n />\n\n {/* Highlight color section */}\n <div\n style={{\n fontSize: \"10.5px\",\n fontWeight: 600,\n color: \"var(--blokhaus-text-tertiary)\",\n textTransform: \"uppercase\",\n letterSpacing: \"0.05em\",\n padding: \"6px 4px 6px\",\n userSelect: \"none\",\n }}\n >\n Background\n </div>\n <div style={{ display: \"flex\", flexWrap: \"wrap\", gap: \"2px\" }}>\n {palette.highlight.map((entry) => {\n const isActive =\n entry.value === \"\"\n ? !activeHighlightColor\n : activeHighlightColor === entry.value;\n\n return (\n <button\n key={`highlight-${entry.label}`}\n type=\"button\"\n title={entry.label}\n aria-label={entry.label}\n data-testid={`color-highlight-${entry.label.toLowerCase()}`}\n onMouseDown={(e) => {\n e.preventDefault();\n handleHighlightColor(entry.value);\n }}\n style={{\n width: \"24px\",\n height: \"24px\",\n borderRadius: \"4px\",\n border: \"1px solid var(--blokhaus-popover-border)\",\n cursor: \"pointer\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n backgroundColor:\n entry.swatch === \"transparent\" ? \"transparent\" : entry.swatch,\n position: \"relative\",\n }}\n >\n {entry.swatch === \"transparent\" && (\n <span\n style={{\n fontSize: \"11px\",\n color: \"var(--blokhaus-text-tertiary)\",\n lineHeight: 1,\n }}\n >\n ∅\n </span>\n )}\n {isActive && (\n <CheckIcon\n size={10}\n weight=\"bold\"\n style={{\n color:\n entry.swatch === \"transparent\"\n ? \"var(--blokhaus-accent, #007AFF)\"\n : \"var(--blokhaus-icon-secondary)\",\n }}\n />\n )}\n </button>\n );\n })}\n </div>\n </div>\n );\n}\n","/**\n * Color palette types and default palette for text color & background highlighting.\n *\n * Colors are stored as CSS variable references (e.g., \"var(--blokhaus-text-red)\")\n * so developers can override them via tokens.css to rebrand.\n */\n\nexport interface ColorEntry {\n /** Human-readable label shown in the picker */\n label: string;\n /** CSS value to apply — should be a var() reference */\n value: string;\n /** Preview swatch color (raw hex/hsl for rendering the dot in the picker) */\n swatch: string;\n}\n\nexport interface ColorPalette {\n text: ColorEntry[];\n highlight: ColorEntry[];\n}\n\nexport const DEFAULT_COLOR_PALETTE: ColorPalette = {\n text: [\n { label: \"Default\", value: \"\", swatch: \"currentColor\" },\n { label: \"Gray\", value: \"var(--blokhaus-text-gray)\", swatch: \"#9b9a97\" },\n { label: \"Brown\", value: \"var(--blokhaus-text-brown)\", swatch: \"#64473a\" },\n { label: \"Orange\", value: \"var(--blokhaus-text-orange)\", swatch: \"#d9730d\" },\n { label: \"Yellow\", value: \"var(--blokhaus-text-yellow)\", swatch: \"#dfab01\" },\n { label: \"Green\", value: \"var(--blokhaus-text-green)\", swatch: \"#0f7b6c\" },\n { label: \"Blue\", value: \"var(--blokhaus-text-blue)\", swatch: \"#0b6e99\" },\n { label: \"Purple\", value: \"var(--blokhaus-text-purple)\", swatch: \"#6940a5\" },\n { label: \"Pink\", value: \"var(--blokhaus-text-pink)\", swatch: \"#ad1a72\" },\n { label: \"Red\", value: \"var(--blokhaus-text-red)\", swatch: \"#e03e3e\" },\n ],\n highlight: [\n { label: \"Default\", value: \"\", swatch: \"transparent\" },\n { label: \"Gray\", value: \"var(--blokhaus-highlight-gray)\", swatch: \"#ebeced\" },\n { label: \"Brown\", value: \"var(--blokhaus-highlight-brown)\", swatch: \"#e9e5e3\" },\n { label: \"Orange\", value: \"var(--blokhaus-highlight-orange)\", swatch: \"#faebdd\" },\n { label: \"Yellow\", value: \"var(--blokhaus-highlight-yellow)\", swatch: \"#fbf3db\" },\n { label: \"Green\", value: \"var(--blokhaus-highlight-green)\", swatch: \"#ddedea\" },\n { label: \"Blue\", value: \"var(--blokhaus-highlight-blue)\", swatch: \"#ddebf1\" },\n { label: \"Purple\", value: \"var(--blokhaus-highlight-purple)\", swatch: \"#eae4f2\" },\n { label: \"Pink\", value: \"var(--blokhaus-highlight-pink)\", swatch: \"#f4dfeb\" },\n { label: \"Red\", value: \"var(--blokhaus-highlight-red)\", swatch: \"#fbe4e4\" },\n ],\n};\n","\"use client\";\n\nimport { useCallback } from \"react\";\nimport { useLexicalComposerContext } from \"@lexical/react/LexicalComposerContext\";\nimport { CheckIcon } from \"@phosphor-icons/react\";\n\nimport { SET_FONT_FAMILY_COMMAND } from \"../commands\";\nimport type { FontFamilyEntry } from \"../data/font-families\";\nimport { DEFAULT_FONT_FAMILIES } from \"../data/font-families\";\n\ninterface FontPickerProps {\n fonts?: FontFamilyEntry[];\n activeFont: string | null;\n onClose: () => void;\n}\n\nexport function FontPicker({\n fonts = DEFAULT_FONT_FAMILIES,\n activeFont,\n onClose,\n}: FontPickerProps) {\n const [editor] = useLexicalComposerContext();\n\n const handleSelect = useCallback(\n (value: string) => {\n editor.dispatchCommand(SET_FONT_FAMILY_COMMAND, value);\n editor.focus();\n onClose();\n },\n [editor, onClose],\n );\n\n return (\n <div\n data-testid=\"font-picker\"\n onMouseDown={(e) => e.preventDefault()}\n style={{\n padding: \"4px\",\n minWidth: \"160px\",\n fontFamily:\n '-apple-system, BlinkMacSystemFont, \"SF Pro Text\", system-ui, sans-serif',\n }}\n >\n {fonts.map((entry) => {\n const isActive =\n entry.value === \"\" ? !activeFont : activeFont === entry.value;\n\n return (\n <button\n key={entry.label}\n type=\"button\"\n aria-label={entry.label}\n data-testid={`font-${entry.label.toLowerCase()}`}\n onMouseDown={(e) => {\n e.preventDefault();\n handleSelect(entry.value);\n }}\n style={{\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"space-between\",\n width: \"100%\",\n padding: \"6px 8px\",\n borderRadius: \"6px\",\n border: \"none\",\n cursor: \"pointer\",\n backgroundColor: isActive\n ? \"var(--blokhaus-hover-bg)\"\n : \"transparent\",\n color: \"var(--blokhaus-foreground, #1d1d1f)\",\n transition: \"background-color 80ms ease\",\n fontFamily: entry.preview,\n fontSize: \"13px\",\n lineHeight: \"1.4\",\n textAlign: \"start\",\n }}\n >\n <span>{entry.label}</span>\n {isActive && (\n <CheckIcon\n size={12}\n weight=\"bold\"\n style={{\n color: \"var(--blokhaus-accent, #007AFF)\",\n flexShrink: 0,\n marginInlineStart: \"8px\",\n }}\n />\n )}\n </button>\n );\n })}\n </div>\n );\n}\n","/**\n * Font family entries for the FontPicker dropdown.\n *\n * Values use CSS variable references so apps can swap the actual\n * Google Font (or any other font) without touching the library.\n */\n\nexport interface FontFamilyEntry {\n /** Human-readable label shown in the picker */\n label: string;\n /** CSS font-family value to apply. Empty string = remove / default. */\n value: string;\n /** Font stack used to render the preview text in the picker dropdown */\n preview: string;\n}\n\nexport const DEFAULT_FONT_FAMILIES: FontFamilyEntry[] = [\n { label: \"Default\", value: \"\", preview: \"var(--blokhaus-font-sans)\" },\n { label: \"Serif\", value: \"var(--blokhaus-font-serif)\", preview: \"var(--blokhaus-font-serif)\" },\n { label: \"Mono\", value: \"var(--blokhaus-font-mono)\", preview: \"var(--blokhaus-font-mono)\" },\n { label: \"Hand\", value: \"var(--blokhaus-font-hand)\", preview: \"var(--blokhaus-font-hand)\" },\n];\n","\"use client\";\n\n// REACT\nimport { useCallback, useEffect, useMemo, useRef, useState } from \"react\";\n\n// LEXICAL\nimport { useLexicalComposerContext } from \"@lexical/react/LexicalComposerContext\";\nimport {\n $createParagraphNode,\n $getRoot,\n $getSelection,\n $isElementNode,\n $isRangeSelection,\n $isRootNode,\n COMMAND_PRIORITY_LOW,\n KEY_ARROW_DOWN_COMMAND,\n KEY_ARROW_UP_COMMAND,\n KEY_ENTER_COMMAND,\n KEY_ESCAPE_COMMAND,\n TextNode,\n} from \"lexical\";\nimport { $createHeadingNode, $createQuoteNode } from \"@lexical/rich-text\";\nimport { $createListNode, $createListItemNode } from \"@lexical/list\";\n\n// REACT DOM\nimport { createPortal } from \"react-dom\";\n\n// PHOSPHOR ICONS — Duotone wrappers for the slash menu\nimport {\n TextHOneIcon,\n TextHTwoIcon,\n TextHThreeIcon,\n QuotesIcon,\n ListBulletsIcon,\n ListNumbersIcon,\n CheckSquareIcon,\n MinusSquareIcon,\n ImageSquareIcon,\n SparkleIcon,\n CodeSimpleIcon,\n TableIcon,\n InfoIcon,\n SmileyIcon,\n VideoCameraIcon,\n CaretCircleDownIcon,\n TextAaIcon,\n TextAlignLeftIcon,\n TextAlignRightIcon,\n} from \"@phosphor-icons/react\";\n\n// COMMANDS\nimport {\n OPEN_SLASH_MENU_COMMAND,\n INSERT_IMAGE_COMMAND,\n OPEN_AI_PROMPT_COMMAND,\n OPEN_EMOJI_PICKER_COMMAND,\n INSERT_TABLE_COMMAND_BLOKHAUS,\n INSERT_CALLOUT_COMMAND,\n OPEN_VIDEO_INPUT_COMMAND,\n INSERT_TOGGLE_COMMAND,\n} from \"../commands\";\n\nimport { $patchStyleText } from \"@lexical/selection\";\nimport { $createCodeBlockNode } from \"../nodes/CodeBlockNode\";\nimport { $createHorizontalRuleNode } from \"../nodes/HorizontalRuleNode\";\nimport { DEFAULT_FONT_FAMILIES } from \"../data/font-families\";\n\n// ── Duotone icon wrappers (stable references, no re-creation) ───────────────\n\nconst IconH1 = ({ size }: { size?: number }) => (\n <TextHOneIcon size={size} weight=\"duotone\" />\n);\nconst IconH2 = ({ size }: { size?: number }) => (\n <TextHTwoIcon size={size} weight=\"duotone\" />\n);\nconst IconH3 = ({ size }: { size?: number }) => (\n <TextHThreeIcon size={size} weight=\"duotone\" />\n);\nconst IconQuote = ({ size }: { size?: number }) => (\n <QuotesIcon size={size} weight=\"duotone\" />\n);\nconst IconBulletList = ({ size }: { size?: number }) => (\n <ListBulletsIcon size={size} weight=\"duotone\" />\n);\nconst IconNumberedList = ({ size }: { size?: number }) => (\n <ListNumbersIcon size={size} weight=\"duotone\" />\n);\nconst IconDivider = ({ size }: { size?: number }) => (\n <MinusSquareIcon size={size} weight=\"duotone\" />\n);\nconst IconImage = ({ size }: { size?: number }) => (\n <ImageSquareIcon size={size} weight=\"duotone\" />\n);\nconst IconCode = ({ size }: { size?: number }) => (\n <CodeSimpleIcon size={size} weight=\"duotone\" />\n);\nconst IconAI = ({ size }: { size?: number }) => (\n <SparkleIcon size={size} weight=\"duotone\" />\n);\nconst IconTable = ({ size }: { size?: number }) => (\n <TableIcon size={size} weight=\"duotone\" />\n);\nconst IconCallout = ({ size }: { size?: number }) => (\n <InfoIcon size={size} weight=\"duotone\" />\n);\nconst IconEmoji = ({ size }: { size?: number }) => (\n <SmileyIcon size={size} weight=\"duotone\" />\n);\nconst IconVideo = ({ size }: { size?: number }) => (\n <VideoCameraIcon size={size} weight=\"duotone\" />\n);\nconst IconChecklist = ({ size }: { size?: number }) => (\n <CheckSquareIcon size={size} weight=\"duotone\" />\n);\nconst IconToggle = ({ size }: { size?: number }) => (\n <CaretCircleDownIcon size={size} weight=\"duotone\" />\n);\nconst IconFont = ({ size }: { size?: number }) => (\n <TextAaIcon size={size} weight=\"duotone\" />\n);\nconst IconLTR = ({ size }: { size?: number }) => (\n <TextAlignLeftIcon size={size} weight=\"duotone\" />\n);\nconst IconRTL = ({ size }: { size?: number }) => (\n <TextAlignRightIcon size={size} weight=\"duotone\" />\n);\n\n// ── Public interface ────────────────────────────────────────────────────────\n\nexport interface SlashMenuItem {\n id: string;\n label: string;\n description: string;\n icon: React.ComponentType<{ size?: number }>;\n onSelect: () => void;\n /** Extra search terms (e.g. \"h1\" for \"Heading 1\") */\n keywords?: string[];\n}\n\n// ── Markdown shortcut hints (shown on the right of each item) ───────────────\n\nconst SHORTCUT_HINTS: Record<string, string> = {\n \"heading-1\": \"#\",\n \"heading-2\": \"##\",\n \"heading-3\": \"###\",\n quote: \">\",\n \"bullet-list\": \"-\",\n \"numbered-list\": \"1.\",\n \"check-list\": \"[]\",\n divider: \"---\",\n code: \"```\",\n};\n\n// ── Category color system ───────────────────────────────────────────────────\n\ninterface CategoryStyle {\n bg: string;\n icon: string;\n}\n\nconst CATEGORY_COLORS: Record<string, CategoryStyle> = {\n ai: { bg: \"var(--blokhaus-muted)\", icon: \"#3366CC\" },\n headings: { bg: \"var(--blokhaus-muted)\", icon: \"#6366F1\" },\n blocks: { bg: \"var(--blokhaus-muted)\", icon: \"#8B5CF6\" },\n lists: { bg: \"var(--blokhaus-muted)\", icon: \"#10B981\" },\n media: { bg: \"var(--blokhaus-muted)\", icon: \"#F59E0B\" },\n format: { bg: \"var(--blokhaus-muted)\", icon: \"#EC4899\" },\n other: { bg: \"var(--blokhaus-muted)\", icon: \"#6B7280\" },\n};\n\nfunction getCategoryForId(id: string): string {\n if (id === \"ai\") return \"ai\";\n if (id.startsWith(\"heading\")) return \"headings\";\n if (id === \"quote\" || id === \"divider\" || id === \"code\" || id === \"table\" || id === \"callout\" || id === \"toggle\") return \"blocks\";\n if (id === \"bullet-list\" || id === \"numbered-list\" || id === \"check-list\")\n return \"lists\";\n if (id === \"image\" || id === \"emoji\" || id === \"video\") return \"media\";\n if (id.startsWith(\"font-\") || id.startsWith(\"direction-\")) return \"format\";\n return \"other\";\n}\n\n// ── Injected CSS for animations ─────────────────────────────────────────────\n\nconst SLASH_MENU_STYLES = `\n@keyframes blokhaus-menu-enter {\n from {\n opacity: 0;\n transform: scale(0.98) translateY(3px);\n }\n to {\n opacity: 1;\n transform: scale(1) translateY(0);\n }\n}\n@keyframes blokhaus-icon-lift {\n 0%, 100% { transform: translateY(0) scale(1); }\n 40% { transform: translateY(-2px) scale(1.08); }\n 70% { transform: translateY(0.5px) scale(0.98); }\n}\n[data-testid=\"slash-menu\"]::-webkit-scrollbar {\n display: none;\n}\n`;\n\n// ── Default items factory ───────────────────────────────────────────────────\n\nfunction getDefaultItems(\n editor: ReturnType<typeof useLexicalComposerContext>[0],\n): SlashMenuItem[] {\n const replaceCurrentBlock = (\n createNode: () => import(\"lexical\").ElementNode,\n ) => {\n editor.update(() => {\n const selection = $getSelection();\n if (!$isRangeSelection(selection)) return;\n const anchor = selection.anchor.getNode();\n\n // Walk up to find the top-level block BEFORE removing anything\n let block: import(\"lexical\").LexicalNode = anchor;\n while (block.getParent() && !$isRootNode(block.getParent())) {\n block = block.getParent()!;\n }\n\n // Remove the \"/\" text\n if (anchor instanceof TextNode) {\n anchor.remove();\n }\n\n const newNode = createNode();\n if ($isRootNode(block)) {\n $getRoot().append(newNode);\n } else if (\n \"getChildrenSize\" in block &&\n typeof block.getChildrenSize === \"function\" &&\n (block.getChildrenSize as () => number)() === 0\n ) {\n block.replace(newNode);\n } else {\n block.insertAfter(newNode);\n }\n newNode.selectEnd();\n });\n };\n\n return [\n {\n id: \"ai\",\n label: \"Ask AI\",\n description: \"Generate content with AI\",\n icon: IconAI,\n onSelect: () => {\n // Remove the \"/\" trigger text first\n editor.update(() => {\n const selection = $getSelection();\n if (!$isRangeSelection(selection)) return;\n const anchor = selection.anchor.getNode();\n if (anchor instanceof TextNode) {\n anchor.remove();\n }\n });\n // Then open the AI prompt input\n editor.dispatchCommand(OPEN_AI_PROMPT_COMMAND, undefined);\n },\n },\n {\n id: \"heading-1\",\n label: \"Heading 1\",\n description: \"Large heading\",\n keywords: [\"h1\"],\n icon: IconH1,\n onSelect: () => replaceCurrentBlock(() => $createHeadingNode(\"h1\")),\n },\n {\n id: \"heading-2\",\n label: \"Heading 2\",\n description: \"Medium heading\",\n keywords: [\"h2\"],\n icon: IconH2,\n onSelect: () => replaceCurrentBlock(() => $createHeadingNode(\"h2\")),\n },\n {\n id: \"heading-3\",\n label: \"Heading 3\",\n description: \"Small heading\",\n keywords: [\"h3\"],\n icon: IconH3,\n onSelect: () => replaceCurrentBlock(() => $createHeadingNode(\"h3\")),\n },\n {\n id: \"quote\",\n label: \"Quote\",\n description: \"Blockquote\",\n icon: IconQuote,\n onSelect: () => replaceCurrentBlock(() => $createQuoteNode()),\n },\n {\n id: \"bullet-list\",\n label: \"Bullet List\",\n description: \"Unordered list\",\n icon: IconBulletList,\n onSelect: () =>\n replaceCurrentBlock(() => {\n const list = $createListNode(\"bullet\");\n const item = $createListItemNode();\n list.append(item);\n return list;\n }),\n },\n {\n id: \"numbered-list\",\n label: \"Numbered List\",\n description: \"Ordered list\",\n icon: IconNumberedList,\n onSelect: () =>\n replaceCurrentBlock(() => {\n const list = $createListNode(\"number\");\n const item = $createListItemNode();\n list.append(item);\n return list;\n }),\n },\n {\n id: \"check-list\",\n label: \"Checklist\",\n description: \"Task list with checkboxes\",\n keywords: [\"todo\", \"task\", \"checkbox\", \"check\"],\n icon: IconChecklist,\n onSelect: () =>\n replaceCurrentBlock(() => {\n const list = $createListNode(\"check\");\n const item = $createListItemNode();\n list.append(item);\n return list;\n }),\n },\n {\n id: \"divider\",\n label: \"Divider\",\n description: \"Horizontal rule\",\n icon: IconDivider,\n onSelect: () => {\n editor.update(() => {\n const selection = $getSelection();\n if (!$isRangeSelection(selection)) return;\n const anchor = selection.anchor.getNode();\n\n let block: import(\"lexical\").LexicalNode = anchor;\n while (block.getParent() && !$isRootNode(block.getParent())) {\n block = block.getParent()!;\n }\n\n if (anchor instanceof TextNode) {\n anchor.remove();\n }\n\n const rule = $createHorizontalRuleNode();\n const trailingParagraph = $createParagraphNode();\n\n if ($isRootNode(block)) {\n const root = $getRoot();\n root.append(rule);\n root.append(trailingParagraph);\n } else if (\n \"getChildrenSize\" in block &&\n typeof block.getChildrenSize === \"function\" &&\n (block.getChildrenSize as () => number)() === 0\n ) {\n block.replace(rule);\n rule.insertAfter(trailingParagraph);\n } else {\n block.insertAfter(rule);\n rule.insertAfter(trailingParagraph);\n }\n trailingParagraph.selectEnd();\n });\n },\n },\n {\n id: \"code\",\n label: \"Code Block\",\n description: \"Syntax highlighted code\",\n icon: IconCode,\n onSelect: () => {\n editor.update(() => {\n const selection = $getSelection();\n if (!$isRangeSelection(selection)) return;\n const anchor = selection.anchor.getNode();\n\n let block: import(\"lexical\").LexicalNode = anchor;\n while (block.getParent() && !$isRootNode(block.getParent())) {\n block = block.getParent()!;\n }\n\n if (anchor instanceof TextNode) {\n anchor.remove();\n }\n\n const codeBlock = $createCodeBlockNode({ code: \"\", language: \"javascript\", autoFocus: true });\n const trailingParagraph = $createParagraphNode();\n if ($isRootNode(block)) {\n $getRoot().append(codeBlock);\n } else if (\n \"getChildrenSize\" in block &&\n typeof block.getChildrenSize === \"function\" &&\n (block.getChildrenSize as () => number)() === 0\n ) {\n block.replace(codeBlock);\n } else {\n block.insertAfter(codeBlock);\n }\n codeBlock.insertAfter(trailingParagraph);\n trailingParagraph.selectEnd();\n });\n },\n },\n {\n id: \"table\",\n label: \"Table\",\n description: \"Insert a table\",\n icon: IconTable,\n onSelect: () => {\n editor.update(() => {\n const selection = $getSelection();\n if (!$isRangeSelection(selection)) return;\n const anchor = selection.anchor.getNode();\n if (anchor instanceof TextNode) {\n anchor.remove();\n }\n });\n editor.dispatchCommand(INSERT_TABLE_COMMAND_BLOKHAUS, {\n rows: 3,\n columns: 3,\n });\n },\n },\n {\n id: \"callout\",\n label: \"Callout\",\n description: \"Highlighted block with icon\",\n icon: IconCallout,\n onSelect: () => {\n editor.update(() => {\n const selection = $getSelection();\n if (!$isRangeSelection(selection)) return;\n const anchor = selection.anchor.getNode();\n if (anchor instanceof TextNode) {\n anchor.remove();\n }\n });\n editor.dispatchCommand(INSERT_CALLOUT_COMMAND, {});\n },\n },\n {\n id: \"toggle\",\n label: \"Toggle\",\n description: \"Collapsible content block\",\n icon: IconToggle,\n keywords: [\"toggle\", \"collapse\", \"expand\", \"accordion\", \"dropdown\", \"details\", \"fold\"],\n onSelect: () => {\n editor.update(() => {\n const selection = $getSelection();\n if (!$isRangeSelection(selection)) return;\n const anchor = selection.anchor.getNode();\n if (anchor instanceof TextNode) {\n anchor.remove();\n }\n });\n editor.dispatchCommand(INSERT_TOGGLE_COMMAND, {});\n },\n },\n {\n id: \"image\",\n label: \"Image\",\n description: \"Upload an image\",\n icon: IconImage,\n onSelect: () => {\n editor.update(() => {\n const selection = $getSelection();\n if (!$isRangeSelection(selection)) return;\n const anchor = selection.anchor.getNode();\n if (anchor instanceof TextNode) {\n anchor.remove();\n }\n });\n const input = document.createElement(\"input\");\n input.type = \"file\";\n input.accept = \"image/*\";\n input.onchange = () => {\n const file = input.files?.[0];\n if (file) {\n editor.dispatchCommand(INSERT_IMAGE_COMMAND, file);\n }\n };\n input.click();\n },\n },\n {\n id: \"emoji\",\n label: \"Emoji\",\n description: \"Insert an emoji\",\n keywords: [\"smiley\", \"face\", \"emoticon\"],\n icon: IconEmoji,\n onSelect: () => {\n // Remove the \"/\" trigger text, then open the emoji picker via command\n editor.update(() => {\n const selection = $getSelection();\n if (!$isRangeSelection(selection)) return;\n const anchor = selection.anchor.getNode();\n if (anchor instanceof TextNode) {\n anchor.remove();\n }\n });\n editor.dispatchCommand(OPEN_EMOJI_PICKER_COMMAND, undefined);\n },\n },\n {\n id: \"video\",\n label: \"Video\",\n description: \"Embed or upload a video\",\n keywords: [\"youtube\", \"vimeo\", \"loom\", \"embed\", \"movie\", \"clip\"],\n icon: IconVideo,\n onSelect: () => {\n editor.update(() => {\n const selection = $getSelection();\n if (!$isRangeSelection(selection)) return;\n const anchor = selection.anchor.getNode();\n if (anchor instanceof TextNode) {\n anchor.remove();\n }\n });\n editor.dispatchCommand(OPEN_VIDEO_INPUT_COMMAND, undefined);\n },\n },\n // Font family items — skip \"Default\" (index 0) since it just removes the font\n ...DEFAULT_FONT_FAMILIES.filter((f) => f.value !== \"\").map((font) => ({\n id: `font-${font.label.toLowerCase()}`,\n label: `${font.label} font`,\n description: `Switch to ${font.label.toLowerCase()} typeface`,\n keywords: [\"font\", \"typeface\", \"typography\", font.label.toLowerCase()],\n icon: IconFont,\n onSelect: () => {\n editor.update(() => {\n const selection = $getSelection();\n if (!$isRangeSelection(selection)) return;\n const anchor = selection.anchor.getNode();\n if (anchor instanceof TextNode) {\n anchor.remove();\n }\n // $patchStyleText handles collapsed selections by setting a\n // pending style, so newly typed text inherits the font.\n const current = $getSelection();\n if ($isRangeSelection(current)) {\n $patchStyleText(current, { \"font-family\": font.value });\n }\n });\n },\n })),\n // Direction items — set direction in the same update as trigger removal\n // so the block node is still reachable from the selection\n {\n id: \"direction-ltr\",\n label: \"Left to Right\",\n description: \"Set paragraph direction to LTR\",\n keywords: [\"ltr\", \"direction\", \"english\", \"latin\"],\n icon: IconLTR,\n onSelect: () => {\n editor.update(() => {\n const selection = $getSelection();\n if (!$isRangeSelection(selection)) return;\n const anchor = selection.anchor.getNode();\n\n // Find the top-level block before removing trigger text\n let block: import(\"lexical\").LexicalNode = anchor;\n while (block.getParent() && !$isRootNode(block.getParent())) {\n block = block.getParent()!;\n }\n\n if (anchor instanceof TextNode) {\n anchor.remove();\n }\n\n if ($isElementNode(block) && !$isRootNode(block)) {\n block.setDirection(\"ltr\");\n }\n });\n },\n },\n {\n id: \"direction-rtl\",\n label: \"Right to Left\",\n description: \"Set paragraph direction to RTL\",\n keywords: [\"rtl\", \"direction\", \"hebrew\", \"arabic\"],\n icon: IconRTL,\n onSelect: () => {\n editor.update(() => {\n const selection = $getSelection();\n if (!$isRangeSelection(selection)) return;\n const anchor = selection.anchor.getNode();\n\n // Find the top-level block before removing trigger text\n let block: import(\"lexical\").LexicalNode = anchor;\n while (block.getParent() && !$isRootNode(block.getParent())) {\n block = block.getParent()!;\n }\n\n if (anchor instanceof TextNode) {\n anchor.remove();\n }\n\n if ($isElementNode(block) && !$isRootNode(block)) {\n block.setDirection(\"rtl\");\n }\n });\n },\n },\n ];\n}\n\n// ── Item grouping ───────────────────────────────────────────────────────────\n\ninterface ItemGroup {\n label: string;\n category: string;\n items: SlashMenuItem[];\n}\n\nfunction groupItems(items: SlashMenuItem[]): ItemGroup[] {\n const buckets: Record<string, SlashMenuItem[]> = {};\n const categoryLabels: Record<string, string> = {\n ai: \"AI\",\n headings: \"Headings\",\n blocks: \"Blocks\",\n lists: \"Lists\",\n media: \"Media\",\n format: \"Format\",\n other: \"Other\",\n };\n const order = [\"ai\", \"headings\", \"blocks\", \"lists\", \"media\", \"format\", \"other\"];\n\n for (const item of items) {\n const cat = getCategoryForId(item.id);\n if (!buckets[cat]) buckets[cat] = [];\n buckets[cat]!.push(item);\n }\n\n const groups: ItemGroup[] = [];\n for (const cat of order) {\n const bucket = buckets[cat];\n if (bucket && bucket.length > 0) {\n groups.push({\n label: categoryLabels[cat] ?? cat,\n category: cat,\n items: bucket,\n });\n }\n }\n return groups;\n}\n\n// ── Component ───────────────────────────────────────────────────────────────\n\ninterface SlashMenuProps {\n items?: SlashMenuItem[];\n}\n\nexport function SlashMenu({ items: externalItems }: SlashMenuProps) {\n const [editor] = useLexicalComposerContext();\n const [isOpen, setIsOpen] = useState(false);\n const [position, setPosition] = useState({ top: 0, left: 0 });\n const [query, setQuery] = useState(\"\");\n const [selectedIndex, setSelectedIndex] = useState(0);\n const menuRef = useRef<HTMLDivElement>(null);\n const [portalContainer, setPortalContainer] = useState<HTMLElement | null>(\n null,\n );\n\n useEffect(() => {\n if (typeof window === \"undefined\") return;\n setPortalContainer(document.body);\n }, []);\n\n const defaultItems = useMemo(() => getDefaultItems(editor), [editor]);\n const allItems = externalItems\n ? [...defaultItems, ...externalItems]\n : defaultItems;\n\n const filteredItems = query\n ? allItems.filter((item) => {\n const q = query.toLowerCase();\n return (\n item.label.toLowerCase().includes(q) ||\n item.description.toLowerCase().includes(q) ||\n item.keywords?.some((kw) => kw.toLowerCase().includes(q)) ||\n false\n );\n })\n : allItems;\n\n // Group and flatten for sectioned display\n const groupedItems = groupItems(filteredItems);\n const flatItems: SlashMenuItem[] = [];\n for (const group of groupedItems) {\n for (const item of group.items) {\n flatItems.push(item);\n }\n }\n\n const close = useCallback(() => {\n setIsOpen(false);\n setQuery(\"\");\n setSelectedIndex(0);\n }, []);\n\n const selectItem = useCallback(\n (index: number) => {\n const item = flatItems[index];\n if (item) {\n close();\n item.onSelect();\n }\n },\n [flatItems, close],\n );\n\n // Listen for the slash menu command\n useEffect(() => {\n return editor.registerCommand(\n OPEN_SLASH_MENU_COMMAND,\n () => {\n const domSelection = window.getSelection();\n if (!domSelection || domSelection.rangeCount === 0) return false;\n\n const range = domSelection.getRangeAt(0);\n const rect = range.getBoundingClientRect();\n\n setPosition({\n top: rect.bottom + 6,\n left: rect.left,\n });\n setIsOpen(true);\n setQuery(\"\");\n setSelectedIndex(0);\n return true;\n },\n COMMAND_PRIORITY_LOW,\n );\n }, [editor]);\n\n // Track text typed after \"/\"\n useEffect(() => {\n if (!isOpen) return;\n\n return editor.registerUpdateListener(({ editorState }) => {\n editorState.read(() => {\n const selection = $getSelection();\n if (!$isRangeSelection(selection)) {\n close();\n return;\n }\n const anchor = selection.anchor.getNode();\n if (anchor instanceof TextNode) {\n const text = anchor.getTextContent();\n if (text.startsWith(\"/\")) {\n setQuery(text.slice(1));\n setSelectedIndex(0);\n } else if (text === \"\") {\n close();\n } else {\n close();\n }\n }\n });\n });\n }, [editor, isOpen, close]);\n\n // Keyboard navigation\n useEffect(() => {\n if (!isOpen) return;\n\n const removeArrowDown = editor.registerCommand(\n KEY_ARROW_DOWN_COMMAND,\n (event) => {\n event?.preventDefault();\n setSelectedIndex((prev) => Math.min(prev + 1, flatItems.length - 1));\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((prev) => Math.max(prev - 1, 0));\n return true;\n },\n COMMAND_PRIORITY_LOW,\n );\n\n const removeEnter = editor.registerCommand(\n KEY_ENTER_COMMAND,\n (event) => {\n event?.preventDefault();\n selectItem(selectedIndex);\n return true;\n },\n COMMAND_PRIORITY_LOW,\n );\n\n const removeEscape = editor.registerCommand(\n KEY_ESCAPE_COMMAND,\n () => {\n close();\n return true;\n },\n COMMAND_PRIORITY_LOW,\n );\n\n return () => {\n removeArrowDown();\n removeArrowUp();\n removeEnter();\n removeEscape();\n };\n }, [editor, isOpen, flatItems.length, selectedIndex, selectItem, close]);\n\n // Auto-scroll the selected item into view\n useEffect(() => {\n if (!isOpen || !menuRef.current) return;\n const selected = menuRef.current.querySelector(\n '[aria-selected=\"true\"]',\n ) as HTMLElement | null;\n if (selected) {\n selected.scrollIntoView({ block: \"nearest\" });\n }\n }, [isOpen, selectedIndex]);\n\n if (!isOpen || !portalContainer) return null;\n\n let flatIndex = 0;\n\n return createPortal(\n <div\n ref={menuRef}\n role=\"listbox\"\n aria-label=\"Slash menu\"\n data-testid=\"slash-menu\"\n style={{\n position: \"fixed\",\n zIndex: 50,\n width: \"248px\",\n maxHeight: \"min(380px, 60vh)\",\n overflow: \"auto\",\n borderRadius: \"12px\",\n border: \"1px solid var(--blokhaus-popover-border, rgba(0, 0, 0, 0.12))\",\n backgroundColor: \"var(--blokhaus-popover-bg, rgba(255, 255, 255, 0.96))\",\n backdropFilter: \"blur(24px) saturate(190%)\",\n WebkitBackdropFilter: \"blur(24px) saturate(190%)\",\n padding: \"6px\",\n boxShadow: \"var(--blokhaus-popover-shadow, 0 0 0 0.5px rgba(0,0,0,0.06), 0 8px 40px rgba(0,0,0,0.16), 0 2px 8px rgba(0,0,0,0.06))\",\n top: `${position.top}px`,\n left: `${position.left}px`,\n fontFamily:\n '-apple-system, BlinkMacSystemFont, \"SF Pro Text\", \"Segoe UI\", system-ui, sans-serif',\n letterSpacing: \"-0.01em\",\n animation: \"blokhaus-menu-enter 180ms cubic-bezier(0.2, 0.9, 0.3, 1)\",\n scrollbarWidth: \"none\" as const,\n msOverflowStyle: \"none\" as const,\n }}\n >\n <style>{SLASH_MENU_STYLES}</style>\n\n {flatItems.length === 0 ? (\n <div\n style={{\n padding: \"20px 12px\",\n fontSize: \"12.5px\",\n color: \"var(--blokhaus-text-tertiary)\",\n textAlign: \"center\",\n fontWeight: 400,\n }}\n >\n No matching commands\n </div>\n ) : (\n groupedItems.map((group, groupIdx) => (\n <div key={group.label}>\n {/* Section separator */}\n {groupIdx > 0 && (\n <div\n style={{\n height: \"0.5px\",\n backgroundColor: \"var(--blokhaus-separator)\",\n margin: \"4px 10px\",\n }}\n />\n )}\n\n {/* Section header — only when not filtering */}\n {!query && (\n <div\n style={{\n padding: \"7px 10px 4px\",\n fontSize: \"10.5px\",\n fontWeight: 600,\n color: \"var(--blokhaus-text-tertiary)\",\n textTransform: \"uppercase\",\n letterSpacing: \"0.06em\",\n userSelect: \"none\",\n }}\n >\n {group.label}\n </div>\n )}\n\n {group.items.map((item) => {\n const idx = flatIndex++;\n const isActive = idx === selectedIndex;\n const category = getCategoryForId(item.id);\n const colors = CATEGORY_COLORS[category] ?? CATEGORY_COLORS.other!;\n const shortcut = SHORTCUT_HINTS[item.id];\n\n return (\n <button\n key={item.id}\n type=\"button\"\n role=\"option\"\n aria-selected={isActive}\n data-testid={`slash-menu-item-${item.id}`}\n onMouseDown={(e) => {\n e.preventDefault();\n selectItem(idx);\n }}\n onMouseEnter={() => setSelectedIndex(idx)}\n style={{\n display: \"flex\",\n width: \"100%\",\n alignItems: \"center\",\n gap: \"10px\",\n borderRadius: \"8px\",\n padding: \"5px 8px\",\n textAlign: \"start\",\n fontSize: \"13px\",\n border: \"none\",\n cursor: \"default\",\n backgroundColor: isActive\n ? \"var(--blokhaus-accent, #007AFF)\"\n : \"transparent\",\n color: isActive\n ? \"var(--blokhaus-accent-foreground, #fff)\"\n : \"var(--blokhaus-foreground, #1d1d1f)\",\n transition: \"background-color 80ms ease\",\n }}\n >\n {/* Icon tile */}\n <div\n style={{\n width: \"30px\",\n height: \"30px\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n borderRadius: \"7px\",\n background: isActive\n ? \"rgba(255, 255, 255, 0.2)\"\n : colors.bg,\n flexShrink: 0,\n color: isActive ? \"var(--blokhaus-accent-foreground, #fff)\" : colors.icon,\n animation: isActive\n ? \"blokhaus-icon-lift 400ms cubic-bezier(0.34, 1.56, 0.64, 1)\"\n : \"none\",\n }}\n >\n <item.icon size={16} />\n </div>\n\n {/* Label */}\n <div\n style={{\n flex: 1,\n fontWeight: 450,\n lineHeight: \"18px\",\n whiteSpace: \"nowrap\",\n overflow: \"hidden\",\n textOverflow: \"ellipsis\",\n }}\n >\n {item.label}\n </div>\n\n {/* Markdown shortcut hint */}\n {shortcut && (\n <div\n style={{\n fontSize: \"10.5px\",\n fontFamily:\n '\"SF Mono\", \"Fira Code\", \"Cascadia Code\", ui-monospace, monospace',\n fontWeight: 400,\n color: isActive\n ? \"var(--blokhaus-accent-foreground, rgba(255, 255, 255, 0.55))\"\n : \"var(--blokhaus-text-tertiary)\",\n flexShrink: 0,\n paddingInlineEnd: \"2px\",\n }}\n >\n {shortcut}\n </div>\n )}\n </button>\n );\n })}\n </div>\n ))\n )}\n </div>,\n portalContainer,\n );\n}\n","\"use client\";\n\n// REACT\nimport { useCallback, useEffect, useRef, useState } from \"react\";\n\n// LEXICAL\nimport { useLexicalComposerContext } from \"@lexical/react/LexicalComposerContext\";\nimport type { LexicalNode } from \"lexical\";\nimport { $getNodeByKey, $getRoot } from \"lexical\";\nimport { $isToggleContainerNode } from \"../nodes/ToggleContainerNode\";\nimport { $isToggleContentNode } from \"../nodes/ToggleContentNode\";\n\n// REACT DOM\nimport { createPortal } from \"react-dom\";\n\n// PHOSPHOR\nimport { DotsSixVerticalIcon } from \"@phosphor-icons/react\";\n\n// INTERNAL\nimport { TurnIntoMenu } from \"./TurnIntoMenu\";\n\ninterface BlockInfo {\n key: string;\n top: number;\n left: number;\n width: number;\n /** Vertical center of the first line of text in the block */\n firstLineCenter: number;\n /** Text direction of this block (read from the DOM `dir` attribute) */\n direction: \"ltr\" | \"rtl\" | null;\n}\n\n/**\n * Computes BlockInfo for a DOM element/Lexical node pair.\n * Avoids getComputedStyle — uses a fixed approximation for first-line center.\n */\nfunction getBlockInfo(\n node: LexicalNode,\n rect: DOMRect,\n element?: HTMLElement | null,\n): BlockInfo {\n let dir: \"ltr\" | \"rtl\" | null = null;\n if (element) {\n const d = element.getAttribute(\"dir\") || element.dir;\n if (d === \"rtl\") {\n dir = \"rtl\";\n } else if (d === \"ltr\") {\n dir = \"ltr\";\n } else {\n // For dir=\"auto\" or inherited direction, use the computed direction\n // so auto-detected RTL text gets the handle on the right side\n const computed = getComputedStyle(element).direction;\n if (computed === \"rtl\") dir = \"rtl\";\n else if (computed === \"ltr\") dir = \"ltr\";\n }\n }\n return {\n key: node.getKey(),\n top: rect.top,\n left: rect.left,\n width: rect.width,\n firstLineCenter: rect.top + 14,\n direction: dir,\n };\n}\n\n/**\n * Searches children of an open toggle's content node for the nearest\n * match at clientY. Returns null if the mouse isn't over the content area.\n */\nfunction findToggleContentChildAtY(\n clientY: number,\n containerNode: LexicalNode,\n editor: ReturnType<typeof useLexicalComposerContext>[0],\n): BlockInfo | null {\n if (!$isToggleContainerNode(containerNode)) return null;\n\n for (const sub of containerNode.getChildren()) {\n if (!$isToggleContentNode(sub)) continue;\n\n const contentEl = editor.getElementByKey(sub.getKey());\n if (!contentEl) continue;\n const contentRect = contentEl.getBoundingClientRect();\n if (clientY < contentRect.top - 4 || clientY > contentRect.bottom + 4)\n continue;\n\n const children = sub.getChildren();\n\n if (children.length === 0) {\n return getBlockInfo(sub, contentRect, contentEl);\n }\n\n let closestDist = Infinity;\n let match: BlockInfo | null = null;\n\n for (const contentChild of children) {\n const el = editor.getElementByKey(contentChild.getKey());\n if (!el) continue;\n\n const rect = el.getBoundingClientRect();\n\n if (clientY >= rect.top - 4 && clientY <= rect.bottom + 4) {\n return getBlockInfo(contentChild, rect, el);\n }\n\n const dist = Math.min(\n Math.abs(clientY - rect.top),\n Math.abs(clientY - rect.bottom),\n );\n if (dist < closestDist) {\n closestDist = dist;\n match = getBlockInfo(contentChild, rect, el);\n }\n }\n\n if (match) return match;\n\n const firstChild = children[0]!;\n const firstChildEl = editor.getElementByKey(firstChild.getKey());\n if (firstChildEl)\n return getBlockInfo(firstChild, firstChildEl.getBoundingClientRect(), firstChildEl);\n\n return getBlockInfo(sub, contentRect, contentEl);\n }\n\n return null;\n}\n\n/**\n * Finds the nearest draggable block to a given Y coordinate.\n * For open toggle containers, checks content children first.\n */\nfunction findBlockAtY(\n clientY: number,\n editor: ReturnType<typeof useLexicalComposerContext>[0],\n): BlockInfo | null {\n let result: BlockInfo | null = null;\n\n editor.read(() => {\n const root = $getRoot();\n const children = root.getChildren();\n let closestDist = 30;\n\n for (const child of children) {\n const el = editor.getElementByKey(child.getKey());\n if (!el) continue;\n\n const rect = el.getBoundingClientRect();\n\n if (\n $isToggleContainerNode(child) &&\n child.getOpen() &&\n clientY >= rect.top - 4 &&\n clientY <= rect.bottom + 4\n ) {\n const innerMatch = findToggleContentChildAtY(\n clientY,\n child,\n editor,\n );\n if (innerMatch) {\n result = innerMatch;\n return;\n }\n }\n\n if (clientY >= rect.top - 4 && clientY <= rect.bottom + 4) {\n result = getBlockInfo(child, rect, el);\n return;\n }\n\n const dist = Math.min(\n Math.abs(clientY - rect.top),\n Math.abs(clientY - rect.bottom),\n );\n if (dist < closestDist) {\n closestDist = dist;\n result = getBlockInfo(child, rect, el);\n }\n }\n });\n\n return result;\n}\n\ninterface OverlayPortalProps {\n namespace: string;\n}\n\nexport function OverlayPortal({ namespace }: OverlayPortalProps) {\n const [editor] = useLexicalComposerContext();\n const [isTouchDevice, setIsTouchDevice] = useState<boolean | null>(null);\n const [portalContainer, setPortalContainer] = useState<HTMLElement | null>(\n null,\n );\n\n // Use refs for handle position to avoid re-render-triggered unmount/remount\n const handleRef = useRef<HTMLDivElement>(null);\n const hoveredKeyRef = useRef<string | null>(null);\n const isMouseOverHandleRef = useRef(false);\n const handleVisibleRef = useRef(false);\n\n // Drag state\n const isDraggingRef = useRef(false);\n const dragSourceKeyRef = useRef<string | null>(null);\n const dropPositionRef = useRef<\"before\" | \"after\">(\"after\");\n const dropTargetKeyRef = useRef<string | null>(null);\n const indicatorRef = useRef<HTMLDivElement>(null);\n\n // Click vs drag detection\n const mousedownTimeRef = useRef(0);\n const mousedownPosRef = useRef({ x: 0, y: 0 });\n\n // RAF throttle ref\n const rafIdRef = useRef(0);\n\n // Turn Into menu state\n const [menuState, setMenuState] = useState<{\n open: boolean;\n blockKey: string;\n position: { top: number; left: number };\n } | null>(null);\n\n // Detect touch device\n useEffect(() => {\n if (typeof window === \"undefined\") return;\n const isTouch =\n window.matchMedia(\"(pointer: coarse)\").matches ||\n navigator.maxTouchPoints > 0 ||\n \"ontouchstart\" in window;\n setIsTouchDevice(isTouch);\n }, []);\n\n // Portal into document.body\n useEffect(() => {\n if (typeof window === \"undefined\") return;\n setPortalContainer(document.body);\n }, []);\n\n const showHandle = useCallback(\n (firstLineCenter: number, left: number, width: number, direction: \"ltr\" | \"rtl\" | null) => {\n if (!handleRef.current) return;\n handleRef.current.style.top = `${firstLineCenter - 12}px`;\n if (direction === \"rtl\") {\n handleRef.current.style.left = `${left + width + 4}px`;\n } else {\n handleRef.current.style.left = `${left - 28}px`;\n }\n handleRef.current.style.visibility = \"visible\";\n handleVisibleRef.current = true;\n },\n [],\n );\n\n const hideHandle = useCallback(() => {\n if (!handleRef.current) return;\n handleRef.current.style.visibility = \"hidden\";\n handleVisibleRef.current = false;\n hoveredKeyRef.current = null;\n }, []);\n\n const showIndicator = useCallback(\n (top: number, left: number, width: number) => {\n if (!indicatorRef.current) return;\n indicatorRef.current.style.top = `${top - 1}px`;\n indicatorRef.current.style.left = `${left}px`;\n indicatorRef.current.style.width = `${width}px`;\n indicatorRef.current.style.visibility = \"visible\";\n },\n [],\n );\n\n const hideIndicator = useCallback(() => {\n if (!indicatorRef.current) return;\n indicatorRef.current.style.visibility = \"hidden\";\n }, []);\n\n // Track mouse at document level — throttled to one RAF per frame\n useEffect(() => {\n if (isTouchDevice === null || isTouchDevice) return;\n\n let lastClientX = 0;\n let lastClientY = 0;\n\n const processMousePosition = () => {\n rafIdRef.current = 0;\n\n if (isDraggingRef.current) return;\n\n const rootElement = editor.getRootElement();\n if (!rootElement) return;\n\n const wrapperElement = rootElement.closest(\n \"[data-blokhaus-root]\",\n ) as HTMLElement | null;\n if (!wrapperElement) return;\n\n const wrapperRect = wrapperElement.getBoundingClientRect();\n const GUTTER = 40;\n\n const isNearEditor =\n lastClientY >= wrapperRect.top &&\n lastClientY <= wrapperRect.bottom &&\n lastClientX >= wrapperRect.left - GUTTER &&\n lastClientX <= wrapperRect.right + GUTTER;\n\n if (!isNearEditor && !isMouseOverHandleRef.current) {\n hideHandle();\n return;\n }\n\n const block = findBlockAtY(lastClientY, editor);\n if (!block) {\n if (!isMouseOverHandleRef.current) {\n hideHandle();\n }\n return;\n }\n\n hoveredKeyRef.current = block.key;\n showHandle(block.firstLineCenter, block.left, block.width, block.direction);\n };\n\n const onMouseMove = (e: MouseEvent) => {\n lastClientX = e.clientX;\n lastClientY = e.clientY;\n\n if (isDraggingRef.current) return;\n\n // Throttle: only schedule one RAF per frame\n if (rafIdRef.current === 0) {\n rafIdRef.current = requestAnimationFrame(processMousePosition);\n }\n };\n\n document.addEventListener(\"mousemove\", onMouseMove);\n return () => {\n document.removeEventListener(\"mousemove\", onMouseMove);\n if (rafIdRef.current) {\n cancelAnimationFrame(rafIdRef.current);\n rafIdRef.current = 0;\n }\n };\n }, [editor, isTouchDevice, showHandle, hideHandle]);\n\n // Attach native DOM events on the handle for mouseenter/mouseleave/mousedown\n useEffect(() => {\n const handle = handleRef.current;\n if (!handle || isTouchDevice) return;\n\n const onEnter = () => {\n isMouseOverHandleRef.current = true;\n handle.style.opacity = \"1\";\n };\n\n const onLeave = () => {\n isMouseOverHandleRef.current = false;\n if (!isDraggingRef.current) {\n handle.style.opacity = \"0.6\";\n }\n };\n\n const onMouseDown = (e: MouseEvent) => {\n e.preventDefault();\n e.stopPropagation();\n\n const key = hoveredKeyRef.current;\n if (!key) return;\n\n mousedownTimeRef.current = Date.now();\n mousedownPosRef.current = { x: e.clientX, y: e.clientY };\n\n dragSourceKeyRef.current = key;\n let hasMoved = false;\n let dragRafId = 0;\n let pendingMoveEvent: MouseEvent | null = null;\n\n const processDragMove = () => {\n dragRafId = 0;\n const moveEvent = pendingMoveEvent;\n if (!moveEvent) return;\n\n const target = findBlockAtY(moveEvent.clientY, editor);\n if (!target || target.key === dragSourceKeyRef.current) {\n hideIndicator();\n dropTargetKeyRef.current = null;\n return;\n }\n\n const el = editor.getElementByKey(target.key);\n if (!el) return;\n const rect = el.getBoundingClientRect();\n const midY = rect.top + rect.height / 2;\n const isBefore = moveEvent.clientY < midY;\n\n dropPositionRef.current = isBefore ? \"before\" : \"after\";\n dropTargetKeyRef.current = target.key;\n\n showIndicator(\n isBefore ? rect.top : rect.bottom,\n rect.left,\n rect.width,\n );\n };\n\n const onDragMove = (moveEvent: MouseEvent) => {\n const dx = moveEvent.clientX - mousedownPosRef.current.x;\n const dy = moveEvent.clientY - mousedownPosRef.current.y;\n const dist = Math.sqrt(dx * dx + dy * dy);\n\n if (!hasMoved && dist < 5) return;\n hasMoved = true;\n\n if (!isDraggingRef.current) {\n isDraggingRef.current = true;\n handle.style.opacity = \"0.3\";\n handle.style.cursor = \"grabbing\";\n }\n\n pendingMoveEvent = moveEvent;\n if (dragRafId === 0) {\n dragRafId = requestAnimationFrame(processDragMove);\n }\n };\n\n const onDragEnd = () => {\n document.removeEventListener(\"mousemove\", onDragMove);\n document.removeEventListener(\"mouseup\", onDragEnd);\n if (dragRafId) {\n cancelAnimationFrame(dragRafId);\n }\n\n if (!hasMoved) {\n isDraggingRef.current = false;\n const blockKey = dragSourceKeyRef.current;\n if (blockKey && handleRef.current) {\n const handleRect = handleRef.current.getBoundingClientRect();\n setMenuState({\n open: true,\n blockKey,\n position: {\n top: handleRect.bottom + 4,\n left: handleRect.left,\n },\n });\n }\n dragSourceKeyRef.current = null;\n return;\n }\n\n isDraggingRef.current = false;\n hideIndicator();\n\n handle.style.opacity = \"0.6\";\n handle.style.cursor = \"grab\";\n\n const sourceKey = dragSourceKeyRef.current;\n const targetKey = dropTargetKeyRef.current;\n const position = dropPositionRef.current;\n\n if (sourceKey && targetKey && sourceKey !== targetKey) {\n editor.update(() => {\n const sourceNode = $getNodeByKey(sourceKey);\n const targetNode = $getNodeByKey(targetKey);\n\n if (!sourceNode || !targetNode) return;\n\n // Prevent circular drops\n let ancestor: LexicalNode | null = targetNode;\n while (ancestor !== null) {\n if (ancestor.getKey() === sourceKey) return;\n ancestor = ancestor.getParent();\n }\n\n // If target is a ToggleContentNode (empty content area),\n // append source as first child\n if ($isToggleContentNode(targetNode)) {\n sourceNode.remove();\n targetNode.append(sourceNode);\n return;\n }\n\n sourceNode.remove();\n\n if (position === \"before\") {\n targetNode.insertBefore(sourceNode);\n } else {\n targetNode.insertAfter(sourceNode);\n }\n });\n }\n\n dragSourceKeyRef.current = null;\n dropTargetKeyRef.current = null;\n hideHandle();\n };\n\n document.addEventListener(\"mousemove\", onDragMove);\n document.addEventListener(\"mouseup\", onDragEnd);\n };\n\n handle.addEventListener(\"mouseenter\", onEnter);\n handle.addEventListener(\"mouseleave\", onLeave);\n handle.addEventListener(\"mousedown\", onMouseDown);\n\n return () => {\n handle.removeEventListener(\"mouseenter\", onEnter);\n handle.removeEventListener(\"mouseleave\", onLeave);\n handle.removeEventListener(\"mousedown\", onMouseDown);\n };\n }, [editor, isTouchDevice, hideHandle, hideIndicator, showIndicator]);\n\n const closeMenu = useCallback(() => {\n setMenuState(null);\n }, []);\n\n if (isTouchDevice === null || isTouchDevice || !portalContainer) return null;\n\n return (\n <>\n {createPortal(\n <>\n {/* Drag handle — always in DOM, positioned imperatively */}\n <div\n ref={handleRef}\n data-testid=\"overlay-drag-handle\"\n data-namespace={namespace}\n style={{\n position: \"fixed\",\n top: \"0px\",\n left: \"0px\",\n width: \"24px\",\n height: \"24px\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n cursor: \"grab\",\n borderRadius: \"4px\",\n color: \"var(--blokhaus-muted-foreground, #94a3b8)\",\n opacity: 0.6,\n transition: \"opacity 0.15s\",\n userSelect: \"none\",\n zIndex: 40,\n visibility: \"hidden\",\n }}\n >\n <DotsSixVerticalIcon size={16} weight=\"bold\" />\n </div>\n\n {/* Drop indicator line — always in DOM, positioned imperatively */}\n <div\n ref={indicatorRef}\n data-testid=\"overlay-drop-indicator\"\n style={{\n position: \"fixed\",\n top: \"0px\",\n left: \"0px\",\n width: \"0px\",\n height: \"2px\",\n backgroundColor: \"var(--blokhaus-accent, #3b82f6)\",\n pointerEvents: \"none\",\n zIndex: 50,\n visibility: \"hidden\",\n }}\n />\n </>,\n portalContainer,\n )}\n\n {/* Turn Into menu — rendered when drag handle is clicked */}\n {menuState?.open && (\n <TurnIntoMenu\n editor={editor}\n blockKey={menuState.blockKey}\n position={menuState.position}\n onClose={closeMenu}\n />\n )}\n </>\n );\n}\n","\"use client\";\n\n// REACT\nimport { useCallback, useEffect, useRef } from \"react\";\n\n// REACT DOM\nimport { createPortal } from \"react-dom\";\n\n// LEXICAL\nimport type { LexicalEditor } from \"lexical\";\nimport {\n $createParagraphNode,\n $createTextNode,\n $getNodeByKey,\n $isElementNode,\n} from \"lexical\";\nimport {\n $createHeadingNode,\n $isHeadingNode,\n $isQuoteNode,\n $createQuoteNode,\n} from \"@lexical/rich-text\";\nimport {\n $createListNode,\n $createListItemNode,\n $isListNode,\n} from \"@lexical/list\";\nimport { $isCalloutNode } from \"../nodes/CalloutNode\";\nimport { $createCalloutNode } from \"../nodes/CalloutNode\";\nimport { $isCodeBlockNode, $createCodeBlockNode } from \"../nodes/CodeBlockNode\";\nimport { $isToggleContainerNode, $createToggleContainerNode } from \"../nodes/ToggleContainerNode\";\nimport { $createToggleTitleNode } from \"../nodes/ToggleTitleNode\";\nimport { $createToggleContentNode } from \"../nodes/ToggleContentNode\";\n\n// PHOSPHOR ICONS\nimport type { IconWeight } from \"@phosphor-icons/react\";\nimport {\n TextAlignLeftIcon,\n TextHOneIcon,\n TextHTwoIcon,\n TextHThreeIcon,\n QuotesIcon,\n ListBulletsIcon,\n ListNumbersIcon,\n CheckSquareIcon,\n CodeSimpleIcon,\n InfoIcon,\n CheckIcon,\n CaretCircleDownIcon,\n} from \"@phosphor-icons/react\";\n\n// ─── Types ──────────────────────────────────────────────────────────────────\n\ninterface TurnIntoItem {\n id: string;\n label: string;\n icon: React.ComponentType<{ size?: number; weight?: IconWeight }>;\n}\n\nconst TURN_INTO_ITEMS: TurnIntoItem[] = [\n { id: \"paragraph\", label: \"Paragraph\", icon: TextAlignLeftIcon },\n { id: \"heading-1\", label: \"Heading 1\", icon: TextHOneIcon },\n { id: \"heading-2\", label: \"Heading 2\", icon: TextHTwoIcon },\n { id: \"heading-3\", label: \"Heading 3\", icon: TextHThreeIcon },\n { id: \"quote\", label: \"Quote\", icon: QuotesIcon },\n { id: \"bullet-list\", label: \"Bullet List\", icon: ListBulletsIcon },\n { id: \"numbered-list\", label: \"Numbered List\", icon: ListNumbersIcon },\n { id: \"check-list\", label: \"Checklist\", icon: CheckSquareIcon },\n { id: \"code\", label: \"Code Block\", icon: CodeSimpleIcon },\n { id: \"callout\", label: \"Callout\", icon: InfoIcon },\n { id: \"toggle\", label: \"Toggle\", icon: CaretCircleDownIcon },\n];\n\n// ─── Block Type Detection ───────────────────────────────────────────────────\n\nfunction getBlockType(\n editor: LexicalEditor,\n blockKey: string,\n): string | null {\n let type: string | null = null;\n editor.read(() => {\n const node = $getNodeByKey(blockKey);\n if (!node) return;\n if ($isHeadingNode(node)) {\n const tag = node.getTag();\n type = `heading-${tag.replace(\"h\", \"\")}`;\n } else if ($isQuoteNode(node)) {\n type = \"quote\";\n } else if ($isListNode(node)) {\n const listType = node.getListType();\n if (listType === \"bullet\") type = \"bullet-list\";\n else if (listType === \"number\") type = \"numbered-list\";\n else if (listType === \"check\") type = \"check-list\";\n } else if ($isCodeBlockNode(node)) {\n type = \"code\";\n } else if ($isCalloutNode(node)) {\n type = \"callout\";\n } else if ($isToggleContainerNode(node)) {\n type = \"toggle\";\n } else if (node.getType() === \"paragraph\") {\n type = \"paragraph\";\n }\n });\n return type;\n}\n\n// ─── Block Conversion Logic ─────────────────────────────────────────────────\n\nfunction convertBlock(\n editor: LexicalEditor,\n blockKey: string,\n targetType: string,\n): void {\n editor.update(() => {\n const node = $getNodeByKey(blockKey);\n if (!node) return;\n\n // Collect extra paragraphs from multi-item lists\n const extraParagraphs: import(\"lexical\").ParagraphNode[] = [];\n\n // Extract text content for conversion\n const extractChildren = () => {\n if ($isElementNode(node)) {\n const children = node.getChildren();\n // Return cloned children array (removing from parent detaches them)\n return children;\n }\n return [];\n };\n\n const extractTextContent = (): string => {\n return node.getTextContent();\n };\n\n // Helper: move children from source to target ElementNode\n const moveChildrenTo = (\n target: import(\"lexical\").ElementNode,\n ) => {\n if ($isListNode(node)) {\n // For lists, extract children from ALL list items as separate paragraphs\n // (except the first — its children go directly into the target)\n const items = node.getChildren();\n let isFirst = true;\n for (const item of items) {\n if ($isElementNode(item)) {\n if (isFirst) {\n const children = item.getChildren();\n for (const child of children) {\n target.append(child);\n }\n isFirst = false;\n } else {\n // Subsequent list items become sibling paragraphs inserted after target later\n // Store them to be inserted after the replacement\n const p = $createParagraphNode();\n const children = item.getChildren();\n for (const child of children) {\n p.append(child);\n }\n extraParagraphs.push(p);\n }\n }\n }\n } else if ($isElementNode(node)) {\n const children = node.getChildren();\n for (const child of children) {\n target.append(child);\n }\n } else {\n // DecoratorNode — use text content\n target.append($createTextNode(extractTextContent()));\n }\n };\n\n // Helper: wrap children into a list item inside a new list\n const wrapInList = (\n listType: \"bullet\" | \"number\" | \"check\",\n ) => {\n const list = $createListNode(listType);\n const item = $createListItemNode();\n if ($isListNode(node)) {\n // If converting between list types, move all items\n const items = node.getChildren();\n for (const existingItem of items) {\n list.append(existingItem);\n }\n } else {\n moveChildrenTo(item);\n list.append(item);\n }\n return list;\n };\n\n let newNode: import(\"lexical\").LexicalNode | null = null;\n\n switch (targetType) {\n case \"paragraph\": {\n const p = $createParagraphNode();\n moveChildrenTo(p);\n newNode = p;\n break;\n }\n case \"heading-1\": {\n const h = $createHeadingNode(\"h1\");\n moveChildrenTo(h);\n newNode = h;\n break;\n }\n case \"heading-2\": {\n const h = $createHeadingNode(\"h2\");\n moveChildrenTo(h);\n newNode = h;\n break;\n }\n case \"heading-3\": {\n const h = $createHeadingNode(\"h3\");\n moveChildrenTo(h);\n newNode = h;\n break;\n }\n case \"quote\": {\n const q = $createQuoteNode();\n moveChildrenTo(q);\n newNode = q;\n break;\n }\n case \"bullet-list\": {\n newNode = wrapInList(\"bullet\");\n break;\n }\n case \"numbered-list\": {\n newNode = wrapInList(\"number\");\n break;\n }\n case \"check-list\": {\n newNode = wrapInList(\"check\");\n break;\n }\n case \"code\": {\n const text = extractTextContent();\n const codeBlock = $createCodeBlockNode({\n code: text,\n language: \"javascript\",\n });\n const trailing = $createParagraphNode();\n node.replace(codeBlock);\n codeBlock.insertAfter(trailing);\n trailing.selectEnd();\n return; // early return — already handled\n }\n case \"callout\": {\n const callout = $createCalloutNode();\n moveChildrenTo(callout);\n newNode = callout;\n break;\n }\n case \"toggle\": {\n const container = $createToggleContainerNode({ open: true });\n const title = $createToggleTitleNode();\n const content = $createToggleContentNode();\n moveChildrenTo(content);\n container.append(title, content);\n newNode = container;\n break;\n }\n }\n\n if (newNode) {\n node.replace(newNode);\n // Insert any extra paragraphs from multi-item list conversion\n let insertAfter: import(\"lexical\").LexicalNode = newNode;\n for (const p of extraParagraphs) {\n insertAfter.insertAfter(p);\n insertAfter = p;\n }\n if ($isElementNode(newNode)) {\n newNode.selectEnd();\n }\n }\n });\n}\n\n// ─── Component ──────────────────────────────────────────────────────────────\n\ninterface TurnIntoMenuProps {\n editor: LexicalEditor;\n blockKey: string;\n position: { top: number; left: number };\n onClose: () => void;\n}\n\nexport function TurnIntoMenu({\n editor,\n blockKey,\n position,\n onClose,\n}: TurnIntoMenuProps) {\n const containerRef = useRef<HTMLDivElement>(null);\n const currentType = getBlockType(editor, blockKey);\n\n // Click outside to close\n useEffect(() => {\n const handleClickOutside = (e: MouseEvent) => {\n if (\n containerRef.current &&\n !containerRef.current.contains(e.target as Node)\n ) {\n onClose();\n }\n };\n const raf = requestAnimationFrame(() => {\n document.addEventListener(\"mousedown\", handleClickOutside);\n });\n return () => {\n cancelAnimationFrame(raf);\n document.removeEventListener(\"mousedown\", handleClickOutside);\n };\n }, [onClose]);\n\n // Escape to close\n useEffect(() => {\n const handleKeyDown = (e: KeyboardEvent) => {\n if (e.key === \"Escape\") {\n e.preventDefault();\n onClose();\n }\n };\n document.addEventListener(\"keydown\", handleKeyDown);\n return () => document.removeEventListener(\"keydown\", handleKeyDown);\n }, [onClose]);\n\n const handleSelect = useCallback(\n (itemId: string) => {\n if (itemId === currentType) {\n onClose();\n return;\n }\n convertBlock(editor, blockKey, itemId);\n onClose();\n },\n [editor, blockKey, currentType, onClose],\n );\n\n return createPortal(\n <div\n ref={containerRef}\n data-testid=\"turn-into-menu\"\n style={{\n position: \"fixed\",\n top: `${position.top}px`,\n left: `${position.left}px`,\n zIndex: 60,\n display: \"flex\",\n flexDirection: \"column\",\n padding: \"4px\",\n borderRadius: \"12px\",\n border: \"1px solid var(--blokhaus-popover-border, rgba(0,0,0,0.06))\",\n backgroundColor: \"var(--blokhaus-popover-bg)\",\n backdropFilter: \"blur(20px) saturate(180%)\",\n WebkitBackdropFilter: \"blur(20px) saturate(180%)\",\n boxShadow: \"var(--blokhaus-popover-shadow)\",\n fontFamily: \"var(--blokhaus-font-sans, system-ui, sans-serif)\",\n minWidth: \"180px\",\n maxHeight: \"340px\",\n overflowY: \"auto\",\n animation: \"blokhaus-turn-into-enter 0.15s ease-out\",\n }}\n >\n {/* Header */}\n <div\n style={{\n fontSize: \"10.5px\",\n fontWeight: 600,\n textTransform: \"uppercase\",\n letterSpacing: \"0.05em\",\n color: \"var(--blokhaus-muted-foreground, #94a3b8)\",\n padding: \"6px 8px 4px\",\n }}\n >\n Turn into\n </div>\n\n {TURN_INTO_ITEMS.map((item) => {\n const isActive = item.id === currentType;\n const Icon = item.icon;\n\n return (\n <button\n key={item.id}\n type=\"button\"\n onClick={() => handleSelect(item.id)}\n style={{\n display: \"flex\",\n alignItems: \"center\",\n gap: \"8px\",\n width: \"100%\",\n padding: \"6px 8px\",\n borderRadius: \"8px\",\n border: \"none\",\n cursor: \"pointer\",\n backgroundColor: isActive\n ? \"var(--blokhaus-muted, #f1f5f9)\"\n : \"transparent\",\n color: \"var(--blokhaus-foreground, #0f172a)\",\n fontSize: \"13px\",\n fontFamily: \"inherit\",\n textAlign: \"start\",\n transition: \"background-color 0.1s\",\n }}\n onMouseEnter={(e) => {\n if (!isActive) {\n e.currentTarget.style.backgroundColor =\n \"var(--blokhaus-hover-bg, rgba(0,0,0,0.04))\";\n }\n }}\n onMouseLeave={(e) => {\n e.currentTarget.style.backgroundColor = isActive\n ? \"var(--blokhaus-muted, #f1f5f9)\"\n : \"transparent\";\n }}\n >\n <Icon size={16} weight=\"duotone\" />\n <span style={{ flex: 1 }}>{item.label}</span>\n {isActive && (\n <CheckIcon\n size={14}\n weight=\"bold\"\n style={{ color: \"var(--blokhaus-accent, #3b82f6)\" }}\n />\n )}\n </button>\n );\n })}\n\n <style\n dangerouslySetInnerHTML={{\n __html: `\n @keyframes blokhaus-turn-into-enter {\n from {\n opacity: 0;\n transform: translateY(-4px) scale(0.98);\n }\n to {\n opacity: 1;\n transform: translateY(0) scale(1);\n }\n }\n `,\n }}\n />\n </div>,\n document.body,\n );\n}\n","\"use client\";\n\n// REACT\nimport { useEffect } from \"react\";\n\n// LEXICAL\nimport { useLexicalComposerContext } from \"@lexical/react/LexicalComposerContext\";\nimport { TextNode, $createParagraphNode } from \"lexical\";\nimport { $createHeadingNode, $createQuoteNode } from \"@lexical/rich-text\";\nimport { $createListNode, $createListItemNode } from \"@lexical/list\";\nimport { $createCodeBlockNode } from \"../nodes/CodeBlockNode\";\nimport { $createHorizontalRuleNode } from \"../nodes/HorizontalRuleNode\";\n\n// COMMANDS\nimport { OPEN_SLASH_MENU_COMMAND } from \"../commands\";\n\n// TYPES\nimport type { InputRule } from \"../types\";\n\n/**\n * Built-in rules. Note: onMatch runs inside a node transform, which is already\n * within an editor.update() context. Do NOT wrap mutations in editor.update()\n * here — that would be a nested update (see CLAUDE.md Section 7.1).\n */\nconst BUILTIN_RULES: InputRule[] = [\n {\n pattern: /^# $/,\n type: \"heading\",\n onMatch: (_match, node) => {\n const parent = node.getParent();\n if (!parent) return;\n const heading = $createHeadingNode(\"h1\");\n parent.replace(heading);\n heading.selectEnd();\n },\n },\n {\n pattern: /^## $/,\n type: \"heading\",\n onMatch: (_match, node) => {\n const parent = node.getParent();\n if (!parent) return;\n const heading = $createHeadingNode(\"h2\");\n parent.replace(heading);\n heading.selectEnd();\n },\n },\n {\n pattern: /^### $/,\n type: \"heading\",\n onMatch: (_match, node) => {\n const parent = node.getParent();\n if (!parent) return;\n const heading = $createHeadingNode(\"h3\");\n parent.replace(heading);\n heading.selectEnd();\n },\n },\n {\n pattern: /^> $/,\n type: \"quote\",\n onMatch: (_match, node) => {\n const parent = node.getParent();\n if (!parent) return;\n const quote = $createQuoteNode();\n parent.replace(quote);\n quote.selectEnd();\n },\n },\n {\n pattern: /^[-*] $/,\n type: \"custom\",\n onMatch: (_match, node) => {\n const parent = node.getParent();\n if (!parent) return;\n const list = $createListNode(\"bullet\");\n const item = $createListItemNode();\n list.append(item);\n parent.replace(list);\n item.selectEnd();\n },\n },\n {\n pattern: /^1\\. $/,\n type: \"custom\",\n onMatch: (_match, node) => {\n const parent = node.getParent();\n if (!parent) return;\n const list = $createListNode(\"number\");\n const item = $createListItemNode();\n list.append(item);\n parent.replace(list);\n item.selectEnd();\n },\n },\n {\n pattern: /^\\[\\] $/,\n type: \"custom\",\n onMatch: (_match, node) => {\n const parent = node.getParent();\n if (!parent) return;\n const list = $createListNode(\"check\");\n const item = $createListItemNode();\n list.append(item);\n parent.replace(list);\n item.selectEnd();\n },\n },\n {\n pattern: /^\\[x\\] $/,\n type: \"custom\",\n onMatch: (_match, node) => {\n const parent = node.getParent();\n if (!parent) return;\n const list = $createListNode(\"check\");\n const item = $createListItemNode(true);\n list.append(item);\n parent.replace(list);\n item.selectEnd();\n },\n },\n {\n pattern: /^---$/,\n type: \"divider\",\n onMatch: (_match, node) => {\n const parent = node.getParent();\n if (!parent) return;\n const rule = $createHorizontalRuleNode();\n const trailingParagraph = $createParagraphNode();\n parent.replace(rule);\n rule.insertAfter(trailingParagraph);\n trailingParagraph.selectEnd();\n },\n },\n {\n pattern: /^```$/,\n type: \"code\",\n onMatch: (_match, node) => {\n const parent = node.getParent();\n if (!parent) return;\n const codeBlock = $createCodeBlockNode({ code: \"\", language: \"javascript\", autoFocus: true });\n // DecoratorNodes can't hold a cursor, so insert a trailing paragraph\n // to prevent the \"selection lost\" error. The autoFocus flag on the\n // CodeBlockNode will focus the textarea once it mounts.\n const trailingParagraph = $createParagraphNode();\n parent.replace(codeBlock);\n codeBlock.insertAfter(trailingParagraph);\n trailingParagraph.selectEnd();\n },\n },\n];\n\ninterface InputRulePluginProps {\n rules?: InputRule[];\n}\n\nexport function InputRulePlugin({ rules = [] }: InputRulePluginProps) {\n const [editor] = useLexicalComposerContext();\n\n useEffect(() => {\n const allRules = [...BUILTIN_RULES, ...rules];\n\n // Pre-compute the set of first characters that can start a rule match.\n // This lets us skip regex matching entirely for the vast majority of keystrokes.\n const triggerFirstChars = new Set<string>();\n for (const rule of allRules) {\n // Extract the literal first char from each pattern's source.\n // Patterns like /^# $/, /^## $/, /^> $/, /^[-*] $/, /^1\\. $/ etc.\n const src = rule.pattern.source;\n // Skip the leading ^ if present\n const start = src.startsWith(\"^\") ? 1 : 0;\n const ch = src[start];\n if (ch && ch !== \"[\" && ch !== \"(\" && ch !== \"\\\\\") {\n triggerFirstChars.add(ch);\n } else if (ch === \"[\") {\n // Character class like [-*] — extract individual chars\n for (let i = start + 1; i < src.length; i++) {\n if (src[i] === \"]\") break;\n if (src[i] !== \"-\" || i === start + 1) triggerFirstChars.add(src[i]!);\n }\n } else if (ch === \"\\\\\") {\n // Escaped char like \\[\n const next = src[start + 1];\n if (next) triggerFirstChars.add(next);\n }\n }\n\n return editor.registerNodeTransform(TextNode, (textNode) => {\n // IME safety: skip transforms during composition\n const editorWithComposition = editor as unknown as {\n _compositionKey: string | null;\n };\n if (editorWithComposition._compositionKey !== null) return;\n\n const text = textNode.getTextContent();\n\n // Fast exit: skip everything for text longer than 6 chars.\n // All built-in rules match patterns ≤ 6 chars (e.g. \"### \", \"[x] \", \"```\").\n if (text.length > 6) return;\n\n // Slash menu trigger: \"/\" at start of an otherwise empty paragraph\n if (text === \"/\") {\n const parent = textNode.getParent();\n if (parent && parent.getChildrenSize() === 1) {\n // Dispatch needs to happen outside the transform — defer with queueMicrotask\n queueMicrotask(() => {\n editor.dispatchCommand(OPEN_SLASH_MENU_COMMAND, undefined);\n });\n return;\n }\n }\n\n // Fast exit: if first char doesn't match any rule's trigger, skip regex\n const firstChar = text[0];\n if (!firstChar || !triggerFirstChars.has(firstChar)) return;\n\n // Check against all registered rules\n for (const rule of allRules) {\n const match = text.match(rule.pattern);\n if (match) {\n // Remove trigger text, then call onMatch (already in update context)\n textNode.setTextContent(\"\");\n rule.onMatch(match, textNode, editor);\n return;\n }\n }\n });\n }, [editor, rules]);\n\n return null;\n}\n","\"use client\";\n\nimport { useEffect, useRef } from \"react\";\n\nimport { useLexicalComposerContext } from \"@lexical/react/LexicalComposerContext\";\nimport {\n $getNodeByKey,\n $getRoot,\n $getSelection,\n $isRangeSelection,\n $isRootNode,\n COMMAND_PRIORITY_LOW,\n} from \"lexical\";\n\nimport {\n $createLoadingImageNode,\n $isLoadingImageNode,\n} from \"../nodes/LoadingImageNode\";\nimport { $createImageNode } from \"../nodes/ImageNode\";\n\nimport { INSERT_IMAGE_COMMAND } from \"../commands\";\n\nimport type { UploadHandler } from \"../types\";\n\nconst DEFAULT_MAX_FILE_SIZE = 10 * 1024 * 1024; // 10MB\nconst DEFAULT_ALLOWED_FORMATS = [\n \"image/jpeg\",\n \"image/png\",\n \"image/gif\",\n \"image/webp\",\n \"image/svg+xml\",\n];\n\ninterface ImagePluginProps {\n uploadHandler: UploadHandler;\n /** Maximum file size in bytes. Default: 10MB. */\n maxFileSize?: number;\n /** Allowed MIME types. Default: jpeg, png, gif, webp, svg+xml. */\n allowedFormats?: string[];\n /** Called when a file is rejected (too large or wrong format). */\n onFileRejected?: (file: File, reason: \"size\" | \"format\") => void;\n /** Called when an upload fails. */\n onUploadError?: (file: File, error: unknown) => void;\n}\n\nexport function ImagePlugin({\n uploadHandler,\n maxFileSize = DEFAULT_MAX_FILE_SIZE,\n allowedFormats = DEFAULT_ALLOWED_FORMATS,\n onFileRejected,\n onUploadError,\n}: ImagePluginProps) {\n const [editor] = useLexicalComposerContext();\n const uploadHandlerRef = useRef(uploadHandler);\n uploadHandlerRef.current = uploadHandler;\n const onUploadErrorRef = useRef(onUploadError);\n onUploadErrorRef.current = onUploadError;\n\n const validateFile = (file: File): boolean => {\n if (!allowedFormats.some((fmt) => file.type === fmt)) {\n onFileRejected?.(file, \"format\");\n return false;\n }\n if (file.size > maxFileSize) {\n onFileRejected?.(file, \"size\");\n return false;\n }\n return true;\n };\n\n useEffect(() => {\n return editor.registerCommand(\n INSERT_IMAGE_COMMAND,\n (file: File) => {\n if (!validateFile(file)) return true;\n handleImageUpload(file, editor, uploadHandlerRef.current, onUploadErrorRef.current);\n return true;\n },\n COMMAND_PRIORITY_LOW,\n );\n }, [editor, maxFileSize, allowedFormats, onFileRejected]);\n\n useEffect(() => {\n const rootElement = editor.getRootElement();\n if (!rootElement) return;\n\n const onDrop = (e: DragEvent) => {\n const files = e.dataTransfer?.files;\n if (!files || files.length === 0) return;\n\n const imageFiles = Array.from(files).filter((f) =>\n f.type.startsWith(\"image/\"),\n );\n if (imageFiles.length === 0) return;\n\n e.preventDefault();\n e.stopPropagation();\n\n for (const file of imageFiles) {\n if (!validateFile(file)) continue;\n handleImageUpload(file, editor, uploadHandlerRef.current, onUploadErrorRef.current);\n }\n };\n\n rootElement.addEventListener(\"drop\", onDrop);\n return () => rootElement.removeEventListener(\"drop\", onDrop);\n }, [editor, maxFileSize, allowedFormats, onFileRejected]);\n\n useEffect(() => {\n const rootElement = editor.getRootElement();\n if (!rootElement) return;\n\n const onPaste = (e: ClipboardEvent) => {\n const files = e.clipboardData?.files;\n if (!files || files.length === 0) return;\n\n const imageFiles = Array.from(files).filter((f) =>\n f.type.startsWith(\"image/\"),\n );\n if (imageFiles.length === 0) return;\n\n e.preventDefault();\n\n for (const file of imageFiles) {\n if (!validateFile(file)) continue;\n handleImageUpload(file, editor, uploadHandlerRef.current, onUploadErrorRef.current);\n }\n };\n\n rootElement.addEventListener(\"paste\", onPaste);\n return () => rootElement.removeEventListener(\"paste\", onPaste);\n }, [editor, maxFileSize, allowedFormats, onFileRejected]);\n\n return null;\n}\n\nfunction handleImageUpload(\n file: File,\n editor: ReturnType<typeof useLexicalComposerContext>[0],\n uploadHandler: UploadHandler,\n onUploadError?: (file: File, error: unknown) => void,\n) {\n // Step 1: Create objectURL for optimistic preview\n const objectURL = URL.createObjectURL(file);\n\n // Step 2: Insert LoadingImageNode into the AST\n let loadingNodeKey: string | null = null;\n\n editor.update(() => {\n const loadingNode = $createLoadingImageNode(objectURL);\n loadingNodeKey = loadingNode.getKey();\n\n const root = $getRoot();\n const selection = $getSelection();\n\n // Find the top-level block to insert after\n let targetBlock: import(\"lexical\").LexicalNode | null = null;\n\n if ($isRangeSelection(selection)) {\n let node: import(\"lexical\").LexicalNode = selection.anchor.getNode();\n // Walk up to find the top-level block (direct child of root)\n while (!$isRootNode(node)) {\n const parent = node.getParent();\n if (!parent || $isRootNode(parent)) {\n // node is a direct child of root (or has no parent)\n if (parent) targetBlock = node;\n break;\n }\n node = parent;\n }\n }\n\n if (targetBlock && !$isRootNode(targetBlock)) {\n targetBlock.insertAfter(loadingNode);\n } else {\n root.append(loadingNode);\n }\n });\n\n // Step 3: Call the upload handler\n uploadHandler(file)\n .then((remoteURL) => {\n // Step 4: Replace LoadingImageNode with ImageNode\n try {\n editor.update(() => {\n if (!loadingNodeKey) return;\n\n const loadingNode = $getNodeByKey(loadingNodeKey);\n if (!loadingNode || !$isLoadingImageNode(loadingNode)) return;\n\n const imageNode = $createImageNode({\n src: remoteURL,\n altText: file.name,\n });\n\n loadingNode.replace(imageNode);\n });\n } catch {\n // Editor may have been disposed if component unmounted during upload\n }\n\n URL.revokeObjectURL(objectURL);\n })\n .catch((error: unknown) => {\n // Step 5: Remove LoadingImageNode on failure\n try {\n editor.update(() => {\n if (!loadingNodeKey) return;\n\n const loadingNode = $getNodeByKey(loadingNodeKey);\n if (!loadingNode) return;\n\n loadingNode.remove();\n });\n } catch {\n // Editor may have been disposed if component unmounted during upload\n }\n\n onUploadError?.(file, error);\n URL.revokeObjectURL(objectURL);\n });\n}\n","\"use client\";\n\nimport { useCallback, useEffect, useRef, useState } from \"react\";\n\nimport { createPortal } from \"react-dom\";\n\nimport { useLexicalComposerContext } from \"@lexical/react/LexicalComposerContext\";\nimport {\n $getRoot,\n $getSelection,\n $isRangeSelection,\n $isRootNode,\n COMMAND_PRIORITY_LOW,\n} from \"lexical\";\n\nimport type { AIProvider, AIPluginConfig, AIPromptInputRenderProps } from \"../types\";\nimport {\n registerAIProvider,\n unregisterAIProvider,\n} from \"./aiProviderRegistry\";\nimport {\n INSERT_AI_PREVIEW_COMMAND,\n OPEN_AI_PROMPT_COMMAND,\n} from \"../commands\";\nimport { $createAIPreviewNode } from \"../nodes/AIPreviewNode\";\nimport { serializeNodesToMarkdown } from \"../utils/markdown\";\n\nimport { PaperPlaneRightIcon } from \"@phosphor-icons/react\";\n\ninterface AIPluginProps {\n /** The AI provider that supplies streaming text generation. */\n provider: AIProvider;\n /**\n * Optional configuration for the AI integration.\n * Controls model parameters, UI labels, retry behaviour, context window,\n * error handling, analytics callbacks, and custom prompt input rendering.\n */\n config?: AIPluginConfig;\n}\n\nexport function AIPlugin({ provider, config = {} }: AIPluginProps) {\n const [editor] = useLexicalComposerContext();\n const [isPromptOpen, setIsPromptOpen] = useState(false);\n const [promptPosition, setPromptPosition] = useState({ top: 0, left: 0 });\n const [portalContainer, setPortalContainer] = useState<HTMLElement | null>(\n null,\n );\n const inputRef = useRef<HTMLInputElement>(null);\n\n // Configurable context window size (default: 3 blocks)\n const contextWindowSize = config.contextWindowSize ?? 3;\n\n useEffect(() => {\n if (typeof window === \"undefined\") return;\n setPortalContainer(document.body);\n }, []);\n\n // Register provider + config in the WeakMap registry\n useEffect(() => {\n registerAIProvider(editor, provider, config);\n return () => {\n unregisterAIProvider(editor);\n };\n }, [editor, provider, config]);\n\n useEffect(() => {\n return editor.registerCommand(\n OPEN_AI_PROMPT_COMMAND,\n () => {\n // Get cursor position for popover anchoring — same line as trigger\n const domSelection = window.getSelection();\n if (domSelection && domSelection.rangeCount > 0) {\n const range = domSelection.getRangeAt(0);\n const rect = range.getBoundingClientRect();\n setPromptPosition({\n top: rect.top,\n left: rect.left,\n });\n }\n\n setIsPromptOpen(true);\n\n return true;\n },\n COMMAND_PRIORITY_LOW,\n );\n }, [editor, config.renderPrompt]);\n\n useEffect(() => {\n return editor.registerCommand(\n INSERT_AI_PREVIEW_COMMAND,\n (payload) => {\n // Build context from surrounding nodes\n let contextMarkdown = \"\";\n editor.read(() => {\n const root = $getRoot();\n const children = root.getChildren();\n const contextNodes = children.slice(-contextWindowSize);\n contextMarkdown = serializeNodesToMarkdown(contextNodes);\n });\n\n // Insert AIPreviewNode into the AST — replace the current block if empty\n editor.update(() => {\n const selection = $getSelection();\n let targetBlock: import(\"lexical\").LexicalNode | null = null;\n\n if ($isRangeSelection(selection)) {\n let node: import(\"lexical\").LexicalNode =\n selection.anchor.getNode();\n while (!$isRootNode(node)) {\n const parent = node.getParent();\n if (!parent || $isRootNode(parent)) {\n if (parent) targetBlock = node;\n break;\n }\n node = parent;\n }\n }\n\n const aiNode = $createAIPreviewNode({\n prompt: payload.prompt,\n context: contextMarkdown,\n });\n\n if (targetBlock && !$isRootNode(targetBlock)) {\n // If the current block is empty, replace it with the AI node\n const textContent = targetBlock.getTextContent();\n if (textContent.trim() === \"\") {\n targetBlock.replace(aiNode);\n } else {\n targetBlock.insertAfter(aiNode);\n }\n } else {\n const root = $getRoot();\n root.append(aiNode);\n }\n });\n\n return true;\n },\n COMMAND_PRIORITY_LOW,\n );\n }, [editor, contextWindowSize]);\n\n const handleSubmit = useCallback(\n (promptText: string) => {\n if (!promptText.trim()) return;\n\n setIsPromptOpen(false);\n editor.dispatchCommand(INSERT_AI_PREVIEW_COMMAND, {\n prompt: promptText.trim(),\n });\n },\n [editor],\n );\n\n const handleClose = useCallback(() => {\n setIsPromptOpen(false);\n editor.focus();\n }, [editor]);\n\n if (!portalContainer) return null;\n\n // Build the prompt input render props\n const promptRenderProps: AIPromptInputRenderProps = {\n position: promptPosition,\n onSubmit: handleSubmit,\n onClose: handleClose,\n };\n\n return (\n <>\n {isPromptOpen &&\n createPortal(\n config.renderPrompt ? (\n config.renderPrompt(promptRenderProps)\n ) : (\n <AIPromptInput\n ref={inputRef}\n position={promptPosition}\n onSubmit={handleSubmit}\n onClose={handleClose}\n />\n ),\n portalContainer,\n )}\n </>\n );\n}\n\nimport { forwardRef } from \"react\";\n\ninterface AIPromptInputProps {\n position: { top: number; left: number };\n onSubmit: (prompt: string) => void;\n onClose: () => void;\n}\n\nconst AIPromptInput = forwardRef<HTMLInputElement, AIPromptInputProps>(\n function AIPromptInput({ position, onSubmit, onClose }, ref) {\n const [value, setValue] = useState(\"\");\n const containerRef = useRef<HTMLDivElement>(null);\n // Close on click outside — deferred to avoid catching the click that opened the prompt\n useEffect(() => {\n const handleClickOutside = (e: MouseEvent) => {\n if (\n containerRef.current &&\n !containerRef.current.contains(e.target as Node)\n ) {\n onClose();\n }\n };\n\n // Defer registration to the next frame so the opening click doesn't\n // immediately trigger the outside-click handler\n const raf = requestAnimationFrame(() => {\n document.addEventListener(\"mousedown\", handleClickOutside);\n });\n return () => {\n cancelAnimationFrame(raf);\n document.removeEventListener(\"mousedown\", handleClickOutside);\n };\n }, [onClose]);\n\n const handleKeyDown = (e: React.KeyboardEvent<HTMLInputElement>) => {\n // Stop propagation on ALL keys to prevent Lexical from intercepting\n // arrow keys, shift+arrow selections, etc.\n e.stopPropagation();\n\n if (e.key === \"Enter\" && !e.shiftKey) {\n e.preventDefault();\n onSubmit(value);\n }\n if (e.key === \"Escape\") {\n e.preventDefault();\n onClose();\n }\n };\n\n return (\n <div\n ref={containerRef}\n data-testid=\"ai-prompt-input\"\n style={{\n position: \"fixed\",\n top: `${position.top}px`,\n left: `${position.left}px`,\n zIndex: 60,\n display: \"flex\",\n alignItems: \"center\",\n gap: \"8px\",\n padding: \"6px 8px 6px 14px\",\n borderRadius: \"12px\",\n border: \"1px solid rgba(51, 102, 204, 0.2)\",\n backgroundColor: \"var(--blokhaus-popover-bg)\",\n backdropFilter: \"blur(20px) saturate(180%)\",\n WebkitBackdropFilter: \"blur(20px) saturate(180%)\",\n boxShadow: \"var(--blokhaus-popover-shadow)\",\n fontFamily:\n '-apple-system, BlinkMacSystemFont, \"SF Pro Text\", system-ui, sans-serif',\n animation: \"blokhaus-prompt-enter 0.2s ease-out\",\n minWidth: \"320px\",\n }}\n >\n <input\n ref={(el) => {\n if (el) el.focus();\n if (typeof ref === \"function\") ref(el);\n else if (ref) ref.current = el;\n }}\n type=\"text\"\n value={value}\n onChange={(e) => setValue(e.target.value)}\n onKeyDown={handleKeyDown}\n placeholder=\"Ask AI to write...\"\n style={{\n flex: 1,\n border: \"none\",\n outline: \"none\",\n background: \"transparent\",\n fontSize: \"14px\",\n color: \"var(--blokhaus-foreground, #0f172a)\",\n fontFamily: \"inherit\",\n }}\n />\n <button\n type=\"button\"\n data-testid=\"ai-prompt-submit\"\n onClick={() => onSubmit(value)}\n disabled={!value.trim()}\n style={{\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n width: \"28px\",\n height: \"28px\",\n borderRadius: \"8px\",\n border: \"none\",\n cursor: value.trim() ? \"pointer\" : \"default\",\n backgroundColor: value.trim()\n ? \"var(--blokhaus-ai-stream, #3366cc)\"\n : \"rgba(51, 102, 204, 0.15)\",\n color: value.trim() ? \"var(--blokhaus-accent-foreground, #fff)\" : \"rgba(51, 102, 204, 0.35)\",\n transition: \"background-color 0.15s, color 0.15s\",\n }}\n >\n <PaperPlaneRightIcon size={14} weight=\"fill\" />\n </button>\n\n <style\n dangerouslySetInnerHTML={{\n __html: `\n @keyframes blokhaus-prompt-enter {\n from {\n opacity: 0;\n transform: translateY(-4px) scale(0.98);\n }\n to {\n opacity: 1;\n transform: translateY(0) scale(1);\n }\n }\n `,\n }}\n />\n </div>\n );\n },\n);\n","\"use client\";\n\n// REACT\nimport { useCallback, useEffect, useRef, useState } from \"react\";\n\n// REACT DOM\nimport { createPortal } from \"react-dom\";\n\n// LEXICAL\nimport { useLexicalComposerContext } from \"@lexical/react/LexicalComposerContext\";\nimport {\n $getSelection,\n $isRangeSelection,\n $isTextNode,\n COMMAND_PRIORITY_HIGH,\n KEY_ARROW_DOWN_COMMAND,\n KEY_ARROW_UP_COMMAND,\n KEY_ENTER_COMMAND,\n KEY_ESCAPE_COMMAND,\n KEY_TAB_COMMAND,\n TextNode,\n} from \"lexical\";\n\n// TYPES\nimport type { MentionProvider, MentionItem } from \"../types\";\n\n// ─── Plugin Props ────────────────────────────────────────────────────────────\n\ninterface MentionPluginProps {\n /** One or more mention providers, each with their own trigger character. */\n providers: MentionProvider[];\n}\n\n// ─── Plugin Component ────────────────────────────────────────────────────────\n\nexport function MentionPlugin({ providers }: MentionPluginProps) {\n const [editor] = useLexicalComposerContext();\n const [isOpen, setIsOpen] = useState(false);\n const [query, setQuery] = useState(\"\");\n const [items, setItems] = useState<MentionItem[]>([]);\n const [selectedIndex, setSelectedIndex] = useState(0);\n const [position, setPosition] = useState({ top: 0, left: 0 });\n const [portalContainer, setPortalContainer] = useState<HTMLElement | null>(\n null,\n );\n const activeProviderRef = useRef<MentionProvider | null>(null);\n const triggerOffsetRef = useRef<number>(0);\n const searchTimeoutRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n\n // Portal container\n useEffect(() => {\n if (typeof window === \"undefined\") return;\n setPortalContainer(document.body);\n }, []);\n\n // Build a set of trigger characters\n const triggers = providers.map((p) => p.trigger);\n\n // Close the dropdown\n const close = useCallback(() => {\n setIsOpen(false);\n setQuery(\"\");\n setItems([]);\n setSelectedIndex(0);\n activeProviderRef.current = null;\n }, []);\n\n // Track text changes to detect trigger characters and query text\n useEffect(() => {\n let mentionRafId = 0;\n\n const unregister = editor.registerUpdateListener(({ editorState }) => {\n // Coalesce rapid updates into a single RAF frame\n if (mentionRafId !== 0) cancelAnimationFrame(mentionRafId);\n mentionRafId = requestAnimationFrame(() => {\n mentionRafId = 0;\n editorState.read(() => {\n const selection = $getSelection();\n if (!$isRangeSelection(selection) || !selection.isCollapsed()) {\n if (isOpen) close();\n return;\n }\n\n const anchor = selection.anchor;\n const node = anchor.getNode();\n if (!$isTextNode(node)) {\n if (isOpen) close();\n return;\n }\n\n const text = node.getTextContent();\n const offset = anchor.offset;\n\n // Fast path: if text has no trigger characters at all, skip scanning\n if (!isOpen && !triggers.some((t) => text.includes(t))) {\n return;\n }\n\n // Look backwards from cursor to find a trigger character\n let triggerIndex = -1;\n let matchedTrigger = \"\";\n\n for (let i = offset - 1; i >= 0; i--) {\n const char = text[i];\n if (char === undefined) break;\n\n if (triggers.includes(char)) {\n if (i === 0 || text[i - 1] === \" \" || text[i - 1] === \"\\n\") {\n triggerIndex = i;\n matchedTrigger = char;\n }\n break;\n }\n\n if (char === \" \" || char === \"\\n\") {\n break;\n }\n }\n\n if (triggerIndex === -1 || !matchedTrigger) {\n if (isOpen) close();\n return;\n }\n\n const queryText = text.slice(triggerIndex + 1, offset);\n\n const provider = providers.find((p) => p.trigger === matchedTrigger);\n if (!provider) {\n if (isOpen) close();\n return;\n }\n\n // Only measure DOM position when actually opening/updating the dropdown\n const domSelection = window.getSelection();\n if (domSelection && domSelection.rangeCount > 0) {\n const range = domSelection.getRangeAt(0);\n const rect = range.getBoundingClientRect();\n setPosition({\n top: rect.bottom + 4,\n left: rect.left,\n });\n }\n\n activeProviderRef.current = provider;\n triggerOffsetRef.current = triggerIndex;\n setQuery(queryText);\n setIsOpen(true);\n\n if (searchTimeoutRef.current) {\n clearTimeout(searchTimeoutRef.current);\n }\n searchTimeoutRef.current = setTimeout(() => {\n provider.onSearch(queryText).then((results) => {\n setItems(results);\n setSelectedIndex(0);\n });\n }, 50);\n });\n });\n });\n\n return () => {\n unregister();\n if (mentionRafId !== 0) cancelAnimationFrame(mentionRafId);\n };\n }, [editor, isOpen, close, triggers, providers]);\n\n // Select an item and replace trigger+query with a MentionNode\n const selectItem = useCallback(\n (item: MentionItem) => {\n const provider = activeProviderRef.current;\n if (!provider) return;\n\n editor.update(() => {\n const selection = $getSelection();\n if (!$isRangeSelection(selection)) return;\n\n const anchor = selection.anchor;\n const node = anchor.getNode();\n if (!$isTextNode(node)) return;\n\n const text = node.getTextContent();\n const offset = anchor.offset;\n\n // Find the trigger in the text\n const triggerIndex = triggerOffsetRef.current;\n const trigger = provider.trigger;\n\n // Text before trigger\n const before = text.slice(0, triggerIndex);\n // Text after cursor\n const after = text.slice(offset);\n\n // Create the mention node from the provider\n const mentionNode = provider.onSelect(item);\n\n if (before === \"\" && after === \"\") {\n // The entire text node is the trigger+query — replace it\n node.replace(mentionNode);\n } else {\n // Split: set current node to \"before\" text, insert mention after it\n node.setTextContent(before);\n\n // Insert mention after the current node\n node.insertAfter(mentionNode);\n\n // If there's text after the cursor, create a new text node\n if (after) {\n const afterNode = new TextNode(after);\n mentionNode.insertAfter(afterNode);\n }\n }\n\n // Move selection after the mention node\n mentionNode.selectNext(0, 0);\n });\n\n close();\n },\n [editor, close],\n );\n\n // Keyboard navigation — register at HIGH priority to intercept before editor\n useEffect(() => {\n if (!isOpen) return;\n\n const unregisterDown = editor.registerCommand(\n KEY_ARROW_DOWN_COMMAND,\n (event) => {\n if (!isOpen || items.length === 0) return false;\n event?.preventDefault();\n setSelectedIndex((prev) => (prev + 1) % items.length);\n return true;\n },\n COMMAND_PRIORITY_HIGH,\n );\n\n const unregisterUp = editor.registerCommand(\n KEY_ARROW_UP_COMMAND,\n (event) => {\n if (!isOpen || items.length === 0) return false;\n event?.preventDefault();\n setSelectedIndex((prev) => (prev - 1 + items.length) % items.length);\n return true;\n },\n COMMAND_PRIORITY_HIGH,\n );\n\n const unregisterEnter = editor.registerCommand(\n KEY_ENTER_COMMAND,\n (event) => {\n if (!isOpen || items.length === 0) return false;\n event?.preventDefault();\n const item = items[selectedIndex];\n if (item) selectItem(item);\n return true;\n },\n COMMAND_PRIORITY_HIGH,\n );\n\n const unregisterTab = editor.registerCommand(\n KEY_TAB_COMMAND,\n (event) => {\n if (!isOpen || items.length === 0) return false;\n event?.preventDefault();\n const item = items[selectedIndex];\n if (item) selectItem(item);\n return true;\n },\n COMMAND_PRIORITY_HIGH,\n );\n\n const unregisterEscape = editor.registerCommand(\n KEY_ESCAPE_COMMAND,\n (event) => {\n if (!isOpen) return false;\n event?.preventDefault();\n close();\n return true;\n },\n COMMAND_PRIORITY_HIGH,\n );\n\n return () => {\n unregisterDown();\n unregisterUp();\n unregisterEnter();\n unregisterTab();\n unregisterEscape();\n };\n }, [editor, isOpen, items, selectedIndex, selectItem, close]);\n\n if (!portalContainer || !isOpen || items.length === 0) return null;\n\n return createPortal(\n <MentionDropdown\n items={items}\n selectedIndex={selectedIndex}\n position={position}\n provider={activeProviderRef.current}\n onSelect={selectItem}\n onHover={setSelectedIndex}\n />,\n portalContainer,\n );\n}\n\n// ─── Dropdown Component ──────────────────────────────────────────────────────\n\nfunction MentionDropdown({\n items,\n selectedIndex,\n position,\n provider,\n onSelect,\n onHover,\n}: {\n items: MentionItem[];\n selectedIndex: number;\n position: { top: number; left: number };\n provider: MentionProvider | null;\n onSelect: (item: MentionItem) => void;\n onHover: (index: number) => void;\n}) {\n const listRef = useRef<HTMLDivElement>(null);\n\n // Scroll selected item into view\n useEffect(() => {\n const list = listRef.current;\n if (!list) return;\n const selected = list.children[selectedIndex] as HTMLElement | undefined;\n if (selected) {\n selected.scrollIntoView({ block: \"nearest\" });\n }\n }, [selectedIndex]);\n\n // Determine accent based on trigger\n const trigger = provider?.trigger ?? \"@\";\n const accentColor =\n trigger === \"#\"\n ? \"var(--blokhaus-accent, #3b82f6)\"\n : \"var(--blokhaus-ai-stream, #3366cc)\";\n\n return (\n <div\n data-testid=\"mention-dropdown\"\n style={{\n position: \"fixed\",\n top: `${position.top}px`,\n left: `${position.left}px`,\n zIndex: 60,\n minWidth: \"200px\",\n maxWidth: \"320px\",\n maxHeight: \"240px\",\n overflowY: \"auto\",\n borderRadius: \"10px\",\n border: \"1px solid var(--blokhaus-border, #e2e8f0)\",\n backgroundColor: \"var(--blokhaus-popover-bg)\",\n backdropFilter: \"blur(20px) saturate(180%)\",\n WebkitBackdropFilter: \"blur(20px) saturate(180%)\",\n boxShadow: \"var(--blokhaus-popover-shadow)\",\n fontFamily: \"var(--blokhaus-font-sans, system-ui, sans-serif)\",\n animation: \"blokhaus-mention-enter 0.15s ease-out\",\n padding: \"4px\",\n }}\n ref={listRef}\n >\n {items.map((item, index) => (\n <div\n key={item.id}\n data-testid={`mention-item-${item.id}`}\n role=\"option\"\n aria-selected={index === selectedIndex}\n onMouseDown={(e) => {\n e.preventDefault();\n onSelect(item);\n }}\n onMouseEnter={() => onHover(index)}\n style={{\n display: \"flex\",\n alignItems: \"center\",\n gap: \"10px\",\n padding: \"8px 10px\",\n borderRadius: \"6px\",\n cursor: \"pointer\",\n backgroundColor:\n index === selectedIndex\n ? `color-mix(in srgb, ${accentColor} 8%, transparent)`\n : \"transparent\",\n transition: \"background-color 0.1s\",\n }}\n >\n {/* Icon / Avatar */}\n {item.icon && (\n <img\n src={item.icon}\n alt=\"\"\n style={{\n width: \"24px\",\n height: \"24px\",\n borderRadius: \"50%\",\n objectFit: \"cover\",\n flexShrink: 0,\n }}\n />\n )}\n {!item.icon && (\n <div\n style={{\n width: \"24px\",\n height: \"24px\",\n borderRadius: \"50%\",\n backgroundColor: `color-mix(in srgb, ${accentColor} 15%, transparent)`,\n color: accentColor,\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n fontSize: \"12px\",\n fontWeight: 600,\n flexShrink: 0,\n }}\n >\n {item.label.charAt(0).toUpperCase()}\n </div>\n )}\n\n {/* Label + Meta */}\n <div style={{ flex: 1, minWidth: 0 }}>\n <div\n style={{\n fontSize: \"13px\",\n fontWeight: 500,\n color: \"var(--blokhaus-foreground, #0f172a)\",\n whiteSpace: \"nowrap\",\n overflow: \"hidden\",\n textOverflow: \"ellipsis\",\n }}\n >\n {provider ? provider.renderItem(item) : item.label}\n </div>\n {item.meta && (\n <div\n style={{\n fontSize: \"11px\",\n color: \"var(--blokhaus-muted-foreground, #94a3b8)\",\n whiteSpace: \"nowrap\",\n overflow: \"hidden\",\n textOverflow: \"ellipsis\",\n }}\n >\n {item.meta}\n </div>\n )}\n </div>\n </div>\n ))}\n\n {/* Animation */}\n <style\n dangerouslySetInnerHTML={{\n __html: `\n @keyframes blokhaus-mention-enter {\n from {\n opacity: 0;\n transform: translateY(-4px) scale(0.98);\n }\n to {\n opacity: 1;\n transform: translateY(0) scale(1);\n }\n }\n `,\n }}\n />\n </div>\n );\n}\n","\"use client\";\n\nimport { useEffect } from \"react\";\n\nimport { useLexicalComposerContext } from \"@lexical/react/LexicalComposerContext\";\nimport {\n $getSelection,\n $isRangeSelection,\n $insertNodes,\n COMMAND_PRIORITY_EDITOR,\n PASTE_COMMAND,\n} from \"lexical\";\nimport { $generateNodesFromDOM } from \"@lexical/html\";\n\nimport { sanitizePastedHTML } from \"../utils/sanitize\";\n\n/**\n * PastePlugin — intercepts paste events, sanitises incoming HTML,\n * and inserts clean Lexical nodes into the AST.\n *\n * See CLAUDE.md Section 13 for the full specification.\n */\nexport function PastePlugin() {\n const [editor] = useLexicalComposerContext();\n\n useEffect(() => {\n return editor.registerCommand(\n PASTE_COMMAND,\n (event: ClipboardEvent) => {\n const clipboardData = event.clipboardData;\n if (!clipboardData) return false;\n\n const hasImageFiles = Array.from(clipboardData.files).some((file) =>\n file.type.startsWith(\"image/\"),\n );\n if (hasImageFiles) return false;\n\n const html = clipboardData.getData(\"text/html\");\n if (!html) return false; // Fall through to Lexical's default plain-text paste\n\n const sanitizedHTML = sanitizePastedHTML(html);\n\n const parser = new DOMParser();\n const dom = parser.parseFromString(sanitizedHTML, \"text/html\");\n\n const nodes = $generateNodesFromDOM(editor, dom);\n\n if (nodes.length === 0) return false;\n\n const selection = $getSelection();\n if ($isRangeSelection(selection)) {\n selection.removeText();\n }\n $insertNodes(nodes);\n\n event.preventDefault();\n return true;\n },\n COMMAND_PRIORITY_EDITOR,\n );\n }, [editor]);\n\n return null;\n}\n","/**\n * Paste sanitisation pipeline.\n *\n * Takes a raw HTML string (typically from clipboard) and returns clean,\n * semantic HTML safe for conversion into Lexical nodes.\n *\n * See CLAUDE.md Section 13.2 for the full specification.\n */\n\n/**\n * Strict allowlist of HTML tag names that survive sanitisation.\n * Anything not on this list is unwrapped to its text content.\n */\nconst ALLOWED_TAGS = new Set([\n 'P', 'BR', 'H1', 'H2', 'H3', 'H4', 'H5', 'H6',\n 'STRONG', 'B', 'EM', 'I', 'U', 'S', 'DEL', 'STRIKE',\n 'CODE', 'PRE', 'BLOCKQUOTE',\n 'UL', 'OL', 'LI',\n 'A', 'IMG',\n 'TABLE', 'THEAD', 'TBODY', 'TR', 'TH', 'TD',\n 'HR',\n]);\n\n/**\n * Tags that are stripped entirely (element + all children).\n */\nconst STRIP_ENTIRELY_TAGS = new Set(['SCRIPT', 'STYLE', 'IFRAME', 'OBJECT', 'NOSCRIPT']);\n\n/**\n * Semantic attribute allowlist per tag.\n * Only these attributes survive on their respective elements.\n */\nconst ALLOWED_ATTRIBUTES: Record<string, Set<string>> = {\n A: new Set(['href']),\n IMG: new Set(['src', 'alt']),\n};\n\n/**\n * Maps common non-semantic bold/italic tags to their semantic equivalents.\n */\nfunction normalizeTagName(tagName: string): string | null {\n switch (tagName) {\n case 'B': return 'STRONG';\n case 'I': return 'EM';\n case 'DEL': return 'S';\n case 'STRIKE': return 'S';\n default: return null;\n }\n}\n\n/**\n * Font-size thresholds for heading level normalization.\n * Google Docs uses inline font-size styles on generic elements.\n * We map font sizes to heading levels before stripping styles.\n */\nfunction fontSizeToHeadingLevel(fontSize: string): number | null {\n const match = fontSize.match(/^([\\d.]+)\\s*(px|pt|em|rem)?$/);\n if (!match) return null;\n\n const value = parseFloat(match[1]!);\n const unit = match[2] ?? 'px';\n\n // Normalize to px\n let px: number;\n switch (unit) {\n case 'pt': px = value * (4 / 3); break;\n case 'em':\n case 'rem': px = value * 16; break;\n default: px = value;\n }\n\n // Map pixel ranges to heading levels\n if (px >= 32) return 1;\n if (px >= 24) return 2;\n if (px >= 18) return 3;\n return null; // Normal text — no heading\n}\n\n/**\n * Strips all attributes from an element except those in the allowlist.\n */\nfunction stripAttributes(el: Element): void {\n const allowed = ALLOWED_ATTRIBUTES[el.tagName];\n const attrs = Array.from(el.attributes);\n\n for (const attr of attrs) {\n if (!allowed || !allowed.has(attr.name)) {\n el.removeAttribute(attr.name);\n }\n }\n}\n\n/**\n * Recursively sanitises a DOM tree in place.\n *\n * Returns true if the node should be kept, false if it was removed.\n */\nfunction sanitizeNode(node: Node, doc: Document): void {\n if (node.nodeType === 3 /* TEXT_NODE */) {\n return; // Keep text nodes as-is\n }\n\n if (node.nodeType !== 1 /* ELEMENT_NODE */) {\n // Remove comments, processing instructions, etc.\n node.parentNode?.removeChild(node);\n return;\n }\n\n const el = node as Element;\n const tagName = el.tagName;\n\n // Strip dangerous tags entirely (element + children)\n if (STRIP_ENTIRELY_TAGS.has(tagName)) {\n el.parentNode?.removeChild(el);\n return;\n }\n\n // Before stripping styles, check for font-size-based heading normalization\n const inlineStyle = el.getAttribute('style');\n let headingLevel: number | null = null;\n\n if (inlineStyle) {\n const fontSizeMatch = inlineStyle.match(/font-size\\s*:\\s*([^;]+)/i);\n if (fontSizeMatch) {\n headingLevel = fontSizeToHeadingLevel(fontSizeMatch[1]!.trim());\n }\n }\n\n // Process children first (bottom-up traversal to handle mutations safely)\n const children = Array.from(el.childNodes);\n for (const child of children) {\n sanitizeNode(child, doc);\n }\n\n // Handle SPAN: always unwrap (spans are non-semantic after style stripping)\n if (tagName === 'SPAN' || tagName === 'FONT') {\n // If this span had a font-size that maps to a heading, wrap in heading\n if (headingLevel !== null && headingLevel >= 1 && headingLevel <= 3) {\n const heading = doc.createElement(`h${headingLevel}`);\n while (el.firstChild) {\n heading.appendChild(el.firstChild);\n }\n el.parentNode?.replaceChild(heading, el);\n return;\n }\n\n // Otherwise just unwrap\n unwrapElement(el);\n return;\n }\n\n // Handle DIV: treat as paragraph if it has content, otherwise unwrap\n if (tagName === 'DIV') {\n // If this div had a heading font-size, convert to heading\n if (headingLevel !== null && headingLevel >= 1 && headingLevel <= 3) {\n const heading = doc.createElement(`h${headingLevel}`);\n while (el.firstChild) {\n heading.appendChild(el.firstChild);\n }\n el.parentNode?.replaceChild(heading, el);\n return;\n }\n\n // Convert div to p\n const p = doc.createElement('p');\n while (el.firstChild) {\n p.appendChild(el.firstChild);\n }\n el.parentNode?.replaceChild(p, el);\n return;\n }\n\n // Check allowlist\n if (!ALLOWED_TAGS.has(tagName)) {\n // Normalize non-semantic tags (B→STRONG, I→EM, etc.)\n const normalized = normalizeTagName(tagName);\n if (normalized && ALLOWED_TAGS.has(normalized)) {\n const replacement = doc.createElement(normalized);\n while (el.firstChild) {\n replacement.appendChild(el.firstChild);\n }\n el.parentNode?.replaceChild(replacement, el);\n stripAttributes(replacement);\n return;\n }\n\n // Unknown tag: unwrap to text content\n unwrapElement(el);\n return;\n }\n\n // Normalize B/I/DEL/STRIKE even if they're in the allowlist\n const normalized = normalizeTagName(tagName);\n if (normalized) {\n const replacement = doc.createElement(normalized);\n while (el.firstChild) {\n replacement.appendChild(el.firstChild);\n }\n el.parentNode?.replaceChild(replacement, el);\n stripAttributes(replacement);\n return;\n }\n\n // Element is allowed — strip non-semantic attributes\n stripAttributes(el);\n}\n\n/**\n * Unwraps an element, replacing it with its child nodes.\n */\nfunction unwrapElement(el: Element): void {\n const parent = el.parentNode;\n if (!parent) return;\n\n while (el.firstChild) {\n parent.insertBefore(el.firstChild, el);\n }\n parent.removeChild(el);\n}\n\n/**\n * Sanitises pasted HTML for safe insertion into the Lexical AST.\n *\n * This is a pure function: it takes an HTML string and returns a sanitised\n * HTML string. It uses `DOMParser` (browser API) to parse and manipulate\n * the HTML.\n *\n * @param html - Raw HTML string from the clipboard\n * @returns Sanitised HTML string safe for `$generateNodesFromDOM`\n */\nexport function sanitizePastedHTML(html: string): string {\n const parser = new DOMParser();\n const doc = parser.parseFromString(html, 'text/html');\n\n // Sanitise the body (which contains the pasted content)\n const body = doc.body;\n\n // Process all children\n const children = Array.from(body.childNodes);\n for (const child of children) {\n sanitizeNode(child, doc);\n }\n\n return body.innerHTML;\n}\n","\"use client\";\n\nimport { useCallback, useEffect, useRef, useState } from \"react\";\n\nimport { createPortal } from \"react-dom\";\n\nimport { useLexicalComposerContext } from \"@lexical/react/LexicalComposerContext\";\nimport {\n $getSelection,\n $isRangeSelection,\n $isTextNode,\n COMMAND_PRIORITY_HIGH,\n COMMAND_PRIORITY_LOW,\n KEY_ARROW_DOWN_COMMAND,\n KEY_ARROW_UP_COMMAND,\n KEY_ENTER_COMMAND,\n KEY_ESCAPE_COMMAND,\n KEY_TAB_COMMAND,\n TextNode,\n} from \"lexical\";\n\nimport { OPEN_EMOJI_PICKER_COMMAND } from \"../commands\";\n\nimport type { EmojiItem } from \"../data/emoji-list\";\nimport { DEFAULT_EMOJIS } from \"../data/emoji-list\";\n\nexport interface EmojiPickerPluginProps {\n /** Override the built-in emoji list. */\n emojis?: EmojiItem[];\n /** Max results shown in dropdown (default: 8). */\n maxResults?: number;\n /** Custom render function for each emoji row. */\n renderItem?: (item: EmojiItem, isSelected: boolean) => React.ReactNode;\n /** Custom render function for the dropdown container. */\n renderDropdown?: (props: {\n children: React.ReactNode;\n position: { top: number; left: number };\n }) => React.ReactNode;\n}\n\nexport function EmojiPickerPlugin({\n emojis,\n maxResults = 8,\n renderItem,\n renderDropdown,\n}: EmojiPickerPluginProps = {}) {\n const [editor] = useLexicalComposerContext();\n const [isOpen, setIsOpen] = useState(false);\n const [query, setQuery] = useState(\"\");\n const [results, setResults] = useState<EmojiItem[]>([]);\n const [selectedIndex, setSelectedIndex] = useState(0);\n const [position, setPosition] = useState({ top: 0, left: 0 });\n const [portalContainer, setPortalContainer] = useState<HTMLElement | null>(\n null,\n );\n const triggerOffsetRef = useRef<number>(0);\n const openedViaCommandRef = useRef(false);\n const emojiList = emojis ?? DEFAULT_EMOJIS;\n\n useEffect(() => {\n if (typeof window === \"undefined\") return;\n setPortalContainer(document.body);\n }, []);\n\n const close = useCallback(() => {\n setIsOpen(false);\n setQuery(\"\");\n setResults([]);\n setSelectedIndex(0);\n openedViaCommandRef.current = false;\n }, []);\n\n const filterEmojis = useCallback(\n (q: string): EmojiItem[] => {\n if (!q) return [];\n const lower = q.toLowerCase();\n return emojiList\n .filter(\n (e) =>\n e.name.includes(lower) ||\n e.keywords.some((k) => k.includes(lower)),\n )\n .slice(0, maxResults);\n },\n [emojiList, maxResults],\n );\n\n // Handle OPEN_EMOJI_PICKER_COMMAND — open picker at cursor with all emojis\n useEffect(() => {\n return editor.registerCommand(\n OPEN_EMOJI_PICKER_COMMAND,\n () => {\n const domSelection = window.getSelection();\n if (domSelection && domSelection.rangeCount > 0) {\n const range = domSelection.getRangeAt(0);\n const rect = range.getBoundingClientRect();\n setPosition({ top: rect.bottom + 4, left: rect.left });\n }\n\n openedViaCommandRef.current = true;\n setQuery(\"\");\n setResults(emojiList.slice(0, maxResults));\n setSelectedIndex(0);\n setIsOpen(true);\n return true;\n },\n COMMAND_PRIORITY_LOW,\n );\n }, [editor, emojiList, maxResults]);\n\n // Track text changes to detect : trigger and query text\n useEffect(() => {\n let emojiRafId = 0;\n\n const unregister = editor.registerUpdateListener(({ editorState }) => {\n // Coalesce rapid updates into a single RAF frame\n if (emojiRafId !== 0) cancelAnimationFrame(emojiRafId);\n emojiRafId = requestAnimationFrame(() => {\n emojiRafId = 0;\n\n // Command-opened mode: use typed text as search query\n if (openedViaCommandRef.current) {\n editorState.read(() => {\n const selection = $getSelection();\n if (!$isRangeSelection(selection) || !selection.isCollapsed()) {\n if (isOpen) close();\n return;\n }\n\n const anchor = selection.anchor;\n const node = anchor.getNode();\n\n // Get typed text — entire text content of the current node\n const queryText = $isTextNode(node)\n ? node.getTextContent().slice(0, anchor.offset)\n : \"\";\n\n if (queryText.length === 0) {\n // No query yet — show initial emojis\n setResults(emojiList.slice(0, maxResults));\n setSelectedIndex(0);\n return;\n }\n\n // Filter by typed text — keep picker open even with no results\n const filtered = filterEmojis(queryText);\n setQuery(queryText);\n setResults(filtered);\n setSelectedIndex(0);\n });\n return;\n }\n\n editorState.read(() => {\n const selection = $getSelection();\n if (!$isRangeSelection(selection) || !selection.isCollapsed()) {\n if (isOpen) close();\n return;\n }\n\n const anchor = selection.anchor;\n const node = anchor.getNode();\n if (!$isTextNode(node)) {\n if (isOpen) close();\n return;\n }\n\n const text = node.getTextContent();\n const offset = anchor.offset;\n\n // Fast path: skip scanning if no colon in text at all\n if (!isOpen && !text.includes(\":\")) {\n return;\n }\n\n // Look backwards from cursor for ':'\n let colonIndex = -1;\n\n for (let i = offset - 1; i >= 0; i--) {\n const char = text[i];\n if (char === undefined) break;\n\n if (char === \":\") {\n if (i === 0 || text[i - 1] === \" \" || text[i - 1] === \"\\n\") {\n colonIndex = i;\n }\n break;\n }\n\n if (char === \" \" || char === \"\\n\") {\n break;\n }\n }\n\n if (colonIndex === -1) {\n if (isOpen) close();\n return;\n }\n\n const queryText = text.slice(colonIndex + 1, offset);\n\n if (queryText.length < 1) {\n if (isOpen) close();\n return;\n }\n\n const filtered = filterEmojis(queryText);\n if (filtered.length === 0) {\n if (isOpen) close();\n return;\n }\n\n // Only measure DOM when actually showing the picker\n const domSelection = window.getSelection();\n if (domSelection && domSelection.rangeCount > 0) {\n const range = domSelection.getRangeAt(0);\n const rect = range.getBoundingClientRect();\n setPosition({\n top: rect.bottom + 4,\n left: rect.left,\n });\n }\n\n triggerOffsetRef.current = colonIndex;\n setQuery(queryText);\n setResults(filtered);\n setSelectedIndex(0);\n setIsOpen(true);\n });\n\n });\n });\n\n return () => {\n unregister();\n if (emojiRafId !== 0) cancelAnimationFrame(emojiRafId);\n };\n }, [editor, isOpen, close, filterEmojis]);\n\n // Select an emoji — either replace :query text or insert at cursor\n const selectItem = useCallback(\n (item: EmojiItem) => {\n if (openedViaCommandRef.current) {\n // Opened via command — focus editor, remove any typed query, insert emoji\n editor.focus(() => {\n editor.update(() => {\n const selection = $getSelection();\n if (!$isRangeSelection(selection)) return;\n\n const anchor = selection.anchor;\n const node = anchor.getNode();\n\n // Remove the typed search query text before inserting\n if ($isTextNode(node)) {\n const text = node.getTextContent();\n const offset = anchor.offset;\n const after = text.slice(offset);\n node.setTextContent(item.emoji + after);\n node.select(item.emoji.length, item.emoji.length);\n } else {\n selection.insertRawText(item.emoji);\n }\n });\n });\n } else {\n // Opened via : trigger — replace :query with emoji\n editor.update(() => {\n const selection = $getSelection();\n if (!$isRangeSelection(selection)) return;\n\n const anchor = selection.anchor;\n const node = anchor.getNode();\n if (!$isTextNode(node)) return;\n\n const text = node.getTextContent();\n const offset = anchor.offset;\n const triggerIndex = triggerOffsetRef.current;\n\n const before = text.slice(0, triggerIndex);\n const after = text.slice(offset);\n\n node.setTextContent(before + item.emoji + after);\n\n const newOffset = before.length + item.emoji.length;\n node.select(newOffset, newOffset);\n });\n }\n\n close();\n },\n [editor, close],\n );\n\n useEffect(() => {\n if (!isOpen) return;\n\n const unregisterDown = editor.registerCommand(\n KEY_ARROW_DOWN_COMMAND,\n (event) => {\n if (!isOpen || results.length === 0) return false;\n event?.preventDefault();\n setSelectedIndex((prev) => (prev + 1) % results.length);\n return true;\n },\n COMMAND_PRIORITY_HIGH,\n );\n\n const unregisterUp = editor.registerCommand(\n KEY_ARROW_UP_COMMAND,\n (event) => {\n if (!isOpen || results.length === 0) return false;\n event?.preventDefault();\n setSelectedIndex(\n (prev) => (prev - 1 + results.length) % results.length,\n );\n return true;\n },\n COMMAND_PRIORITY_HIGH,\n );\n\n const unregisterEnter = editor.registerCommand(\n KEY_ENTER_COMMAND,\n (event) => {\n if (!isOpen || results.length === 0) return false;\n event?.preventDefault();\n const item = results[selectedIndex];\n if (item) selectItem(item);\n return true;\n },\n COMMAND_PRIORITY_HIGH,\n );\n\n const unregisterTab = editor.registerCommand(\n KEY_TAB_COMMAND,\n (event) => {\n if (!isOpen || results.length === 0) return false;\n event?.preventDefault();\n const item = results[selectedIndex];\n if (item) selectItem(item);\n return true;\n },\n COMMAND_PRIORITY_HIGH,\n );\n\n const unregisterEscape = editor.registerCommand(\n KEY_ESCAPE_COMMAND,\n (event) => {\n if (!isOpen) return false;\n event?.preventDefault();\n close();\n return true;\n },\n COMMAND_PRIORITY_HIGH,\n );\n\n return () => {\n unregisterDown();\n unregisterUp();\n unregisterEnter();\n unregisterTab();\n unregisterEscape();\n };\n }, [editor, isOpen, results, selectedIndex, selectItem, close]);\n\n if (!portalContainer || !isOpen) return null;\n if (results.length === 0 && !openedViaCommandRef.current) return null;\n\n // Custom dropdown render\n if (renderDropdown) {\n return createPortal(\n renderDropdown({\n position,\n children: results.map((item, index) => (\n <div\n key={item.name}\n onMouseDown={(e) => {\n e.preventDefault();\n selectItem(item);\n }}\n onMouseEnter={() => setSelectedIndex(index)}\n >\n {renderItem ? (\n renderItem(item, index === selectedIndex)\n ) : (\n <DefaultEmojiRow item={item} isSelected={index === selectedIndex} />\n )}\n </div>\n )),\n }),\n portalContainer,\n );\n }\n\n return createPortal(\n <EmojiDropdown\n items={results}\n selectedIndex={selectedIndex}\n position={position}\n onSelect={selectItem}\n onHover={setSelectedIndex}\n renderItem={renderItem}\n />,\n portalContainer,\n );\n}\n\nfunction DefaultEmojiRow({\n item,\n isSelected,\n}: {\n item: EmojiItem;\n isSelected: boolean;\n}) {\n return (\n <div\n style={{\n display: \"flex\",\n alignItems: \"center\",\n gap: \"10px\",\n padding: \"6px 10px\",\n borderRadius: \"6px\",\n cursor: \"pointer\",\n backgroundColor: isSelected\n ? \"var(--blokhaus-hover-bg)\"\n : \"transparent\",\n transition: \"background-color 0.1s\",\n }}\n >\n <span style={{ fontSize: \"20px\", lineHeight: 1 }}>{item.emoji}</span>\n <span\n style={{\n fontSize: \"13px\",\n color: \"var(--blokhaus-foreground, #0f172a)\",\n fontWeight: isSelected ? 500 : 400,\n }}\n >\n {item.name.replace(/_/g, \" \")}\n </span>\n </div>\n );\n}\n\nfunction EmojiDropdown({\n items,\n selectedIndex,\n position,\n onSelect,\n onHover,\n renderItem,\n}: {\n items: EmojiItem[];\n selectedIndex: number;\n position: { top: number; left: number };\n onSelect: (item: EmojiItem) => void;\n onHover: (index: number) => void;\n renderItem?: (item: EmojiItem, isSelected: boolean) => React.ReactNode;\n}) {\n const listRef = useRef<HTMLDivElement>(null);\n\n useEffect(() => {\n const list = listRef.current;\n if (!list) return;\n const selected = list.children[selectedIndex] as HTMLElement | undefined;\n if (selected) {\n selected.scrollIntoView({ block: \"nearest\" });\n }\n }, [selectedIndex]);\n\n return (\n <div\n ref={listRef}\n data-testid=\"emoji-picker-dropdown\"\n style={{\n position: \"fixed\",\n top: `${position.top}px`,\n left: `${position.left}px`,\n zIndex: 60,\n minWidth: \"220px\",\n maxWidth: \"320px\",\n maxHeight: \"280px\",\n overflowY: \"auto\",\n borderRadius: \"10px\",\n border: \"1px solid var(--blokhaus-border, #e2e8f0)\",\n backgroundColor: \"var(--blokhaus-popover-bg)\",\n backdropFilter: \"blur(20px) saturate(180%)\",\n WebkitBackdropFilter: \"blur(20px) saturate(180%)\",\n boxShadow: \"var(--blokhaus-popover-shadow)\",\n fontFamily: \"var(--blokhaus-font-sans, system-ui, sans-serif)\",\n animation: \"blokhaus-emoji-enter 0.15s ease-out\",\n padding: \"4px\",\n }}\n >\n {items.length === 0 ? (\n <div\n style={{\n padding: \"12px 10px\",\n fontSize: \"13px\",\n color: \"var(--blokhaus-text-tertiary, #999)\",\n textAlign: \"center\",\n }}\n >\n No matching emojis\n </div>\n ) : (\n items.map((item, index) => (\n <div\n key={item.name}\n data-testid={`emoji-item-${item.name}`}\n role=\"option\"\n aria-selected={index === selectedIndex}\n onMouseDown={(e) => {\n e.preventDefault();\n onSelect(item);\n }}\n onMouseEnter={() => onHover(index)}\n >\n {renderItem ? (\n renderItem(item, index === selectedIndex)\n ) : (\n <DefaultEmojiRow item={item} isSelected={index === selectedIndex} />\n )}\n </div>\n ))\n )}\n\n <style\n dangerouslySetInnerHTML={{\n __html: `\n @keyframes blokhaus-emoji-enter {\n from {\n opacity: 0;\n transform: translateY(-4px) scale(0.98);\n }\n to {\n opacity: 1;\n transform: translateY(0) scale(1);\n }\n }\n `,\n }}\n />\n </div>\n );\n}\n","export interface EmojiItem {\n emoji: string;\n name: string;\n keywords: string[];\n}\n\nexport const DEFAULT_EMOJIS: EmojiItem[] = [\n { emoji: \"\\u{1F600}\", name: \"grinning_face\", keywords: [\"happy\", \"smile\", \"joy\", \"grin\"] },\n { emoji: \"\\u{1F603}\", name: \"grinning_face_with_big_eyes\", keywords: [\"happy\", \"smile\", \"joy\", \"excited\"] },\n { emoji: \"\\u{1F604}\", name: \"grinning_face_with_smiling_eyes\", keywords: [\"happy\", \"smile\", \"joy\", \"laugh\"] },\n { emoji: \"\\u{1F601}\", name: \"beaming_face_with_smiling_eyes\", keywords: [\"happy\", \"smile\", \"grin\", \"beam\"] },\n { emoji: \"\\u{1F606}\", name: \"grinning_squinting_face\", keywords: [\"happy\", \"laugh\", \"satisfied\", \"haha\"] },\n { emoji: \"\\u{1F605}\", name: \"grinning_face_with_sweat\", keywords: [\"happy\", \"laugh\", \"sweat\", \"relief\", \"nervous\"] },\n { emoji: \"\\u{1F923}\", name: \"rolling_on_the_floor_laughing\", keywords: [\"laugh\", \"rofl\", \"lmao\", \"hilarious\", \"funny\"] },\n { emoji: \"\\u{1F602}\", name: \"face_with_tears_of_joy\", keywords: [\"laugh\", \"cry\", \"happy\", \"tears\", \"lol\", \"funny\"] },\n { emoji: \"\\u{1F642}\", name: \"slightly_smiling_face\", keywords: [\"smile\", \"happy\", \"content\", \"pleased\"] },\n { emoji: \"\\u{1F643}\", name: \"upside_down_face\", keywords: [\"silly\", \"sarcasm\", \"irony\", \"playful\"] },\n { emoji: \"\\u{1FAE0}\", name: \"melting_face\", keywords: [\"melt\", \"hot\", \"embarrassed\", \"sarcasm\", \"disappear\"] },\n { emoji: \"\\u{1F609}\", name: \"winking_face\", keywords: [\"wink\", \"flirt\", \"playful\", \"joke\"] },\n { emoji: \"\\u{1F60A}\", name: \"smiling_face_with_smiling_eyes\", keywords: [\"happy\", \"blush\", \"warm\", \"content\"] },\n { emoji: \"\\u{1F607}\", name: \"smiling_face_with_halo\", keywords: [\"angel\", \"innocent\", \"good\", \"blessed\"] },\n { emoji: \"\\u{1F970}\", name: \"smiling_face_with_hearts\", keywords: [\"love\", \"adore\", \"crush\", \"affection\", \"hearts\"] },\n { emoji: \"\\u{1F60D}\", name: \"smiling_face_with_heart_eyes\", keywords: [\"love\", \"crush\", \"heart\", \"adore\", \"infatuation\"] },\n { emoji: \"\\u{1F929}\", name: \"star_struck\", keywords: [\"star\", \"eyes\", \"amazed\", \"wow\", \"excited\", \"fan\"] },\n { emoji: \"\\u{1F618}\", name: \"face_blowing_a_kiss\", keywords: [\"kiss\", \"love\", \"flirt\", \"affection\"] },\n { emoji: \"\\u{1F617}\", name: \"kissing_face\", keywords: [\"kiss\", \"love\", \"lips\"] },\n { emoji: \"\\u{263A}\\u{FE0F}\", name: \"smiling_face\", keywords: [\"happy\", \"warm\", \"blush\", \"relaxed\"] },\n { emoji: \"\\u{1F61A}\", name: \"kissing_face_with_closed_eyes\", keywords: [\"kiss\", \"love\", \"affection\"] },\n { emoji: \"\\u{1F619}\", name: \"kissing_face_with_smiling_eyes\", keywords: [\"kiss\", \"love\", \"happy\"] },\n { emoji: \"\\u{1F972}\", name: \"smiling_face_with_tear\", keywords: [\"happy\", \"sad\", \"grateful\", \"moved\", \"bittersweet\"] },\n { emoji: \"\\u{1F60B}\", name: \"face_savoring_food\", keywords: [\"yummy\", \"delicious\", \"tongue\", \"tasty\", \"food\"] },\n { emoji: \"\\u{1F61B}\", name: \"face_with_tongue\", keywords: [\"tongue\", \"playful\", \"silly\", \"joke\"] },\n { emoji: \"\\u{1F61C}\", name: \"winking_face_with_tongue\", keywords: [\"tongue\", \"wink\", \"playful\", \"silly\", \"joke\"] },\n { emoji: \"\\u{1F92A}\", name: \"zany_face\", keywords: [\"crazy\", \"wild\", \"silly\", \"goofy\", \"wacky\"] },\n { emoji: \"\\u{1F61D}\", name: \"squinting_face_with_tongue\", keywords: [\"tongue\", \"playful\", \"silly\", \"taste\"] },\n { emoji: \"\\u{1F911}\", name: \"money_mouth_face\", keywords: [\"money\", \"rich\", \"dollar\", \"cash\", \"wealth\"] },\n { emoji: \"\\u{1F917}\", name: \"hugging_face\", keywords: [\"hug\", \"embrace\", \"warm\", \"care\", \"love\"] },\n { emoji: \"\\u{1F92D}\", name: \"face_with_hand_over_mouth\", keywords: [\"oops\", \"giggle\", \"secret\", \"shy\", \"whoops\"] },\n { emoji: \"\\u{1FAE2}\", name: \"face_with_open_eyes_and_hand_over_mouth\", keywords: [\"shock\", \"surprise\", \"gasp\", \"oops\"] },\n { emoji: \"\\u{1FAE3}\", name: \"face_with_peeking_eye\", keywords: [\"peek\", \"shy\", \"scared\", \"nervous\", \"hiding\"] },\n { emoji: \"\\u{1F910}\", name: \"zipper_mouth_face\", keywords: [\"quiet\", \"secret\", \"mute\", \"silence\", \"zip\"] },\n { emoji: \"\\u{1F914}\", name: \"thinking_face\", keywords: [\"think\", \"hmm\", \"ponder\", \"consider\", \"wondering\"] },\n { emoji: \"\\u{1F928}\", name: \"face_with_raised_eyebrow\", keywords: [\"skeptical\", \"suspicious\", \"doubt\", \"really\"] },\n { emoji: \"\\u{1F610}\", name: \"neutral_face\", keywords: [\"meh\", \"blank\", \"indifferent\", \"neutral\"] },\n { emoji: \"\\u{1F611}\", name: \"expressionless_face\", keywords: [\"blank\", \"unimpressed\", \"annoyed\", \"deadpan\"] },\n { emoji: \"\\u{1F636}\", name: \"face_without_mouth\", keywords: [\"silent\", \"speechless\", \"mute\", \"quiet\"] },\n { emoji: \"\\u{1FAE5}\", name: \"dotted_line_face\", keywords: [\"invisible\", \"hidden\", \"shy\", \"disappear\"] },\n { emoji: \"\\u{1F636}\\u{200D}\\u{1F32B}\\u{FE0F}\", name: \"face_in_clouds\", keywords: [\"dreamy\", \"foggy\", \"confused\", \"lost\"] },\n { emoji: \"\\u{1F60F}\", name: \"smirking_face\", keywords: [\"smirk\", \"smug\", \"sly\", \"flirt\", \"cocky\"] },\n { emoji: \"\\u{1F612}\", name: \"unamused_face\", keywords: [\"annoyed\", \"unimpressed\", \"bored\", \"meh\", \"dissatisfied\"] },\n { emoji: \"\\u{1F644}\", name: \"face_with_rolling_eyes\", keywords: [\"eyeroll\", \"annoyed\", \"whatever\", \"bored\", \"frustrated\"] },\n { emoji: \"\\u{1F62C}\", name: \"grimacing_face\", keywords: [\"grimace\", \"awkward\", \"nervous\", \"cringe\", \"teeth\"] },\n { emoji: \"\\u{1F62E}\\u{200D}\\u{1F4A8}\", name: \"face_exhaling\", keywords: [\"exhale\", \"sigh\", \"relief\", \"tired\", \"breath\"] },\n { emoji: \"\\u{1F925}\", name: \"lying_face\", keywords: [\"lie\", \"pinocchio\", \"dishonest\", \"liar\"] },\n { emoji: \"\\u{1F60C}\", name: \"relieved_face\", keywords: [\"relieved\", \"relaxed\", \"calm\", \"content\", \"peace\"] },\n { emoji: \"\\u{1F614}\", name: \"pensive_face\", keywords: [\"sad\", \"pensive\", \"thoughtful\", \"disappointed\"] },\n { emoji: \"\\u{1F62A}\", name: \"sleepy_face\", keywords: [\"sleepy\", \"tired\", \"exhausted\", \"rest\"] },\n { emoji: \"\\u{1F924}\", name: \"drooling_face\", keywords: [\"drool\", \"hungry\", \"yummy\", \"want\"] },\n { emoji: \"\\u{1F634}\", name: \"sleeping_face\", keywords: [\"sleep\", \"zzz\", \"tired\", \"rest\", \"nap\"] },\n { emoji: \"\\u{1F637}\", name: \"face_with_medical_mask\", keywords: [\"sick\", \"mask\", \"covid\", \"ill\", \"doctor\"] },\n { emoji: \"\\u{1F912}\", name: \"face_with_thermometer\", keywords: [\"sick\", \"fever\", \"ill\", \"temperature\"] },\n { emoji: \"\\u{1F915}\", name: \"face_with_head_bandage\", keywords: [\"hurt\", \"injured\", \"bandage\", \"pain\", \"clumsy\"] },\n { emoji: \"\\u{1F922}\", name: \"nauseated_face\", keywords: [\"sick\", \"nauseous\", \"green\", \"vomit\", \"gross\"] },\n { emoji: \"\\u{1F92E}\", name: \"face_vomiting\", keywords: [\"sick\", \"vomit\", \"gross\", \"disgusted\", \"puke\"] },\n { emoji: \"\\u{1F927}\", name: \"sneezing_face\", keywords: [\"sneeze\", \"cold\", \"sick\", \"tissue\", \"allergies\"] },\n { emoji: \"\\u{1F975}\", name: \"hot_face\", keywords: [\"hot\", \"heat\", \"sweat\", \"warm\", \"summer\"] },\n { emoji: \"\\u{1F976}\", name: \"cold_face\", keywords: [\"cold\", \"freeze\", \"winter\", \"ice\", \"brr\"] },\n { emoji: \"\\u{1F974}\", name: \"woozy_face\", keywords: [\"dizzy\", \"drunk\", \"tipsy\", \"woozy\", \"disoriented\"] },\n { emoji: \"\\u{1F635}\", name: \"face_with_crossed_out_eyes\", keywords: [\"dead\", \"dizzy\", \"knocked_out\", \"unconscious\"] },\n { emoji: \"\\u{1F92F}\", name: \"exploding_head\", keywords: [\"mind_blown\", \"shocked\", \"amazed\", \"explosion\", \"wow\"] },\n { emoji: \"\\u{1F920}\", name: \"cowboy_hat_face\", keywords: [\"cowboy\", \"western\", \"hat\", \"yeehaw\"] },\n { emoji: \"\\u{1F973}\", name: \"partying_face\", keywords: [\"party\", \"celebrate\", \"birthday\", \"fun\", \"confetti\"] },\n { emoji: \"\\u{1F978}\", name: \"disguised_face\", keywords: [\"disguise\", \"spy\", \"incognito\", \"glasses\", \"mustache\"] },\n { emoji: \"\\u{1F60E}\", name: \"smiling_face_with_sunglasses\", keywords: [\"cool\", \"sunglasses\", \"confident\", \"awesome\"] },\n { emoji: \"\\u{1F913}\", name: \"nerd_face\", keywords: [\"nerd\", \"geek\", \"smart\", \"glasses\", \"study\"] },\n { emoji: \"\\u{1F9D0}\", name: \"face_with_monocle\", keywords: [\"monocle\", \"classy\", \"skeptical\", \"inspect\", \"fancy\"] },\n { emoji: \"\\u{1F615}\", name: \"confused_face\", keywords: [\"confused\", \"puzzled\", \"lost\", \"unsure\"] },\n { emoji: \"\\u{1FAE4}\", name: \"face_with_diagonal_mouth\", keywords: [\"skeptical\", \"unsure\", \"meh\", \"hmm\"] },\n { emoji: \"\\u{1F61F}\", name: \"worried_face\", keywords: [\"worried\", \"nervous\", \"anxious\", \"concerned\"] },\n { emoji: \"\\u{1F641}\", name: \"slightly_frowning_face\", keywords: [\"sad\", \"frown\", \"disappointed\", \"unhappy\"] },\n { emoji: \"\\u{2639}\\u{FE0F}\", name: \"frowning_face\", keywords: [\"sad\", \"frown\", \"unhappy\", \"disappointed\"] },\n { emoji: \"\\u{1F62E}\", name: \"face_with_open_mouth\", keywords: [\"surprise\", \"shock\", \"wow\", \"gasp\"] },\n { emoji: \"\\u{1F62F}\", name: \"hushed_face\", keywords: [\"surprise\", \"shock\", \"stunned\", \"wow\"] },\n { emoji: \"\\u{1F632}\", name: \"astonished_face\", keywords: [\"astonished\", \"shocked\", \"amazed\", \"surprise\"] },\n { emoji: \"\\u{1F633}\", name: \"flushed_face\", keywords: [\"blush\", \"embarrassed\", \"shy\", \"flushed\"] },\n { emoji: \"\\u{1F97A}\", name: \"pleading_face\", keywords: [\"please\", \"puppy_eyes\", \"beg\", \"cute\", \"adorable\"] },\n { emoji: \"\\u{1F979}\", name: \"face_holding_back_tears\", keywords: [\"sad\", \"cry\", \"holding_back\", \"emotional\", \"proud\"] },\n { emoji: \"\\u{1F626}\", name: \"frowning_face_with_open_mouth\", keywords: [\"shock\", \"surprise\", \"anguish\"] },\n { emoji: \"\\u{1F627}\", name: \"anguished_face\", keywords: [\"anguish\", \"pain\", \"distress\", \"oh_no\"] },\n { emoji: \"\\u{1F628}\", name: \"fearful_face\", keywords: [\"fear\", \"scared\", \"shock\", \"terrified\"] },\n { emoji: \"\\u{1F630}\", name: \"anxious_face_with_sweat\", keywords: [\"anxious\", \"nervous\", \"sweat\", \"worried\"] },\n { emoji: \"\\u{1F625}\", name: \"sad_but_relieved_face\", keywords: [\"sad\", \"relieved\", \"disappointed\", \"phew\"] },\n { emoji: \"\\u{1F622}\", name: \"crying_face\", keywords: [\"cry\", \"sad\", \"tears\", \"upset\"] },\n { emoji: \"\\u{1F62D}\", name: \"loudly_crying_face\", keywords: [\"cry\", \"sob\", \"sad\", \"tears\", \"wail\"] },\n { emoji: \"\\u{1F631}\", name: \"face_screaming_in_fear\", keywords: [\"scream\", \"fear\", \"horror\", \"scared\", \"omg\"] },\n { emoji: \"\\u{1F616}\", name: \"confounded_face\", keywords: [\"confused\", \"frustrated\", \"quivering\"] },\n { emoji: \"\\u{1F623}\", name: \"persevering_face\", keywords: [\"persevere\", \"struggle\", \"frustrated\", \"endure\"] },\n { emoji: \"\\u{1F61E}\", name: \"disappointed_face\", keywords: [\"sad\", \"disappointed\", \"unhappy\", \"down\"] },\n { emoji: \"\\u{1F613}\", name: \"downcast_face_with_sweat\", keywords: [\"sad\", \"sweat\", \"tired\", \"hard_work\"] },\n { emoji: \"\\u{1F629}\", name: \"weary_face\", keywords: [\"weary\", \"tired\", \"exhausted\", \"frustrated\"] },\n { emoji: \"\\u{1F62B}\", name: \"tired_face\", keywords: [\"tired\", \"exhausted\", \"frustrated\", \"whine\"] },\n { emoji: \"\\u{1F971}\", name: \"yawning_face\", keywords: [\"yawn\", \"tired\", \"bored\", \"sleepy\"] },\n { emoji: \"\\u{1F624}\", name: \"face_with_steam_from_nose\", keywords: [\"angry\", \"frustrated\", \"huffing\", \"triumph\"] },\n { emoji: \"\\u{1F621}\", name: \"pouting_face\", keywords: [\"angry\", \"mad\", \"rage\", \"furious\", \"red\"] },\n { emoji: \"\\u{1F620}\", name: \"angry_face\", keywords: [\"angry\", \"mad\", \"annoyed\", \"grumpy\"] },\n { emoji: \"\\u{1F92C}\", name: \"face_with_symbols_on_mouth\", keywords: [\"swear\", \"cursing\", \"angry\", \"expletive\"] },\n { emoji: \"\\u{1F608}\", name: \"smiling_face_with_horns\", keywords: [\"devil\", \"evil\", \"mischief\", \"naughty\"] },\n { emoji: \"\\u{1F47F}\", name: \"angry_face_with_horns\", keywords: [\"devil\", \"evil\", \"angry\", \"demon\"] },\n { emoji: \"\\u{1F480}\", name: \"skull\", keywords: [\"death\", \"dead\", \"skeleton\", \"danger\", \"dying_laughing\"] },\n { emoji: \"\\u{2620}\\u{FE0F}\", name: \"skull_and_crossbones\", keywords: [\"death\", \"danger\", \"poison\", \"pirate\"] },\n { emoji: \"\\u{1F4A9}\", name: \"pile_of_poo\", keywords: [\"poop\", \"shit\", \"crap\", \"funny\"] },\n { emoji: \"\\u{1F921}\", name: \"clown_face\", keywords: [\"clown\", \"funny\", \"silly\", \"joke\", \"circus\"] },\n { emoji: \"\\u{1F47B}\", name: \"ghost\", keywords: [\"ghost\", \"halloween\", \"spooky\", \"scary\", \"boo\"] },\n { emoji: \"\\u{1F47D}\", name: \"alien\", keywords: [\"alien\", \"space\", \"ufo\", \"extraterrestrial\"] },\n { emoji: \"\\u{1F916}\", name: \"robot\", keywords: [\"robot\", \"bot\", \"machine\", \"ai\", \"technology\"] },\n { emoji: \"\\u{1F63A}\", name: \"grinning_cat\", keywords: [\"cat\", \"happy\", \"smile\", \"grin\"] },\n { emoji: \"\\u{1F639}\", name: \"cat_with_tears_of_joy\", keywords: [\"cat\", \"laugh\", \"happy\", \"tears\"] },\n { emoji: \"\\u{1F63B}\", name: \"smiling_cat_with_heart_eyes\", keywords: [\"cat\", \"love\", \"heart\", \"adore\"] },\n { emoji: \"\\u{1F63D}\", name: \"kissing_cat\", keywords: [\"cat\", \"kiss\", \"love\", \"affection\"] },\n { emoji: \"\\u{1F640}\", name: \"weary_cat\", keywords: [\"cat\", \"weary\", \"shocked\", \"scared\"] },\n { emoji: \"\\u{1F63F}\", name: \"crying_cat\", keywords: [\"cat\", \"cry\", \"sad\", \"tears\"] },\n { emoji: \"\\u{1F63E}\", name: \"pouting_cat\", keywords: [\"cat\", \"angry\", \"pout\", \"grumpy\"] },\n { emoji: \"\\u{1FAE1}\", name: \"saluting_face\", keywords: [\"salute\", \"respect\", \"yes_sir\", \"honor\"] },\n { emoji: \"\\u{1FAE8}\", name: \"shaking_face\", keywords: [\"shake\", \"shock\", \"earthquake\", \"vibrate\"] },\n\n { emoji: \"\\u{1F44D}\", name: \"thumbs_up\", keywords: [\"thumbsup\", \"yes\", \"approve\", \"good\", \"like\", \"ok\"] },\n { emoji: \"\\u{1F44E}\", name: \"thumbs_down\", keywords: [\"thumbsdown\", \"no\", \"dislike\", \"bad\", \"disapprove\"] },\n { emoji: \"\\u{1F44F}\", name: \"clapping_hands\", keywords: [\"clap\", \"applause\", \"bravo\", \"congratulations\", \"well_done\"] },\n { emoji: \"\\u{1F64C}\", name: \"raising_hands\", keywords: [\"celebrate\", \"hooray\", \"praise\", \"hallelujah\", \"yay\"] },\n { emoji: \"\\u{1F44B}\", name: \"waving_hand\", keywords: [\"wave\", \"hello\", \"hi\", \"bye\", \"goodbye\", \"greet\"] },\n { emoji: \"\\u{1F91A}\", name: \"raised_back_of_hand\", keywords: [\"hand\", \"backhand\", \"raised\", \"stop\"] },\n { emoji: \"\\u{1F590}\\u{FE0F}\", name: \"hand_with_fingers_splayed\", keywords: [\"hand\", \"fingers\", \"high_five\", \"stop\", \"five\"] },\n { emoji: \"\\u{270B}\", name: \"raised_hand\", keywords: [\"hand\", \"stop\", \"high_five\", \"halt\"] },\n { emoji: \"\\u{1F596}\", name: \"vulcan_salute\", keywords: [\"spock\", \"star_trek\", \"vulcan\", \"live_long\"] },\n { emoji: \"\\u{1FAF1}\", name: \"rightwards_hand\", keywords: [\"hand\", \"right\", \"point\", \"direction\"] },\n { emoji: \"\\u{1FAF2}\", name: \"leftwards_hand\", keywords: [\"hand\", \"left\", \"point\", \"direction\"] },\n { emoji: \"\\u{1FAF3}\", name: \"palm_down_hand\", keywords: [\"hand\", \"down\", \"lower\", \"calm\"] },\n { emoji: \"\\u{1FAF4}\", name: \"palm_up_hand\", keywords: [\"hand\", \"up\", \"offer\", \"present\", \"beckon\"] },\n { emoji: \"\\u{1F44C}\", name: \"ok_hand\", keywords: [\"ok\", \"perfect\", \"fine\", \"good\", \"nice\", \"chef_kiss\"] },\n { emoji: \"\\u{1F90C}\", name: \"pinched_fingers\", keywords: [\"italian\", \"gesture\", \"what\", \"perfetto\"] },\n { emoji: \"\\u{1F90F}\", name: \"pinching_hand\", keywords: [\"small\", \"tiny\", \"little\", \"pinch\"] },\n { emoji: \"\\u{270C}\\u{FE0F}\", name: \"victory_hand\", keywords: [\"peace\", \"victory\", \"two\", \"v\"] },\n { emoji: \"\\u{1F91E}\", name: \"crossed_fingers\", keywords: [\"luck\", \"hope\", \"fingers_crossed\", \"wish\"] },\n { emoji: \"\\u{1FAF0}\", name: \"hand_with_index_finger_and_thumb_crossed\", keywords: [\"money\", \"snap\", \"love\", \"heart\"] },\n { emoji: \"\\u{1F91F}\", name: \"love_you_gesture\", keywords: [\"love\", \"ily\", \"rock\", \"sign_language\"] },\n { emoji: \"\\u{1F918}\", name: \"sign_of_the_horns\", keywords: [\"rock\", \"metal\", \"horns\", \"devil\"] },\n { emoji: \"\\u{1F919}\", name: \"call_me_hand\", keywords: [\"call\", \"shaka\", \"hang_loose\", \"phone\"] },\n { emoji: \"\\u{1F448}\", name: \"backhand_index_pointing_left\", keywords: [\"left\", \"point\", \"direction\", \"this\"] },\n { emoji: \"\\u{1F449}\", name: \"backhand_index_pointing_right\", keywords: [\"right\", \"point\", \"direction\", \"this\"] },\n { emoji: \"\\u{1F446}\", name: \"backhand_index_pointing_up\", keywords: [\"up\", \"point\", \"above\", \"this\"] },\n { emoji: \"\\u{1F447}\", name: \"backhand_index_pointing_down\", keywords: [\"down\", \"point\", \"below\", \"this\"] },\n { emoji: \"\\u{261D}\\u{FE0F}\", name: \"index_pointing_up\", keywords: [\"up\", \"point\", \"one\", \"first\", \"attention\"] },\n { emoji: \"\\u{1FAF5}\", name: \"index_pointing_at_the_viewer\", keywords: [\"point\", \"you\", \"hey\", \"pick\"] },\n { emoji: \"\\u{1F4AA}\", name: \"flexed_biceps\", keywords: [\"strong\", \"muscle\", \"flex\", \"power\", \"workout\"] },\n { emoji: \"\\u{1F9BE}\", name: \"mechanical_arm\", keywords: [\"prosthetic\", \"robot\", \"arm\", \"mechanical\"] },\n { emoji: \"\\u{1F64F}\", name: \"folded_hands\", keywords: [\"pray\", \"please\", \"thank_you\", \"hope\", \"namaste\", \"high_five\"] },\n { emoji: \"\\u{1F91D}\", name: \"handshake\", keywords: [\"handshake\", \"deal\", \"agree\", \"meeting\", \"greeting\"] },\n { emoji: \"\\u{1F91B}\", name: \"left_facing_fist\", keywords: [\"fist\", \"bump\", \"punch\", \"left\"] },\n { emoji: \"\\u{1F91C}\", name: \"right_facing_fist\", keywords: [\"fist\", \"bump\", \"punch\", \"right\"] },\n { emoji: \"\\u{1F44A}\", name: \"oncoming_fist\", keywords: [\"fist\", \"punch\", \"bump\", \"attack\"] },\n { emoji: \"\\u{270D}\\u{FE0F}\", name: \"writing_hand\", keywords: [\"write\", \"pen\", \"note\", \"compose\"] },\n { emoji: \"\\u{1F485}\", name: \"nail_polish\", keywords: [\"nails\", \"beauty\", \"manicure\", \"fabulous\", \"sassy\"] },\n { emoji: \"\\u{1F933}\", name: \"selfie\", keywords: [\"selfie\", \"phone\", \"camera\", \"photo\"] },\n { emoji: \"\\u{1F926}\", name: \"person_facepalming\", keywords: [\"facepalm\", \"frustrated\", \"disappointed\", \"smh\"] },\n { emoji: \"\\u{1F937}\", name: \"person_shrugging\", keywords: [\"shrug\", \"dunno\", \"idk\", \"whatever\", \"who_knows\"] },\n { emoji: \"\\u{1F645}\", name: \"person_gesturing_no\", keywords: [\"no\", \"stop\", \"forbidden\", \"not_allowed\"] },\n { emoji: \"\\u{1F646}\", name: \"person_gesturing_ok\", keywords: [\"ok\", \"yes\", \"approve\", \"all_good\"] },\n { emoji: \"\\u{1F64B}\", name: \"person_raising_hand\", keywords: [\"hand\", \"raise\", \"question\", \"volunteer\", \"me\"] },\n { emoji: \"\\u{1F647}\", name: \"person_bowing\", keywords: [\"bow\", \"respect\", \"sorry\", \"thank_you\", \"namaste\"] },\n { emoji: \"\\u{1FAF6}\", name: \"heart_hands\", keywords: [\"heart\", \"hands\", \"love\", \"gesture\", \"appreciate\"] },\n { emoji: \"\\u{1F9B5}\", name: \"leg\", keywords: [\"leg\", \"kick\", \"limb\"] },\n { emoji: \"\\u{1F9B6}\", name: \"foot\", keywords: [\"foot\", \"kick\", \"stomp\"] },\n { emoji: \"\\u{1F9B7}\", name: \"tooth\", keywords: [\"tooth\", \"dentist\", \"teeth\"] },\n { emoji: \"\\u{1F9B4}\", name: \"bone\", keywords: [\"bone\", \"skeleton\", \"body\"] },\n { emoji: \"\\u{1F440}\", name: \"eyes\", keywords: [\"eyes\", \"look\", \"see\", \"watch\", \"stare\", \"peek\"] },\n { emoji: \"\\u{1F441}\\u{FE0F}\", name: \"eye\", keywords: [\"eye\", \"look\", \"see\", \"vision\"] },\n { emoji: \"\\u{1F442}\", name: \"ear\", keywords: [\"ear\", \"hear\", \"listen\", \"sound\"] },\n { emoji: \"\\u{1F443}\", name: \"nose\", keywords: [\"nose\", \"smell\", \"sniff\"] },\n { emoji: \"\\u{1F444}\", name: \"mouth\", keywords: [\"mouth\", \"lips\", \"kiss\"] },\n { emoji: \"\\u{1F445}\", name: \"tongue\", keywords: [\"tongue\", \"taste\", \"lick\"] },\n { emoji: \"\\u{1F9E0}\", name: \"brain\", keywords: [\"brain\", \"smart\", \"think\", \"mind\", \"intelligence\"] },\n { emoji: \"\\u{1FAC0}\", name: \"anatomical_heart\", keywords: [\"heart\", \"organ\", \"medical\", \"body\"] },\n { emoji: \"\\u{1FAC1}\", name: \"lungs\", keywords: [\"lungs\", \"breathe\", \"organ\", \"body\"] },\n { emoji: \"\\u{1F476}\", name: \"baby\", keywords: [\"baby\", \"child\", \"infant\", \"newborn\"] },\n { emoji: \"\\u{1F466}\", name: \"boy\", keywords: [\"boy\", \"child\", \"male\", \"kid\"] },\n { emoji: \"\\u{1F467}\", name: \"girl\", keywords: [\"girl\", \"child\", \"female\", \"kid\"] },\n { emoji: \"\\u{1F468}\", name: \"man\", keywords: [\"man\", \"male\", \"adult\", \"person\"] },\n { emoji: \"\\u{1F469}\", name: \"woman\", keywords: [\"woman\", \"female\", \"adult\", \"person\"] },\n { emoji: \"\\u{1F474}\", name: \"old_man\", keywords: [\"old\", \"man\", \"elderly\", \"grandpa\"] },\n { emoji: \"\\u{1F475}\", name: \"old_woman\", keywords: [\"old\", \"woman\", \"elderly\", \"grandma\"] },\n { emoji: \"\\u{1F9D1}\\u{200D}\\u{1F4BB}\", name: \"technologist\", keywords: [\"developer\", \"programmer\", \"coder\", \"computer\", \"tech\"] },\n { emoji: \"\\u{1F9D1}\\u{200D}\\u{1F3A8}\", name: \"artist\", keywords: [\"artist\", \"painter\", \"creative\", \"art\"] },\n { emoji: \"\\u{1F9D1}\\u{200D}\\u{1F52C}\", name: \"scientist\", keywords: [\"scientist\", \"research\", \"lab\", \"science\"] },\n { emoji: \"\\u{1F9D1}\\u{200D}\\u{1F680}\", name: \"astronaut\", keywords: [\"astronaut\", \"space\", \"rocket\", \"nasa\"] },\n { emoji: \"\\u{1F9D1}\\u{200D}\\u{1F692}\", name: \"firefighter\", keywords: [\"firefighter\", \"fire\", \"rescue\", \"emergency\"] },\n { emoji: \"\\u{1F9D1}\\u{200D}\\u{2696}\\u{FE0F}\", name: \"judge\", keywords: [\"judge\", \"law\", \"court\", \"justice\"] },\n { emoji: \"\\u{1F9D1}\\u{200D}\\u{1F3EB}\", name: \"teacher\", keywords: [\"teacher\", \"school\", \"education\", \"professor\"] },\n { emoji: \"\\u{1F9D1}\\u{200D}\\u{1F373}\", name: \"cook\", keywords: [\"cook\", \"chef\", \"food\", \"kitchen\"] },\n\n { emoji: \"\\u{2764}\\u{FE0F}\", name: \"red_heart\", keywords: [\"love\", \"heart\", \"red\", \"romance\", \"like\", \"valentines\"] },\n { emoji: \"\\u{1F9E1}\", name: \"orange_heart\", keywords: [\"love\", \"heart\", \"orange\", \"warm\"] },\n { emoji: \"\\u{1F49B}\", name: \"yellow_heart\", keywords: [\"love\", \"heart\", \"yellow\", \"friendship\"] },\n { emoji: \"\\u{1F49A}\", name: \"green_heart\", keywords: [\"love\", \"heart\", \"green\", \"nature\", \"envy\"] },\n { emoji: \"\\u{1F499}\", name: \"blue_heart\", keywords: [\"love\", \"heart\", \"blue\", \"trust\", \"calm\"] },\n { emoji: \"\\u{1F49C}\", name: \"purple_heart\", keywords: [\"love\", \"heart\", \"purple\", \"honor\"] },\n { emoji: \"\\u{1F90E}\", name: \"brown_heart\", keywords: [\"love\", \"heart\", \"brown\", \"earth\"] },\n { emoji: \"\\u{1F5A4}\", name: \"black_heart\", keywords: [\"love\", \"heart\", \"black\", \"dark\", \"evil\", \"goth\"] },\n { emoji: \"\\u{1FA76}\", name: \"light_blue_heart\", keywords: [\"love\", \"heart\", \"light_blue\", \"sky\"] },\n { emoji: \"\\u{1FA77}\", name: \"pink_heart\", keywords: [\"love\", \"heart\", \"pink\", \"cute\", \"romance\"] },\n { emoji: \"\\u{1FA75}\", name: \"grey_heart\", keywords: [\"love\", \"heart\", \"grey\", \"gray\", \"neutral\"] },\n { emoji: \"\\u{1F90D}\", name: \"white_heart\", keywords: [\"love\", \"heart\", \"white\", \"pure\", \"clean\"] },\n { emoji: \"\\u{1F494}\", name: \"broken_heart\", keywords: [\"heartbreak\", \"sad\", \"breakup\", \"loss\", \"pain\"] },\n { emoji: \"\\u{2764}\\u{FE0F}\\u{200D}\\u{1F525}\", name: \"heart_on_fire\", keywords: [\"love\", \"passion\", \"fire\", \"desire\"] },\n { emoji: \"\\u{2764}\\u{FE0F}\\u{200D}\\u{1FA79}\", name: \"mending_heart\", keywords: [\"heart\", \"heal\", \"recover\", \"bandage\"] },\n { emoji: \"\\u{1F496}\", name: \"sparkling_heart\", keywords: [\"love\", \"sparkle\", \"heart\", \"shine\", \"cute\"] },\n { emoji: \"\\u{1F497}\", name: \"growing_heart\", keywords: [\"love\", \"heart\", \"growing\", \"bigger\"] },\n { emoji: \"\\u{1F493}\", name: \"beating_heart\", keywords: [\"love\", \"heart\", \"beat\", \"pulse\", \"alive\"] },\n { emoji: \"\\u{1F49E}\", name: \"revolving_hearts\", keywords: [\"love\", \"hearts\", \"revolving\", \"romance\"] },\n { emoji: \"\\u{1F495}\", name: \"two_hearts\", keywords: [\"love\", \"hearts\", \"pair\", \"romance\"] },\n { emoji: \"\\u{1F48C}\", name: \"love_letter\", keywords: [\"letter\", \"love\", \"mail\", \"romance\", \"envelope\"] },\n { emoji: \"\\u{1F48B}\", name: \"kiss_mark\", keywords: [\"kiss\", \"lips\", \"love\", \"smooch\"] },\n { emoji: \"\\u{1F48D}\", name: \"ring\", keywords: [\"ring\", \"engagement\", \"wedding\", \"marriage\", \"diamond\"] },\n { emoji: \"\\u{1F490}\", name: \"bouquet\", keywords: [\"flowers\", \"bouquet\", \"romance\", \"gift\", \"love\"] },\n\n { emoji: \"\\u{1F436}\", name: \"dog_face\", keywords: [\"dog\", \"puppy\", \"pet\", \"animal\", \"cute\", \"woof\"] },\n { emoji: \"\\u{1F431}\", name: \"cat_face\", keywords: [\"cat\", \"kitten\", \"pet\", \"animal\", \"cute\", \"meow\"] },\n { emoji: \"\\u{1F42D}\", name: \"mouse_face\", keywords: [\"mouse\", \"rodent\", \"animal\", \"small\"] },\n { emoji: \"\\u{1F439}\", name: \"hamster\", keywords: [\"hamster\", \"pet\", \"animal\", \"cute\"] },\n { emoji: \"\\u{1F430}\", name: \"rabbit_face\", keywords: [\"rabbit\", \"bunny\", \"animal\", \"cute\", \"easter\"] },\n { emoji: \"\\u{1F43B}\", name: \"bear\", keywords: [\"bear\", \"animal\", \"nature\", \"grizzly\"] },\n { emoji: \"\\u{1F43C}\", name: \"panda\", keywords: [\"panda\", \"bear\", \"animal\", \"cute\", \"bamboo\"] },\n { emoji: \"\\u{1F428}\", name: \"koala\", keywords: [\"koala\", \"animal\", \"australia\", \"cute\"] },\n { emoji: \"\\u{1F42F}\", name: \"tiger_face\", keywords: [\"tiger\", \"animal\", \"cat\", \"wild\", \"fierce\"] },\n { emoji: \"\\u{1F981}\", name: \"lion\", keywords: [\"lion\", \"animal\", \"king\", \"wild\", \"roar\"] },\n { emoji: \"\\u{1F42E}\", name: \"cow_face\", keywords: [\"cow\", \"animal\", \"farm\", \"moo\"] },\n { emoji: \"\\u{1F437}\", name: \"pig_face\", keywords: [\"pig\", \"animal\", \"farm\", \"oink\"] },\n { emoji: \"\\u{1F438}\", name: \"frog\", keywords: [\"frog\", \"animal\", \"toad\", \"ribbit\"] },\n { emoji: \"\\u{1F435}\", name: \"monkey_face\", keywords: [\"monkey\", \"animal\", \"primate\", \"ape\"] },\n { emoji: \"\\u{1F648}\", name: \"see_no_evil_monkey\", keywords: [\"monkey\", \"see_no_evil\", \"shy\", \"oops\"] },\n { emoji: \"\\u{1F649}\", name: \"hear_no_evil_monkey\", keywords: [\"monkey\", \"hear_no_evil\", \"ignore\"] },\n { emoji: \"\\u{1F64A}\", name: \"speak_no_evil_monkey\", keywords: [\"monkey\", \"speak_no_evil\", \"secret\", \"quiet\"] },\n { emoji: \"\\u{1F414}\", name: \"chicken\", keywords: [\"chicken\", \"bird\", \"poultry\", \"farm\", \"hen\"] },\n { emoji: \"\\u{1F427}\", name: \"penguin\", keywords: [\"penguin\", \"bird\", \"animal\", \"cold\", \"arctic\"] },\n { emoji: \"\\u{1F426}\", name: \"bird\", keywords: [\"bird\", \"animal\", \"fly\", \"tweet\", \"chirp\"] },\n { emoji: \"\\u{1F985}\", name: \"eagle\", keywords: [\"eagle\", \"bird\", \"america\", \"freedom\", \"majestic\"] },\n { emoji: \"\\u{1F98B}\", name: \"butterfly\", keywords: [\"butterfly\", \"insect\", \"nature\", \"beautiful\", \"spring\"] },\n { emoji: \"\\u{1F41B}\", name: \"bug\", keywords: [\"bug\", \"insect\", \"caterpillar\", \"nature\"] },\n { emoji: \"\\u{1F41D}\", name: \"honeybee\", keywords: [\"bee\", \"insect\", \"honey\", \"buzz\", \"sting\"] },\n { emoji: \"\\u{1F422}\", name: \"turtle\", keywords: [\"turtle\", \"tortoise\", \"slow\", \"animal\", \"shell\"] },\n { emoji: \"\\u{1F40D}\", name: \"snake\", keywords: [\"snake\", \"reptile\", \"animal\", \"slither\"] },\n { emoji: \"\\u{1F433}\", name: \"spouting_whale\", keywords: [\"whale\", \"ocean\", \"sea\", \"animal\", \"water\"] },\n { emoji: \"\\u{1F42C}\", name: \"dolphin\", keywords: [\"dolphin\", \"ocean\", \"sea\", \"animal\", \"smart\"] },\n { emoji: \"\\u{1F41F}\", name: \"fish\", keywords: [\"fish\", \"ocean\", \"sea\", \"animal\", \"swim\"] },\n { emoji: \"\\u{1F419}\", name: \"octopus\", keywords: [\"octopus\", \"ocean\", \"sea\", \"tentacle\"] },\n { emoji: \"\\u{1F40C}\", name: \"snail\", keywords: [\"snail\", \"slow\", \"animal\", \"shell\"] },\n { emoji: \"\\u{1F984}\", name: \"unicorn\", keywords: [\"unicorn\", \"fantasy\", \"magical\", \"horse\", \"rainbow\"] },\n { emoji: \"\\u{1F409}\", name: \"dragon\", keywords: [\"dragon\", \"fantasy\", \"fire\", \"mythical\"] },\n { emoji: \"\\u{1FAB7}\", name: \"jellyfish\", keywords: [\"jellyfish\", \"ocean\", \"sea\", \"sting\", \"tentacle\"] },\n { emoji: \"\\u{1FACE}\", name: \"moose\", keywords: [\"moose\", \"animal\", \"elk\", \"antlers\"] },\n { emoji: \"\\u{1FACF}\", name: \"donkey\", keywords: [\"donkey\", \"animal\", \"mule\", \"burro\"] },\n { emoji: \"\\u{1FABF}\", name: \"goose\", keywords: [\"goose\", \"bird\", \"honk\", \"animal\"] },\n { emoji: \"\\u{1F426}\\u{200D}\\u{1F525}\", name: \"phoenix\", keywords: [\"phoenix\", \"bird\", \"fire\", \"mythical\", \"rebirth\"] },\n { emoji: \"\\u{1F9A5}\", name: \"sloth\", keywords: [\"sloth\", \"animal\", \"slow\", \"lazy\", \"cute\"] },\n { emoji: \"\\u{1F9A6}\", name: \"otter\", keywords: [\"otter\", \"animal\", \"cute\", \"water\", \"playful\"] },\n { emoji: \"\\u{1F9A7}\", name: \"orangutan\", keywords: [\"orangutan\", \"animal\", \"primate\", \"ape\"] },\n { emoji: \"\\u{1F99D}\", name: \"raccoon\", keywords: [\"raccoon\", \"animal\", \"trash_panda\", \"cute\"] },\n { emoji: \"\\u{1F999}\", name: \"llama\", keywords: [\"llama\", \"animal\", \"alpaca\", \"wool\"] },\n { emoji: \"\\u{1F9A9}\", name: \"flamingo\", keywords: [\"flamingo\", \"bird\", \"pink\", \"tropical\"] },\n { emoji: \"\\u{1F99A}\", name: \"peacock\", keywords: [\"peacock\", \"bird\", \"feathers\", \"beautiful\"] },\n { emoji: \"\\u{1F99C}\", name: \"parrot\", keywords: [\"parrot\", \"bird\", \"tropical\", \"talk\", \"colorful\"] },\n { emoji: \"\\u{1F99E}\", name: \"lobster\", keywords: [\"lobster\", \"seafood\", \"ocean\", \"crab\", \"food\"] },\n { emoji: \"\\u{1F99F}\", name: \"mosquito\", keywords: [\"mosquito\", \"bug\", \"insect\", \"bite\"] },\n { emoji: \"\\u{1FAB6}\", name: \"feather\", keywords: [\"feather\", \"bird\", \"light\", \"write\", \"quill\"] },\n { emoji: \"\\u{1FAB8}\", name: \"coral\", keywords: [\"coral\", \"ocean\", \"reef\", \"sea\", \"nature\"] },\n { emoji: \"\\u{1F40E}\", name: \"horse\", keywords: [\"horse\", \"animal\", \"ride\", \"equestrian\", \"racing\"] },\n { emoji: \"\\u{1F98A}\", name: \"fox\", keywords: [\"fox\", \"animal\", \"clever\", \"wild\", \"cute\"] },\n { emoji: \"\\u{1F98E}\", name: \"lizard\", keywords: [\"lizard\", \"reptile\", \"animal\", \"gecko\"] },\n { emoji: \"\\u{1F98D}\", name: \"gorilla\", keywords: [\"gorilla\", \"animal\", \"primate\", \"ape\", \"strong\"] },\n { emoji: \"\\u{1F98C}\", name: \"deer\", keywords: [\"deer\", \"animal\", \"nature\", \"bambi\", \"doe\"] },\n { emoji: \"\\u{1F40A}\", name: \"crocodile\", keywords: [\"crocodile\", \"alligator\", \"reptile\", \"animal\"] },\n { emoji: \"\\u{1F988}\", name: \"shark\", keywords: [\"shark\", \"ocean\", \"fish\", \"jaws\", \"predator\"] },\n { emoji: \"\\u{1F989}\", name: \"owl\", keywords: [\"owl\", \"bird\", \"night\", \"wise\", \"hoot\"] },\n { emoji: \"\\u{1F98F}\", name: \"rhinoceros\", keywords: [\"rhino\", \"animal\", \"horn\", \"wild\"] },\n { emoji: \"\\u{1F992}\", name: \"giraffe\", keywords: [\"giraffe\", \"animal\", \"tall\", \"africa\", \"spots\"] },\n { emoji: \"\\u{1F993}\", name: \"zebra\", keywords: [\"zebra\", \"animal\", \"stripes\", \"africa\"] },\n { emoji: \"\\u{1F994}\", name: \"hedgehog\", keywords: [\"hedgehog\", \"animal\", \"spiny\", \"cute\"] },\n { emoji: \"\\u{1F995}\", name: \"sauropod\", keywords: [\"dinosaur\", \"sauropod\", \"extinct\", \"prehistoric\"] },\n { emoji: \"\\u{1F996}\", name: \"t_rex\", keywords: [\"dinosaur\", \"trex\", \"extinct\", \"prehistoric\", \"rawr\"] },\n { emoji: \"\\u{1F40B}\", name: \"whale\", keywords: [\"whale\", \"ocean\", \"animal\", \"sea\", \"big\"] },\n { emoji: \"\\u{1F418}\", name: \"elephant\", keywords: [\"elephant\", \"animal\", \"big\", \"africa\", \"trunk\"] },\n { emoji: \"\\u{1F417}\", name: \"boar\", keywords: [\"boar\", \"pig\", \"wild\", \"animal\"] },\n { emoji: \"\\u{1F412}\", name: \"monkey\", keywords: [\"monkey\", \"animal\", \"primate\", \"fun\"] },\n { emoji: \"\\u{1F40F}\", name: \"ram\", keywords: [\"ram\", \"sheep\", \"animal\", \"zodiac\", \"aries\"] },\n { emoji: \"\\u{1F410}\", name: \"goat\", keywords: [\"goat\", \"animal\", \"greatest\", \"goat_emoji\"] },\n { emoji: \"\\u{1F415}\", name: \"dog\", keywords: [\"dog\", \"pet\", \"animal\", \"puppy\", \"faithful\"] },\n { emoji: \"\\u{1F408}\", name: \"cat\", keywords: [\"cat\", \"pet\", \"animal\", \"kitty\"] },\n { emoji: \"\\u{1F335}\", name: \"cactus\", keywords: [\"cactus\", \"plant\", \"desert\", \"nature\"] },\n { emoji: \"\\u{1F332}\", name: \"evergreen_tree\", keywords: [\"tree\", \"pine\", \"nature\", \"forest\", \"christmas\"] },\n { emoji: \"\\u{1F333}\", name: \"deciduous_tree\", keywords: [\"tree\", \"nature\", \"forest\", \"park\"] },\n { emoji: \"\\u{1F334}\", name: \"palm_tree\", keywords: [\"palm\", \"tree\", \"beach\", \"tropical\", \"vacation\"] },\n { emoji: \"\\u{1F33B}\", name: \"sunflower\", keywords: [\"flower\", \"sunflower\", \"nature\", \"yellow\", \"sun\"] },\n { emoji: \"\\u{1F339}\", name: \"rose\", keywords: [\"flower\", \"rose\", \"love\", \"romance\", \"red\", \"beauty\"] },\n { emoji: \"\\u{1F33A}\", name: \"hibiscus\", keywords: [\"flower\", \"hibiscus\", \"tropical\", \"nature\", \"beautiful\"] },\n { emoji: \"\\u{1F337}\", name: \"tulip\", keywords: [\"flower\", \"tulip\", \"spring\", \"nature\", \"beauty\"] },\n { emoji: \"\\u{1F338}\", name: \"cherry_blossom\", keywords: [\"flower\", \"blossom\", \"cherry\", \"spring\", \"japan\"] },\n { emoji: \"\\u{1F340}\", name: \"four_leaf_clover\", keywords: [\"clover\", \"luck\", \"lucky\", \"nature\", \"irish\"] },\n { emoji: \"\\u{1F341}\", name: \"maple_leaf\", keywords: [\"leaf\", \"maple\", \"fall\", \"autumn\", \"canada\"] },\n { emoji: \"\\u{1F343}\", name: \"leaf_fluttering_in_wind\", keywords: [\"leaf\", \"wind\", \"nature\", \"fall\", \"breeze\"] },\n { emoji: \"\\u{1F331}\", name: \"seedling\", keywords: [\"seedling\", \"plant\", \"grow\", \"sprout\", \"nature\", \"new\"] },\n { emoji: \"\\u{1FAB4}\", name: \"potted_plant\", keywords: [\"plant\", \"pot\", \"houseplant\", \"nature\", \"green\", \"grow\"] },\n { emoji: \"\\u{1F33E}\", name: \"sheaf_of_rice\", keywords: [\"rice\", \"grain\", \"harvest\", \"crop\", \"nature\"] },\n { emoji: \"\\u{1F33F}\", name: \"herb\", keywords: [\"herb\", \"leaf\", \"green\", \"plant\", \"nature\"] },\n { emoji: \"\\u{2618}\\u{FE0F}\", name: \"shamrock\", keywords: [\"shamrock\", \"clover\", \"irish\", \"luck\", \"green\"] },\n { emoji: \"\\u{1FAB9}\", name: \"empty_nest\", keywords: [\"nest\", \"empty\", \"bird\", \"home\"] },\n { emoji: \"\\u{1FABA}\", name: \"nest_with_eggs\", keywords: [\"nest\", \"eggs\", \"bird\", \"home\", \"family\"] },\n { emoji: \"\\u{1FAB5}\", name: \"wood\", keywords: [\"wood\", \"log\", \"lumber\", \"timber\", \"nature\"] },\n\n { emoji: \"\\u{2600}\\u{FE0F}\", name: \"sun\", keywords: [\"sun\", \"sunny\", \"weather\", \"hot\", \"bright\", \"summer\"] },\n { emoji: \"\\u{1F324}\\u{FE0F}\", name: \"sun_behind_small_cloud\", keywords: [\"sun\", \"cloud\", \"partly_cloudy\", \"weather\"] },\n { emoji: \"\\u{26C5}\", name: \"sun_behind_cloud\", keywords: [\"sun\", \"cloud\", \"partly_cloudy\", \"weather\"] },\n { emoji: \"\\u{2601}\\u{FE0F}\", name: \"cloud\", keywords: [\"cloud\", \"weather\", \"overcast\", \"sky\"] },\n { emoji: \"\\u{1F327}\\u{FE0F}\", name: \"cloud_with_rain\", keywords: [\"rain\", \"cloud\", \"weather\", \"rainy\"] },\n { emoji: \"\\u{26C8}\\u{FE0F}\", name: \"cloud_with_lightning_and_rain\", keywords: [\"storm\", \"thunder\", \"lightning\", \"rain\"] },\n { emoji: \"\\u{1F329}\\u{FE0F}\", name: \"cloud_with_lightning\", keywords: [\"lightning\", \"thunder\", \"storm\", \"weather\"] },\n { emoji: \"\\u{2744}\\u{FE0F}\", name: \"snowflake\", keywords: [\"snow\", \"cold\", \"winter\", \"ice\", \"freeze\"] },\n { emoji: \"\\u{1F328}\\u{FE0F}\", name: \"cloud_with_snow\", keywords: [\"snow\", \"cloud\", \"weather\", \"winter\", \"cold\"] },\n { emoji: \"\\u{1F308}\", name: \"rainbow\", keywords: [\"rainbow\", \"weather\", \"colorful\", \"pride\", \"arc\"] },\n { emoji: \"\\u{2B50}\", name: \"star\", keywords: [\"star\", \"night\", \"sky\", \"yellow\", \"favorite\"] },\n { emoji: \"\\u{1F31F}\", name: \"glowing_star\", keywords: [\"star\", \"glow\", \"sparkle\", \"shine\", \"awesome\"] },\n { emoji: \"\\u{1F319}\", name: \"crescent_moon\", keywords: [\"moon\", \"crescent\", \"night\", \"sky\", \"sleep\"] },\n { emoji: \"\\u{1F31E}\", name: \"sun_with_face\", keywords: [\"sun\", \"face\", \"happy\", \"warm\", \"morning\"] },\n { emoji: \"\\u{1F31D}\", name: \"full_moon_face\", keywords: [\"moon\", \"face\", \"full\", \"night\", \"creepy\"] },\n { emoji: \"\\u{1F525}\", name: \"fire\", keywords: [\"fire\", \"flame\", \"hot\", \"lit\", \"burn\", \"trending\"] },\n { emoji: \"\\u{1F4A7}\", name: \"droplet\", keywords: [\"water\", \"drop\", \"sweat\", \"rain\", \"tear\"] },\n { emoji: \"\\u{1F30A}\", name: \"water_wave\", keywords: [\"wave\", \"water\", \"ocean\", \"sea\", \"surf\"] },\n\n { emoji: \"\\u{1F34E}\", name: \"red_apple\", keywords: [\"apple\", \"fruit\", \"red\", \"healthy\", \"food\"] },\n { emoji: \"\\u{1F34A}\", name: \"tangerine\", keywords: [\"orange\", \"tangerine\", \"fruit\", \"citrus\"] },\n { emoji: \"\\u{1F34B}\", name: \"lemon\", keywords: [\"lemon\", \"fruit\", \"citrus\", \"yellow\", \"sour\"] },\n { emoji: \"\\u{1F34C}\", name: \"banana\", keywords: [\"banana\", \"fruit\", \"yellow\", \"food\"] },\n { emoji: \"\\u{1F349}\", name: \"watermelon\", keywords: [\"watermelon\", \"fruit\", \"summer\", \"food\"] },\n { emoji: \"\\u{1F347}\", name: \"grapes\", keywords: [\"grapes\", \"fruit\", \"wine\", \"purple\"] },\n { emoji: \"\\u{1F353}\", name: \"strawberry\", keywords: [\"strawberry\", \"fruit\", \"berry\", \"red\"] },\n { emoji: \"\\u{1FAD0}\", name: \"blueberries\", keywords: [\"blueberry\", \"fruit\", \"berry\", \"blue\"] },\n { emoji: \"\\u{1F351}\", name: \"peach\", keywords: [\"peach\", \"fruit\", \"butt\", \"food\"] },\n { emoji: \"\\u{1F352}\", name: \"cherries\", keywords: [\"cherry\", \"cherries\", \"fruit\", \"red\"] },\n { emoji: \"\\u{1F348}\", name: \"melon\", keywords: [\"melon\", \"fruit\", \"green\", \"food\"] },\n { emoji: \"\\u{1F350}\", name: \"pear\", keywords: [\"pear\", \"fruit\", \"green\", \"food\"] },\n { emoji: \"\\u{1F34D}\", name: \"pineapple\", keywords: [\"pineapple\", \"fruit\", \"tropical\", \"food\"] },\n { emoji: \"\\u{1F96D}\", name: \"mango\", keywords: [\"mango\", \"fruit\", \"tropical\", \"food\"] },\n { emoji: \"\\u{1F951}\", name: \"avocado\", keywords: [\"avocado\", \"food\", \"guacamole\", \"healthy\", \"green\"] },\n { emoji: \"\\u{1F955}\", name: \"carrot\", keywords: [\"carrot\", \"vegetable\", \"food\", \"orange\"] },\n { emoji: \"\\u{1F33D}\", name: \"ear_of_corn\", keywords: [\"corn\", \"vegetable\", \"food\", \"maize\"] },\n { emoji: \"\\u{1F336}\\u{FE0F}\", name: \"hot_pepper\", keywords: [\"pepper\", \"hot\", \"spicy\", \"chili\"] },\n { emoji: \"\\u{1F966}\", name: \"broccoli\", keywords: [\"broccoli\", \"vegetable\", \"green\", \"healthy\", \"food\"] },\n { emoji: \"\\u{1F9C5}\", name: \"onion\", keywords: [\"onion\", \"vegetable\", \"food\", \"cry\"] },\n { emoji: \"\\u{1F344}\", name: \"mushroom\", keywords: [\"mushroom\", \"fungus\", \"food\", \"nature\"] },\n { emoji: \"\\u{1F95C}\", name: \"peanuts\", keywords: [\"peanut\", \"nut\", \"food\", \"snack\"] },\n { emoji: \"\\u{1F35E}\", name: \"bread\", keywords: [\"bread\", \"food\", \"bakery\", \"toast\", \"loaf\"] },\n { emoji: \"\\u{1F950}\", name: \"croissant\", keywords: [\"croissant\", \"bread\", \"french\", \"pastry\", \"breakfast\"] },\n { emoji: \"\\u{1F956}\", name: \"baguette_bread\", keywords: [\"baguette\", \"bread\", \"french\", \"food\"] },\n { emoji: \"\\u{1F968}\", name: \"pretzel\", keywords: [\"pretzel\", \"snack\", \"food\", \"bread\"] },\n { emoji: \"\\u{1F9C0}\", name: \"cheese_wedge\", keywords: [\"cheese\", \"food\", \"dairy\", \"cheddar\"] },\n { emoji: \"\\u{1F356}\", name: \"meat_on_bone\", keywords: [\"meat\", \"food\", \"bone\", \"bbq\"] },\n { emoji: \"\\u{1F354}\", name: \"hamburger\", keywords: [\"burger\", \"hamburger\", \"fast_food\", \"food\", \"cheeseburger\"] },\n { emoji: \"\\u{1F35F}\", name: \"french_fries\", keywords: [\"fries\", \"french_fries\", \"fast_food\", \"food\", \"chips\"] },\n { emoji: \"\\u{1F355}\", name: \"pizza\", keywords: [\"pizza\", \"food\", \"italian\", \"slice\", \"cheese\"] },\n { emoji: \"\\u{1F32E}\", name: \"taco\", keywords: [\"taco\", \"food\", \"mexican\", \"tuesday\"] },\n { emoji: \"\\u{1F32F}\", name: \"burrito\", keywords: [\"burrito\", \"food\", \"mexican\", \"wrap\"] },\n { emoji: \"\\u{1F363}\", name: \"sushi\", keywords: [\"sushi\", \"food\", \"japanese\", \"fish\", \"rice\"] },\n { emoji: \"\\u{1F35C}\", name: \"steaming_bowl\", keywords: [\"ramen\", \"noodles\", \"soup\", \"food\", \"japanese\", \"pho\"] },\n { emoji: \"\\u{1F35D}\", name: \"spaghetti\", keywords: [\"spaghetti\", \"pasta\", \"food\", \"italian\", \"noodles\"] },\n { emoji: \"\\u{1F35B}\", name: \"curry_rice\", keywords: [\"curry\", \"rice\", \"food\", \"indian\", \"japanese\"] },\n { emoji: \"\\u{1F364}\", name: \"fried_shrimp\", keywords: [\"shrimp\", \"tempura\", \"fried\", \"food\", \"seafood\"] },\n { emoji: \"\\u{1F373}\", name: \"cooking\", keywords: [\"egg\", \"frying\", \"cooking\", \"breakfast\", \"food\"] },\n { emoji: \"\\u{1F382}\", name: \"birthday_cake\", keywords: [\"cake\", \"birthday\", \"celebration\", \"dessert\", \"party\"] },\n { emoji: \"\\u{1F370}\", name: \"shortcake\", keywords: [\"cake\", \"dessert\", \"strawberry\", \"sweet\"] },\n { emoji: \"\\u{1F36B}\", name: \"chocolate_bar\", keywords: [\"chocolate\", \"candy\", \"sweet\", \"dessert\"] },\n { emoji: \"\\u{1F36C}\", name: \"candy\", keywords: [\"candy\", \"sweet\", \"sugar\", \"treat\"] },\n { emoji: \"\\u{1F369}\", name: \"doughnut\", keywords: [\"donut\", \"doughnut\", \"dessert\", \"sweet\", \"food\"] },\n { emoji: \"\\u{1F366}\", name: \"soft_ice_cream\", keywords: [\"ice_cream\", \"dessert\", \"sweet\", \"cold\", \"summer\"] },\n { emoji: \"\\u{1F36A}\", name: \"cookie\", keywords: [\"cookie\", \"dessert\", \"sweet\", \"biscuit\", \"snack\"] },\n { emoji: \"\\u{2615}\", name: \"hot_beverage\", keywords: [\"coffee\", \"tea\", \"hot\", \"drink\", \"cafe\", \"cup\"] },\n { emoji: \"\\u{1F375}\", name: \"teacup_without_handle\", keywords: [\"tea\", \"green_tea\", \"drink\", \"cup\", \"matcha\"] },\n { emoji: \"\\u{1F37A}\", name: \"beer_mug\", keywords: [\"beer\", \"drink\", \"alcohol\", \"pub\", \"cheers\"] },\n { emoji: \"\\u{1F37B}\", name: \"clinking_beer_mugs\", keywords: [\"beer\", \"cheers\", \"drink\", \"celebrate\", \"toast\"] },\n { emoji: \"\\u{1F377}\", name: \"wine_glass\", keywords: [\"wine\", \"drink\", \"alcohol\", \"glass\", \"red\"] },\n { emoji: \"\\u{1F378}\", name: \"cocktail_glass\", keywords: [\"cocktail\", \"drink\", \"alcohol\", \"martini\", \"bar\"] },\n { emoji: \"\\u{1F379}\", name: \"tropical_drink\", keywords: [\"tropical\", \"drink\", \"cocktail\", \"vacation\", \"beach\"] },\n { emoji: \"\\u{1F9CB}\", name: \"bubble_tea\", keywords: [\"bubble_tea\", \"boba\", \"drink\", \"tea\", \"milk_tea\"] },\n { emoji: \"\\u{1F9C3}\", name: \"beverage_box\", keywords: [\"juice\", \"box\", \"drink\", \"straw\"] },\n { emoji: \"\\u{1F95B}\", name: \"glass_of_milk\", keywords: [\"milk\", \"drink\", \"glass\", \"dairy\"] },\n { emoji: \"\\u{1F96F}\", name: \"bagel\", keywords: [\"bagel\", \"bread\", \"breakfast\", \"food\"] },\n { emoji: \"\\u{1F9C7}\", name: \"waffle\", keywords: [\"waffle\", \"breakfast\", \"food\", \"syrup\"] },\n { emoji: \"\\u{1F96A}\", name: \"sandwich\", keywords: [\"sandwich\", \"food\", \"lunch\", \"bread\"] },\n { emoji: \"\\u{1F96B}\", name: \"canned_food\", keywords: [\"can\", \"food\", \"canned\", \"tinned\"] },\n { emoji: \"\\u{1F9C6}\", name: \"falafel\", keywords: [\"falafel\", \"food\", \"middle_eastern\", \"vegetarian\"] },\n { emoji: \"\\u{1F9C4}\", name: \"garlic\", keywords: [\"garlic\", \"food\", \"cooking\", \"flavor\"] },\n { emoji: \"\\u{1F96C}\", name: \"leafy_green\", keywords: [\"salad\", \"lettuce\", \"kale\", \"vegetable\", \"healthy\"] },\n { emoji: \"\\u{1FAD2}\", name: \"olive\", keywords: [\"olive\", \"food\", \"oil\", \"mediterranean\"] },\n { emoji: \"\\u{1FAD8}\", name: \"beans\", keywords: [\"beans\", \"food\", \"legume\", \"kidney\"] },\n { emoji: \"\\u{1F9C1}\", name: \"cupcake\", keywords: [\"cupcake\", \"cake\", \"dessert\", \"sweet\", \"treat\"] },\n { emoji: \"\\u{1F9C2}\", name: \"salt\", keywords: [\"salt\", \"seasoning\", \"food\", \"salty\"] },\n { emoji: \"\\u{1FAD6}\", name: \"teapot\", keywords: [\"teapot\", \"tea\", \"drink\", \"brew\"] },\n { emoji: \"\\u{1F9C9}\", name: \"mate\", keywords: [\"mate\", \"drink\", \"tea\", \"yerba\", \"argentine\"] },\n { emoji: \"\\u{1F9CA}\", name: \"ice\", keywords: [\"ice\", \"cube\", \"cold\", \"frozen\", \"drink\"] },\n { emoji: \"\\u{1FAD7}\", name: \"pouring_liquid\", keywords: [\"pour\", \"liquid\", \"water\", \"drink\", \"glass\"] },\n { emoji: \"\\u{1F943}\", name: \"tumbler_glass\", keywords: [\"whiskey\", \"glass\", \"drink\", \"alcohol\", \"bourbon\"] },\n { emoji: \"\\u{1F942}\", name: \"clinking_glasses\", keywords: [\"champagne\", \"cheers\", \"toast\", \"celebrate\", \"glass\"] },\n { emoji: \"\\u{1F37E}\", name: \"bottle_with_popping_cork\", keywords: [\"champagne\", \"bottle\", \"celebrate\", \"party\", \"pop\"] },\n { emoji: \"\\u{1F4A5}\", name: \"collision\", keywords: [\"boom\", \"explosion\", \"crash\", \"impact\", \"pow\"] },\n\n { emoji: \"\\u{1F697}\", name: \"automobile\", keywords: [\"car\", \"drive\", \"vehicle\", \"transport\", \"auto\"] },\n { emoji: \"\\u{1F695}\", name: \"taxi\", keywords: [\"taxi\", \"cab\", \"car\", \"ride\", \"transport\"] },\n { emoji: \"\\u{1F68C}\", name: \"bus\", keywords: [\"bus\", \"transport\", \"public\", \"vehicle\"] },\n { emoji: \"\\u{1F691}\", name: \"ambulance\", keywords: [\"ambulance\", \"emergency\", \"hospital\", \"vehicle\"] },\n { emoji: \"\\u{1F692}\", name: \"fire_engine\", keywords: [\"fire\", \"engine\", \"truck\", \"emergency\", \"vehicle\"] },\n { emoji: \"\\u{1F693}\", name: \"police_car\", keywords: [\"police\", \"car\", \"law\", \"emergency\", \"vehicle\"] },\n { emoji: \"\\u{1F3CD}\\u{FE0F}\", name: \"motorcycle\", keywords: [\"motorcycle\", \"bike\", \"vehicle\", \"racing\"] },\n { emoji: \"\\u{1F6B2}\", name: \"bicycle\", keywords: [\"bicycle\", \"bike\", \"cycling\", \"sport\", \"ride\"] },\n { emoji: \"\\u{2708}\\u{FE0F}\", name: \"airplane\", keywords: [\"airplane\", \"plane\", \"flight\", \"travel\", \"fly\"] },\n { emoji: \"\\u{1F6EB}\", name: \"airplane_departure\", keywords: [\"airplane\", \"departure\", \"flight\", \"travel\", \"takeoff\"] },\n { emoji: \"\\u{1F6EC}\", name: \"airplane_arrival\", keywords: [\"airplane\", \"arrival\", \"flight\", \"travel\", \"landing\"] },\n { emoji: \"\\u{1F680}\", name: \"rocket\", keywords: [\"rocket\", \"space\", \"launch\", \"ship\", \"fast\", \"moon\"] },\n { emoji: \"\\u{1F6F8}\", name: \"flying_saucer\", keywords: [\"ufo\", \"alien\", \"space\", \"flying_saucer\"] },\n { emoji: \"\\u{1F6A2}\", name: \"ship\", keywords: [\"ship\", \"boat\", \"cruise\", \"ocean\", \"travel\"] },\n { emoji: \"\\u{1F6A4}\", name: \"speedboat\", keywords: [\"speedboat\", \"boat\", \"fast\", \"water\"] },\n { emoji: \"\\u{1F689}\", name: \"station\", keywords: [\"station\", \"train\", \"railway\", \"transport\"] },\n { emoji: \"\\u{1F684}\", name: \"high_speed_train\", keywords: [\"train\", \"fast\", \"bullet\", \"transport\", \"railway\"] },\n { emoji: \"\\u{1F3E0}\", name: \"house\", keywords: [\"house\", \"home\", \"building\", \"residence\"] },\n { emoji: \"\\u{1F3E2}\", name: \"office_building\", keywords: [\"office\", \"building\", \"work\", \"business\"] },\n { emoji: \"\\u{1F3E5}\", name: \"hospital\", keywords: [\"hospital\", \"health\", \"medical\", \"building\", \"doctor\"] },\n { emoji: \"\\u{1F3EB}\", name: \"school\", keywords: [\"school\", \"education\", \"building\", \"study\"] },\n { emoji: \"\\u{1F3D6}\\u{FE0F}\", name: \"beach_with_umbrella\", keywords: [\"beach\", \"vacation\", \"sand\", \"ocean\", \"summer\"] },\n { emoji: \"\\u{1F3D4}\\u{FE0F}\", name: \"snow_capped_mountain\", keywords: [\"mountain\", \"snow\", \"nature\", \"hiking\", \"cold\"] },\n { emoji: \"\\u{26F0}\\u{FE0F}\", name: \"mountain\", keywords: [\"mountain\", \"nature\", \"hiking\", \"climb\"] },\n { emoji: \"\\u{1F30B}\", name: \"volcano\", keywords: [\"volcano\", \"eruption\", \"lava\", \"nature\", \"mountain\"] },\n { emoji: \"\\u{1F5FC}\", name: \"tokyo_tower\", keywords: [\"tokyo\", \"tower\", \"japan\", \"landmark\"] },\n { emoji: \"\\u{1F5FD}\", name: \"statue_of_liberty\", keywords: [\"statue\", \"liberty\", \"nyc\", \"america\", \"landmark\"] },\n { emoji: \"\\u{1F3F0}\", name: \"castle\", keywords: [\"castle\", \"medieval\", \"fairy_tale\", \"kingdom\"] },\n { emoji: \"\\u{26FA}\", name: \"tent\", keywords: [\"tent\", \"camping\", \"outdoor\", \"nature\", \"camp\"] },\n { emoji: \"\\u{1F3DD}\\u{FE0F}\", name: \"desert_island\", keywords: [\"island\", \"desert\", \"tropical\", \"beach\", \"palm\"] },\n { emoji: \"\\u{1F30D}\", name: \"globe_showing_europe_africa\", keywords: [\"globe\", \"earth\", \"world\", \"europe\", \"africa\", \"international\"] },\n { emoji: \"\\u{1F30E}\", name: \"globe_showing_americas\", keywords: [\"globe\", \"earth\", \"world\", \"americas\", \"international\"] },\n { emoji: \"\\u{1F30F}\", name: \"globe_showing_asia_australia\", keywords: [\"globe\", \"earth\", \"world\", \"asia\", \"australia\", \"international\"] },\n { emoji: \"\\u{1F310}\", name: \"globe_with_meridians\", keywords: [\"globe\", \"earth\", \"world\", \"internet\", \"web\", \"international\", \"meridians\"] },\n { emoji: \"\\u{1F5FA}\\u{FE0F}\", name: \"world_map\", keywords: [\"map\", \"world\", \"globe\", \"geography\", \"travel\"] },\n { emoji: \"\\u{1F9ED}\", name: \"compass\", keywords: [\"compass\", \"navigate\", \"direction\", \"travel\", \"explore\"] },\n { emoji: \"\\u{1F3D7}\\u{FE0F}\", name: \"building_construction\", keywords: [\"construction\", \"building\", \"crane\", \"build\"] },\n { emoji: \"\\u{1F3D8}\\u{FE0F}\", name: \"houses\", keywords: [\"houses\", \"neighborhood\", \"buildings\", \"suburb\", \"city\"] },\n { emoji: \"\\u{1F3DA}\\u{FE0F}\", name: \"derelict_house\", keywords: [\"house\", \"abandoned\", \"derelict\", \"old\"] },\n { emoji: \"\\u{1F3E3}\", name: \"japanese_post_office\", keywords: [\"post\", \"office\", \"building\", \"mail\"] },\n { emoji: \"\\u{1F3E8}\", name: \"hotel\", keywords: [\"hotel\", \"building\", \"travel\", \"accommodation\", \"stay\"] },\n { emoji: \"\\u{1F3EA}\", name: \"convenience_store\", keywords: [\"store\", \"shop\", \"building\", \"convenience\"] },\n { emoji: \"\\u{26F2}\", name: \"fountain\", keywords: [\"fountain\", \"park\", \"water\", \"monument\"] },\n { emoji: \"\\u{26F5}\", name: \"sailboat\", keywords: [\"sailboat\", \"boat\", \"sailing\", \"water\", \"ocean\"] },\n { emoji: \"\\u{1F6F3}\\u{FE0F}\", name: \"passenger_ship\", keywords: [\"ship\", \"cruise\", \"boat\", \"travel\", \"ocean\"] },\n { emoji: \"\\u{1F682}\", name: \"locomotive\", keywords: [\"train\", \"locomotive\", \"railway\", \"steam\", \"engine\"] },\n { emoji: \"\\u{1F683}\", name: \"railway_car\", keywords: [\"train\", \"railway\", \"car\", \"transport\"] },\n { emoji: \"\\u{1F699}\", name: \"sport_utility_vehicle\", keywords: [\"suv\", \"car\", \"vehicle\", \"jeep\", \"drive\"] },\n { emoji: \"\\u{1F6FB}\", name: \"pickup_truck\", keywords: [\"truck\", \"pickup\", \"vehicle\", \"drive\"] },\n { emoji: \"\\u{1F6F4}\", name: \"kick_scooter\", keywords: [\"scooter\", \"kick\", \"ride\", \"transport\"] },\n { emoji: \"\\u{1F6F5}\", name: \"motor_scooter\", keywords: [\"scooter\", \"motor\", \"ride\", \"vespa\"] },\n { emoji: \"\\u{1F6FA}\", name: \"auto_rickshaw\", keywords: [\"rickshaw\", \"auto\", \"tuk_tuk\", \"transport\"] },\n { emoji: \"\\u{1F6F6}\", name: \"canoe\", keywords: [\"canoe\", \"kayak\", \"boat\", \"paddle\", \"water\"] },\n { emoji: \"\\u{1F681}\", name: \"helicopter\", keywords: [\"helicopter\", \"fly\", \"vehicle\", \"transport\"] },\n { emoji: \"\\u{1F6A6}\", name: \"vertical_traffic_light\", keywords: [\"traffic\", \"light\", \"signal\", \"road\"] },\n { emoji: \"\\u{1F6A8}\", name: \"police_car_light\", keywords: [\"police\", \"light\", \"siren\", \"emergency\", \"alert\"] },\n { emoji: \"\\u{26FD}\", name: \"fuel_pump\", keywords: [\"fuel\", \"gas\", \"petrol\", \"station\", \"pump\"] },\n { emoji: \"\\u{1F5FF}\", name: \"moai\", keywords: [\"moai\", \"statue\", \"easter_island\", \"stone\", \"face\"] },\n\n { emoji: \"\\u{26BD}\", name: \"soccer_ball\", keywords: [\"soccer\", \"football\", \"sport\", \"ball\", \"game\"] },\n { emoji: \"\\u{1F3C0}\", name: \"basketball\", keywords: [\"basketball\", \"sport\", \"ball\", \"game\", \"nba\"] },\n { emoji: \"\\u{1F3C8}\", name: \"american_football\", keywords: [\"football\", \"american\", \"sport\", \"nfl\"] },\n { emoji: \"\\u{26BE}\", name: \"baseball\", keywords: [\"baseball\", \"sport\", \"ball\", \"game\"] },\n { emoji: \"\\u{1F3BE}\", name: \"tennis\", keywords: [\"tennis\", \"sport\", \"ball\", \"racket\"] },\n { emoji: \"\\u{1F3D0}\", name: \"volleyball\", keywords: [\"volleyball\", \"sport\", \"ball\", \"game\"] },\n { emoji: \"\\u{1F3C9}\", name: \"rugby_football\", keywords: [\"rugby\", \"sport\", \"ball\", \"football\"] },\n { emoji: \"\\u{1F3B3}\", name: \"bowling\", keywords: [\"bowling\", \"sport\", \"game\", \"pin\", \"ball\"] },\n { emoji: \"\\u{1F3CF}\", name: \"cricket_game\", keywords: [\"cricket\", \"sport\", \"bat\", \"ball\"] },\n { emoji: \"\\u{26F3}\", name: \"flag_in_hole\", keywords: [\"golf\", \"sport\", \"hole\", \"flag\"] },\n { emoji: \"\\u{1F3C6}\", name: \"trophy\", keywords: [\"trophy\", \"award\", \"winner\", \"champion\", \"prize\", \"gold\"] },\n { emoji: \"\\u{1F3C5}\", name: \"sports_medal\", keywords: [\"medal\", \"award\", \"sport\", \"winner\"] },\n { emoji: \"\\u{1F947}\", name: \"first_place_medal\", keywords: [\"gold\", \"medal\", \"first\", \"winner\", \"champion\"] },\n { emoji: \"\\u{1F948}\", name: \"second_place_medal\", keywords: [\"silver\", \"medal\", \"second\", \"runner_up\"] },\n { emoji: \"\\u{1F949}\", name: \"third_place_medal\", keywords: [\"bronze\", \"medal\", \"third\"] },\n { emoji: \"\\u{1F3AE}\", name: \"video_game\", keywords: [\"game\", \"gaming\", \"controller\", \"play\", \"console\"] },\n { emoji: \"\\u{1F3B2}\", name: \"game_die\", keywords: [\"dice\", \"game\", \"roll\", \"chance\", \"random\"] },\n { emoji: \"\\u{265F}\\u{FE0F}\", name: \"chess_pawn\", keywords: [\"chess\", \"game\", \"strategy\", \"pawn\"] },\n { emoji: \"\\u{1F3AF}\", name: \"bullseye\", keywords: [\"target\", \"dart\", \"bullseye\", \"aim\", \"goal\"] },\n { emoji: \"\\u{1F3B5}\", name: \"musical_note\", keywords: [\"music\", \"note\", \"sound\", \"sing\", \"song\"] },\n { emoji: \"\\u{1F3B6}\", name: \"musical_notes\", keywords: [\"music\", \"notes\", \"sound\", \"melody\", \"song\"] },\n { emoji: \"\\u{1F3B8}\", name: \"guitar\", keywords: [\"guitar\", \"music\", \"instrument\", \"rock\"] },\n { emoji: \"\\u{1F3B9}\", name: \"musical_keyboard\", keywords: [\"piano\", \"keyboard\", \"music\", \"instrument\"] },\n { emoji: \"\\u{1F3A4}\", name: \"microphone\", keywords: [\"microphone\", \"music\", \"sing\", \"karaoke\", \"mic\"] },\n { emoji: \"\\u{1F3AC}\", name: \"clapper_board\", keywords: [\"movie\", \"film\", \"cinema\", \"action\", \"clapper\"] },\n { emoji: \"\\u{1F3A8}\", name: \"artist_palette\", keywords: [\"art\", \"paint\", \"palette\", \"creative\", \"draw\"] },\n { emoji: \"\\u{1F3CA}\", name: \"person_swimming\", keywords: [\"swim\", \"swimming\", \"pool\", \"water\", \"sport\"] },\n { emoji: \"\\u{1F3C4}\", name: \"person_surfing\", keywords: [\"surf\", \"surfing\", \"wave\", \"ocean\", \"sport\"] },\n { emoji: \"\\u{1F6B4}\", name: \"person_biking\", keywords: [\"bike\", \"cycling\", \"bicycle\", \"ride\", \"sport\"] },\n { emoji: \"\\u{1F3CB}\\u{FE0F}\", name: \"person_lifting_weights\", keywords: [\"gym\", \"weights\", \"workout\", \"exercise\", \"strong\"] },\n { emoji: \"\\u{1F93A}\", name: \"person_fencing\", keywords: [\"fencing\", \"sword\", \"sport\", \"duel\"] },\n { emoji: \"\\u{1F93C}\", name: \"people_wrestling\", keywords: [\"wrestling\", \"sport\", \"fight\", \"grapple\"] },\n { emoji: \"\\u{1F93D}\", name: \"person_playing_water_polo\", keywords: [\"water_polo\", \"sport\", \"pool\", \"ball\"] },\n { emoji: \"\\u{1F93E}\", name: \"person_playing_handball\", keywords: [\"handball\", \"sport\", \"ball\", \"throw\"] },\n { emoji: \"\\u{1F94A}\", name: \"boxing_glove\", keywords: [\"boxing\", \"fight\", \"glove\", \"sport\", \"punch\"] },\n { emoji: \"\\u{1F94B}\", name: \"martial_arts_uniform\", keywords: [\"karate\", \"martial_arts\", \"judo\", \"sport\"] },\n { emoji: \"\\u{1F94C}\", name: \"curling_stone\", keywords: [\"curling\", \"sport\", \"winter\", \"ice\"] },\n { emoji: \"\\u{1F94D}\", name: \"lacrosse\", keywords: [\"lacrosse\", \"sport\", \"stick\", \"ball\"] },\n { emoji: \"\\u{1F3B1}\", name: \"pool_8_ball\", keywords: [\"pool\", \"billiards\", \"8ball\", \"game\"] },\n { emoji: \"\\u{1F3D3}\", name: \"ping_pong\", keywords: [\"ping_pong\", \"table_tennis\", \"sport\", \"paddle\"] },\n { emoji: \"\\u{1F3F8}\", name: \"badminton\", keywords: [\"badminton\", \"sport\", \"racket\", \"shuttlecock\"] },\n { emoji: \"\\u{1FA80}\", name: \"yo_yo\", keywords: [\"yo_yo\", \"toy\", \"play\", \"skill\"] },\n { emoji: \"\\u{1FA81}\", name: \"kite\", keywords: [\"kite\", \"fly\", \"wind\", \"toy\", \"outdoor\"] },\n { emoji: \"\\u{1FA83}\", name: \"boomerang\", keywords: [\"boomerang\", \"throw\", \"return\", \"australia\"] },\n { emoji: \"\\u{1F3AA}\", name: \"circus_tent\", keywords: [\"circus\", \"tent\", \"show\", \"carnival\", \"fun\"] },\n { emoji: \"\\u{1F3A0}\", name: \"carousel_horse\", keywords: [\"carousel\", \"horse\", \"ride\", \"amusement\", \"park\"] },\n { emoji: \"\\u{1F3A1}\", name: \"ferris_wheel\", keywords: [\"ferris\", \"wheel\", \"amusement\", \"park\", \"ride\"] },\n { emoji: \"\\u{1F3A2}\", name: \"roller_coaster\", keywords: [\"roller_coaster\", \"amusement\", \"park\", \"ride\", \"thrill\"] },\n { emoji: \"\\u{1F39E}\\u{FE0F}\", name: \"film_frames\", keywords: [\"film\", \"movie\", \"cinema\", \"frames\", \"reel\"] },\n { emoji: \"\\u{1F39F}\\u{FE0F}\", name: \"admission_tickets\", keywords: [\"ticket\", \"admission\", \"event\", \"show\", \"concert\"] },\n { emoji: \"\\u{1FA87}\", name: \"maracas\", keywords: [\"maracas\", \"music\", \"shake\", \"instrument\", \"latin\"] },\n { emoji: \"\\u{1FA98}\", name: \"long_drum\", keywords: [\"drum\", \"music\", \"instrument\", \"beat\", \"percussion\"] },\n { emoji: \"\\u{1F3BA}\", name: \"trumpet\", keywords: [\"trumpet\", \"music\", \"instrument\", \"brass\", \"horn\"] },\n { emoji: \"\\u{1F3BB}\", name: \"violin\", keywords: [\"violin\", \"music\", \"instrument\", \"string\", \"classical\"] },\n { emoji: \"\\u{1FA95}\", name: \"banjo\", keywords: [\"banjo\", \"music\", \"instrument\", \"string\", \"country\"] },\n { emoji: \"\\u{1F941}\", name: \"drum\", keywords: [\"drum\", \"music\", \"instrument\", \"beat\", \"percussion\"] },\n\n { emoji: \"\\u{1F4F1}\", name: \"mobile_phone\", keywords: [\"phone\", \"mobile\", \"cell\", \"smartphone\", \"iphone\"] },\n { emoji: \"\\u{1F4F2}\", name: \"mobile_phone_with_arrow\", keywords: [\"phone\", \"call\", \"incoming\", \"mobile\"] },\n { emoji: \"\\u{260E}\\u{FE0F}\", name: \"telephone\", keywords: [\"phone\", \"call\", \"telephone\", \"landline\"] },\n { emoji: \"\\u{1F4BB}\", name: \"laptop\", keywords: [\"laptop\", \"computer\", \"pc\", \"work\", \"coding\"] },\n { emoji: \"\\u{1F5A5}\\u{FE0F}\", name: \"desktop_computer\", keywords: [\"computer\", \"desktop\", \"monitor\", \"screen\", \"pc\"] },\n { emoji: \"\\u{2328}\\u{FE0F}\", name: \"keyboard\", keywords: [\"keyboard\", \"type\", \"computer\", \"input\"] },\n { emoji: \"\\u{1F5A8}\\u{FE0F}\", name: \"printer\", keywords: [\"printer\", \"print\", \"paper\", \"office\"] },\n { emoji: \"\\u{1F4F7}\", name: \"camera\", keywords: [\"camera\", \"photo\", \"picture\", \"photography\"] },\n { emoji: \"\\u{1F4F9}\", name: \"video_camera\", keywords: [\"video\", \"camera\", \"film\", \"record\"] },\n { emoji: \"\\u{1F4FA}\", name: \"television\", keywords: [\"tv\", \"television\", \"screen\", \"watch\", \"show\"] },\n { emoji: \"\\u{1F4FB}\", name: \"radio\", keywords: [\"radio\", \"music\", \"broadcast\", \"listen\"] },\n { emoji: \"\\u{1F50B}\", name: \"battery\", keywords: [\"battery\", \"power\", \"energy\", \"charge\"] },\n { emoji: \"\\u{1F50C}\", name: \"electric_plug\", keywords: [\"plug\", \"electric\", \"power\", \"charge\", \"outlet\"] },\n { emoji: \"\\u{1F4A1}\", name: \"light_bulb\", keywords: [\"bulb\", \"light\", \"idea\", \"bright\", \"think\", \"innovation\"] },\n { emoji: \"\\u{1F526}\", name: \"flashlight\", keywords: [\"flashlight\", \"light\", \"torch\", \"dark\"] },\n { emoji: \"\\u{1F56F}\\u{FE0F}\", name: \"candle\", keywords: [\"candle\", \"light\", \"fire\", \"flame\", \"romantic\"] },\n { emoji: \"\\u{1F4D6}\", name: \"open_book\", keywords: [\"book\", \"read\", \"open\", \"study\", \"literature\"] },\n { emoji: \"\\u{1F4D5}\", name: \"closed_book\", keywords: [\"book\", \"closed\", \"red\", \"read\"] },\n { emoji: \"\\u{1F4DA}\", name: \"books\", keywords: [\"books\", \"library\", \"study\", \"read\", \"stack\"] },\n { emoji: \"\\u{1F4D3}\", name: \"notebook\", keywords: [\"notebook\", \"write\", \"journal\", \"notes\"] },\n { emoji: \"\\u{1F4DD}\", name: \"memo\", keywords: [\"memo\", \"note\", \"write\", \"pencil\", \"document\"] },\n { emoji: \"\\u{1F4C4}\", name: \"page_facing_up\", keywords: [\"page\", \"document\", \"file\", \"paper\"] },\n { emoji: \"\\u{1F4CE}\", name: \"paperclip\", keywords: [\"paperclip\", \"clip\", \"attach\", \"office\"] },\n { emoji: \"\\u{1F4CB}\", name: \"clipboard\", keywords: [\"clipboard\", \"list\", \"notes\", \"paste\"] },\n { emoji: \"\\u{1F4C5}\", name: \"calendar\", keywords: [\"calendar\", \"date\", \"schedule\", \"event\", \"day\"] },\n { emoji: \"\\u{1F4C6}\", name: \"tear_off_calendar\", keywords: [\"calendar\", \"date\", \"schedule\", \"day\"] },\n { emoji: \"\\u{1F4C8}\", name: \"chart_increasing\", keywords: [\"chart\", \"graph\", \"up\", \"growth\", \"increase\", \"trending\"] },\n { emoji: \"\\u{1F4C9}\", name: \"chart_decreasing\", keywords: [\"chart\", \"graph\", \"down\", \"decrease\", \"loss\"] },\n { emoji: \"\\u{1F4CA}\", name: \"bar_chart\", keywords: [\"chart\", \"graph\", \"bar\", \"stats\", \"analytics\"] },\n { emoji: \"\\u{1F4CC}\", name: \"pushpin\", keywords: [\"pin\", \"pushpin\", \"location\", \"mark\"] },\n { emoji: \"\\u{1F4CD}\", name: \"round_pushpin\", keywords: [\"pin\", \"location\", \"map\", \"mark\"] },\n { emoji: \"\\u{2702}\\u{FE0F}\", name: \"scissors\", keywords: [\"scissors\", \"cut\", \"trim\", \"tool\"] },\n { emoji: \"\\u{1F4CF}\", name: \"straight_ruler\", keywords: [\"ruler\", \"measure\", \"straight\", \"tool\"] },\n { emoji: \"\\u{1F512}\", name: \"locked\", keywords: [\"lock\", \"locked\", \"security\", \"private\", \"closed\"] },\n { emoji: \"\\u{1F513}\", name: \"unlocked\", keywords: [\"unlock\", \"open\", \"security\", \"access\"] },\n { emoji: \"\\u{1F511}\", name: \"key\", keywords: [\"key\", \"lock\", \"unlock\", \"password\", \"access\"] },\n { emoji: \"\\u{1F528}\", name: \"hammer\", keywords: [\"hammer\", \"tool\", \"build\", \"fix\", \"construction\"] },\n { emoji: \"\\u{1FA9B}\", name: \"screwdriver\", keywords: [\"screwdriver\", \"tool\", \"fix\", \"repair\"] },\n { emoji: \"\\u{1F527}\", name: \"wrench\", keywords: [\"wrench\", \"tool\", \"fix\", \"repair\", \"settings\"] },\n { emoji: \"\\u{1F6E0}\\u{FE0F}\", name: \"hammer_and_wrench\", keywords: [\"tools\", \"fix\", \"repair\", \"build\", \"settings\"] },\n { emoji: \"\\u{2699}\\u{FE0F}\", name: \"gear\", keywords: [\"gear\", \"settings\", \"cog\", \"configure\", \"mechanical\"] },\n { emoji: \"\\u{1F9F2}\", name: \"magnet\", keywords: [\"magnet\", \"attract\", \"magnetic\", \"pull\"] },\n { emoji: \"\\u{1F50D}\", name: \"magnifying_glass_tilted_left\", keywords: [\"search\", \"magnify\", \"zoom\", \"find\", \"look\", \"investigate\"] },\n { emoji: \"\\u{1F50E}\", name: \"magnifying_glass_tilted_right\", keywords: [\"search\", \"magnify\", \"zoom\", \"find\", \"look\"] },\n { emoji: \"\\u{1F4B0}\", name: \"money_bag\", keywords: [\"money\", \"bag\", \"dollar\", \"rich\", \"wealth\", \"cash\"] },\n { emoji: \"\\u{1F4B5}\", name: \"dollar_banknote\", keywords: [\"money\", \"dollar\", \"cash\", \"bill\", \"usd\"] },\n { emoji: \"\\u{1F4B3}\", name: \"credit_card\", keywords: [\"credit\", \"card\", \"payment\", \"money\", \"buy\"] },\n { emoji: \"\\u{1F4B8}\", name: \"money_with_wings\", keywords: [\"money\", \"flying\", \"spending\", \"expensive\", \"gone\"] },\n { emoji: \"\\u{1F4E7}\", name: \"email\", keywords: [\"email\", \"mail\", \"letter\", \"envelope\", \"message\"] },\n { emoji: \"\\u{1F4E8}\", name: \"incoming_envelope\", keywords: [\"email\", \"envelope\", \"incoming\", \"mail\", \"letter\"] },\n { emoji: \"\\u{1F4E9}\", name: \"envelope_with_arrow\", keywords: [\"email\", \"envelope\", \"send\", \"outgoing\"] },\n { emoji: \"\\u{1F4E6}\", name: \"package\", keywords: [\"package\", \"box\", \"delivery\", \"shipping\", \"parcel\"] },\n { emoji: \"\\u{1F3F7}\\u{FE0F}\", name: \"label\", keywords: [\"label\", \"tag\", \"price\", \"sale\"] },\n { emoji: \"\\u{231A}\", name: \"watch\", keywords: [\"watch\", \"time\", \"clock\", \"wrist\"] },\n { emoji: \"\\u{23F0}\", name: \"alarm_clock\", keywords: [\"alarm\", \"clock\", \"time\", \"wake\", \"morning\"] },\n { emoji: \"\\u{23F3}\", name: \"hourglass_flowing_sand\", keywords: [\"hourglass\", \"time\", \"loading\", \"wait\", \"timer\"] },\n { emoji: \"\\u{1F570}\\u{FE0F}\", name: \"mantelpiece_clock\", keywords: [\"clock\", \"time\", \"vintage\", \"antique\"] },\n { emoji: \"\\u{1F4E2}\", name: \"loudspeaker\", keywords: [\"speaker\", \"loud\", \"announcement\", \"megaphone\"] },\n { emoji: \"\\u{1F514}\", name: \"bell\", keywords: [\"bell\", \"notification\", \"ring\", \"alert\", \"sound\"] },\n { emoji: \"\\u{1F515}\", name: \"bell_with_slash\", keywords: [\"bell\", \"mute\", \"silent\", \"no_notification\", \"quiet\"] },\n { emoji: \"\\u{1F3B0}\", name: \"slot_machine\", keywords: [\"slot\", \"casino\", \"gambling\", \"luck\", \"jackpot\"] },\n { emoji: \"\\u{1F451}\", name: \"crown\", keywords: [\"crown\", \"king\", \"queen\", \"royal\", \"gold\", \"leader\"] },\n { emoji: \"\\u{1F48E}\", name: \"gem_stone\", keywords: [\"gem\", \"diamond\", \"jewel\", \"crystal\", \"precious\", \"ruby\"] },\n { emoji: \"\\u{2728}\", name: \"sparkles\", keywords: [\"sparkles\", \"stars\", \"shine\", \"glitter\", \"magic\", \"new\", \"clean\"] },\n { emoji: \"\\u{1F4AB}\", name: \"dizzy\", keywords: [\"dizzy\", \"star\", \"sparkle\", \"shoot\", \"comic\"] },\n { emoji: \"\\u{1F6E1}\\u{FE0F}\", name: \"shield\", keywords: [\"shield\", \"protect\", \"defense\", \"security\", \"guard\"] },\n { emoji: \"\\u{2694}\\u{FE0F}\", name: \"crossed_swords\", keywords: [\"swords\", \"battle\", \"fight\", \"combat\", \"war\", \"crossed\"] },\n { emoji: \"\\u{1F52E}\", name: \"crystal_ball\", keywords: [\"crystal\", \"ball\", \"fortune\", \"magic\", \"predict\", \"future\"] },\n { emoji: \"\\u{1FA84}\", name: \"magic_wand\", keywords: [\"magic\", \"wand\", \"wizard\", \"spell\", \"sparkle\"] },\n { emoji: \"\\u{1F9FF}\", name: \"nazar_amulet\", keywords: [\"nazar\", \"evil_eye\", \"amulet\", \"charm\", \"protection\"] },\n { emoji: \"\\u{1F9F9}\", name: \"broom\", keywords: [\"broom\", \"sweep\", \"clean\", \"witch\"] },\n { emoji: \"\\u{1FA9C}\", name: \"ladder\", keywords: [\"ladder\", \"climb\", \"steps\", \"tool\"] },\n { emoji: \"\\u{1F5D1}\\u{FE0F}\", name: \"wastebasket\", keywords: [\"trash\", \"delete\", \"bin\", \"waste\", \"garbage\", \"recycle\"] },\n { emoji: \"\\u{1F9F3}\", name: \"luggage\", keywords: [\"luggage\", \"suitcase\", \"travel\", \"bag\", \"trip\"] },\n { emoji: \"\\u{1F392}\", name: \"backpack\", keywords: [\"backpack\", \"bag\", \"school\", \"travel\", \"hiking\"] },\n { emoji: \"\\u{1F393}\", name: \"graduation_cap\", keywords: [\"graduation\", \"cap\", \"school\", \"education\", \"degree\", \"hat\"] },\n { emoji: \"\\u{1F4F0}\", name: \"newspaper\", keywords: [\"newspaper\", \"news\", \"press\", \"media\", \"article\"] },\n { emoji: \"\\u{1F4DC}\", name: \"scroll\", keywords: [\"scroll\", \"document\", \"ancient\", \"paper\", \"parchment\"] },\n { emoji: \"\\u{1F4D1}\", name: \"bookmark_tabs\", keywords: [\"bookmark\", \"tabs\", \"mark\", \"save\"] },\n { emoji: \"\\u{1F516}\", name: \"bookmark\", keywords: [\"bookmark\", \"mark\", \"save\", \"read\", \"favorite\"] },\n { emoji: \"\\u{1F3AD}\", name: \"performing_arts\", keywords: [\"theater\", \"drama\", \"masks\", \"acting\", \"performance\"] },\n { emoji: \"\\u{1F9E9}\", name: \"puzzle_piece\", keywords: [\"puzzle\", \"piece\", \"jigsaw\", \"fit\", \"solve\", \"game\"] },\n { emoji: \"\\u{1F9F1}\", name: \"brick\", keywords: [\"brick\", \"build\", \"wall\", \"construction\", \"block\"] },\n { emoji: \"\\u{1FA99}\", name: \"coin\", keywords: [\"coin\", \"money\", \"gold\", \"currency\", \"pay\"] },\n { emoji: \"\\u{1F4B4}\", name: \"yen_banknote\", keywords: [\"money\", \"yen\", \"japan\", \"cash\", \"bill\"] },\n { emoji: \"\\u{1F4B6}\", name: \"euro_banknote\", keywords: [\"money\", \"euro\", \"europe\", \"cash\", \"bill\"] },\n { emoji: \"\\u{1F4B7}\", name: \"pound_banknote\", keywords: [\"money\", \"pound\", \"british\", \"cash\", \"bill\"] },\n { emoji: \"\\u{1F4E4}\", name: \"outbox_tray\", keywords: [\"outbox\", \"send\", \"mail\", \"email\", \"upload\"] },\n { emoji: \"\\u{1F4E5}\", name: \"inbox_tray\", keywords: [\"inbox\", \"receive\", \"mail\", \"email\", \"download\"] },\n { emoji: \"\\u{1F4EC}\", name: \"open_mailbox_with_raised_flag\", keywords: [\"mailbox\", \"mail\", \"letter\", \"post\"] },\n { emoji: \"\\u{1F5C3}\\u{FE0F}\", name: \"card_file_box\", keywords: [\"file\", \"box\", \"archive\", \"storage\", \"organize\"] },\n { emoji: \"\\u{1F5C4}\\u{FE0F}\", name: \"file_cabinet\", keywords: [\"file\", \"cabinet\", \"archive\", \"storage\", \"office\"] },\n { emoji: \"\\u{1F5C2}\\u{FE0F}\", name: \"card_index_dividers\", keywords: [\"dividers\", \"index\", \"tabs\", \"organize\", \"file\"] },\n { emoji: \"\\u{1F4C1}\", name: \"file_folder\", keywords: [\"folder\", \"file\", \"directory\", \"organize\"] },\n { emoji: \"\\u{1F4C2}\", name: \"open_file_folder\", keywords: [\"folder\", \"file\", \"open\", \"directory\"] },\n { emoji: \"\\u{1F5F3}\\u{FE0F}\", name: \"ballot_box_with_ballot\", keywords: [\"ballot\", \"vote\", \"election\", \"box\", \"democracy\"] },\n { emoji: \"\\u{1F4C7}\", name: \"card_index\", keywords: [\"card\", \"index\", \"rolodex\", \"contacts\"] },\n { emoji: \"\\u{1F4BC}\", name: \"briefcase\", keywords: [\"briefcase\", \"work\", \"business\", \"job\", \"office\"] },\n { emoji: \"\\u{1F489}\", name: \"syringe\", keywords: [\"syringe\", \"vaccine\", \"injection\", \"medical\", \"needle\", \"health\"] },\n { emoji: \"\\u{1FA7A}\", name: \"stethoscope\", keywords: [\"stethoscope\", \"medical\", \"doctor\", \"health\", \"hospital\"] },\n { emoji: \"\\u{1F48A}\", name: \"pill\", keywords: [\"pill\", \"medicine\", \"drug\", \"health\", \"pharmacy\"] },\n { emoji: \"\\u{1F9EA}\", name: \"test_tube\", keywords: [\"test_tube\", \"science\", \"experiment\", \"chemistry\", \"lab\"] },\n { emoji: \"\\u{1F52C}\", name: \"microscope\", keywords: [\"microscope\", \"science\", \"research\", \"lab\", \"biology\"] },\n { emoji: \"\\u{1F52D}\", name: \"telescope\", keywords: [\"telescope\", \"space\", \"astronomy\", \"stars\", \"look\"] },\n { emoji: \"\\u{1F4E1}\", name: \"satellite_antenna\", keywords: [\"satellite\", \"antenna\", \"signal\", \"broadcast\", \"communication\"] },\n { emoji: \"\\u{1F50F}\", name: \"locked_with_pen\", keywords: [\"lock\", \"pen\", \"secure\", \"privacy\", \"write\"] },\n { emoji: \"\\u{1F510}\", name: \"locked_with_key\", keywords: [\"lock\", \"key\", \"secure\", \"privacy\", \"closed\"] },\n { emoji: \"\\u{1F4D2}\", name: \"ledger\", keywords: [\"ledger\", \"notebook\", \"green\", \"accounting\", \"record\"] },\n { emoji: \"\\u{1F4D4}\", name: \"notebook_with_decorative_cover\", keywords: [\"notebook\", \"decorative\", \"fancy\", \"diary\"] },\n { emoji: \"\\u{1F4D7}\", name: \"green_book\", keywords: [\"book\", \"green\", \"read\", \"study\"] },\n { emoji: \"\\u{1F4D8}\", name: \"blue_book\", keywords: [\"book\", \"blue\", \"read\", \"study\"] },\n { emoji: \"\\u{1F4D9}\", name: \"orange_book\", keywords: [\"book\", \"orange\", \"read\", \"study\"] },\n { emoji: \"\\u{23F1}\\u{FE0F}\", name: \"stopwatch\", keywords: [\"stopwatch\", \"time\", \"timer\", \"speed\", \"race\"] },\n { emoji: \"\\u{23F2}\\u{FE0F}\", name: \"timer_clock\", keywords: [\"timer\", \"clock\", \"countdown\", \"time\"] },\n { emoji: \"\\u{231B}\", name: \"hourglass_done\", keywords: [\"hourglass\", \"time\", \"done\", \"complete\", \"sand\"] },\n { emoji: \"\\u{1F4BF}\", name: \"optical_disc\", keywords: [\"cd\", \"disc\", \"dvd\", \"music\", \"data\"] },\n { emoji: \"\\u{1F4BE}\", name: \"floppy_disk\", keywords: [\"floppy\", \"disk\", \"save\", \"data\", \"retro\"] },\n { emoji: \"\\u{1F4BD}\", name: \"minidisc\", keywords: [\"disc\", \"data\", \"storage\", \"retro\"] },\n { emoji: \"\\u{1F4C0}\", name: \"dvd\", keywords: [\"dvd\", \"disc\", \"movie\", \"data\", \"video\"] },\n { emoji: \"\\u{1FA78}\", name: \"drop_of_blood\", keywords: [\"blood\", \"drop\", \"medical\", \"health\", \"donate\"] },\n { emoji: \"\\u{1FA7C}\", name: \"crutch\", keywords: [\"crutch\", \"medical\", \"injury\", \"walk\", \"support\"] },\n { emoji: \"\\u{1FA7B}\", name: \"x_ray\", keywords: [\"xray\", \"medical\", \"bones\", \"doctor\", \"scan\"] },\n { emoji: \"\\u{1F6D2}\", name: \"shopping_cart\", keywords: [\"cart\", \"shopping\", \"buy\", \"store\", \"grocery\"] },\n { emoji: \"\\u{1F381}\", name: \"wrapped_gift\", keywords: [\"gift\", \"present\", \"birthday\", \"christmas\", \"wrap\"] },\n { emoji: \"\\u{1F380}\", name: \"ribbon\", keywords: [\"ribbon\", \"bow\", \"gift\", \"decoration\", \"pink\"] },\n { emoji: \"\\u{1F388}\", name: \"balloon\", keywords: [\"balloon\", \"party\", \"celebrate\", \"birthday\", \"float\"] },\n { emoji: \"\\u{1F389}\", name: \"party_popper\", keywords: [\"party\", \"celebrate\", \"confetti\", \"tada\", \"congratulations\"] },\n { emoji: \"\\u{1F38A}\", name: \"confetti_ball\", keywords: [\"confetti\", \"party\", \"celebrate\", \"ball\"] },\n { emoji: \"\\u{1F38E}\", name: \"japanese_dolls\", keywords: [\"dolls\", \"japanese\", \"festival\", \"hinamatsuri\"] },\n { emoji: \"\\u{1F3EE}\", name: \"red_paper_lantern\", keywords: [\"lantern\", \"red\", \"japanese\", \"light\", \"izakaya\"] },\n { emoji: \"\\u{1F9E8}\", name: \"firecracker\", keywords: [\"firecracker\", \"firework\", \"celebration\", \"new_year\", \"bang\"] },\n { emoji: \"\\u{1F386}\", name: \"fireworks\", keywords: [\"fireworks\", \"celebrate\", \"night\", \"sparkle\", \"new_year\"] },\n { emoji: \"\\u{1F387}\", name: \"sparkler\", keywords: [\"sparkler\", \"firework\", \"celebrate\", \"night\"] },\n { emoji: \"\\u{1FA9E}\", name: \"mirror\", keywords: [\"mirror\", \"reflection\", \"look\", \"vanity\"] },\n { emoji: \"\\u{1FA9F}\", name: \"window\", keywords: [\"window\", \"view\", \"frame\", \"glass\", \"house\"] },\n { emoji: \"\\u{1F6AA}\", name: \"door\", keywords: [\"door\", \"entrance\", \"exit\", \"open\", \"knock\"] },\n { emoji: \"\\u{1FA91}\", name: \"chair\", keywords: [\"chair\", \"seat\", \"sit\", \"furniture\"] },\n { emoji: \"\\u{1F6CB}\\u{FE0F}\", name: \"couch_and_lamp\", keywords: [\"couch\", \"sofa\", \"lamp\", \"furniture\", \"living_room\"] },\n { emoji: \"\\u{1F6CF}\\u{FE0F}\", name: \"bed\", keywords: [\"bed\", \"sleep\", \"bedroom\", \"furniture\", \"rest\"] },\n { emoji: \"\\u{1F6C1}\", name: \"bathtub\", keywords: [\"bathtub\", \"bath\", \"clean\", \"relax\", \"bathroom\"] },\n { emoji: \"\\u{1F6BF}\", name: \"shower\", keywords: [\"shower\", \"bath\", \"clean\", \"water\", \"bathroom\"] },\n { emoji: \"\\u{1F9F4}\", name: \"lotion_bottle\", keywords: [\"lotion\", \"cream\", \"moisturizer\", \"sunscreen\"] },\n { emoji: \"\\u{1F9F7}\", name: \"safety_pin\", keywords: [\"safety_pin\", \"pin\", \"diaper\", \"fix\"] },\n { emoji: \"\\u{1F9F5}\", name: \"thread\", keywords: [\"thread\", \"sewing\", \"needle\", \"string\"] },\n { emoji: \"\\u{1F9F6}\", name: \"yarn\", keywords: [\"yarn\", \"knitting\", \"crochet\", \"ball\", \"craft\"] },\n { emoji: \"\\u{1F453}\", name: \"glasses\", keywords: [\"glasses\", \"eyeglasses\", \"vision\", \"reading\", \"nerd\"] },\n { emoji: \"\\u{1F576}\\u{FE0F}\", name: \"sunglasses\", keywords: [\"sunglasses\", \"cool\", \"sun\", \"shades\", \"summer\"] },\n { emoji: \"\\u{1F302}\", name: \"closed_umbrella\", keywords: [\"umbrella\", \"rain\", \"weather\", \"closed\"] },\n { emoji: \"\\u{2602}\\u{FE0F}\", name: \"umbrella\", keywords: [\"umbrella\", \"rain\", \"weather\", \"wet\"] },\n { emoji: \"\\u{1F45C}\", name: \"handbag\", keywords: [\"handbag\", \"purse\", \"bag\", \"fashion\"] },\n { emoji: \"\\u{1F452}\", name: \"womans_hat\", keywords: [\"hat\", \"fashion\", \"sun\", \"accessory\"] },\n { emoji: \"\\u{1F3A9}\", name: \"top_hat\", keywords: [\"hat\", \"top_hat\", \"classy\", \"gentleman\", \"magic\"] },\n { emoji: \"\\u{1F455}\", name: \"t_shirt\", keywords: [\"tshirt\", \"shirt\", \"clothes\", \"top\", \"fashion\"] },\n { emoji: \"\\u{1F457}\", name: \"dress\", keywords: [\"dress\", \"clothes\", \"fashion\", \"outfit\"] },\n { emoji: \"\\u{1F45F}\", name: \"running_shoe\", keywords: [\"shoe\", \"sneaker\", \"running\", \"sport\", \"nike\"] },\n { emoji: \"\\u{1F460}\", name: \"high_heeled_shoe\", keywords: [\"heel\", \"shoe\", \"fashion\", \"stiletto\"] },\n\n { emoji: \"\\u{2705}\", name: \"check_mark_button\", keywords: [\"check\", \"done\", \"yes\", \"complete\", \"approve\", \"green\"] },\n { emoji: \"\\u{2714}\\u{FE0F}\", name: \"check_mark\", keywords: [\"check\", \"done\", \"yes\", \"tick\", \"correct\"] },\n { emoji: \"\\u{274C}\", name: \"cross_mark\", keywords: [\"x\", \"no\", \"wrong\", \"delete\", \"cancel\", \"red\"] },\n { emoji: \"\\u{274E}\", name: \"cross_mark_button\", keywords: [\"x\", \"no\", \"wrong\", \"cancel\", \"green\"] },\n { emoji: \"\\u{2B55}\", name: \"hollow_red_circle\", keywords: [\"circle\", \"red\", \"o\", \"ring\"] },\n { emoji: \"\\u{26A0}\\u{FE0F}\", name: \"warning\", keywords: [\"warning\", \"caution\", \"alert\", \"danger\", \"attention\"] },\n { emoji: \"\\u{1F6AB}\", name: \"prohibited\", keywords: [\"prohibited\", \"forbidden\", \"no\", \"banned\", \"stop\"] },\n { emoji: \"\\u{2139}\\u{FE0F}\", name: \"information\", keywords: [\"info\", \"information\", \"help\", \"details\"] },\n { emoji: \"\\u{2757}\", name: \"red_exclamation_mark\", keywords: [\"exclamation\", \"important\", \"warning\", \"alert\", \"bang\"] },\n { emoji: \"\\u{2753}\", name: \"red_question_mark\", keywords: [\"question\", \"what\", \"confused\", \"help\"] },\n { emoji: \"\\u{2049}\\u{FE0F}\", name: \"exclamation_question_mark\", keywords: [\"exclamation\", \"question\", \"surprise\", \"interrobang\"] },\n { emoji: \"\\u{1F198}\", name: \"sos_button\", keywords: [\"sos\", \"help\", \"emergency\", \"danger\"] },\n { emoji: \"\\u{1F195}\", name: \"new_button\", keywords: [\"new\", \"fresh\", \"update\", \"release\"] },\n { emoji: \"\\u{1F199}\", name: \"up_button\", keywords: [\"up\", \"update\", \"upgrade\", \"arrow\"] },\n { emoji: \"\\u{1F197}\", name: \"ok_button\", keywords: [\"ok\", \"approve\", \"accept\", \"good\"] },\n { emoji: \"\\u{1F192}\", name: \"cool_button\", keywords: [\"cool\", \"awesome\", \"great\", \"nice\"] },\n { emoji: \"\\u{1F193}\", name: \"free_button\", keywords: [\"free\", \"gratis\", \"no_charge\"] },\n { emoji: \"\\u{27A1}\\u{FE0F}\", name: \"right_arrow\", keywords: [\"arrow\", \"right\", \"direction\", \"next\", \"forward\"] },\n { emoji: \"\\u{2B05}\\u{FE0F}\", name: \"left_arrow\", keywords: [\"arrow\", \"left\", \"direction\", \"back\", \"previous\"] },\n { emoji: \"\\u{2B06}\\u{FE0F}\", name: \"up_arrow\", keywords: [\"arrow\", \"up\", \"direction\", \"top\"] },\n { emoji: \"\\u{2B07}\\u{FE0F}\", name: \"down_arrow\", keywords: [\"arrow\", \"down\", \"direction\", \"bottom\"] },\n { emoji: \"\\u{21A9}\\u{FE0F}\", name: \"right_arrow_curving_left\", keywords: [\"arrow\", \"return\", \"back\", \"reply\", \"undo\"] },\n { emoji: \"\\u{21AA}\\u{FE0F}\", name: \"left_arrow_curving_right\", keywords: [\"arrow\", \"forward\", \"redo\", \"redirect\"] },\n { emoji: \"\\u{1F504}\", name: \"counterclockwise_arrows_button\", keywords: [\"refresh\", \"reload\", \"sync\", \"rotate\", \"undo\"] },\n { emoji: \"\\u{1F503}\", name: \"clockwise_vertical_arrows\", keywords: [\"refresh\", \"reload\", \"sync\", \"cycle\"] },\n { emoji: \"\\u{267B}\\u{FE0F}\", name: \"recycling_symbol\", keywords: [\"recycle\", \"green\", \"environment\", \"eco\"] },\n { emoji: \"\\u{1F4AF}\", name: \"hundred_points\", keywords: [\"100\", \"hundred\", \"perfect\", \"score\", \"full\"] },\n { emoji: \"\\u{1F4A2}\", name: \"anger_symbol\", keywords: [\"anger\", \"angry\", \"mad\", \"punch\"] },\n { emoji: \"\\u{1F4AC}\", name: \"speech_balloon\", keywords: [\"speech\", \"bubble\", \"chat\", \"talk\", \"message\", \"comment\"] },\n { emoji: \"\\u{1F4AD}\", name: \"thought_balloon\", keywords: [\"thought\", \"thinking\", \"bubble\", \"dream\"] },\n { emoji: \"\\u{1F4A4}\", name: \"zzz\", keywords: [\"sleep\", \"zzz\", \"tired\", \"rest\", \"snore\"] },\n { emoji: \"\\u{1F508}\", name: \"speaker_low_volume\", keywords: [\"speaker\", \"volume\", \"low\", \"quiet\", \"sound\"] },\n { emoji: \"\\u{1F509}\", name: \"speaker_medium_volume\", keywords: [\"speaker\", \"volume\", \"medium\", \"sound\"] },\n { emoji: \"\\u{1F50A}\", name: \"speaker_high_volume\", keywords: [\"speaker\", \"volume\", \"high\", \"loud\", \"sound\"] },\n { emoji: \"\\u{1F507}\", name: \"muted_speaker\", keywords: [\"mute\", \"silent\", \"speaker\", \"no_sound\", \"quiet\"] },\n { emoji: \"\\u{2795}\", name: \"plus\", keywords: [\"plus\", \"add\", \"increase\", \"positive\", \"math\"] },\n { emoji: \"\\u{2796}\", name: \"minus\", keywords: [\"minus\", \"subtract\", \"decrease\", \"negative\", \"math\"] },\n { emoji: \"\\u{2716}\\u{FE0F}\", name: \"multiply\", keywords: [\"multiply\", \"times\", \"x\", \"math\", \"cancel\"] },\n { emoji: \"\\u{2797}\", name: \"divide\", keywords: [\"divide\", \"division\", \"math\", \"split\"] },\n { emoji: \"\\u{267E}\\u{FE0F}\", name: \"infinity\", keywords: [\"infinity\", \"forever\", \"unlimited\", \"math\", \"endless\"] },\n { emoji: \"\\u{1F4F4}\", name: \"mobile_phone_off\", keywords: [\"phone\", \"off\", \"silent\", \"airplane_mode\"] },\n { emoji: \"\\u{1F4F6}\", name: \"antenna_bars\", keywords: [\"signal\", \"bars\", \"wifi\", \"reception\", \"network\"] },\n { emoji: \"\\u{1F4E3}\", name: \"megaphone\", keywords: [\"megaphone\", \"announce\", \"shout\", \"loud\", \"speaker\"] },\n { emoji: \"\\u{269B}\\u{FE0F}\", name: \"atom_symbol\", keywords: [\"atom\", \"science\", \"physics\", \"nuclear\", \"symbol\"] },\n { emoji: \"\\u{2622}\\u{FE0F}\", name: \"radioactive\", keywords: [\"radioactive\", \"nuclear\", \"hazard\", \"danger\", \"radiation\"] },\n { emoji: \"\\u{2623}\\u{FE0F}\", name: \"biohazard\", keywords: [\"biohazard\", \"danger\", \"toxic\", \"hazard\", \"virus\"] },\n { emoji: \"\\u{262F}\\u{FE0F}\", name: \"yin_yang\", keywords: [\"yin_yang\", \"balance\", \"harmony\", \"zen\", \"tao\"] },\n { emoji: \"\\u{271D}\\u{FE0F}\", name: \"latin_cross\", keywords: [\"cross\", \"christian\", \"religion\", \"church\"] },\n { emoji: \"\\u{262E}\\u{FE0F}\", name: \"peace_symbol\", keywords: [\"peace\", \"symbol\", \"hippie\", \"love\", \"harmony\"] },\n { emoji: \"\\u{2648}\", name: \"aries\", keywords: [\"aries\", \"zodiac\", \"horoscope\", \"astrology\"] },\n { emoji: \"\\u{2649}\", name: \"taurus\", keywords: [\"taurus\", \"zodiac\", \"horoscope\", \"astrology\"] },\n { emoji: \"\\u{264A}\", name: \"gemini\", keywords: [\"gemini\", \"zodiac\", \"horoscope\", \"astrology\"] },\n { emoji: \"\\u{264B}\", name: \"cancer\", keywords: [\"cancer\", \"zodiac\", \"horoscope\", \"astrology\"] },\n { emoji: \"\\u{264C}\", name: \"leo\", keywords: [\"leo\", \"zodiac\", \"horoscope\", \"astrology\"] },\n { emoji: \"\\u{264D}\", name: \"virgo\", keywords: [\"virgo\", \"zodiac\", \"horoscope\", \"astrology\"] },\n { emoji: \"\\u{264E}\", name: \"libra\", keywords: [\"libra\", \"zodiac\", \"horoscope\", \"astrology\"] },\n { emoji: \"\\u{264F}\", name: \"scorpio\", keywords: [\"scorpio\", \"zodiac\", \"horoscope\", \"astrology\"] },\n { emoji: \"\\u{2650}\", name: \"sagittarius\", keywords: [\"sagittarius\", \"zodiac\", \"horoscope\", \"astrology\"] },\n { emoji: \"\\u{2651}\", name: \"capricorn\", keywords: [\"capricorn\", \"zodiac\", \"horoscope\", \"astrology\"] },\n { emoji: \"\\u{2652}\", name: \"aquarius\", keywords: [\"aquarius\", \"zodiac\", \"horoscope\", \"astrology\"] },\n { emoji: \"\\u{2653}\", name: \"pisces\", keywords: [\"pisces\", \"zodiac\", \"horoscope\", \"astrology\"] },\n { emoji: \"\\u{1F4AE}\", name: \"white_flower\", keywords: [\"flower\", \"white\", \"japanese\", \"score\", \"brilliant\"] },\n { emoji: \"\\u{1F4B2}\", name: \"heavy_dollar_sign\", keywords: [\"dollar\", \"money\", \"currency\", \"cash\", \"price\"] },\n { emoji: \"\\u{00A9}\\u{FE0F}\", name: \"copyright\", keywords: [\"copyright\", \"ip\", \"legal\", \"circle_c\"] },\n { emoji: \"\\u{00AE}\\u{FE0F}\", name: \"registered\", keywords: [\"registered\", \"trademark\", \"legal\", \"brand\"] },\n { emoji: \"\\u{2122}\\u{FE0F}\", name: \"trade_mark\", keywords: [\"trademark\", \"tm\", \"brand\", \"legal\"] },\n { emoji: \"\\u{0023}\\u{FE0F}\\u{20E3}\", name: \"keycap_hash\", keywords: [\"hash\", \"number\", \"hashtag\", \"pound\"] },\n { emoji: \"\\u{002A}\\u{FE0F}\\u{20E3}\", name: \"keycap_asterisk\", keywords: [\"asterisk\", \"star\", \"symbol\", \"key\"] },\n { emoji: \"\\u{0030}\\u{FE0F}\\u{20E3}\", name: \"keycap_0\", keywords: [\"zero\", \"0\", \"number\", \"key\"] },\n { emoji: \"\\u{0031}\\u{FE0F}\\u{20E3}\", name: \"keycap_1\", keywords: [\"one\", \"1\", \"number\", \"key\"] },\n { emoji: \"\\u{0032}\\u{FE0F}\\u{20E3}\", name: \"keycap_2\", keywords: [\"two\", \"2\", \"number\", \"key\"] },\n { emoji: \"\\u{0033}\\u{FE0F}\\u{20E3}\", name: \"keycap_3\", keywords: [\"three\", \"3\", \"number\", \"key\"] },\n { emoji: \"\\u{1F3B4}\", name: \"flower_playing_cards\", keywords: [\"cards\", \"game\", \"japanese\", \"hanafuda\"] },\n { emoji: \"\\u{1F0CF}\", name: \"joker\", keywords: [\"joker\", \"card\", \"wild\", \"game\", \"playing\"] },\n { emoji: \"\\u{2660}\\u{FE0F}\", name: \"spade_suit\", keywords: [\"spade\", \"card\", \"suit\", \"poker\"] },\n { emoji: \"\\u{2665}\\u{FE0F}\", name: \"heart_suit\", keywords: [\"heart\", \"card\", \"suit\", \"poker\", \"love\"] },\n { emoji: \"\\u{2666}\\u{FE0F}\", name: \"diamond_suit\", keywords: [\"diamond\", \"card\", \"suit\", \"poker\"] },\n { emoji: \"\\u{2663}\\u{FE0F}\", name: \"club_suit\", keywords: [\"club\", \"card\", \"suit\", \"poker\"] },\n { emoji: \"\\u{1F500}\", name: \"shuffle_tracks_button\", keywords: [\"shuffle\", \"random\", \"mix\", \"music\"] },\n { emoji: \"\\u{1F501}\", name: \"repeat_button\", keywords: [\"repeat\", \"loop\", \"again\", \"music\"] },\n { emoji: \"\\u{25B6}\\u{FE0F}\", name: \"play_button\", keywords: [\"play\", \"start\", \"video\", \"music\", \"go\"] },\n { emoji: \"\\u{23F8}\\u{FE0F}\", name: \"pause_button\", keywords: [\"pause\", \"stop\", \"wait\", \"hold\"] },\n { emoji: \"\\u{23F9}\\u{FE0F}\", name: \"stop_button\", keywords: [\"stop\", \"end\", \"halt\", \"square\"] },\n { emoji: \"\\u{23ED}\\u{FE0F}\", name: \"next_track_button\", keywords: [\"next\", \"skip\", \"forward\", \"track\"] },\n { emoji: \"\\u{23EE}\\u{FE0F}\", name: \"previous_track_button\", keywords: [\"previous\", \"back\", \"rewind\", \"track\"] },\n { emoji: \"\\u{23FA}\\u{FE0F}\", name: \"record_button\", keywords: [\"record\", \"red\", \"circle\", \"recording\"] },\n { emoji: \"\\u{1F505}\", name: \"dim_button\", keywords: [\"brightness\", \"dim\", \"low\", \"dark\"] },\n { emoji: \"\\u{1F506}\", name: \"bright_button\", keywords: [\"brightness\", \"bright\", \"high\", \"light\"] },\n { emoji: \"\\u{1F170}\\u{FE0F}\", name: \"a_button_blood_type\", keywords: [\"a\", \"blood\", \"type\", \"letter\"] },\n { emoji: \"\\u{1F171}\\u{FE0F}\", name: \"b_button_blood_type\", keywords: [\"b\", \"blood\", \"type\", \"letter\"] },\n { emoji: \"\\u{1F17E}\\u{FE0F}\", name: \"o_button_blood_type\", keywords: [\"o\", \"blood\", \"type\", \"letter\"] },\n\n { emoji: \"\\u{1F1FA}\\u{1F1F8}\", name: \"flag_united_states\", keywords: [\"flag\", \"us\", \"usa\", \"america\", \"united_states\"] },\n { emoji: \"\\u{1F1EC}\\u{1F1E7}\", name: \"flag_united_kingdom\", keywords: [\"flag\", \"uk\", \"britain\", \"england\", \"united_kingdom\"] },\n { emoji: \"\\u{1F1EB}\\u{1F1F7}\", name: \"flag_france\", keywords: [\"flag\", \"france\", \"french\", \"paris\"] },\n { emoji: \"\\u{1F1E9}\\u{1F1EA}\", name: \"flag_germany\", keywords: [\"flag\", \"germany\", \"german\", \"berlin\"] },\n { emoji: \"\\u{1F1EE}\\u{1F1F9}\", name: \"flag_italy\", keywords: [\"flag\", \"italy\", \"italian\", \"rome\"] },\n { emoji: \"\\u{1F1EA}\\u{1F1F8}\", name: \"flag_spain\", keywords: [\"flag\", \"spain\", \"spanish\", \"madrid\"] },\n { emoji: \"\\u{1F1F5}\\u{1F1F9}\", name: \"flag_portugal\", keywords: [\"flag\", \"portugal\", \"portuguese\", \"lisbon\"] },\n { emoji: \"\\u{1F1EF}\\u{1F1F5}\", name: \"flag_japan\", keywords: [\"flag\", \"japan\", \"japanese\", \"tokyo\"] },\n { emoji: \"\\u{1F1F0}\\u{1F1F7}\", name: \"flag_south_korea\", keywords: [\"flag\", \"korea\", \"south_korea\", \"korean\", \"seoul\"] },\n { emoji: \"\\u{1F1E8}\\u{1F1F3}\", name: \"flag_china\", keywords: [\"flag\", \"china\", \"chinese\", \"beijing\"] },\n { emoji: \"\\u{1F1EE}\\u{1F1F3}\", name: \"flag_india\", keywords: [\"flag\", \"india\", \"indian\", \"delhi\"] },\n { emoji: \"\\u{1F1E7}\\u{1F1F7}\", name: \"flag_brazil\", keywords: [\"flag\", \"brazil\", \"brazilian\"] },\n { emoji: \"\\u{1F1E8}\\u{1F1E6}\", name: \"flag_canada\", keywords: [\"flag\", \"canada\", \"canadian\", \"maple\"] },\n { emoji: \"\\u{1F1E6}\\u{1F1FA}\", name: \"flag_australia\", keywords: [\"flag\", \"australia\", \"australian\"] },\n { emoji: \"\\u{1F1F7}\\u{1F1FA}\", name: \"flag_russia\", keywords: [\"flag\", \"russia\", \"russian\", \"moscow\"] },\n { emoji: \"\\u{1F1F2}\\u{1F1FD}\", name: \"flag_mexico\", keywords: [\"flag\", \"mexico\", \"mexican\"] },\n { emoji: \"\\u{1F1E6}\\u{1F1F7}\", name: \"flag_argentina\", keywords: [\"flag\", \"argentina\", \"argentine\"] },\n { emoji: \"\\u{1F1F3}\\u{1F1EC}\", name: \"flag_nigeria\", keywords: [\"flag\", \"nigeria\", \"nigerian\"] },\n { emoji: \"\\u{1F1F8}\\u{1F1E6}\", name: \"flag_saudi_arabia\", keywords: [\"flag\", \"saudi_arabia\", \"saudi\"] },\n { emoji: \"\\u{1F1F9}\\u{1F1F7}\", name: \"flag_turkey\", keywords: [\"flag\", \"turkey\", \"turkish\"] },\n { emoji: \"\\u{1F1EE}\\u{1F1F1}\", name: \"flag_israel\", keywords: [\"flag\", \"israel\", \"israeli\", \"jerusalem\"] },\n { emoji: \"\\u{1F3C1}\", name: \"chequered_flag\", keywords: [\"flag\", \"checkered\", \"race\", \"finish\", \"winner\"] },\n { emoji: \"\\u{1F6A9}\", name: \"triangular_flag\", keywords: [\"flag\", \"triangle\", \"red\", \"mark\"] },\n { emoji: \"\\u{1F3F3}\\u{FE0F}\", name: \"white_flag\", keywords: [\"flag\", \"white\", \"surrender\", \"peace\"] },\n { emoji: \"\\u{1F3F4}\", name: \"black_flag\", keywords: [\"flag\", \"black\", \"pirate\"] },\n { emoji: \"\\u{1F3F3}\\u{FE0F}\\u{200D}\\u{1F308}\", name: \"rainbow_flag\", keywords: [\"flag\", \"rainbow\", \"pride\", \"lgbtq\", \"gay\"] },\n];\n","\"use client\";\n\nimport { useCallback, useEffect, useRef, useState } from \"react\";\n\nimport { createPortal } from \"react-dom\";\n\nimport { useLexicalComposerContext } from \"@lexical/react/LexicalComposerContext\";\nimport {\n $getSelection,\n $isRangeSelection,\n COMMAND_PRIORITY_LOW,\n SELECTION_CHANGE_COMMAND,\n} from \"lexical\";\n\nimport { OPEN_LINK_INPUT_COMMAND } from \"../commands\";\n\nimport {\n $isLinkNode,\n $toggleLink,\n TOGGLE_LINK_COMMAND,\n LinkNode,\n} from \"@lexical/link\";\n\nimport {\n LinkIcon,\n PencilSimpleIcon,\n TrashIcon,\n ArrowSquareOutIcon,\n} from \"@phosphor-icons/react\";\n\nexport interface LinkInputRenderProps {\n initialUrl: string;\n onSubmit: (url: string) => void;\n onRemove: () => void;\n onClose: () => void;\n position: { top: number; left: number };\n}\n\nexport interface LinkPreviewRenderProps {\n url: string;\n onEdit: () => void;\n onRemove: () => void;\n onClose: () => void;\n position: { top: number; left: number };\n}\n\nexport interface LinkPluginConfig {\n /** Custom render for the link input popover. */\n renderLinkInput?: (props: LinkInputRenderProps) => React.ReactNode;\n /** Custom render for the link preview popover. */\n renderLinkPreview?: (props: LinkPreviewRenderProps) => React.ReactNode;\n /** Validate URL before applying (default: basic URL validation). */\n validateUrl?: (url: string) => boolean;\n /** Link target behavior (default: \"_blank\"). */\n target?: string;\n /** Link rel attribute (default: \"noopener noreferrer\"). */\n rel?: string;\n}\n\nexport function LinkPlugin({ config = {} }: { config?: LinkPluginConfig } = {}) {\n const [editor] = useLexicalComposerContext();\n const [portalContainer, setPortalContainer] = useState<HTMLElement | null>(\n null,\n );\n const [showInput, setShowInput] = useState(false);\n const [showPreview, setShowPreview] = useState(false);\n const [inputPosition, setInputPosition] = useState({ top: 0, left: 0 });\n const [previewPosition, setPreviewPosition] = useState({ top: 0, left: 0 });\n const [currentUrl, setCurrentUrl] = useState(\"\");\n const [editingUrl, setEditingUrl] = useState(\"\");\n const inputRef = useRef<HTMLInputElement>(null);\n\n const target = config.target ?? \"_blank\";\n const rel = config.rel ?? \"noopener noreferrer\";\n\n const validateUrl =\n config.validateUrl ??\n ((url: string) => {\n try {\n // Allow URLs with or without protocol\n const withProtocol = url.match(/^https?:\\/\\//) ? url : `https://${url}`;\n new URL(withProtocol);\n return true;\n } catch {\n return false;\n }\n });\n\n useEffect(() => {\n if (typeof window === \"undefined\") return;\n setPortalContainer(document.body);\n }, []);\n\n // Register TOGGLE_LINK_COMMAND handler (required for $toggleLink to work)\n useEffect(() => {\n return editor.registerCommand(\n TOGGLE_LINK_COMMAND,\n (payload) => {\n if (payload === null) {\n $toggleLink(null);\n } else if (typeof payload === \"string\") {\n $toggleLink(payload, { target, rel });\n } else {\n $toggleLink(payload.url, {\n target: payload.target ?? target,\n rel: payload.rel ?? rel,\n title: payload.title ?? null,\n });\n }\n return true;\n },\n COMMAND_PRIORITY_LOW,\n );\n }, [editor, target, rel]);\n\n const getSelectionPosition = useCallback(() => {\n const domSelection = window.getSelection();\n if (domSelection && domSelection.rangeCount > 0) {\n const range = domSelection.getRangeAt(0);\n const rect = range.getBoundingClientRect();\n return {\n top: rect.bottom + 6,\n left: rect.left + rect.width / 2,\n };\n }\n return { top: 0, left: 0 };\n }, []);\n\n const findLinkNode = useCallback((): LinkNode | null => {\n let linkNode: LinkNode | null = null;\n editor.read(() => {\n const selection = $getSelection();\n if (!$isRangeSelection(selection)) return;\n const node = selection.anchor.getNode();\n const parent = node.getParent();\n if ($isLinkNode(parent)) {\n linkNode = parent;\n } else if ($isLinkNode(node)) {\n linkNode = node;\n }\n });\n return linkNode;\n }, [editor]);\n\n const openInput = useCallback(\n (initialUrl = \"\") => {\n setEditingUrl(initialUrl);\n setInputPosition(getSelectionPosition());\n setShowPreview(false);\n setShowInput(true);\n\n // Focus input after render (only for built-in input)\n if (!config.renderLinkInput) {\n requestAnimationFrame(() => {\n inputRef.current?.focus();\n inputRef.current?.select();\n });\n }\n },\n [getSelectionPosition, config.renderLinkInput],\n );\n\n const closeAll = useCallback(() => {\n setShowInput(false);\n setShowPreview(false);\n setCurrentUrl(\"\");\n setEditingUrl(\"\");\n editor.focus();\n }, [editor]);\n\n const submitLink = useCallback(\n (url: string) => {\n const trimmed = url.trim();\n if (!trimmed) {\n closeAll();\n return;\n }\n\n // Add protocol if missing\n const finalUrl = trimmed.match(/^https?:\\/\\//)\n ? trimmed\n : `https://${trimmed}`;\n\n if (!validateUrl(finalUrl)) {\n closeAll();\n return;\n }\n\n editor.dispatchCommand(TOGGLE_LINK_COMMAND, {\n url: finalUrl,\n target,\n rel,\n });\n closeAll();\n },\n [editor, validateUrl, target, rel, closeAll],\n );\n\n const removeLink = useCallback(() => {\n editor.dispatchCommand(TOGGLE_LINK_COMMAND, null);\n closeAll();\n }, [editor, closeAll]);\n\n const triggerLinkInput = useCallback(() => {\n const linkNode = findLinkNode();\n if (linkNode) {\n openInput(linkNode.getURL());\n } else {\n let hasSelection = false;\n editor.read(() => {\n const selection = $getSelection();\n if (\n $isRangeSelection(selection) &&\n !selection.isCollapsed()\n ) {\n hasSelection = true;\n }\n });\n\n if (hasSelection) {\n openInput();\n }\n }\n }, [editor, findLinkNode, openInput]);\n\n // Double-click on a link opens it in a new tab\n useEffect(() => {\n const rootElement = editor.getRootElement();\n if (!rootElement) return;\n\n const handleDblClick = (event: MouseEvent) => {\n const target = event.target as HTMLElement;\n const anchor = target.closest(\"a\");\n if (!anchor || !rootElement.contains(anchor)) return;\n\n const href = anchor.getAttribute(\"href\");\n if (href) {\n event.preventDefault();\n window.open(href, \"_blank\", \"noopener,noreferrer\");\n }\n };\n\n rootElement.addEventListener(\"dblclick\", handleDblClick);\n return () => rootElement.removeEventListener(\"dblclick\", handleDblClick);\n }, [editor]);\n\n // Cmd+K shortcut — listen on document for reliable interception\n useEffect(() => {\n const handleKeyDown = (event: KeyboardEvent) => {\n if ((event.metaKey || event.ctrlKey) && event.key === \"k\") {\n // Check if our editor has focus BEFORE manipulating the event\n const rootElement = editor.getRootElement();\n if (!rootElement) return;\n const activeElement = document.activeElement;\n if (!rootElement.contains(activeElement) && activeElement !== rootElement) return;\n\n event.preventDefault();\n event.stopPropagation();\n triggerLinkInput();\n }\n };\n\n document.addEventListener(\"keydown\", handleKeyDown);\n\n // Signal that the link plugin's keyboard handler is ready\n const rootElement = editor.getRootElement();\n if (rootElement) {\n rootElement.setAttribute(\"data-link-plugin-ready\", \"true\");\n }\n\n return () => {\n document.removeEventListener(\"keydown\", handleKeyDown);\n const el = editor.getRootElement();\n if (el) {\n el.removeAttribute(\"data-link-plugin-ready\");\n }\n };\n }, [editor, triggerLinkInput]);\n\n // Listen for OPEN_LINK_INPUT_COMMAND (from FloatingToolbar link button)\n useEffect(() => {\n return editor.registerCommand(\n OPEN_LINK_INPUT_COMMAND,\n () => {\n triggerLinkInput();\n return true;\n },\n COMMAND_PRIORITY_LOW,\n );\n }, [editor, triggerLinkInput]);\n\n const linkSelRafRef = useRef(0);\n useEffect(() => {\n return editor.registerCommand(\n SELECTION_CHANGE_COMMAND,\n () => {\n if (linkSelRafRef.current === 0) {\n linkSelRafRef.current = requestAnimationFrame(() => {\n linkSelRafRef.current = 0;\n // Don't show preview if input is open\n if (showInput) return;\n\n const linkNode = findLinkNode();\n if (linkNode) {\n setCurrentUrl(linkNode.getURL());\n setPreviewPosition(getSelectionPosition());\n setShowPreview(true);\n } else {\n if (showPreview) {\n setShowPreview(false);\n setCurrentUrl(\"\");\n }\n }\n });\n }\n return false;\n },\n COMMAND_PRIORITY_LOW,\n );\n }, [editor, findLinkNode, getSelectionPosition, showInput, showPreview]);\n\n if (!portalContainer) return null;\n\n const inputRenderProps: LinkInputRenderProps = {\n initialUrl: editingUrl,\n onSubmit: submitLink,\n onRemove: removeLink,\n onClose: closeAll,\n position: inputPosition,\n };\n\n const inputPopover = showInput\n ? createPortal(\n config.renderLinkInput ? (\n config.renderLinkInput(inputRenderProps)\n ) : (\n <LinkInputPopover\n ref={inputRef}\n {...inputRenderProps}\n />\n ),\n portalContainer,\n )\n : null;\n\n const previewRenderProps: LinkPreviewRenderProps = {\n url: currentUrl,\n onEdit: () => openInput(currentUrl),\n onRemove: removeLink,\n onClose: () => {\n setShowPreview(false);\n setCurrentUrl(\"\");\n },\n position: previewPosition,\n };\n\n const previewPopover =\n showPreview && !showInput\n ? createPortal(\n config.renderLinkPreview ? (\n config.renderLinkPreview(previewRenderProps)\n ) : (\n <LinkPreviewPopover {...previewRenderProps} />\n ),\n portalContainer,\n )\n : null;\n\n return (\n <>\n {inputPopover}\n {previewPopover}\n </>\n );\n}\n\nimport { forwardRef } from \"react\";\n\nconst LinkInputPopover = forwardRef<HTMLInputElement, LinkInputRenderProps>(\n function LinkInputPopover(\n { initialUrl, onSubmit, onRemove, onClose, position },\n ref,\n ) {\n const [value, setValue] = useState(initialUrl);\n const containerRef = useRef<HTMLDivElement>(null);\n const isEditing = initialUrl !== \"\";\n\n // Initialize value when initialUrl changes\n useEffect(() => {\n setValue(initialUrl);\n }, [initialUrl]);\n\n // Close on click outside\n useEffect(() => {\n const handleClickOutside = (e: MouseEvent) => {\n if (\n containerRef.current &&\n !containerRef.current.contains(e.target as Node)\n ) {\n onClose();\n }\n };\n\n const raf = requestAnimationFrame(() => {\n document.addEventListener(\"mousedown\", handleClickOutside);\n });\n return () => {\n cancelAnimationFrame(raf);\n document.removeEventListener(\"mousedown\", handleClickOutside);\n };\n }, [onClose]);\n\n const handleKeyDown = (e: React.KeyboardEvent<HTMLInputElement>) => {\n e.stopPropagation();\n\n if (e.key === \"Enter\" && !e.shiftKey) {\n e.preventDefault();\n onSubmit(value);\n }\n if (e.key === \"Escape\") {\n e.preventDefault();\n onClose();\n }\n };\n\n return (\n <div\n ref={containerRef}\n data-testid=\"link-input-popover\"\n style={{\n position: \"fixed\",\n top: `${position.top}px`,\n left: `${position.left}px`,\n transform: \"translateX(-50%)\",\n zIndex: 60,\n display: \"flex\",\n alignItems: \"center\",\n gap: \"6px\",\n padding: \"6px 8px 6px 12px\",\n borderRadius: \"12px\",\n border: \"1px solid var(--blokhaus-popover-border)\",\n backgroundColor: \"var(--blokhaus-popover-bg)\",\n backdropFilter: \"blur(20px) saturate(180%)\",\n WebkitBackdropFilter: \"blur(20px) saturate(180%)\",\n boxShadow: \"var(--blokhaus-popover-shadow)\",\n fontFamily:\n '-apple-system, BlinkMacSystemFont, \"SF Pro Text\", system-ui, sans-serif',\n animation: \"blokhaus-link-enter 0.15s ease-out\",\n minWidth: \"300px\",\n }}\n >\n <LinkIcon size={14} style={{ color: \"var(--blokhaus-text-tertiary)\", flexShrink: 0 }} />\n <input\n ref={ref}\n type=\"text\"\n value={value}\n onChange={(e) => setValue(e.target.value)}\n onKeyDown={handleKeyDown}\n placeholder=\"Paste or type a link...\"\n style={{\n flex: 1,\n border: \"none\",\n outline: \"none\",\n background: \"transparent\",\n fontSize: \"13px\",\n color: \"var(--blokhaus-foreground, #0f172a)\",\n fontFamily: \"inherit\",\n }}\n />\n <button\n type=\"button\"\n data-testid=\"link-input-apply\"\n onMouseDown={(e) => {\n e.preventDefault();\n onSubmit(value);\n }}\n disabled={!value.trim()}\n style={{\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n padding: \"4px 10px\",\n borderRadius: \"8px\",\n border: \"none\",\n cursor: value.trim() ? \"pointer\" : \"default\",\n backgroundColor: value.trim()\n ? \"var(--blokhaus-accent, #007AFF)\"\n : \"var(--blokhaus-hover-bg)\",\n color: value.trim() ? \"var(--blokhaus-accent-foreground, #fff)\" : \"var(--blokhaus-text-tertiary)\",\n fontSize: \"12px\",\n fontWeight: 500,\n fontFamily: \"inherit\",\n transition: \"background-color 0.15s, color 0.15s\",\n }}\n >\n {isEditing ? \"Update\" : \"Apply\"}\n </button>\n {isEditing && (\n <button\n type=\"button\"\n data-testid=\"link-input-remove\"\n onMouseDown={(e) => {\n e.preventDefault();\n onRemove();\n }}\n title=\"Remove link\"\n style={{\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n width: \"28px\",\n height: \"28px\",\n borderRadius: \"8px\",\n border: \"none\",\n cursor: \"pointer\",\n backgroundColor: \"transparent\",\n color: \"var(--blokhaus-destructive, #ef4444)\",\n transition: \"background-color 0.15s\",\n }}\n >\n <TrashIcon size={14} />\n </button>\n )}\n\n <style\n dangerouslySetInnerHTML={{\n __html: `\n @keyframes blokhaus-link-enter {\n from {\n opacity: 0;\n transform: translateX(-50%) translateY(-4px) scale(0.98);\n }\n to {\n opacity: 1;\n transform: translateX(-50%) translateY(0) scale(1);\n }\n }\n `,\n }}\n />\n </div>\n );\n },\n);\n\nfunction LinkPreviewPopover({\n url,\n onEdit,\n onRemove,\n onClose,\n position,\n}: LinkPreviewRenderProps) {\n const containerRef = useRef<HTMLDivElement>(null);\n\n // Close on click outside\n useEffect(() => {\n const handleClickOutside = (e: MouseEvent) => {\n if (\n containerRef.current &&\n !containerRef.current.contains(e.target as Node)\n ) {\n onClose();\n }\n };\n\n const raf = requestAnimationFrame(() => {\n document.addEventListener(\"mousedown\", handleClickOutside);\n });\n return () => {\n cancelAnimationFrame(raf);\n document.removeEventListener(\"mousedown\", handleClickOutside);\n };\n }, [onClose]);\n\n // Truncate long URLs for display\n const displayUrl =\n url.length > 40 ? url.slice(0, 37) + \"...\" : url;\n\n return (\n <div\n ref={containerRef}\n data-testid=\"link-preview-popover\"\n style={{\n position: \"fixed\",\n top: `${position.top}px`,\n left: `${position.left}px`,\n transform: \"translateX(-50%)\",\n zIndex: 60,\n display: \"flex\",\n alignItems: \"center\",\n gap: \"6px\",\n padding: \"5px 6px 5px 12px\",\n borderRadius: \"10px\",\n border: \"1px solid var(--blokhaus-popover-border)\",\n backgroundColor: \"var(--blokhaus-popover-bg)\",\n backdropFilter: \"blur(20px) saturate(180%)\",\n WebkitBackdropFilter: \"blur(20px) saturate(180%)\",\n boxShadow: \"var(--blokhaus-popover-shadow)\",\n fontFamily:\n '-apple-system, BlinkMacSystemFont, \"SF Pro Text\", system-ui, sans-serif',\n animation: \"blokhaus-link-preview-enter 0.12s ease-out\",\n }}\n >\n <a\n href={url}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n style={{\n fontSize: \"12px\",\n color: \"var(--blokhaus-accent, #007AFF)\",\n textDecoration: \"none\",\n whiteSpace: \"nowrap\",\n overflow: \"hidden\",\n textOverflow: \"ellipsis\",\n maxWidth: \"200px\",\n }}\n title={url}\n >\n {displayUrl}\n </a>\n\n <div\n style={{\n width: \"1px\",\n height: \"16px\",\n backgroundColor: \"var(--blokhaus-separator)\",\n flexShrink: 0,\n }}\n />\n\n <button\n type=\"button\"\n data-testid=\"link-preview-open\"\n onMouseDown={(e) => {\n e.preventDefault();\n window.open(url, \"_blank\", \"noopener,noreferrer\");\n }}\n title=\"Open in new tab\"\n style={{\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n width: \"26px\",\n height: \"26px\",\n borderRadius: \"6px\",\n border: \"none\",\n cursor: \"pointer\",\n backgroundColor: \"transparent\",\n color: \"var(--blokhaus-icon-secondary)\",\n }}\n >\n <ArrowSquareOutIcon size={14} />\n </button>\n\n <button\n type=\"button\"\n data-testid=\"link-preview-edit\"\n onMouseDown={(e) => {\n e.preventDefault();\n onEdit();\n }}\n title=\"Edit link\"\n style={{\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n width: \"26px\",\n height: \"26px\",\n borderRadius: \"6px\",\n border: \"none\",\n cursor: \"pointer\",\n backgroundColor: \"transparent\",\n color: \"var(--blokhaus-icon-secondary)\",\n }}\n >\n <PencilSimpleIcon size={14} />\n </button>\n\n <button\n type=\"button\"\n data-testid=\"link-preview-remove\"\n onMouseDown={(e) => {\n e.preventDefault();\n onRemove();\n }}\n title=\"Remove link\"\n style={{\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n width: \"26px\",\n height: \"26px\",\n borderRadius: \"6px\",\n border: \"none\",\n cursor: \"pointer\",\n backgroundColor: \"transparent\",\n color: \"var(--blokhaus-destructive, #ef4444)\",\n }}\n >\n <TrashIcon size={14} />\n </button>\n\n <style\n dangerouslySetInnerHTML={{\n __html: `\n @keyframes blokhaus-link-preview-enter {\n from {\n opacity: 0;\n transform: translateX(-50%) translateY(-2px);\n }\n to {\n opacity: 1;\n transform: translateX(-50%) translateY(0);\n }\n }\n `,\n }}\n />\n </div>\n );\n}\n","'use client';\n\n// REACT\nimport { useEffect, useRef, useState } from 'react';\n\n// LEXICAL\nimport { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext';\n\ninterface UseEditorStateOptions {\n /**\n * Debounce delay in milliseconds. Do not set below 200ms.\n * High-frequency editor.update() calls on every keystroke will\n * degrade performance on large documents.\n */\n debounceMs?: number;\n onChange?: (serializedState: string) => void;\n}\n\nexport function useEditorState({\n debounceMs = 300,\n onChange,\n}: UseEditorStateOptions = {}) {\n const [editor] = useLexicalComposerContext();\n const [serializedState, setSerializedState] = useState<string>('');\n const onChangeRef = useRef(onChange);\n onChangeRef.current = onChange;\n\n useEffect(() => {\n let timeout: ReturnType<typeof setTimeout> | null = null;\n // Keep a ref to the latest editorState so we only serialize once when\n // the debounce fires, using the most recent state (not every intermediate one).\n let latestEditorState: import('lexical').EditorState | null = null;\n\n const unregister = editor.registerUpdateListener(({ editorState }) => {\n latestEditorState = editorState;\n if (timeout) clearTimeout(timeout);\n\n timeout = setTimeout(() => {\n if (!latestEditorState) return;\n const json = JSON.stringify(latestEditorState.toJSON());\n latestEditorState = null;\n // Only trigger React re-render if no onChange callback is handling it\n if (!onChangeRef.current) {\n setSerializedState(json);\n }\n onChangeRef.current?.(json);\n }, debounceMs);\n });\n\n return () => {\n unregister();\n if (timeout) clearTimeout(timeout);\n };\n }, [editor, debounceMs]);\n\n return { serializedState };\n}\n","'use client';\n\nimport { useEffect, useRef, useState } from 'react';\nimport { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext';\nimport { $getRoot } from 'lexical';\n\ninterface WordCountResult {\n words: number;\n characters: number;\n}\n\nexport function useWordCount(debounceMs = 300): WordCountResult {\n const [editor] = useLexicalComposerContext();\n const [counts, setCounts] = useState<WordCountResult>({ words: 0, characters: 0 });\n const timeoutRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n\n useEffect(() => {\n const unregister = editor.registerUpdateListener(({ editorState }) => {\n if (timeoutRef.current) clearTimeout(timeoutRef.current);\n\n timeoutRef.current = setTimeout(() => {\n editorState.read(() => {\n const text = $getRoot().getTextContent();\n const characters = text.length;\n const words = text.trim() === '' ? 0 : text.trim().split(/\\s+/).length;\n setCounts({ words, characters });\n });\n }, debounceMs);\n });\n\n return () => {\n unregister();\n if (timeoutRef.current) clearTimeout(timeoutRef.current);\n };\n }, [editor, debounceMs]);\n\n return counts;\n}\n","\"use client\";\n\n// REACT\nimport { useCallback, useEffect, useRef, useState } from \"react\";\n\n// LEXICAL\nimport { useLexicalComposerContext } from \"@lexical/react/LexicalComposerContext\";\nimport { FORMAT_TEXT_COMMAND } from \"lexical\";\n\n// REACT DOM\nimport { createPortal } from \"react-dom\";\n\n// PHOSPHOR ICONS\nimport {\n TextBIcon,\n TextItalicIcon,\n TextUnderlineIcon,\n TextStrikethroughIcon,\n CodeIcon,\n} from \"@phosphor-icons/react\";\nimport type { IconWeight } from \"@phosphor-icons/react\";\n\ntype TextFormat = \"bold\" | \"italic\" | \"underline\" | \"strikethrough\" | \"code\";\n\ninterface ToolbarButton {\n icon: React.ComponentType<{ size?: number; weight?: IconWeight }>;\n format: TextFormat;\n label: string;\n}\n\nconst TOOLBAR_BUTTONS: ToolbarButton[] = [\n { icon: TextBIcon, format: \"bold\", label: \"Bold\" },\n { icon: TextItalicIcon, format: \"italic\", label: \"Italic\" },\n { icon: TextUnderlineIcon, format: \"underline\", label: \"Underline\" },\n { icon: TextStrikethroughIcon, format: \"strikethrough\", label: \"Strikethrough\" },\n { icon: CodeIcon, format: \"code\", label: \"Inline Code\" },\n];\n\n/**\n * MobileToolbar — bottom-anchored formatting toolbar for touch devices.\n *\n * Renders a fixed toolbar at the bottom of the viewport when the user\n * has selected text inside the editor. Completely hidden on non-touch devices.\n *\n * See CLAUDE.md Section 14 for the specification.\n */\nexport function MobileToolbar() {\n const [editor] = useLexicalComposerContext();\n const [isTouchDevice, setIsTouchDevice] = useState<boolean | null>(null);\n const [isVisible, setIsVisible] = useState(false);\n const [portalContainer, setPortalContainer] = useState<HTMLElement | null>(null);\n const rootElementRef = useRef<HTMLElement | null>(null);\n\n // Detect touch device once on mount — use multiple signals for reliability\n // Chrome DevTools device emulation doesn't always set pointer: coarse\n useEffect(() => {\n if (typeof window === \"undefined\") return;\n const isTouch =\n window.matchMedia(\"(pointer: coarse)\").matches ||\n navigator.maxTouchPoints > 0 ||\n \"ontouchstart\" in window;\n setIsTouchDevice(isTouch);\n setPortalContainer(document.body);\n }, []);\n\n // Cache the editor root element\n useEffect(() => {\n rootElementRef.current = editor.getRootElement();\n }, [editor]);\n\n // Listen to selectionchange to show/hide toolbar\n useEffect(() => {\n if (isTouchDevice !== true) return;\n\n const onSelectionChange = () => {\n const domSelection = window.getSelection();\n if (!domSelection || domSelection.isCollapsed || domSelection.rangeCount === 0) {\n setIsVisible(false);\n return;\n }\n\n // Check if the selection is inside our editor\n const rootEl = rootElementRef.current;\n if (!rootEl) {\n setIsVisible(false);\n return;\n }\n\n const anchorNode = domSelection.anchorNode;\n if (!anchorNode || !rootEl.contains(anchorNode)) {\n setIsVisible(false);\n return;\n }\n\n setIsVisible(true);\n };\n\n document.addEventListener(\"selectionchange\", onSelectionChange);\n return () => document.removeEventListener(\"selectionchange\", onSelectionChange);\n }, [isTouchDevice]);\n\n const handleFormat = useCallback(\n (format: TextFormat) => {\n editor.dispatchCommand(FORMAT_TEXT_COMMAND, format);\n },\n [editor],\n );\n\n // Don't render on non-touch devices or during SSR\n if (isTouchDevice !== true || !portalContainer) return null;\n\n if (!isVisible) return null;\n\n return createPortal(\n <div\n role=\"toolbar\"\n aria-label=\"Text formatting\"\n data-testid=\"mobile-toolbar\"\n style={{\n position: \"fixed\",\n bottom: 0,\n left: 0,\n right: 0,\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n gap: \"2px\",\n padding: \"8px 12px\",\n paddingBottom: \"calc(8px + env(safe-area-inset-bottom, 0px))\",\n backgroundColor: \"var(--blokhaus-popover-bg)\",\n backdropFilter: \"blur(20px) saturate(180%)\",\n WebkitBackdropFilter: \"blur(20px) saturate(180%)\",\n borderTop: \"1px solid var(--blokhaus-popover-border)\",\n zIndex: 50,\n fontFamily:\n '-apple-system, BlinkMacSystemFont, \"SF Pro Text\", system-ui, sans-serif',\n }}\n >\n {TOOLBAR_BUTTONS.map(({ icon: Icon, format, label }) => (\n <button\n key={format}\n type=\"button\"\n title={label}\n aria-label={label}\n data-testid={`mobile-toolbar-${format}`}\n onMouseDown={(e) => {\n e.preventDefault();\n handleFormat(format);\n }}\n onTouchStart={(e) => {\n e.preventDefault();\n handleFormat(format);\n }}\n style={{\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n width: \"44px\",\n height: \"44px\",\n borderRadius: \"10px\",\n border: \"none\",\n cursor: \"default\",\n backgroundColor: \"transparent\",\n color: \"var(--blokhaus-icon-secondary)\",\n }}\n >\n <Icon size={20} weight=\"regular\" />\n </button>\n ))}\n </div>,\n portalContainer,\n );\n}\n","\"use client\";\n\nimport { useEffect } from \"react\";\nimport { useLexicalComposerContext } from \"@lexical/react/LexicalComposerContext\";\nimport {\n $getSelection,\n $isRangeSelection,\n $isTextNode,\n COMMAND_PRIORITY_LOW,\n} from \"lexical\";\nimport { SET_TEXT_COLOR_COMMAND, SET_HIGHLIGHT_COLOR_COMMAND, SET_FONT_FAMILY_COMMAND } from \"../commands\";\nimport { mergeInlineStyle } from \"../utils/style\";\n\nexport function ColorPlugin() {\n const [editor] = useLexicalComposerContext();\n\n useEffect(() => {\n return editor.registerCommand(\n SET_TEXT_COLOR_COMMAND,\n (color: string) => {\n editor.update(() => {\n const selection = $getSelection();\n if (!$isRangeSelection(selection)) return;\n\n // Empty string means \"default\" — remove the color property\n const nodes = selection.getNodes();\n for (const node of nodes) {\n if ($isTextNode(node)) {\n const existing = node.getStyle();\n const merged = mergeInlineStyle(existing, \"color\", color || null);\n node.setStyle(merged);\n }\n }\n });\n return true;\n },\n COMMAND_PRIORITY_LOW,\n );\n }, [editor]);\n\n useEffect(() => {\n return editor.registerCommand(\n SET_HIGHLIGHT_COLOR_COMMAND,\n (color: string) => {\n editor.update(() => {\n const selection = $getSelection();\n if (!$isRangeSelection(selection)) return;\n\n const nodes = selection.getNodes();\n for (const node of nodes) {\n if ($isTextNode(node)) {\n const existing = node.getStyle();\n const merged = mergeInlineStyle(\n existing,\n \"background-color\",\n color || null,\n );\n node.setStyle(merged);\n }\n }\n });\n return true;\n },\n COMMAND_PRIORITY_LOW,\n );\n }, [editor]);\n\n useEffect(() => {\n return editor.registerCommand(\n SET_FONT_FAMILY_COMMAND,\n (fontFamily: string) => {\n editor.update(() => {\n const selection = $getSelection();\n if (!$isRangeSelection(selection)) return;\n\n const nodes = selection.getNodes();\n for (const node of nodes) {\n if ($isTextNode(node)) {\n const existing = node.getStyle();\n const merged = mergeInlineStyle(\n existing,\n \"font-family\",\n fontFamily || null,\n );\n node.setStyle(merged);\n }\n }\n });\n return true;\n },\n COMMAND_PRIORITY_LOW,\n );\n }, [editor]);\n\n return null;\n}\n","\"use client\";\n\nimport { useEffect } from \"react\";\n\nimport { useLexicalComposerContext } from \"@lexical/react/LexicalComposerContext\";\nimport { registerList, registerCheckList } from \"@lexical/list\";\n\n/**\n * Registers @lexical/list behaviour: Enter on an empty list item exits the list,\n * Tab/Shift-Tab for indent/outdent, and other list integrity transforms.\n * Also registers check list behaviour: click/spacebar to toggle checkbox state.\n */\nexport function ListPlugin() {\n const [editor] = useLexicalComposerContext();\n\n useEffect(() => {\n const unregisterList = registerList(editor);\n const unregisterCheckList = registerCheckList(editor);\n return () => {\n unregisterList();\n unregisterCheckList();\n };\n }, [editor]);\n\n return null;\n}\n","\"use client\";\n\nimport { useEffect } from \"react\";\nimport { useLexicalComposerContext } from \"@lexical/react/LexicalComposerContext\";\nimport {\n $createParagraphNode,\n $getSelection,\n $isNodeSelection,\n $isRangeSelection,\n COMMAND_PRIORITY_LOW,\n KEY_BACKSPACE_COMMAND,\n KEY_DELETE_COMMAND,\n} from \"lexical\";\nimport {\n $createTableNodeWithDimensions,\n $isTableNode,\n $isTableRowNode,\n $isTableCellNode,\n registerTablePlugin,\n registerTableSelectionObserver,\n registerTableCellUnmergeTransform,\n} from \"@lexical/table\";\n\nimport { INSERT_TABLE_COMMAND_BLOKHAUS } from \"../commands\";\n\ninterface TablePluginProps {\n hasCellMerge?: boolean;\n hasCellBackgroundColor?: boolean;\n hasTabHandler?: boolean;\n}\n\nexport function TablePlugin({\n hasCellMerge = true,\n hasTabHandler = true,\n}: TablePluginProps) {\n const [editor] = useLexicalComposerContext();\n\n useEffect(() => {\n return registerTablePlugin(editor);\n }, [editor]);\n\n useEffect(() => {\n return registerTableSelectionObserver(editor, hasTabHandler);\n }, [editor, hasTabHandler]);\n\n useEffect(() => {\n if (!hasCellMerge) {\n return registerTableCellUnmergeTransform(editor);\n }\n }, [editor, hasCellMerge]);\n\n useEffect(() => {\n return editor.registerCommand(\n INSERT_TABLE_COMMAND_BLOKHAUS,\n (payload: { rows: number; columns: number }) => {\n editor.update(() => {\n const selection = $getSelection();\n if (!$isRangeSelection(selection)) return;\n\n const tableNode = $createTableNodeWithDimensions(\n payload.rows,\n payload.columns,\n false,\n );\n\n const focusNode = selection.focus.getNode();\n const topLevelNode = focusNode.getTopLevelElement();\n if (topLevelNode) {\n topLevelNode.insertAfter(tableNode);\n if (\n topLevelNode.getTextContent().trim() === \"\" &&\n topLevelNode.getType() === \"paragraph\"\n ) {\n topLevelNode.remove();\n }\n\n const firstRow = tableNode.getChildren().find($isTableRowNode);\n if (firstRow) {\n const firstCell = firstRow.getChildren().find($isTableCellNode);\n if (firstCell) {\n firstCell.selectStart();\n }\n }\n }\n });\n return true;\n },\n COMMAND_PRIORITY_LOW,\n );\n }, [editor]);\n\n useEffect(() => {\n const handleDelete = (event: KeyboardEvent) => {\n const selection = $getSelection();\n if (!$isNodeSelection(selection)) return false;\n\n const nodes = selection.getNodes();\n const tableNode = nodes.find($isTableNode);\n if (!tableNode) return false;\n\n event.preventDefault();\n const paragraph = $createParagraphNode();\n tableNode.insertBefore(paragraph);\n tableNode.remove();\n paragraph.selectStart();\n return true;\n };\n\n const unregisterBackspace = editor.registerCommand(\n KEY_BACKSPACE_COMMAND,\n handleDelete,\n COMMAND_PRIORITY_LOW,\n );\n const unregisterDelete = editor.registerCommand(\n KEY_DELETE_COMMAND,\n handleDelete,\n COMMAND_PRIORITY_LOW,\n );\n\n return () => {\n unregisterBackspace();\n unregisterDelete();\n };\n }, [editor]);\n\n return null;\n}\n","\"use client\";\n\nimport { useCallback, useEffect, useRef, useState } from \"react\";\nimport { useLexicalComposerContext } from \"@lexical/react/LexicalComposerContext\";\nimport { createPortal } from \"react-dom\";\nimport {\n $getSelection,\n $isRangeSelection,\n COMMAND_PRIORITY_LOW,\n SELECTION_CHANGE_COMMAND,\n} from \"lexical\";\nimport {\n $getTableCellNodeFromLexicalNode,\n $getTableNodeFromLexicalNodeOrThrow,\n $insertTableRowAtSelection,\n $insertTableColumnAtSelection,\n $deleteTableRowAtSelection,\n $deleteTableColumnAtSelection,\n $mergeCells,\n $unmergeCell,\n $isTableCellNode,\n $isTableSelection,\n TableCellNode,\n} from \"@lexical/table\";\n\nimport type { ColorPalette } from \"../data/color-palette\";\nimport { DEFAULT_COLOR_PALETTE } from \"../data/color-palette\";\n\n// Cell background colors — derived from highlight palette\nconst CELL_BG_COLORS = [\n { label: \"Default\", value: \"\", swatch: \"transparent\" },\n { label: \"Gray\", value: \"var(--blokhaus-cell-bg-gray)\", swatch: \"#f1f1ef\" },\n { label: \"Brown\", value: \"var(--blokhaus-cell-bg-brown)\", swatch: \"#f4f0ee\" },\n { label: \"Orange\", value: \"var(--blokhaus-cell-bg-orange)\", swatch: \"#fbecdd\" },\n { label: \"Yellow\", value: \"var(--blokhaus-cell-bg-yellow)\", swatch: \"#fbf3db\" },\n { label: \"Green\", value: \"var(--blokhaus-cell-bg-green)\", swatch: \"#edf3ec\" },\n { label: \"Blue\", value: \"var(--blokhaus-cell-bg-blue)\", swatch: \"#e7f3f8\" },\n { label: \"Purple\", value: \"var(--blokhaus-cell-bg-purple)\", swatch: \"#f4f0f7\" },\n { label: \"Pink\", value: \"var(--blokhaus-cell-bg-pink)\", swatch: \"#f9f0f5\" },\n { label: \"Red\", value: \"var(--blokhaus-cell-bg-red)\", swatch: \"#fdebec\" },\n];\n\ntype MenuAction =\n | \"insert-row-above\"\n | \"insert-row-below\"\n | \"insert-col-left\"\n | \"insert-col-right\"\n | \"delete-row\"\n | \"delete-col\"\n | \"merge-cells\"\n | \"unmerge-cell\"\n | \"delete-table\";\n\ninterface MenuItem {\n id: MenuAction | \"cell-color\";\n label: string;\n danger?: boolean;\n}\n\nconst MENU_ITEMS: MenuItem[] = [\n { id: \"insert-row-above\", label: \"Insert row above\" },\n { id: \"insert-row-below\", label: \"Insert row below\" },\n { id: \"insert-col-left\", label: \"Insert column left\" },\n { id: \"insert-col-right\", label: \"Insert column right\" },\n { id: \"delete-row\", label: \"Delete row\" },\n { id: \"delete-col\", label: \"Delete column\" },\n { id: \"merge-cells\", label: \"Merge cells\" },\n { id: \"unmerge-cell\", label: \"Unmerge cell\" },\n { id: \"cell-color\", label: \"Cell background\" },\n { id: \"delete-table\", label: \"Delete table\", danger: true },\n];\n\nexport function TableActionMenu() {\n const [editor] = useLexicalComposerContext();\n const [isOpen, setIsOpen] = useState(false);\n const [position, setPosition] = useState({ top: 0, left: 0 });\n const [showColorSubmenu, setShowColorSubmenu] = useState(false);\n const [currentCellBg, setCurrentCellBg] = useState<string | null>(null);\n const [hasTableSelection, setHasTableSelection] = useState(false);\n const [canUnmerge, setCanUnmerge] = useState(false);\n const menuRef = useRef<HTMLDivElement>(null);\n const [portalContainer, setPortalContainer] = useState<HTMLElement | null>(null);\n\n useEffect(() => {\n if (typeof window === \"undefined\") return;\n setPortalContainer(document.body);\n }, []);\n\n // Right-click on table cell to open menu\n useEffect(() => {\n const rootElement = editor.getRootElement();\n if (!rootElement) return;\n\n const handleContextMenu = (e: MouseEvent) => {\n editor.read(() => {\n const selection = $getSelection();\n if (!selection) return;\n\n // Check if we're in a table cell\n let cellNode: TableCellNode | null = null;\n\n if ($isRangeSelection(selection)) {\n cellNode = $getTableCellNodeFromLexicalNode(selection.anchor.getNode());\n } else if ($isTableSelection(selection)) {\n const nodes = selection.getNodes();\n const firstCell = nodes.find((n) => $isTableCellNode(n));\n cellNode = firstCell ? (firstCell as TableCellNode) : null;\n setHasTableSelection(true);\n }\n\n if (!cellNode) return;\n\n e.preventDefault();\n e.stopPropagation();\n\n setCurrentCellBg(cellNode.getBackgroundColor());\n setCanUnmerge(cellNode.getColSpan() > 1 || cellNode.getRowSpan() > 1);\n\n if ($isTableSelection(selection)) {\n setHasTableSelection(true);\n } else {\n setHasTableSelection(false);\n }\n\n setPosition({ top: e.clientY, left: e.clientX });\n setIsOpen(true);\n setShowColorSubmenu(false);\n });\n };\n\n rootElement.addEventListener(\"contextmenu\", handleContextMenu);\n return () => rootElement.removeEventListener(\"contextmenu\", handleContextMenu);\n }, [editor]);\n\n // Close on outside click or escape\n useEffect(() => {\n if (!isOpen) return;\n\n const handleClick = (e: MouseEvent) => {\n if (menuRef.current && !menuRef.current.contains(e.target as Node)) {\n setIsOpen(false);\n }\n };\n\n const handleKeyDown = (e: KeyboardEvent) => {\n if (e.key === \"Escape\") {\n setIsOpen(false);\n }\n };\n\n document.addEventListener(\"mousedown\", handleClick);\n document.addEventListener(\"keydown\", handleKeyDown);\n return () => {\n document.removeEventListener(\"mousedown\", handleClick);\n document.removeEventListener(\"keydown\", handleKeyDown);\n };\n }, [isOpen]);\n\n const handleAction = useCallback(\n (action: MenuAction) => {\n setIsOpen(false);\n\n editor.update(() => {\n switch (action) {\n case \"insert-row-above\":\n $insertTableRowAtSelection(false);\n break;\n case \"insert-row-below\":\n $insertTableRowAtSelection(true);\n break;\n case \"insert-col-left\":\n $insertTableColumnAtSelection(false);\n break;\n case \"insert-col-right\":\n $insertTableColumnAtSelection(true);\n break;\n case \"delete-row\":\n $deleteTableRowAtSelection();\n break;\n case \"delete-col\":\n $deleteTableColumnAtSelection();\n break;\n case \"merge-cells\": {\n const selection = $getSelection();\n if ($isTableSelection(selection)) {\n const nodes = selection.getNodes();\n const cells = nodes.filter((n): n is TableCellNode =>\n $isTableCellNode(n),\n );\n if (cells.length > 1) {\n $mergeCells(cells);\n }\n }\n break;\n }\n case \"unmerge-cell\":\n $unmergeCell();\n break;\n case \"delete-table\": {\n const selection = $getSelection();\n if (!selection) break;\n let cellNode: TableCellNode | null = null;\n if ($isRangeSelection(selection)) {\n cellNode = $getTableCellNodeFromLexicalNode(\n selection.anchor.getNode(),\n );\n } else if ($isTableSelection(selection)) {\n const nodes = selection.getNodes();\n const firstCell = nodes.find((n) => $isTableCellNode(n));\n cellNode = firstCell ? (firstCell as TableCellNode) : null;\n }\n if (cellNode) {\n const tableNode = $getTableNodeFromLexicalNodeOrThrow(cellNode);\n tableNode.remove();\n }\n break;\n }\n }\n });\n },\n [editor],\n );\n\n const handleCellColor = useCallback(\n (color: string) => {\n setIsOpen(false);\n\n editor.update(() => {\n const selection = $getSelection();\n if (!selection) return;\n\n const setCellBg = (cell: TableCellNode) => {\n cell.setBackgroundColor(color || null);\n };\n\n if ($isTableSelection(selection)) {\n const nodes = selection.getNodes();\n for (const node of nodes) {\n if ($isTableCellNode(node)) {\n setCellBg(node);\n }\n }\n } else if ($isRangeSelection(selection)) {\n const cellNode = $getTableCellNodeFromLexicalNode(\n selection.anchor.getNode(),\n );\n if (cellNode) {\n setCellBg(cellNode);\n }\n }\n });\n },\n [editor],\n );\n\n if (!isOpen || !portalContainer) return null;\n\n return createPortal(\n <div\n ref={menuRef}\n data-testid=\"table-action-menu\"\n onMouseDown={(e) => e.preventDefault()}\n style={{\n position: \"fixed\",\n zIndex: 100,\n top: `${position.top}px`,\n left: `${position.left}px`,\n minWidth: \"180px\",\n borderRadius: \"10px\",\n border: \"1px solid var(--blokhaus-popover-border)\",\n backgroundColor: \"var(--blokhaus-popover-bg)\",\n backdropFilter: \"blur(20px) saturate(180%)\",\n WebkitBackdropFilter: \"blur(20px) saturate(180%)\",\n boxShadow: \"var(--blokhaus-popover-shadow)\",\n padding: \"4px\",\n fontFamily:\n '-apple-system, BlinkMacSystemFont, \"SF Pro Text\", system-ui, sans-serif',\n }}\n >\n {MENU_ITEMS.map((item) => {\n // Hide merge when no table selection\n if (item.id === \"merge-cells\" && !hasTableSelection) return null;\n // Hide unmerge when cell isn't merged\n if (item.id === \"unmerge-cell\" && !canUnmerge) return null;\n\n if (item.id === \"cell-color\") {\n return (\n <div key={item.id} style={{ position: \"relative\" }}>\n <button\n type=\"button\"\n data-testid=\"table-action-cell-color\"\n onMouseEnter={() => setShowColorSubmenu(true)}\n onClick={() => setShowColorSubmenu((prev) => !prev)}\n style={{\n display: \"flex\",\n width: \"100%\",\n alignItems: \"center\",\n justifyContent: \"space-between\",\n gap: \"8px\",\n padding: \"6px 8px\",\n borderRadius: \"6px\",\n border: \"none\",\n cursor: \"default\",\n backgroundColor: \"transparent\",\n fontSize: \"13px\",\n color: \"var(--blokhaus-foreground, #1d1d1f)\",\n }}\n >\n <span>{item.label}</span>\n <span style={{ fontSize: \"10px\", color: \"var(--blokhaus-text-tertiary)\" }}>\n {\"\\u25B6\"}\n </span>\n </button>\n\n {showColorSubmenu && (\n <div\n style={{\n position: \"absolute\",\n top: 0,\n left: \"100%\",\n marginLeft: \"4px\",\n borderRadius: \"10px\",\n border: \"1px solid var(--blokhaus-popover-border)\",\n backgroundColor: \"var(--blokhaus-popover-bg)\",\n backdropFilter: \"blur(20px) saturate(180%)\",\n WebkitBackdropFilter: \"blur(20px) saturate(180%)\",\n boxShadow: \"var(--blokhaus-popover-shadow)\",\n padding: \"6px\",\n display: \"flex\",\n flexWrap: \"wrap\",\n gap: \"2px\",\n width: \"140px\",\n }}\n >\n {CELL_BG_COLORS.map((color) => (\n <button\n key={color.label}\n type=\"button\"\n title={color.label}\n data-testid={`table-cell-color-${color.label.toLowerCase()}`}\n onMouseDown={(e) => {\n e.preventDefault();\n handleCellColor(color.value);\n }}\n style={{\n width: \"24px\",\n height: \"24px\",\n borderRadius: \"4px\",\n border:\n currentCellBg === color.value ||\n (!currentCellBg && color.value === \"\")\n ? \"2px solid var(--blokhaus-accent, #007AFF)\"\n : \"1px solid var(--blokhaus-popover-border)\",\n cursor: \"pointer\",\n backgroundColor:\n color.swatch === \"transparent\"\n ? \"transparent\"\n : color.swatch,\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n }}\n >\n {color.swatch === \"transparent\" && (\n <span\n style={{\n fontSize: \"11px\",\n color: \"var(--blokhaus-text-tertiary)\",\n }}\n >\n {\"\\u2205\"}\n </span>\n )}\n </button>\n ))}\n </div>\n )}\n </div>\n );\n }\n\n // Separator before delete table\n const showSep = item.id === \"delete-table\";\n\n return (\n <div key={item.id}>\n {showSep && (\n <div\n style={{\n height: \"0.5px\",\n backgroundColor: \"var(--blokhaus-separator)\",\n margin: \"3px 6px\",\n }}\n />\n )}\n <button\n type=\"button\"\n data-testid={`table-action-${item.id}`}\n onMouseDown={(e) => {\n e.preventDefault();\n handleAction(item.id as MenuAction);\n }}\n onMouseEnter={() => setShowColorSubmenu(false)}\n style={{\n display: \"flex\",\n width: \"100%\",\n alignItems: \"center\",\n gap: \"8px\",\n padding: \"6px 8px\",\n borderRadius: \"6px\",\n border: \"none\",\n cursor: \"default\",\n backgroundColor: \"transparent\",\n fontSize: \"13px\",\n color: item.danger\n ? \"var(--blokhaus-destructive, #e03e3e)\"\n : \"var(--blokhaus-foreground, #1d1d1f)\",\n }}\n >\n {item.label}\n </button>\n </div>\n );\n })}\n </div>,\n portalContainer,\n );\n}\n","\"use client\";\n\nimport { useEffect, useRef, useState, useCallback } from \"react\";\nimport { useLexicalComposerContext } from \"@lexical/react/LexicalComposerContext\";\nimport { createPortal } from \"react-dom\";\nimport {\n $createNodeSelection,\n $getNearestNodeFromDOMNode,\n $getNodeByKey,\n $getSelection,\n $isRangeSelection,\n $setSelection,\n} from \"lexical\";\nimport {\n $isTableNode,\n $isTableRowNode,\n $isTableCellNode,\n $insertTableRowAtSelection,\n $insertTableColumnAtSelection,\n $deleteTableRowAtSelection,\n $deleteTableColumnAtSelection,\n} from \"@lexical/table\";\n\ntype MenuType = \"row\" | \"column\";\n\ninterface MenuState {\n type: MenuType;\n top: number;\n left: number;\n /** Row or column index the menu targets */\n index: number;\n}\n\nexport function TableHoverActions() {\n const [editor] = useLexicalComposerContext();\n const [portalContainer, setPortalContainer] = useState<HTMLElement | null>(null);\n const [menu, setMenu] = useState<MenuState | null>(null);\n\n // Refs for the currently hovered table\n const activeTableRef = useRef<HTMLTableElement | null>(null);\n const activeTableKeyRef = useRef<string | null>(null);\n\n // Refs for overlay containers (imperative positioning)\n const rowHandlesRef = useRef<HTMLDivElement>(null);\n const colHandlesRef = useRef<HTMLDivElement>(null);\n const addRowBtnRef = useRef<HTMLDivElement>(null);\n const addColBtnRef = useRef<HTMLDivElement>(null);\n const tableGripRef = useRef<HTMLDivElement>(null);\n const resizeHandleRef = useRef<HTMLDivElement>(null);\n const resizeGuideRef = useRef<HTMLDivElement>(null);\n\n // Resize drag state\n const resizingRef = useRef<{\n columnIndex: number;\n startX: number;\n startWidth: number;\n colWidths: number[];\n tableElement: HTMLTableElement;\n tableNodeKey: string;\n } | null>(null);\n\n // Touch device check\n const isTouchRef = useRef(false);\n\n useEffect(() => {\n if (typeof window === \"undefined\") return;\n isTouchRef.current = window.matchMedia(\"(pointer: coarse)\").matches;\n setPortalContainer(document.body);\n }, []);\n\n const hideAll = useCallback(() => {\n const els = [\n rowHandlesRef.current,\n colHandlesRef.current,\n addRowBtnRef.current,\n addColBtnRef.current,\n tableGripRef.current,\n resizeHandleRef.current,\n ];\n for (const el of els) {\n if (el) el.style.visibility = \"hidden\";\n }\n }, []);\n\n const getColumnWidths = useCallback((table: HTMLTableElement): number[] => {\n const firstRow = table.rows[0];\n if (!firstRow) return [];\n const widths: number[] = [];\n for (let i = 0; i < firstRow.cells.length; i++) {\n widths.push(firstRow.cells[i]!.offsetWidth);\n }\n return widths;\n }, []);\n\n const selectCell = useCallback(\n (rowIndex: number, colIndex: number) => {\n const key = activeTableKeyRef.current;\n if (!key) return;\n\n editor.update(() => {\n const tableNode = $getNodeByKey(key);\n if (!tableNode || !$isTableNode(tableNode)) return;\n const rows = tableNode.getChildren().filter($isTableRowNode);\n const row = rows[rowIndex];\n if (!row) return;\n const cells = row.getChildren().filter($isTableCellNode);\n const cell = cells[colIndex];\n if (!cell) return;\n cell.selectEnd();\n });\n },\n [editor],\n );\n\n const insertRowAt = useCallback(\n (rowIndex: number, after: boolean) => {\n const key = activeTableKeyRef.current;\n if (!key) return;\n\n editor.update(() => {\n const tableNode = $getNodeByKey(key);\n if (!tableNode || !$isTableNode(tableNode)) return;\n\n const rows = tableNode.getChildren().filter($isTableRowNode);\n const targetRow = rows[rowIndex];\n if (!targetRow) return;\n const cells = targetRow.getChildren().filter($isTableCellNode);\n const cell = cells[0];\n if (!cell) return;\n\n cell.selectEnd();\n $insertTableRowAtSelection(after);\n });\n editor.focus();\n },\n [editor],\n );\n\n const insertColAt = useCallback(\n (colIndex: number, after: boolean) => {\n const key = activeTableKeyRef.current;\n if (!key) return;\n\n editor.update(() => {\n const tableNode = $getNodeByKey(key);\n if (!tableNode || !$isTableNode(tableNode)) return;\n\n const rows = tableNode.getChildren().filter($isTableRowNode);\n const firstRow = rows[0];\n if (!firstRow) return;\n const cells = firstRow.getChildren().filter($isTableCellNode);\n const cell = cells[colIndex];\n if (!cell) return;\n\n cell.selectEnd();\n $insertTableColumnAtSelection(after);\n });\n editor.focus();\n },\n [editor],\n );\n\n const deleteRowAt = useCallback(\n (rowIndex: number) => {\n const key = activeTableKeyRef.current;\n if (!key) return;\n\n editor.update(() => {\n const tableNode = $getNodeByKey(key);\n if (!tableNode || !$isTableNode(tableNode)) return;\n\n const rows = tableNode.getChildren().filter($isTableRowNode);\n // Don't delete the last remaining row\n if (rows.length <= 1) return;\n\n const targetRow = rows[rowIndex];\n if (!targetRow) return;\n const cells = targetRow.getChildren().filter($isTableCellNode);\n const cell = cells[0];\n if (!cell) return;\n\n cell.selectEnd();\n $deleteTableRowAtSelection();\n });\n editor.focus();\n },\n [editor],\n );\n\n const deleteColAt = useCallback(\n (colIndex: number) => {\n const key = activeTableKeyRef.current;\n if (!key) return;\n\n editor.update(() => {\n const tableNode = $getNodeByKey(key);\n if (!tableNode || !$isTableNode(tableNode)) return;\n\n const rows = tableNode.getChildren().filter($isTableRowNode);\n const firstRow = rows[0];\n if (!firstRow) return;\n const cells = firstRow.getChildren().filter($isTableCellNode);\n // Don't delete the last remaining column\n if (cells.length <= 1) return;\n\n const cell = cells[colIndex];\n if (!cell) return;\n\n cell.selectEnd();\n $deleteTableColumnAtSelection();\n });\n editor.focus();\n },\n [editor],\n );\n\n const selectTable = useCallback(() => {\n const key = activeTableKeyRef.current;\n if (!key) return;\n\n editor.update(() => {\n const nodeSelection = $createNodeSelection();\n nodeSelection.add(key);\n $setSelection(nodeSelection);\n });\n editor.focus();\n }, [editor]);\n\n const buildRowHandles = useCallback(\n (tableEl: HTMLTableElement, tableRect: DOMRect) => {\n const container = rowHandlesRef.current;\n if (!container) return;\n\n container.style.visibility = \"visible\";\n\n // Build handle elements for each row\n const handles: string[] = [];\n for (let i = 0; i < tableEl.rows.length; i++) {\n const row = tableEl.rows[i]!;\n const rowRect = row.getBoundingClientRect();\n handles.push(\n `<div data-row-handle=\"${i}\" style=\"\n position:fixed;\n top:${rowRect.top}px;\n left:${tableRect.left - 28}px;\n width:22px;\n height:${rowRect.height}px;\n display:flex;\n align-items:center;\n justify-content:center;\n cursor:pointer;\n border-radius:4px;\n color:var(--blokhaus-text-tertiary);\n transition:background-color 100ms, color 100ms;\n \">\n <svg width=\"10\" height=\"10\" viewBox=\"0 0 10 10\" fill=\"currentColor\">\n <rect x=\"0\" y=\"1\" width=\"10\" height=\"2\" rx=\"1\"/>\n <rect x=\"0\" y=\"5\" width=\"10\" height=\"2\" rx=\"1\"/>\n </svg>\n </div>`,\n );\n }\n container.innerHTML = handles.join(\"\");\n\n // Attach event listeners\n const handleEls = container.querySelectorAll(\"[data-row-handle]\");\n handleEls.forEach((el) => {\n const htmlEl = el as HTMLElement;\n htmlEl.addEventListener(\"mouseenter\", () => {\n htmlEl.style.backgroundColor = \"var(--blokhaus-hover-bg)\";\n htmlEl.style.color = \"var(--blokhaus-icon-secondary)\";\n });\n htmlEl.addEventListener(\"mouseleave\", () => {\n htmlEl.style.backgroundColor = \"transparent\";\n htmlEl.style.color = \"var(--blokhaus-text-tertiary)\";\n });\n htmlEl.addEventListener(\"mousedown\", (e) => {\n e.preventDefault();\n e.stopPropagation();\n const idx = parseInt(htmlEl.dataset.rowHandle ?? \"0\", 10);\n const rect = htmlEl.getBoundingClientRect();\n setMenu({\n type: \"row\",\n top: rect.top,\n left: rect.left - 4,\n index: idx,\n });\n });\n });\n },\n [],\n );\n\n const buildColHandles = useCallback(\n (tableEl: HTMLTableElement, tableRect: DOMRect) => {\n const container = colHandlesRef.current;\n if (!container) return;\n\n container.style.visibility = \"visible\";\n\n const firstRow = tableEl.rows[0];\n if (!firstRow) return;\n\n const handles: string[] = [];\n for (let i = 0; i < firstRow.cells.length; i++) {\n const cell = firstRow.cells[i]!;\n const cellRect = cell.getBoundingClientRect();\n handles.push(\n `<div data-col-handle=\"${i}\" style=\"\n position:fixed;\n top:${tableRect.top - 24}px;\n left:${cellRect.left}px;\n width:${cellRect.width}px;\n height:20px;\n display:flex;\n align-items:center;\n justify-content:center;\n cursor:pointer;\n border-radius:4px;\n color:var(--blokhaus-text-tertiary);\n transition:background-color 100ms, color 100ms;\n \">\n <svg width=\"10\" height=\"10\" viewBox=\"0 0 10 10\" fill=\"currentColor\">\n <rect x=\"1\" y=\"0\" width=\"2\" height=\"10\" rx=\"1\"/>\n <rect x=\"5\" y=\"0\" width=\"2\" height=\"10\" rx=\"1\"/>\n </svg>\n </div>`,\n );\n }\n container.innerHTML = handles.join(\"\");\n\n // Attach event listeners\n const handleEls = container.querySelectorAll(\"[data-col-handle]\");\n handleEls.forEach((el) => {\n const htmlEl = el as HTMLElement;\n htmlEl.addEventListener(\"mouseenter\", () => {\n htmlEl.style.backgroundColor = \"var(--blokhaus-hover-bg)\";\n htmlEl.style.color = \"var(--blokhaus-icon-secondary)\";\n });\n htmlEl.addEventListener(\"mouseleave\", () => {\n htmlEl.style.backgroundColor = \"transparent\";\n htmlEl.style.color = \"var(--blokhaus-text-tertiary)\";\n });\n htmlEl.addEventListener(\"mousedown\", (e) => {\n e.preventDefault();\n e.stopPropagation();\n const idx = parseInt(htmlEl.dataset.colHandle ?? \"0\", 10);\n const rect = htmlEl.getBoundingClientRect();\n setMenu({\n type: \"column\",\n top: rect.top - 4,\n left: rect.left,\n index: idx,\n });\n });\n });\n },\n [],\n );\n\n useEffect(() => {\n if (isTouchRef.current) return;\n\n const handleMouseMove = (e: MouseEvent) => {\n // Don't reposition during resize drag\n if (resizingRef.current) return;\n\n const target = e.target as HTMLElement;\n\n // Check if we're hovering a portal element (our own UI)\n if (target.closest(\"[data-table-hover-actions]\")) return;\n\n const tableEl = target.closest(\"table\") as HTMLTableElement | null;\n\n if (!tableEl) {\n // Check if mouse is near the currently active table (for edge buttons)\n const active = activeTableRef.current;\n if (active) {\n const r = active.getBoundingClientRect();\n const margin = 40;\n if (\n e.clientX >= r.left - margin &&\n e.clientX <= r.right + margin &&\n e.clientY >= r.top - margin &&\n e.clientY <= r.bottom + margin\n ) {\n return;\n }\n }\n activeTableRef.current = null;\n activeTableKeyRef.current = null;\n setMenu(null);\n hideAll();\n return;\n }\n\n // Resolve Lexical TableNode\n let tableKey: string | null = null;\n editor.read(() => {\n const lexNode = $getNearestNodeFromDOMNode(tableEl);\n if (lexNode && $isTableNode(lexNode)) {\n tableKey = lexNode.getKey();\n } else {\n const parent = tableEl.parentElement;\n if (parent) {\n const parentNode = $getNearestNodeFromDOMNode(parent);\n if (parentNode && $isTableNode(parentNode)) {\n tableKey = parentNode.getKey();\n }\n }\n }\n });\n\n if (!tableKey) {\n hideAll();\n return;\n }\n\n // If it's the same table, just update resize handle position\n if (activeTableRef.current === tableEl) {\n const r = tableEl.getBoundingClientRect();\n positionResizeHandle(e, tableEl, r);\n return;\n }\n\n activeTableRef.current = tableEl;\n activeTableKeyRef.current = tableKey;\n\n const r = tableEl.getBoundingClientRect();\n\n // Build row handles (left side)\n buildRowHandles(tableEl, r);\n\n // Build column handles (top side)\n buildColHandles(tableEl, r);\n\n // Position \"+\" row button (bottom edge)\n if (addRowBtnRef.current) {\n const btn = addRowBtnRef.current;\n btn.style.visibility = \"visible\";\n btn.style.top = `${r.bottom + 2}px`;\n btn.style.left = `${r.left}px`;\n btn.style.width = `${r.width}px`;\n }\n\n // Position \"+\" column button (right edge)\n if (addColBtnRef.current) {\n const btn = addColBtnRef.current;\n btn.style.visibility = \"visible\";\n btn.style.top = `${r.top}px`;\n btn.style.left = `${r.right + 2}px`;\n btn.style.height = `${r.height}px`;\n }\n\n // Position table grip (top-left corner)\n if (tableGripRef.current) {\n const grip = tableGripRef.current;\n grip.style.visibility = \"visible\";\n grip.style.top = `${r.top - 26}px`;\n grip.style.left = `${r.left - 28}px`;\n }\n\n // Position resize handle near column borders\n positionResizeHandle(e, tableEl, r);\n };\n\n const positionResizeHandle = (\n e: MouseEvent,\n tableEl: HTMLTableElement,\n r: DOMRect,\n ) => {\n const handle = resizeHandleRef.current;\n if (!handle) return;\n\n const firstRow = tableEl.rows[0];\n if (!firstRow) return;\n\n for (let i = 0; i < firstRow.cells.length - 1; i++) {\n const cell = firstRow.cells[i]!;\n const cellRect = cell.getBoundingClientRect();\n const borderX = cellRect.right;\n\n if (Math.abs(e.clientX - borderX) < 12) {\n handle.style.visibility = \"visible\";\n handle.style.top = `${r.top}px`;\n handle.style.left = `${borderX - 2}px`;\n handle.style.height = `${r.height}px`;\n handle.dataset.columnIndex = String(i);\n return;\n }\n }\n\n handle.style.visibility = \"hidden\";\n };\n\n let tableRafId = 0;\n let pendingEvent: MouseEvent | null = null;\n\n const throttledMouseMove = (e: MouseEvent) => {\n pendingEvent = e;\n if (tableRafId === 0) {\n tableRafId = requestAnimationFrame(() => {\n tableRafId = 0;\n if (pendingEvent) {\n handleMouseMove(pendingEvent);\n }\n });\n }\n };\n\n document.addEventListener(\"mousemove\", throttledMouseMove);\n return () => {\n document.removeEventListener(\"mousemove\", throttledMouseMove);\n if (tableRafId) cancelAnimationFrame(tableRafId);\n };\n }, [editor, hideAll, buildRowHandles, buildColHandles]);\n\n useEffect(() => {\n if (isTouchRef.current) return;\n\n const handle = resizeHandleRef.current;\n if (!handle) return;\n\n const onMouseDown = (e: MouseEvent) => {\n e.preventDefault();\n e.stopPropagation();\n\n const tableEl = activeTableRef.current;\n const tableKey = activeTableKeyRef.current;\n if (!tableEl || !tableKey) return;\n\n const colIndex = parseInt(handle.dataset.columnIndex ?? \"0\", 10);\n const colWidths = getColumnWidths(tableEl);\n const startWidth = colWidths[colIndex] ?? 0;\n\n resizingRef.current = {\n columnIndex: colIndex,\n startX: e.clientX,\n startWidth,\n colWidths: [...colWidths],\n tableElement: tableEl,\n tableNodeKey: tableKey,\n };\n\n document.body.style.cursor = \"col-resize\";\n document.body.style.userSelect = \"none\";\n\n if (resizeGuideRef.current) {\n const r = tableEl.getBoundingClientRect();\n const guide = resizeGuideRef.current;\n guide.style.visibility = \"visible\";\n guide.style.top = `${r.top}px`;\n guide.style.height = `${r.height}px`;\n guide.style.left = `${e.clientX}px`;\n }\n };\n\n const onMouseMove = (e: MouseEvent) => {\n if (!resizingRef.current) return;\n\n const { columnIndex, startX, startWidth, colWidths, tableElement } =\n resizingRef.current;\n const delta = e.clientX - startX;\n const newWidth = Math.max(40, startWidth + delta);\n colWidths[columnIndex] = newWidth;\n\n const cols = tableElement.querySelectorAll(\"colgroup col\");\n const col = cols[columnIndex] as HTMLElement | undefined;\n if (col) {\n col.style.width = `${newWidth}px`;\n }\n\n if (resizeGuideRef.current) {\n resizeGuideRef.current.style.left = `${e.clientX}px`;\n }\n };\n\n const onMouseUp = () => {\n if (!resizingRef.current) return;\n\n const { colWidths, tableNodeKey } = resizingRef.current;\n\n editor.update(() => {\n const tableNode = $getNodeByKey(tableNodeKey);\n if (tableNode && $isTableNode(tableNode)) {\n tableNode.getLatest().setColWidths(colWidths);\n }\n });\n\n resizingRef.current = null;\n document.body.style.cursor = \"\";\n document.body.style.userSelect = \"\";\n\n if (resizeGuideRef.current) {\n resizeGuideRef.current.style.visibility = \"hidden\";\n }\n\n // Force re-render handles since column widths changed\n const tableEl = activeTableRef.current;\n if (tableEl) {\n const r = tableEl.getBoundingClientRect();\n buildColHandles(tableEl, r);\n }\n };\n\n handle.addEventListener(\"mousedown\", onMouseDown);\n document.addEventListener(\"mousemove\", onMouseMove);\n document.addEventListener(\"mouseup\", onMouseUp);\n\n return () => {\n handle.removeEventListener(\"mousedown\", onMouseDown);\n document.removeEventListener(\"mousemove\", onMouseMove);\n document.removeEventListener(\"mouseup\", onMouseUp);\n document.body.style.cursor = \"\";\n document.body.style.userSelect = \"\";\n };\n }, [editor, getColumnWidths, portalContainer, buildColHandles]);\n\n useEffect(() => {\n if (!menu) return;\n\n const handleClick = (e: MouseEvent) => {\n const menuEl = document.querySelector(\"[data-table-menu-popover]\");\n if (menuEl && !menuEl.contains(e.target as Node)) {\n setMenu(null);\n }\n };\n\n const handleKey = (e: KeyboardEvent) => {\n if (e.key === \"Escape\") setMenu(null);\n };\n\n document.addEventListener(\"mousedown\", handleClick);\n document.addEventListener(\"keydown\", handleKey);\n return () => {\n document.removeEventListener(\"mousedown\", handleClick);\n document.removeEventListener(\"keydown\", handleKey);\n };\n }, [menu]);\n\n if (!portalContainer || isTouchRef.current) return null;\n\n const handleMenuAction = (action: string) => {\n if (!menu) return;\n const { type, index } = menu;\n setMenu(null);\n\n switch (action) {\n case \"insert-above\":\n insertRowAt(index, false);\n break;\n case \"insert-below\":\n insertRowAt(index, true);\n break;\n case \"delete-row\":\n deleteRowAt(index);\n break;\n case \"insert-left\":\n insertColAt(index, false);\n break;\n case \"insert-right\":\n insertColAt(index, true);\n break;\n case \"delete-col\":\n deleteColAt(index);\n break;\n }\n };\n\n const edgeButtonBase: React.CSSProperties = {\n position: \"fixed\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n cursor: \"pointer\",\n zIndex: 45,\n visibility: \"hidden\" as const,\n borderRadius: \"4px\",\n border: \"1px dashed var(--blokhaus-separator)\",\n backgroundColor: \"transparent\",\n color: \"var(--blokhaus-text-tertiary)\",\n fontSize: \"15px\",\n fontWeight: 600,\n transition: \"background-color 120ms, color 120ms, border-color 120ms\",\n };\n\n const menuItemStyle: React.CSSProperties = {\n display: \"flex\",\n width: \"100%\",\n alignItems: \"center\",\n gap: \"8px\",\n padding: \"6px 10px\",\n borderRadius: \"5px\",\n border: \"none\",\n cursor: \"default\",\n backgroundColor: \"transparent\",\n fontSize: \"13px\",\n color: \"var(--blokhaus-foreground, #1d1d1f)\",\n };\n\n const menuPopoverStyle: React.CSSProperties = {\n position: \"fixed\",\n minWidth: \"160px\",\n borderRadius: \"8px\",\n border: \"1px solid var(--blokhaus-popover-border)\",\n backgroundColor: \"var(--blokhaus-popover-bg)\",\n backdropFilter: \"blur(20px) saturate(180%)\",\n WebkitBackdropFilter: \"blur(20px) saturate(180%)\",\n boxShadow: \"var(--blokhaus-popover-shadow)\",\n padding: \"4px\",\n zIndex: 100,\n fontFamily:\n '-apple-system, BlinkMacSystemFont, \"SF Pro Text\", system-ui, sans-serif',\n };\n\n const MenuButton = ({\n label,\n action,\n destructive,\n }: {\n label: string;\n action: string;\n destructive?: boolean;\n }) => (\n <button\n type=\"button\"\n onMouseDown={(e) => {\n e.preventDefault();\n handleMenuAction(action);\n }}\n style={{\n ...menuItemStyle,\n ...(destructive ? { color: \"var(--blokhaus-destructive, #e03e3e)\" } : {}),\n }}\n onMouseEnter={(e) => {\n e.currentTarget.style.backgroundColor = \"var(--blokhaus-hover-bg)\";\n }}\n onMouseLeave={(e) => {\n e.currentTarget.style.backgroundColor = \"transparent\";\n }}\n >\n {label}\n </button>\n );\n\n const Separator = () => (\n <div\n style={{\n height: \"1px\",\n backgroundColor: \"var(--blokhaus-separator)\",\n margin: \"3px 4px\",\n }}\n />\n );\n\n return createPortal(\n <div data-table-hover-actions>\n {/* ── Row handles container ───────────────────────────────── */}\n <div ref={rowHandlesRef} style={{ visibility: \"hidden\" }} />\n\n {/* ── Column handles container ────────────────────────────── */}\n <div ref={colHandlesRef} style={{ visibility: \"hidden\" }} />\n\n {/* ── Column resize handle ──────────────────────────────────── */}\n <div\n ref={resizeHandleRef}\n style={{\n position: \"fixed\",\n width: \"6px\",\n cursor: \"col-resize\",\n zIndex: 47,\n visibility: \"hidden\",\n backgroundColor: \"transparent\",\n transition: \"background-color 100ms\",\n }}\n onMouseEnter={(e) => {\n (e.currentTarget as HTMLDivElement).style.backgroundColor =\n \"var(--blokhaus-accent, #007AFF)\";\n }}\n onMouseLeave={(e) => {\n if (!resizingRef.current) {\n (e.currentTarget as HTMLDivElement).style.backgroundColor =\n \"transparent\";\n }\n }}\n />\n\n {/* ── Resize guide line ─────────────────────────────────────── */}\n <div\n ref={resizeGuideRef}\n style={{\n position: \"fixed\",\n width: \"1px\",\n backgroundColor: \"var(--blokhaus-accent, #007AFF)\",\n opacity: 0.5,\n zIndex: 48,\n visibility: \"hidden\",\n pointerEvents: \"none\",\n }}\n />\n\n {/* ── \"+ Row\" button (bottom edge) ──────────────────────────── */}\n <div\n ref={addRowBtnRef}\n onMouseDown={(e) => e.preventDefault()}\n onClick={() => {\n const table = activeTableRef.current;\n if (!table) return;\n const lastRowIdx = table.rows.length - 1;\n if (lastRowIdx >= 0) insertRowAt(lastRowIdx, true);\n }}\n onMouseEnter={(e) => {\n const el = e.currentTarget;\n el.style.backgroundColor = \"var(--blokhaus-muted, #f1f5f9)\";\n el.style.color = \"var(--blokhaus-accent, #007AFF)\";\n el.style.borderColor = \"var(--blokhaus-accent, #007AFF)\";\n }}\n onMouseLeave={(e) => {\n const el = e.currentTarget;\n el.style.backgroundColor = \"transparent\";\n el.style.color = \"var(--blokhaus-text-tertiary)\";\n el.style.borderColor = \"var(--blokhaus-separator)\";\n }}\n style={{\n ...edgeButtonBase,\n height: \"20px\",\n }}\n >\n +\n </div>\n\n {/* ── \"+ Column\" button (right edge) ────────────────────────── */}\n <div\n ref={addColBtnRef}\n onMouseDown={(e) => e.preventDefault()}\n onClick={() => {\n const table = activeTableRef.current;\n if (!table) return;\n const firstRow = table.rows[0];\n if (!firstRow) return;\n const lastColIdx = firstRow.cells.length - 1;\n if (lastColIdx >= 0) insertColAt(lastColIdx, true);\n }}\n onMouseEnter={(e) => {\n const el = e.currentTarget;\n el.style.backgroundColor = \"var(--blokhaus-muted, #f1f5f9)\";\n el.style.color = \"var(--blokhaus-accent, #007AFF)\";\n el.style.borderColor = \"var(--blokhaus-accent, #007AFF)\";\n }}\n onMouseLeave={(e) => {\n const el = e.currentTarget;\n el.style.backgroundColor = \"transparent\";\n el.style.color = \"var(--blokhaus-text-tertiary)\";\n el.style.borderColor = \"var(--blokhaus-separator)\";\n }}\n style={{\n ...edgeButtonBase,\n width: \"20px\",\n }}\n >\n +\n </div>\n\n {/* ── Table grip handle (top-left corner) — click to select ── */}\n <div\n ref={tableGripRef}\n title=\"Click to select table, then press Delete to remove\"\n onMouseDown={(e) => {\n e.preventDefault();\n selectTable();\n }}\n style={{\n position: \"fixed\",\n width: \"22px\",\n height: \"22px\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n borderRadius: \"4px\",\n cursor: \"pointer\",\n color: \"var(--blokhaus-text-tertiary)\",\n backgroundColor: \"transparent\",\n zIndex: 46,\n visibility: \"hidden\",\n transition: \"background-color 100ms, color 100ms\",\n fontSize: \"14px\",\n }}\n onMouseEnter={(e) => {\n const el = e.currentTarget;\n el.style.backgroundColor = \"var(--blokhaus-hover-bg)\";\n el.style.color = \"var(--blokhaus-icon-secondary)\";\n }}\n onMouseLeave={(e) => {\n const el = e.currentTarget;\n el.style.backgroundColor = \"transparent\";\n el.style.color = \"var(--blokhaus-text-tertiary)\";\n }}\n >\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 14 14\" fill=\"currentColor\">\n <circle cx=\"4\" cy=\"3\" r=\"1.2\" />\n <circle cx=\"10\" cy=\"3\" r=\"1.2\" />\n <circle cx=\"4\" cy=\"7\" r=\"1.2\" />\n <circle cx=\"10\" cy=\"7\" r=\"1.2\" />\n <circle cx=\"4\" cy=\"11\" r=\"1.2\" />\n <circle cx=\"10\" cy=\"11\" r=\"1.2\" />\n </svg>\n </div>\n\n {/* ── Context menu popover ────────────────────────────────── */}\n {menu && (\n <div\n data-table-hover-actions\n data-table-menu-popover\n onMouseDown={(e) => e.preventDefault()}\n style={{\n ...menuPopoverStyle,\n top: `${menu.top}px`,\n left:\n menu.type === \"column\"\n ? `${menu.left}px`\n : menu.type === \"row\"\n ? `${menu.left - 164}px`\n : `${menu.left}px`,\n }}\n >\n {menu.type === \"row\" && (\n <>\n <MenuButton label=\"Insert row above\" action=\"insert-above\" />\n <MenuButton label=\"Insert row below\" action=\"insert-below\" />\n <Separator />\n <MenuButton label=\"Delete row\" action=\"delete-row\" destructive />\n </>\n )}\n {menu.type === \"column\" && (\n <>\n <MenuButton label=\"Insert column left\" action=\"insert-left\" />\n <MenuButton label=\"Insert column right\" action=\"insert-right\" />\n <Separator />\n <MenuButton label=\"Delete column\" action=\"delete-col\" destructive />\n </>\n )}\n </div>\n )}\n </div>,\n portalContainer,\n );\n}\n","\"use client\";\n\nimport { useEffect } from \"react\";\n\nimport { useLexicalComposerContext } from \"@lexical/react/LexicalComposerContext\";\nimport {\n $getSelection,\n $isRangeSelection,\n $isElementNode,\n $isRootNode,\n ParagraphNode,\n COMMAND_PRIORITY_LOW,\n LexicalNode,\n} from \"lexical\";\n\nimport { SET_BLOCK_DIRECTION_COMMAND } from \"../commands\";\n\n// Same regex Lexical uses internally to detect RTL text\nconst RTL = \"\\u0591-\\u07FF\\uFB1D-\\uFDFD\\uFE70-\\uFEFC\";\nconst LTR =\n \"A-Za-z\\u00C0-\\u00D6\\u00D8-\\u00F6\" +\n \"\\u00F8-\\u02B8\\u0300-\\u0590\\u0800-\\u1FFF\\u200E\\u2C00-\\uFB1C\" +\n \"\\uFE00-\\uFE6F\\uFEFD-\\uFFFF\";\n// eslint-disable-next-line no-misleading-character-class\nconst RTL_REGEX = new RegExp(\"^[^\" + LTR + \"]*[\" + RTL + \"]\");\n\nexport const DirectionPlugin = () => {\n const [editor] = useLexicalComposerContext();\n\n useEffect(() => {\n return editor.registerCommand(\n SET_BLOCK_DIRECTION_COMMAND,\n (direction) => {\n editor.update(() => {\n const selection = $getSelection();\n if (!$isRangeSelection(selection)) return;\n\n const nodes: LexicalNode[] = selection.getNodes();\n const blockNodes = new Set<import(\"lexical\").ElementNode>();\n\n for (const node of nodes) {\n let current = $isElementNode(node) ? node : node.getParent();\n while (\n current &&\n current.getParent() &&\n !$isRootNode(current.getParent())\n ) {\n current = current.getParent();\n }\n if (current && $isElementNode(current) && !$isRootNode(current)) {\n blockNodes.add(current);\n }\n }\n\n for (const block of blockNodes) {\n block.setDirection(direction);\n }\n });\n return true;\n },\n COMMAND_PRIORITY_LOW,\n );\n }, [editor]);\n\n // Inherit direction from previous sibling for new empty paragraphs.\n // When a user presses Enter after RTL text, the new paragraph has\n // dir=\"auto\" which resolves to LTR for empty content. This transform\n // detects that case and explicitly sets the direction.\n useEffect(() => {\n return editor.registerNodeTransform(ParagraphNode, (node) => {\n // Only act on paragraphs with no explicit direction\n if (node.getDirection() !== null) return;\n\n // Only act on empty paragraphs (newly created via Enter)\n if (node.getTextContentSize() > 0) return;\n\n const prev = node.getPreviousSibling();\n if (!prev || !$isElementNode(prev)) return;\n\n // Check if the previous sibling has explicit RTL direction\n const prevDir = prev.getDirection();\n if (prevDir !== null) {\n node.setDirection(prevDir);\n return;\n }\n\n // For auto-detected direction, check the previous sibling's text content\n const prevText = prev.getTextContent();\n if (prevText && RTL_REGEX.test(prevText)) {\n node.setDirection(\"rtl\");\n }\n });\n }, [editor]);\n\n return null;\n};\n","\"use client\";\n\nimport { useCallback, useEffect, useRef, useState } from \"react\";\nimport { createPortal } from \"react-dom\";\nimport { useLexicalComposerContext } from \"@lexical/react/LexicalComposerContext\";\nimport {\n $createParagraphNode,\n $getNodeByKey,\n $getRoot,\n $getSelection,\n $isNodeSelection,\n $isParagraphNode,\n $isRangeSelection,\n $isRootNode,\n COMMAND_PRIORITY_LOW,\n KEY_ARROW_DOWN_COMMAND,\n KEY_BACKSPACE_COMMAND,\n KEY_DELETE_COMMAND,\n KEY_ENTER_COMMAND,\n SELECTION_CHANGE_COMMAND,\n TextNode,\n} from \"lexical\";\n\nimport { INSERT_CALLOUT_COMMAND } from \"../commands\";\nimport { $createCalloutNode, $isCalloutNode } from \"../nodes/CalloutNode\";\nimport type { CalloutPreset } from \"../data/callout-presets\";\nimport { DEFAULT_CALLOUT_PRESETS } from \"../data/callout-presets\";\nimport { DEFAULT_EMOJIS } from \"../data/emoji-list\";\n\ninterface CalloutPluginProps {\n /** Override the default color presets */\n presets?: CalloutPreset[];\n /** Default emoji for newly created callouts */\n defaultEmoji?: string;\n /** Default color preset for newly created callouts */\n defaultPreset?: string;\n}\n\nexport function CalloutPlugin({\n presets,\n defaultEmoji = \"\\u{1F4A1}\",\n defaultPreset = \"default\",\n}: CalloutPluginProps = {}) {\n const [editor] = useLexicalComposerContext();\n const resolvedPresets = presets ?? DEFAULT_CALLOUT_PRESETS;\n\n const [portalContainer, setPortalContainer] = useState<HTMLElement | null>(null);\n const [activeCallout, setActiveCallout] = useState<{\n nodeKey: string;\n emoji: string;\n colorPreset: string;\n rect: DOMRect;\n } | null>(null);\n\n const [showEmojiPicker, setShowEmojiPicker] = useState(false);\n const [emojiSearch, setEmojiSearch] = useState(\"\");\n const emojiInputRef = useRef<HTMLInputElement>(null);\n\n useEffect(() => {\n if (typeof window === \"undefined\") return;\n setPortalContainer(document.body);\n }, []);\n\n useEffect(() => {\n return editor.registerCommand(\n INSERT_CALLOUT_COMMAND,\n (payload: { emoji?: string; colorPreset?: string }) => {\n editor.update(() => {\n const selection = $getSelection();\n if (!$isRangeSelection(selection)) return;\n\n const calloutNode = $createCalloutNode({\n emoji: payload.emoji ?? defaultEmoji,\n colorPreset: payload.colorPreset ?? defaultPreset,\n });\n\n const paragraph = $createParagraphNode();\n calloutNode.append(paragraph);\n\n const anchor = selection.anchor.getNode();\n let block = anchor as import(\"lexical\").LexicalNode;\n while (block.getParent() && !$isRootNode(block.getParent())) {\n block = block.getParent()!;\n }\n\n if (anchor instanceof TextNode) {\n const text = anchor.getTextContent();\n if (text.trim() === \"/\") {\n anchor.remove();\n }\n }\n\n if ($isRootNode(block)) {\n $getRoot().append(calloutNode);\n } else if (\n \"getChildrenSize\" in block &&\n typeof block.getChildrenSize === \"function\" &&\n (block.getChildrenSize as () => number)() === 0\n ) {\n block.replace(calloutNode);\n } else {\n block.insertAfter(calloutNode);\n }\n\n paragraph.selectStart();\n });\n return true;\n },\n COMMAND_PRIORITY_LOW,\n );\n }, [editor, defaultEmoji, defaultPreset]);\n\n const checkActiveCallout = useCallback(() => {\n editor.read(() => {\n const selection = $getSelection();\n if (!$isRangeSelection(selection)) {\n setActiveCallout(null);\n return;\n }\n\n let node = selection.anchor.getNode() as import(\"lexical\").LexicalNode | null;\n while (node) {\n if ($isCalloutNode(node)) {\n const key = node.getKey();\n const domElement = editor.getElementByKey(key);\n if (domElement) {\n const rect = domElement.getBoundingClientRect();\n setActiveCallout({\n nodeKey: key,\n emoji: node.getEmoji(),\n colorPreset: node.getColorPreset(),\n rect,\n });\n }\n return;\n }\n node = node.getParent();\n }\n setActiveCallout(null);\n });\n }, [editor]);\n\n const calloutSelRafRef = useRef(0);\n useEffect(() => {\n return editor.registerCommand(\n SELECTION_CHANGE_COMMAND,\n () => {\n if (calloutSelRafRef.current === 0) {\n calloutSelRafRef.current = requestAnimationFrame(() => {\n calloutSelRafRef.current = 0;\n checkActiveCallout();\n });\n }\n return false;\n },\n COMMAND_PRIORITY_LOW,\n );\n }, [editor, checkActiveCallout]);\n\n // Also clear toolbar when editor loses focus (click outside)\n useEffect(() => {\n const rootElement = editor.getRootElement();\n if (!rootElement) return;\n\n const handleBlur = (e: FocusEvent) => {\n // Don't clear if focus moved to our toolbar\n const related = e.relatedTarget as HTMLElement | null;\n if (related?.closest(\"[data-callout-toolbar]\")) return;\n // Small delay to let Lexical's selection update first\n setTimeout(() => {\n setActiveCallout(null);\n setShowEmojiPicker(false);\n setEmojiSearch(\"\");\n }, 100);\n };\n\n rootElement.addEventListener(\"blur\", handleBlur, true);\n return () => rootElement.removeEventListener(\"blur\", handleBlur, true);\n }, [editor]);\n\n // ── Escape callout: Enter on empty last paragraph ──────────────────────\n\n useEffect(() => {\n return editor.registerCommand(\n KEY_ENTER_COMMAND,\n (event) => {\n const selection = $getSelection();\n if (!$isRangeSelection(selection) || !selection.isCollapsed()) return false;\n\n const anchorNode = selection.anchor.getNode();\n\n // Find the callout ancestor\n let calloutNode: import(\"lexical\").LexicalNode | null = null;\n let current = anchorNode as import(\"lexical\").LexicalNode | null;\n while (current) {\n if ($isCalloutNode(current)) {\n calloutNode = current;\n break;\n }\n current = current.getParent();\n }\n if (!calloutNode || !$isCalloutNode(calloutNode)) return false;\n\n // Check if we're in the last child paragraph and it's empty\n const lastChild = calloutNode.getLastChild();\n const parentParagraph = $isParagraphNode(anchorNode)\n ? anchorNode\n : anchorNode.getParent();\n\n if (\n parentParagraph &&\n $isParagraphNode(parentParagraph) &&\n parentParagraph === lastChild &&\n parentParagraph.getTextContent() === \"\"\n ) {\n // Escape: move this empty paragraph out of the callout\n event?.preventDefault();\n const newParagraph = $createParagraphNode();\n calloutNode.insertAfter(newParagraph);\n parentParagraph.remove();\n newParagraph.selectStart();\n return true;\n }\n\n return false;\n },\n COMMAND_PRIORITY_LOW,\n );\n }, [editor]);\n\n // ── Escape callout: Arrow Down at end of last child ────────────────────\n\n useEffect(() => {\n return editor.registerCommand(\n KEY_ARROW_DOWN_COMMAND,\n (event) => {\n const selection = $getSelection();\n if (!$isRangeSelection(selection) || !selection.isCollapsed()) return false;\n\n const anchorNode = selection.anchor.getNode();\n\n // Find the callout ancestor\n let calloutNode: import(\"lexical\").LexicalNode | null = null;\n let current = anchorNode as import(\"lexical\").LexicalNode | null;\n while (current) {\n if ($isCalloutNode(current)) {\n calloutNode = current;\n break;\n }\n current = current.getParent();\n }\n if (!calloutNode || !$isCalloutNode(calloutNode)) return false;\n\n // Check if cursor is at the very end of the callout\n const lastChild = calloutNode.getLastChild();\n const parentParagraph = $isParagraphNode(anchorNode)\n ? anchorNode\n : anchorNode.getParent();\n\n if (parentParagraph === lastChild) {\n const textLength = parentParagraph?.getTextContentSize() ?? 0;\n if (selection.anchor.offset >= textLength) {\n // At the end of the last paragraph — move to next sibling or create one\n event.preventDefault();\n const nextSibling = calloutNode.getNextSibling();\n if (nextSibling) {\n if (\"selectStart\" in nextSibling && typeof nextSibling.selectStart === \"function\") {\n (nextSibling as import(\"lexical\").ElementNode).selectStart();\n }\n } else {\n const newParagraph = $createParagraphNode();\n calloutNode.insertAfter(newParagraph);\n newParagraph.selectStart();\n }\n return true;\n }\n }\n\n return false;\n },\n COMMAND_PRIORITY_LOW,\n );\n }, [editor]);\n\n useEffect(() => {\n const handleBackspace = (event: KeyboardEvent) => {\n const selection = $getSelection();\n\n // Case 1: NodeSelection containing a callout (e.g. from programmatic select)\n if ($isNodeSelection(selection)) {\n const nodes = selection.getNodes();\n const callout = nodes.find($isCalloutNode);\n if (!callout) return false;\n\n event.preventDefault();\n const paragraph = $createParagraphNode();\n callout.insertBefore(paragraph);\n callout.remove();\n paragraph.selectStart();\n return true;\n }\n\n // Case 2: Cursor at offset 0 of the first child inside a callout\n if (!$isRangeSelection(selection) || !selection.isCollapsed()) return false;\n if (selection.anchor.offset !== 0) return false;\n\n const anchorNode = selection.anchor.getNode();\n\n // Find the callout ancestor\n let calloutNode: import(\"lexical\").LexicalNode | null = null;\n let current = anchorNode as import(\"lexical\").LexicalNode | null;\n while (current) {\n if ($isCalloutNode(current)) {\n calloutNode = current;\n break;\n }\n current = current.getParent();\n }\n if (!calloutNode || !$isCalloutNode(calloutNode)) return false;\n\n // Only unwrap if cursor is in the first child (or at the very start)\n const firstChild = calloutNode.getFirstChild();\n const parentBlock = $isParagraphNode(anchorNode) ? anchorNode : anchorNode.getParent();\n if (parentBlock !== firstChild) return false;\n\n event.preventDefault();\n const children = calloutNode.getChildren();\n for (const child of children) {\n calloutNode.insertBefore(child);\n }\n calloutNode.remove();\n\n if (children[0] && \"selectStart\" in children[0] && typeof children[0].selectStart === \"function\") {\n (children[0] as import(\"lexical\").ElementNode).selectStart();\n }\n return true;\n };\n\n const handleDelete = (event: KeyboardEvent) => {\n const selection = $getSelection();\n if (!$isNodeSelection(selection)) return false;\n\n const nodes = selection.getNodes();\n const callout = nodes.find($isCalloutNode);\n if (!callout) return false;\n\n event.preventDefault();\n const paragraph = $createParagraphNode();\n callout.insertBefore(paragraph);\n callout.remove();\n paragraph.selectStart();\n return true;\n };\n\n const u1 = editor.registerCommand(KEY_BACKSPACE_COMMAND, handleBackspace, COMMAND_PRIORITY_LOW);\n const u2 = editor.registerCommand(KEY_DELETE_COMMAND, handleDelete, COMMAND_PRIORITY_LOW);\n return () => { u1(); u2(); };\n }, [editor]);\n\n useEffect(() => {\n const rootElement = editor.getRootElement();\n if (!rootElement) return;\n\n const handleClick = (e: MouseEvent) => {\n const target = e.target as HTMLElement;\n if (target.hasAttribute(\"data-callout-emoji-display\")) {\n e.preventDefault();\n e.stopPropagation();\n setShowEmojiPicker((prev) => !prev);\n }\n };\n\n rootElement.addEventListener(\"click\", handleClick);\n return () => rootElement.removeEventListener(\"click\", handleClick);\n }, [editor]);\n\n useEffect(() => {\n if (!activeCallout) {\n setShowEmojiPicker(false);\n setEmojiSearch(\"\");\n }\n }, [activeCallout]);\n\n useEffect(() => {\n if (showEmojiPicker && emojiInputRef.current) {\n emojiInputRef.current.focus();\n }\n }, [showEmojiPicker]);\n\n const changeEmoji = useCallback(\n (newEmoji: string) => {\n if (!activeCallout) return;\n editor.update(() => {\n const node = $getNodeByKey(activeCallout.nodeKey);\n if ($isCalloutNode(node)) {\n node.setEmoji(newEmoji);\n }\n });\n setActiveCallout((prev) => (prev ? { ...prev, emoji: newEmoji } : null));\n setShowEmojiPicker(false);\n setEmojiSearch(\"\");\n editor.focus();\n },\n [editor, activeCallout],\n );\n\n const changePreset = useCallback(\n (presetId: string) => {\n if (!activeCallout) return;\n editor.update(() => {\n const node = $getNodeByKey(activeCallout.nodeKey);\n if ($isCalloutNode(node)) {\n node.setColorPreset(presetId);\n }\n });\n setActiveCallout((prev) => (prev ? { ...prev, colorPreset: presetId } : null));\n editor.focus();\n },\n [editor, activeCallout],\n );\n\n const deleteCallout = useCallback(() => {\n if (!activeCallout) return;\n editor.update(() => {\n const node = $getNodeByKey(activeCallout.nodeKey);\n if ($isCalloutNode(node)) {\n const children = node.getChildren();\n const parent = node.getParent();\n if (parent) {\n for (const child of children) {\n node.insertBefore(child);\n }\n }\n node.remove();\n }\n });\n setActiveCallout(null);\n editor.focus();\n }, [editor, activeCallout]);\n\n const filteredEmojis = emojiSearch.trim()\n ? DEFAULT_EMOJIS.filter(\n (e) =>\n e.name.includes(emojiSearch.toLowerCase()) ||\n e.keywords.some((k) => k.includes(emojiSearch.toLowerCase())),\n ).slice(0, 40)\n : DEFAULT_EMOJIS.slice(0, 40);\n\n if (!portalContainer || !activeCallout) return null;\n\n const { rect } = activeCallout;\n\n // Position toolbar at top-right of callout, clamped to viewport\n const toolbarWidth = 240;\n const toolbarLeft = Math.min(rect.right - toolbarWidth, window.innerWidth - toolbarWidth - 16);\n const emojiPickerWidth = 280;\n const emojiPickerLeft = Math.min(toolbarLeft, window.innerWidth - emojiPickerWidth - 16);\n\n return createPortal(\n <div data-callout-toolbar>\n <div\n style={{\n position: \"fixed\",\n top: `${rect.top + 6}px`,\n left: `${toolbarLeft}px`,\n display: \"flex\",\n alignItems: \"center\",\n gap: \"3px\",\n padding: \"3px\",\n borderRadius: \"8px\",\n border: \"1px solid var(--blokhaus-popover-border)\",\n backgroundColor: \"var(--blokhaus-popover-bg)\",\n backdropFilter: \"blur(20px) saturate(180%)\",\n WebkitBackdropFilter: \"blur(20px) saturate(180%)\",\n boxShadow: \"var(--blokhaus-popover-shadow)\",\n zIndex: 50,\n fontFamily:\n '-apple-system, BlinkMacSystemFont, \"SF Pro Text\", system-ui, sans-serif',\n }}\n onMouseDown={(e) => e.preventDefault()}\n >\n <button\n type=\"button\"\n title=\"Change emoji\"\n onMouseDown={(e) => {\n e.preventDefault();\n setShowEmojiPicker((prev) => !prev);\n }}\n style={{\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n width: \"26px\",\n height: \"26px\",\n borderRadius: \"5px\",\n border: \"none\",\n cursor: \"pointer\",\n backgroundColor: showEmojiPicker ? \"var(--blokhaus-hover-bg)\" : \"transparent\",\n fontSize: \"14px\",\n transition: \"background-color 80ms\",\n }}\n >\n {activeCallout.emoji}\n </button>\n\n <div\n style={{\n width: \"1px\",\n height: \"16px\",\n backgroundColor: \"var(--blokhaus-separator)\",\n margin: \"0 1px\",\n }}\n />\n\n {resolvedPresets.map((preset) => (\n <button\n key={preset.id}\n type=\"button\"\n title={preset.label}\n onMouseDown={(e) => {\n e.preventDefault();\n changePreset(preset.id);\n }}\n style={{\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n width: \"20px\",\n height: \"20px\",\n borderRadius: \"50%\",\n border:\n activeCallout.colorPreset === preset.id\n ? \"2px solid var(--blokhaus-accent, #007AFF)\"\n : \"2px solid transparent\",\n cursor: \"pointer\",\n padding: \"0\",\n backgroundColor: \"transparent\",\n transition: \"border-color 80ms\",\n }}\n >\n <span\n style={{\n display: \"block\",\n width: \"12px\",\n height: \"12px\",\n borderRadius: \"50%\",\n backgroundColor: preset.bgSwatch,\n border: `1.5px solid ${preset.borderSwatch}`,\n }}\n />\n </button>\n ))}\n\n <div\n style={{\n width: \"1px\",\n height: \"16px\",\n backgroundColor: \"var(--blokhaus-separator)\",\n margin: \"0 1px\",\n }}\n />\n\n <button\n type=\"button\"\n title=\"Remove callout\"\n onMouseDown={(e) => {\n e.preventDefault();\n deleteCallout();\n }}\n style={{\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n width: \"26px\",\n height: \"26px\",\n borderRadius: \"5px\",\n border: \"none\",\n cursor: \"pointer\",\n backgroundColor: \"transparent\",\n color: \"var(--blokhaus-text-tertiary)\",\n fontSize: \"14px\",\n transition: \"background-color 80ms, color 80ms\",\n }}\n onMouseEnter={(e) => {\n e.currentTarget.style.backgroundColor = \"var(--blokhaus-hover-bg)\";\n e.currentTarget.style.color = \"var(--blokhaus-destructive, #e03e3e)\";\n }}\n onMouseLeave={(e) => {\n e.currentTarget.style.backgroundColor = \"transparent\";\n e.currentTarget.style.color = \"var(--blokhaus-text-tertiary)\";\n }}\n >\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 14 14\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"1.5\">\n <path d=\"M3 3l8 8M11 3l-8 8\" />\n </svg>\n </button>\n </div>\n\n {showEmojiPicker && (\n <div\n data-callout-toolbar\n onMouseDown={(e) => e.preventDefault()}\n style={{\n position: \"fixed\",\n top: `${rect.top + 38}px`,\n left: `${emojiPickerLeft}px`,\n width: `${emojiPickerWidth}px`,\n borderRadius: \"10px\",\n border: \"1px solid var(--blokhaus-popover-border)\",\n backgroundColor: \"var(--blokhaus-popover-bg)\",\n backdropFilter: \"blur(20px) saturate(180%)\",\n WebkitBackdropFilter: \"blur(20px) saturate(180%)\",\n boxShadow: \"var(--blokhaus-popover-shadow)\",\n zIndex: 60,\n fontFamily:\n '-apple-system, BlinkMacSystemFont, \"SF Pro Text\", system-ui, sans-serif',\n }}\n >\n <div style={{ padding: \"8px 8px 4px\" }}>\n <input\n ref={emojiInputRef}\n type=\"text\"\n placeholder=\"Search emoji...\"\n value={emojiSearch}\n onChange={(e) => setEmojiSearch(e.target.value)}\n onKeyDown={(e) => {\n if (e.key === \"Escape\") {\n setShowEmojiPicker(false);\n setEmojiSearch(\"\");\n editor.focus();\n }\n if (e.key === \"Enter\" && filteredEmojis.length > 0) {\n changeEmoji(filteredEmojis[0]!.emoji);\n }\n }}\n style={{\n width: \"100%\",\n padding: \"6px 8px\",\n borderRadius: \"6px\",\n border: \"1px solid var(--blokhaus-popover-border)\",\n fontSize: \"13px\",\n outline: \"none\",\n backgroundColor: \"transparent\",\n }}\n />\n </div>\n\n <div\n style={{\n display: \"grid\",\n gridTemplateColumns: \"repeat(8, 1fr)\",\n gap: \"2px\",\n padding: \"4px 8px 8px\",\n maxHeight: \"200px\",\n overflowY: \"auto\",\n }}\n >\n {filteredEmojis.map((item) => (\n <button\n key={item.name}\n type=\"button\"\n title={item.name.replace(/_/g, \" \")}\n onMouseDown={(e) => {\n e.preventDefault();\n changeEmoji(item.emoji);\n }}\n style={{\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n width: \"28px\",\n height: \"28px\",\n borderRadius: \"5px\",\n border: \"none\",\n cursor: \"pointer\",\n backgroundColor: \"transparent\",\n fontSize: \"16px\",\n transition: \"background-color 60ms\",\n }}\n onMouseEnter={(e) => {\n e.currentTarget.style.backgroundColor = \"var(--blokhaus-hover-bg)\";\n }}\n onMouseLeave={(e) => {\n e.currentTarget.style.backgroundColor = \"transparent\";\n }}\n >\n {item.emoji}\n </button>\n ))}\n </div>\n </div>\n )}\n </div>,\n portalContainer,\n );\n}\n","/**\n * Callout color preset definitions.\n *\n * Each preset maps to CSS variables defined in tokens.css:\n * --blokhaus-callout-{id}-bg (background)\n * --blokhaus-callout-{id}-border (left border accent)\n *\n * Developers can override presets via the `presets` prop on `<CalloutPlugin>`.\n */\n\nexport interface CalloutPreset {\n /** Unique identifier used in CSS class names and serialization */\n id: string;\n /** Human-readable label shown in UI */\n label: string;\n /** Default emoji for this preset */\n emoji: string;\n /** Raw background color for rendering the picker dot */\n bgSwatch: string;\n /** Raw border color for rendering the picker dot */\n borderSwatch: string;\n}\n\nexport const DEFAULT_CALLOUT_PRESETS: CalloutPreset[] = [\n { id: \"default\", label: \"Default\", emoji: \"\\u{1F4A1}\", bgSwatch: \"#f1f1ef\", borderSwatch: \"#d4d4d4\" },\n { id: \"info\", label: \"Info\", emoji: \"\\u{2139}\\u{FE0F}\", bgSwatch: \"#ddebf1\", borderSwatch: \"#0b6e99\" },\n { id: \"warning\", label: \"Warning\", emoji: \"\\u{26A0}\\u{FE0F}\", bgSwatch: \"#fbf3db\", borderSwatch: \"#dfab01\" },\n { id: \"error\", label: \"Error\", emoji: \"\\u{1F6AB}\", bgSwatch: \"#fbe4e4\", borderSwatch: \"#e03e3e\" },\n { id: \"success\", label: \"Success\", emoji: \"\\u{2705}\", bgSwatch: \"#ddedea\", borderSwatch: \"#0f7b6c\" },\n { id: \"purple\", label: \"Note\", emoji: \"\\u{1F4DD}\", bgSwatch: \"#eae4f2\", borderSwatch: \"#6940a5\" },\n];\n","\"use client\";\n\nimport { forwardRef, useCallback, useEffect, useRef, useState } from \"react\";\n\nimport { createPortal } from \"react-dom\";\n\nimport { useLexicalComposerContext } from \"@lexical/react/LexicalComposerContext\";\nimport {\n $getNodeByKey,\n $getRoot,\n $getSelection,\n $isRangeSelection,\n $isRootNode,\n COMMAND_PRIORITY_LOW,\n} from \"lexical\";\n\nimport type { UploadHandler } from \"../types\";\nimport { INSERT_VIDEO_COMMAND, OPEN_VIDEO_INPUT_COMMAND } from \"../commands\";\nimport {\n $createLoadingVideoNode,\n $isLoadingVideoNode,\n} from \"../nodes/LoadingVideoNode\";\nimport { $createVideoNode } from \"../nodes/VideoNode\";\nimport { parseVideoEmbed } from \"../utils/video-embeds\";\n\nimport {\n PaperPlaneRightIcon,\n UploadSimpleIcon,\n} from \"@phosphor-icons/react\";\n\nexport interface VideoEmbedRenderProps {\n src: string;\n provider: string;\n title: string;\n}\n\nexport interface VideoFileRenderProps {\n src: string;\n title: string;\n}\n\nconst DEFAULT_MAX_FILE_SIZE = 50 * 1024 * 1024; // 50MB\nconst DEFAULT_ALLOWED_FORMATS = [\n \"video/mp4\",\n \"video/webm\",\n \"video/quicktime\",\n];\n\ninterface VideoPluginProps {\n /** Handler for uploading video files. Same interface as ImagePlugin. Omit to disable file uploads. */\n uploadHandler?: UploadHandler;\n /** Maximum file size in bytes. Default: 50MB. */\n maxFileSize?: number;\n /** Allowed MIME types for upload. Default: mp4, webm, quicktime. */\n allowedFormats?: string[];\n /** Called when a file is rejected (too large or wrong format). */\n onFileRejected?: (file: File, reason: \"size\" | \"format\") => void;\n}\n\nexport function VideoPlugin({\n uploadHandler,\n maxFileSize = DEFAULT_MAX_FILE_SIZE,\n allowedFormats = DEFAULT_ALLOWED_FORMATS,\n onFileRejected,\n}: VideoPluginProps = {}) {\n const [editor] = useLexicalComposerContext();\n const [isInputOpen, setIsInputOpen] = useState(false);\n const [inputPosition, setInputPosition] = useState({ top: 0, left: 0 });\n const [portalContainer, setPortalContainer] = useState<HTMLElement | null>(\n null,\n );\n const uploadHandlerRef = useRef(uploadHandler);\n uploadHandlerRef.current = uploadHandler;\n\n useEffect(() => {\n if (typeof window === \"undefined\") return;\n setPortalContainer(document.body);\n }, []);\n\n const validateFile = useCallback(\n (file: File): boolean => {\n if (!allowedFormats.some((fmt) => file.type === fmt)) {\n onFileRejected?.(file, \"format\");\n return false;\n }\n if (file.size > maxFileSize) {\n onFileRejected?.(file, \"size\");\n return false;\n }\n return true;\n },\n [allowedFormats, maxFileSize, onFileRejected],\n );\n\n const handleVideoUpload = useCallback(\n (file: File) => {\n const handler = uploadHandlerRef.current;\n if (!handler) return;\n if (!validateFile(file)) return;\n\n const objectURL = URL.createObjectURL(file);\n let loadingNodeKey: string | null = null;\n\n editor.update(() => {\n const loadingNode = $createLoadingVideoNode(objectURL, file.name);\n loadingNodeKey = loadingNode.getKey();\n\n const root = $getRoot();\n const selection = $getSelection();\n let targetBlock: import(\"lexical\").LexicalNode | null = null;\n\n if ($isRangeSelection(selection)) {\n let node: import(\"lexical\").LexicalNode = selection.anchor.getNode();\n while (!$isRootNode(node)) {\n const parent = node.getParent();\n if (!parent || $isRootNode(parent)) {\n if (parent) targetBlock = node;\n break;\n }\n node = parent;\n }\n }\n\n if (targetBlock && !$isRootNode(targetBlock)) {\n targetBlock.insertAfter(loadingNode);\n } else {\n root.append(loadingNode);\n }\n });\n\n handler(file)\n .then((remoteURL) => {\n try {\n editor.update(() => {\n if (!loadingNodeKey) return;\n const loadingNode = $getNodeByKey(loadingNodeKey);\n if (!loadingNode || !$isLoadingVideoNode(loadingNode)) return;\n\n const videoNode = $createVideoNode({\n src: remoteURL,\n videoType: \"file\",\n provider: \"upload\",\n title: file.name,\n });\n loadingNode.replace(videoNode);\n });\n } catch {\n // Editor may have been disposed if component unmounted during upload\n }\n URL.revokeObjectURL(objectURL);\n })\n .catch(() => {\n try {\n editor.update(() => {\n if (!loadingNodeKey) return;\n const loadingNode = $getNodeByKey(loadingNodeKey);\n if (!loadingNode) return;\n loadingNode.remove();\n });\n } catch {\n // Editor may have been disposed if component unmounted during upload\n }\n URL.revokeObjectURL(objectURL);\n });\n },\n [editor, validateFile],\n );\n\n const handleVideoEmbed = useCallback(\n (url: string) => {\n const embedInfo = parseVideoEmbed(url);\n if (!embedInfo) return;\n\n editor.update(() => {\n const root = $getRoot();\n const selection = $getSelection();\n let targetBlock: import(\"lexical\").LexicalNode | null = null;\n\n if ($isRangeSelection(selection)) {\n let node: import(\"lexical\").LexicalNode = selection.anchor.getNode();\n while (!$isRootNode(node)) {\n const parent = node.getParent();\n if (!parent || $isRootNode(parent)) {\n if (parent) targetBlock = node;\n break;\n }\n node = parent;\n }\n }\n\n const videoNode = $createVideoNode({\n src: embedInfo.embedUrl,\n videoType: \"embed\",\n provider: embedInfo.provider,\n title: url,\n });\n\n if (targetBlock && !$isRootNode(targetBlock)) {\n // If block is empty, replace it\n const textContent = targetBlock.getTextContent();\n if (textContent.trim() === \"\") {\n targetBlock.replace(videoNode);\n } else {\n targetBlock.insertAfter(videoNode);\n }\n } else {\n root.append(videoNode);\n }\n });\n },\n [editor],\n );\n\n useEffect(() => {\n return editor.registerCommand(\n INSERT_VIDEO_COMMAND,\n (payload) => {\n if (\"file\" in payload) {\n handleVideoUpload(payload.file);\n } else {\n handleVideoEmbed(payload.url);\n }\n return true;\n },\n COMMAND_PRIORITY_LOW,\n );\n }, [editor, handleVideoUpload, handleVideoEmbed]);\n\n useEffect(() => {\n return editor.registerCommand(\n OPEN_VIDEO_INPUT_COMMAND,\n () => {\n const domSelection = window.getSelection();\n if (domSelection && domSelection.rangeCount > 0) {\n const range = domSelection.getRangeAt(0);\n const rect = range.getBoundingClientRect();\n setInputPosition({ top: rect.top, left: rect.left });\n }\n setIsInputOpen(true);\n return true;\n },\n COMMAND_PRIORITY_LOW,\n );\n }, [editor]);\n\n useEffect(() => {\n if (!uploadHandler) return;\n\n const rootElement = editor.getRootElement();\n if (!rootElement) return;\n\n const onDrop = (e: DragEvent) => {\n const files = e.dataTransfer?.files;\n if (!files || files.length === 0) return;\n\n const videoFiles = Array.from(files).filter((f) =>\n f.type.startsWith(\"video/\"),\n );\n if (videoFiles.length === 0) return;\n\n e.preventDefault();\n e.stopPropagation();\n\n for (const file of videoFiles) {\n handleVideoUpload(file);\n }\n };\n\n rootElement.addEventListener(\"drop\", onDrop);\n return () => rootElement.removeEventListener(\"drop\", onDrop);\n }, [editor, uploadHandler, handleVideoUpload]);\n\n useEffect(() => {\n if (!uploadHandler) return;\n\n const rootElement = editor.getRootElement();\n if (!rootElement) return;\n\n const onPaste = (e: ClipboardEvent) => {\n const files = e.clipboardData?.files;\n if (!files || files.length === 0) return;\n\n const videoFiles = Array.from(files).filter((f) =>\n f.type.startsWith(\"video/\"),\n );\n if (videoFiles.length === 0) return;\n\n e.preventDefault();\n\n for (const file of videoFiles) {\n handleVideoUpload(file);\n }\n };\n\n rootElement.addEventListener(\"paste\", onPaste);\n return () => rootElement.removeEventListener(\"paste\", onPaste);\n }, [editor, uploadHandler, handleVideoUpload]);\n\n const handleSubmitUrl = useCallback(\n (url: string) => {\n setIsInputOpen(false);\n editor.dispatchCommand(INSERT_VIDEO_COMMAND, { url });\n },\n [editor],\n );\n\n const handleSubmitFile = useCallback(\n (file: File) => {\n setIsInputOpen(false);\n editor.dispatchCommand(INSERT_VIDEO_COMMAND, { file });\n },\n [editor],\n );\n\n const handleClose = useCallback(() => {\n setIsInputOpen(false);\n editor.focus();\n }, [editor]);\n\n if (!portalContainer) return null;\n\n return (\n <>\n {isInputOpen &&\n createPortal(\n <VideoUrlInput\n position={inputPosition}\n onSubmitUrl={handleSubmitUrl}\n onSubmitFile={uploadHandler ? handleSubmitFile : undefined}\n onClose={handleClose}\n acceptFormats={allowedFormats}\n />,\n portalContainer,\n )}\n </>\n );\n}\n\ninterface VideoUrlInputProps {\n position: { top: number; left: number };\n onSubmitUrl: (url: string) => void;\n onSubmitFile?: (file: File) => void;\n onClose: () => void;\n acceptFormats: string[];\n}\n\nconst VideoUrlInput = forwardRef<HTMLInputElement, VideoUrlInputProps>(\n function VideoUrlInput(\n { position, onSubmitUrl, onSubmitFile, onClose, acceptFormats },\n ref,\n ) {\n const [value, setValue] = useState(\"\");\n const containerRef = useRef<HTMLDivElement>(null);\n const fileDialogOpenRef = useRef(false);\n\n // Close on click outside — skip while file dialog is open\n useEffect(() => {\n const handleClickOutside = (e: MouseEvent) => {\n if (fileDialogOpenRef.current) return;\n if (\n containerRef.current &&\n !containerRef.current.contains(e.target as Node)\n ) {\n onClose();\n }\n };\n\n const raf = requestAnimationFrame(() => {\n document.addEventListener(\"mousedown\", handleClickOutside);\n });\n return () => {\n cancelAnimationFrame(raf);\n document.removeEventListener(\"mousedown\", handleClickOutside);\n };\n }, [onClose]);\n\n const handleKeyDown = (e: React.KeyboardEvent<HTMLInputElement>) => {\n e.stopPropagation();\n\n if (e.key === \"Enter\" && !e.shiftKey) {\n e.preventDefault();\n if (value.trim()) {\n onSubmitUrl(value.trim());\n }\n }\n if (e.key === \"Escape\") {\n e.preventDefault();\n onClose();\n }\n };\n\n const openFilePicker = () => {\n if (!onSubmitFile) return;\n fileDialogOpenRef.current = true;\n\n const input = document.createElement(\"input\");\n input.type = \"file\";\n input.accept = acceptFormats.join(\",\");\n input.onchange = () => {\n fileDialogOpenRef.current = false;\n const file = input.files?.[0];\n if (file && onSubmitFile) {\n onSubmitFile(file);\n }\n };\n // Handle cancel (user closes file dialog without selecting)\n window.addEventListener(\n \"focus\",\n () => {\n // Small delay — the focus event fires before onchange\n setTimeout(() => {\n fileDialogOpenRef.current = false;\n }, 300);\n },\n { once: true },\n );\n input.click();\n };\n\n return (\n <div\n ref={containerRef}\n data-testid=\"video-url-input\"\n style={{\n position: \"fixed\",\n top: `${position.top}px`,\n left: `${position.left}px`,\n zIndex: 60,\n display: \"flex\",\n alignItems: \"center\",\n gap: \"6px\",\n padding: \"6px 8px 6px 14px\",\n borderRadius: \"12px\",\n border: \"1px solid var(--blokhaus-popover-border, rgba(0,0,0,0.06))\",\n backgroundColor: \"var(--blokhaus-popover-bg)\",\n backdropFilter: \"blur(20px) saturate(180%)\",\n WebkitBackdropFilter: \"blur(20px) saturate(180%)\",\n boxShadow: \"var(--blokhaus-popover-shadow)\",\n fontFamily: \"var(--blokhaus-font-sans, system-ui, sans-serif)\",\n animation: \"blokhaus-video-input-enter 0.2s ease-out\",\n minWidth: \"340px\",\n }}\n >\n <input\n ref={(el) => {\n if (el) el.focus();\n if (typeof ref === \"function\") ref(el);\n else if (ref) ref.current = el;\n }}\n type=\"text\"\n value={value}\n onChange={(e) => setValue(e.target.value)}\n onKeyDown={handleKeyDown}\n placeholder=\"Paste video URL...\"\n style={{\n flex: 1,\n border: \"none\",\n outline: \"none\",\n background: \"transparent\",\n fontSize: \"14px\",\n color: \"var(--blokhaus-foreground, #0f172a)\",\n fontFamily: \"inherit\",\n }}\n />\n\n <button\n type=\"button\"\n data-testid=\"video-url-submit\"\n onClick={() => {\n if (value.trim()) onSubmitUrl(value.trim());\n }}\n disabled={!value.trim()}\n style={{\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n width: \"28px\",\n height: \"28px\",\n borderRadius: \"8px\",\n border: \"none\",\n cursor: value.trim() ? \"pointer\" : \"default\",\n backgroundColor: value.trim()\n ? \"var(--blokhaus-accent, #3b82f6)\"\n : \"var(--blokhaus-muted, #f1f5f9)\",\n color: value.trim()\n ? \"var(--blokhaus-accent-foreground, #fff)\"\n : \"var(--blokhaus-muted-foreground, #94a3b8)\",\n transition: \"background-color 0.15s, color 0.15s\",\n flexShrink: 0,\n }}\n >\n <PaperPlaneRightIcon size={14} weight=\"fill\" />\n </button>\n\n {onSubmitFile && (\n <button\n type=\"button\"\n data-testid=\"video-file-upload\"\n onClick={openFilePicker}\n style={{\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n width: \"28px\",\n height: \"28px\",\n borderRadius: \"8px\",\n border: \"none\",\n cursor: \"pointer\",\n backgroundColor: \"var(--blokhaus-muted, #f1f5f9)\",\n color: \"var(--blokhaus-muted-foreground, #94a3b8)\",\n transition: \"background-color 0.15s\",\n flexShrink: 0,\n }}\n >\n <UploadSimpleIcon size={14} weight=\"bold\" />\n </button>\n )}\n\n <style\n dangerouslySetInnerHTML={{\n __html: `\n @keyframes blokhaus-video-input-enter {\n from {\n opacity: 0;\n transform: translateY(-4px) scale(0.98);\n }\n to {\n opacity: 1;\n transform: translateY(0) scale(1);\n }\n }\n `,\n }}\n />\n </div>\n );\n },\n);\n","/**\n * Video embed URL parser.\n * Extracts provider-specific embed URLs from user-pasted video links.\n * Pure function — no React, no side effects.\n */\n\nexport interface VideoEmbedInfo {\n provider: \"youtube\" | \"vimeo\" | \"loom\" | \"generic\";\n embedUrl: string;\n /** Thumbnail URL when available (YouTube, Vimeo). */\n thumbnailUrl?: string;\n}\n\n/**\n * Parse a URL string and return embed info for known video providers.\n * Returns `null` for non-URL strings. Returns `{ provider: \"generic\" }` for\n * unrecognized but valid URLs, so any iframe-compatible link works.\n */\nexport function parseVideoEmbed(url: string): VideoEmbedInfo | null {\n const trimmed = url.trim();\n if (!trimmed) return null;\n\n // Validate it looks like a URL\n let parsed: URL;\n try {\n parsed = new URL(trimmed);\n } catch {\n return null;\n }\n\n if (parsed.protocol !== \"http:\" && parsed.protocol !== \"https:\") {\n return null;\n }\n\n const hostname = parsed.hostname.replace(/^www\\./, \"\");\n\n if (hostname === \"youtube.com\" || hostname === \"m.youtube.com\") {\n let videoId: string | null = null;\n\n if (parsed.pathname === \"/watch\") {\n videoId = parsed.searchParams.get(\"v\");\n }\n\n if (!videoId) {\n const pathMatch = parsed.pathname.match(\n /^\\/(embed|shorts|live|v)\\/([a-zA-Z0-9_-]+)/,\n );\n if (pathMatch) {\n videoId = pathMatch[2] ?? null;\n }\n }\n\n if (videoId) {\n return {\n provider: \"youtube\",\n embedUrl: `https://www.youtube.com/embed/${videoId}`,\n thumbnailUrl: `https://img.youtube.com/vi/${videoId}/hqdefault.jpg`,\n };\n }\n }\n\n if (hostname === \"youtu.be\") {\n const videoId = parsed.pathname.slice(1).split(\"/\")[0];\n if (videoId) {\n return {\n provider: \"youtube\",\n embedUrl: `https://www.youtube.com/embed/${videoId}`,\n thumbnailUrl: `https://img.youtube.com/vi/${videoId}/hqdefault.jpg`,\n };\n }\n }\n\n if (hostname === \"vimeo.com\" || hostname === \"player.vimeo.com\") {\n const vimeoMatch = parsed.pathname.match(/\\/(?:video\\/|channels\\/[^/]+\\/)?(\\d+)/);\n if (vimeoMatch) {\n const videoId = vimeoMatch[1];\n return {\n provider: \"vimeo\",\n embedUrl: `https://player.vimeo.com/video/${videoId}`,\n };\n }\n }\n\n if (hostname === \"loom.com\") {\n const loomMatch = parsed.pathname.match(/\\/(?:share|embed)\\/([a-zA-Z0-9]+)/);\n if (loomMatch) {\n const videoId = loomMatch[1];\n return {\n provider: \"loom\",\n embedUrl: `https://www.loom.com/embed/${videoId}`,\n };\n }\n }\n\n return {\n provider: \"generic\",\n embedUrl: trimmed,\n };\n}\n","\"use client\";\n\nimport { useEffect } from \"react\";\n\nimport { useLexicalComposerContext } from \"@lexical/react/LexicalComposerContext\";\nimport {\n $findMatchingParent,\n mergeRegister,\n} from \"@lexical/utils\";\nimport {\n $createParagraphNode,\n $getSelection,\n $isElementNode,\n $isRangeSelection,\n $isRootNode,\n COMMAND_PRIORITY_LOW,\n INSERT_PARAGRAPH_COMMAND,\n KEY_ARROW_DOWN_COMMAND,\n KEY_ARROW_LEFT_COMMAND,\n KEY_ARROW_RIGHT_COMMAND,\n KEY_ARROW_UP_COMMAND,\n} from \"lexical\";\n\nimport { INSERT_TOGGLE_COMMAND } from \"../commands\";\nimport {\n $createToggleContainerNode,\n $isToggleContainerNode,\n ToggleContainerNode,\n} from \"../nodes/ToggleContainerNode\";\nimport {\n $createToggleTitleNode,\n $isToggleTitleNode,\n ToggleTitleNode,\n} from \"../nodes/ToggleTitleNode\";\nimport {\n $createToggleContentNode,\n $isToggleContentNode,\n ToggleContentNode,\n} from \"../nodes/ToggleContentNode\";\n\nexport function TogglePlugin() {\n const [editor] = useLexicalComposerContext();\n\n useEffect(() => {\n const $onEscapeUp = () => {\n const selection = $getSelection();\n if (\n $isRangeSelection(selection) &&\n selection.isCollapsed() &&\n selection.anchor.offset === 0\n ) {\n const container = $findMatchingParent(\n selection.anchor.getNode(),\n $isToggleContainerNode,\n );\n if ($isToggleContainerNode(container)) {\n const parent = container.getParent();\n if (\n parent !== null &&\n parent.getFirstChild() === container &&\n selection.anchor.key ===\n container.getFirstDescendant()?.getKey()\n ) {\n container.insertBefore($createParagraphNode());\n }\n }\n }\n return false;\n };\n\n const $onEscapeDown = () => {\n const selection = $getSelection();\n if ($isRangeSelection(selection) && selection.isCollapsed()) {\n const container = $findMatchingParent(\n selection.anchor.getNode(),\n $isToggleContainerNode,\n );\n if ($isToggleContainerNode(container)) {\n const parent = container.getParent();\n if (parent !== null && parent.getLastChild() === container) {\n const lastDescendant = container.getLastDescendant();\n if (\n lastDescendant !== null &&\n selection.anchor.key === lastDescendant.getKey() &&\n selection.anchor.offset ===\n lastDescendant.getTextContentSize()\n ) {\n container.insertAfter($createParagraphNode());\n }\n }\n }\n }\n return false;\n };\n\n return mergeRegister(\n // ContentNode must live inside a ContainerNode\n editor.registerNodeTransform(ToggleContentNode, (node) => {\n const parent = node.getParent();\n if (!$isToggleContainerNode(parent)) {\n const children = node.getChildren();\n for (const child of children) {\n node.insertBefore(child);\n }\n node.remove();\n }\n }),\n\n // TitleNode must live inside a ContainerNode\n editor.registerNodeTransform(ToggleTitleNode, (node) => {\n const parent = node.getParent();\n if (!$isToggleContainerNode(parent)) {\n node.replace(\n $createParagraphNode().append(...node.getChildren()),\n );\n }\n }),\n\n // ContainerNode must have exactly [TitleNode, ContentNode]\n editor.registerNodeTransform(ToggleContainerNode, (node) => {\n const children = node.getChildren();\n if (\n children.length !== 2 ||\n !$isToggleTitleNode(children[0]) ||\n !$isToggleContentNode(children[1])\n ) {\n // Structure is broken — unwrap everything out\n for (const child of children) {\n node.insertBefore(child);\n }\n node.remove();\n }\n }),\n\n editor.registerCommand(\n KEY_ARROW_DOWN_COMMAND,\n $onEscapeDown,\n COMMAND_PRIORITY_LOW,\n ),\n editor.registerCommand(\n KEY_ARROW_RIGHT_COMMAND,\n $onEscapeDown,\n COMMAND_PRIORITY_LOW,\n ),\n editor.registerCommand(\n KEY_ARROW_UP_COMMAND,\n $onEscapeUp,\n COMMAND_PRIORITY_LOW,\n ),\n editor.registerCommand(\n KEY_ARROW_LEFT_COMMAND,\n $onEscapeUp,\n COMMAND_PRIORITY_LOW,\n ),\n\n editor.registerCommand(\n INSERT_PARAGRAPH_COMMAND,\n () => {\n const selection = $getSelection();\n if (!$isRangeSelection(selection)) return false;\n\n const titleNode = $findMatchingParent(\n selection.anchor.getNode(),\n $isToggleTitleNode,\n );\n if (!$isToggleTitleNode(titleNode)) return false;\n\n const container = titleNode.getParent();\n if (!$isToggleContainerNode(container)) return false;\n\n // If closed, open it first\n if (!container.getOpen()) {\n container.toggleOpen();\n }\n\n // Focus the content node\n const content = titleNode.getNextSibling();\n if ($isToggleContentNode(content)) {\n const firstChild = content.getFirstChild();\n if (firstChild && \"selectEnd\" in firstChild) {\n (\n firstChild as import(\"lexical\").ElementNode\n ).selectEnd();\n } else {\n content.selectEnd();\n }\n }\n\n return true;\n },\n COMMAND_PRIORITY_LOW,\n ),\n\n editor.registerCommand(\n INSERT_TOGGLE_COMMAND,\n (payload) => {\n editor.update(() => {\n const selection = $getSelection();\n if (!$isRangeSelection(selection)) return;\n\n const title = $createToggleTitleNode();\n const content = $createToggleContentNode();\n const innerParagraph = $createParagraphNode();\n content.append(innerParagraph);\n\n const container = $createToggleContainerNode({\n open: payload?.isOpen ?? true,\n });\n container.append(title, content);\n\n // Find the top-level block at the selection\n const anchor = selection.anchor.getNode();\n let topBlock = anchor;\n while (\n topBlock.getParent() &&\n !$isRootNode(topBlock.getParent())\n ) {\n topBlock = topBlock.getParent()!;\n }\n\n // Replace the current block if it's empty, otherwise insert after\n if (\n $isElementNode(topBlock) &&\n topBlock.getTextContent().trim() === \"\"\n ) {\n topBlock.replace(container);\n } else {\n topBlock.insertAfter(container);\n }\n\n title.selectEnd();\n });\n return true;\n },\n COMMAND_PRIORITY_LOW,\n ),\n );\n }, [editor]);\n\n return null;\n}\n","\"use client\";\n\nimport { createPortal } from \"react-dom\";\nimport { useBlockHighlight } from \"../hooks/useBlockHighlight\";\nimport { useMarqueeSelect } from \"../hooks/useMarqueeSelect\";\nimport { useBlockSelectionActions } from \"../hooks/useBlockSelectionActions\";\n\nexport function BlockSelectionPlugin() {\n const { clearHighlights, hasBlockSelectionRef, isDraggingRef } =\n useBlockHighlight();\n const { marqueeRect } = useMarqueeSelect(hasBlockSelectionRef, isDraggingRef);\n useBlockSelectionActions(hasBlockSelectionRef, isDraggingRef, clearHighlights);\n\n if (!marqueeRect || typeof document === \"undefined\") return null;\n\n return createPortal(\n <div\n data-testid=\"block-selection-marquee\"\n style={{\n position: \"fixed\",\n top: `${marqueeRect.top}px`,\n left: `${marqueeRect.left}px`,\n width: `${marqueeRect.width}px`,\n height: `${marqueeRect.height}px`,\n backgroundColor:\n \"var(--blokhaus-block-selection, rgba(45, 133, 255, 0.08))\",\n border: \"1px solid rgba(45, 133, 255, 0.25)\",\n borderRadius: \"3px\",\n pointerEvents: \"none\",\n zIndex: 9999,\n }}\n />,\n document.body,\n );\n}\n","\"use client\";\n\nimport { useCallback, useEffect, useRef } from \"react\";\nimport { useLexicalComposerContext } from \"@lexical/react/LexicalComposerContext\";\nimport {\n $getSelection,\n $isRangeSelection,\n $isRootNode,\n COMMAND_PRIORITY_LOW,\n SELECTION_CHANGE_COMMAND,\n} from \"lexical\";\nimport { findTopBlock } from \"../utils/block-selection\";\n\n/**\n * Highlights top-level blocks when the user's text selection spans multiple blocks.\n * Returns a `clearHighlights` function and a ref tracking whether block selection is active.\n */\nexport function useBlockHighlight() {\n const [editor] = useLexicalComposerContext();\n const rafRef = useRef(0);\n const hasBlockSelectionRef = useRef(false);\n const isDraggingRef = useRef(false);\n\n const clearHighlights = useCallback(() => {\n const root = editor.getRootElement();\n if (!root) return;\n const selected = root.querySelectorAll(\"[data-block-selected]\");\n for (let i = 0; i < selected.length; i++) {\n selected[i]!.removeAttribute(\"data-block-selected\");\n }\n hasBlockSelectionRef.current = false;\n }, [editor]);\n\n useEffect(() => {\n return editor.registerCommand(\n SELECTION_CHANGE_COMMAND,\n () => {\n if (isDraggingRef.current) return false;\n\n if (rafRef.current) cancelAnimationFrame(rafRef.current);\n rafRef.current = requestAnimationFrame(() => {\n rafRef.current = 0;\n\n if (hasBlockSelectionRef.current) {\n clearHighlights();\n }\n\n editor.read(() => {\n const root = editor.getRootElement();\n if (!root) return;\n\n const selected = root.querySelectorAll(\"[data-block-selected]\");\n for (let i = 0; i < selected.length; i++) {\n selected[i]!.removeAttribute(\"data-block-selected\");\n }\n\n const selection = $getSelection();\n if (!$isRangeSelection(selection) || selection.isCollapsed()) return;\n\n const anchorBlock = findTopBlock(selection.anchor.getNode());\n const focusBlock = findTopBlock(selection.focus.getNode());\n if (!anchorBlock || !focusBlock) return;\n if (anchorBlock.getKey() === focusBlock.getKey()) return;\n\n const rootNode = anchorBlock.getParent();\n if (!rootNode || !$isRootNode(rootNode)) return;\n\n const children = rootNode.getChildren();\n const anchorIdx = children.findIndex(\n (c) => c.getKey() === anchorBlock.getKey(),\n );\n const focusIdx = children.findIndex(\n (c) => c.getKey() === focusBlock.getKey(),\n );\n if (anchorIdx === -1 || focusIdx === -1) return;\n\n const start = Math.min(anchorIdx, focusIdx);\n const end = Math.max(anchorIdx, focusIdx);\n\n for (let i = start; i <= end; i++) {\n const child = children[i];\n if (!child) continue;\n const el = editor.getElementByKey(child.getKey());\n if (el) el.setAttribute(\"data-block-selected\", \"true\");\n }\n });\n });\n return false;\n },\n COMMAND_PRIORITY_LOW,\n );\n }, [editor, clearHighlights]);\n\n return { clearHighlights, hasBlockSelectionRef, isDraggingRef };\n}\n","// LEXICAL\nimport { $isRootNode, type LexicalNode } from \"lexical\";\n\nexport type MarqueeRect = {\n top: number;\n left: number;\n width: number;\n height: number;\n};\n\nexport const MIN_DRAG_DISTANCE = 5;\n\nexport const INTERACTIVE_SELECTOR =\n \"button, a, input, textarea, select, [role='button'], [contenteditable='true']\";\n\n/**\n * Returns true if two rects (in viewport coordinates) overlap.\n */\nexport function rectsIntersect(\n a: { top: number; left: number; bottom: number; right: number },\n b: { top: number; left: number; bottom: number; right: number },\n): boolean {\n return a.left < b.right && a.right > b.left && a.top < b.bottom && a.bottom > b.top;\n}\n\n/**\n * Walks up from `node` to find the top-level block\n * (a direct child of the root node).\n * Returns `null` if the node is the root itself or has no block ancestor.\n */\nexport function findTopBlock(node: LexicalNode): LexicalNode | null {\n let current: LexicalNode | null = node;\n while (current !== null) {\n const parent: LexicalNode | null = current.getParent();\n if (parent === null) return null;\n if ($isRootNode(parent)) return current;\n current = parent;\n }\n return null;\n}\n","\"use client\";\n\nimport { useEffect, useRef, useState } from \"react\";\nimport { useLexicalComposerContext } from \"@lexical/react/LexicalComposerContext\";\nimport { $getRoot } from \"lexical\";\nimport {\n type MarqueeRect,\n MIN_DRAG_DISTANCE,\n INTERACTIVE_SELECTOR,\n rectsIntersect,\n} from \"../utils/block-selection\";\n\n/**\n * Implements marquee (lasso) drag-to-select for top-level blocks.\n * Renders nothing on touch devices.\n */\nexport function useMarqueeSelect(\n hasBlockSelectionRef: React.RefObject<boolean>,\n isDraggingRef: React.MutableRefObject<boolean>,\n) {\n const [editor] = useLexicalComposerContext();\n const [marqueeRect, setMarqueeRect] = useState<MarqueeRect | null>(null);\n const startPointRef = useRef({ x: 0, y: 0 });\n const hasMovedRef = useRef(false);\n const wrapperRef = useRef<HTMLElement | null>(null);\n const isTouchDeviceRef = useRef(false);\n\n // Detect touch device and find wrapper element\n useEffect(() => {\n if (typeof window === \"undefined\") return;\n\n isTouchDeviceRef.current =\n window.matchMedia(\"(pointer: coarse)\").matches ||\n navigator.maxTouchPoints > 0 ||\n \"ontouchstart\" in window;\n\n const rootEl = editor.getRootElement();\n if (rootEl) {\n let el: HTMLElement | null = rootEl;\n while (el && !el.hasAttribute(\"data-blokhaus-root\")) {\n el = el.parentElement;\n }\n wrapperRef.current = el;\n }\n }, [editor]);\n\n // Document-level marquee drag listeners\n useEffect(() => {\n if (isTouchDeviceRef.current) return;\n if (typeof document === \"undefined\") return;\n\n const rootElement = editor.getRootElement();\n if (!rootElement) return;\n\n let moveRaf = 0;\n\n const onMouseDown = (e: MouseEvent) => {\n if (e.button !== 0) return;\n\n const wrapper = wrapperRef.current;\n if (!wrapper) return;\n\n const target = e.target as HTMLElement;\n\n if (rootElement.contains(target) && target !== rootElement) return;\n\n const closestEditor = target.closest(\"[data-blokhaus-root]\");\n if (closestEditor && closestEditor !== wrapper) return;\n\n if (target.closest(INTERACTIVE_SELECTOR)) return;\n\n const isNearEditor =\n target === wrapper ||\n target === rootElement ||\n target.contains(wrapper);\n if (!isNearEditor) return;\n\n // Vertical proximity check — avoid triggering from far-away ancestor padding\n const wrapperRect = wrapper.getBoundingClientRect();\n if (\n e.clientY < wrapperRect.top - 200 ||\n e.clientY > wrapperRect.bottom + 200\n )\n return;\n\n window.getSelection()?.removeAllRanges();\n e.preventDefault();\n\n startPointRef.current = { x: e.clientX, y: e.clientY };\n hasMovedRef.current = false;\n isDraggingRef.current = true;\n\n document.addEventListener(\"mousemove\", onMouseMove);\n document.addEventListener(\"mouseup\", onMouseUp);\n };\n\n const onMouseMove = (e: MouseEvent) => {\n if (!isDraggingRef.current) return;\n\n const dx = e.clientX - startPointRef.current.x;\n const dy = e.clientY - startPointRef.current.y;\n\n if (!hasMovedRef.current) {\n if (\n Math.abs(dx) < MIN_DRAG_DISTANCE &&\n Math.abs(dy) < MIN_DRAG_DISTANCE\n )\n return;\n hasMovedRef.current = true;\n }\n\n if (moveRaf) cancelAnimationFrame(moveRaf);\n moveRaf = requestAnimationFrame(() => {\n moveRaf = 0;\n if (!isDraggingRef.current) return;\n\n const sx = startPointRef.current.x;\n const sy = startPointRef.current.y;\n const cx = e.clientX;\n const cy = e.clientY;\n\n const left = Math.min(sx, cx);\n const top = Math.min(sy, cy);\n const right = Math.max(sx, cx);\n const bottom = Math.max(sy, cy);\n\n setMarqueeRect({ top, left, width: right - left, height: bottom - top });\n\n const marqueeViewport = { top, left, bottom, right };\n\n editor.read(() => {\n const rootNode = $getRoot();\n const children = rootNode.getChildren();\n\n for (const child of children) {\n const el = editor.getElementByKey(child.getKey());\n if (!el) continue;\n const blockRect = el.getBoundingClientRect();\n\n if (rectsIntersect(marqueeViewport, blockRect)) {\n el.setAttribute(\"data-block-selected\", \"true\");\n } else {\n el.removeAttribute(\"data-block-selected\");\n }\n }\n });\n });\n };\n\n const onMouseUp = () => {\n isDraggingRef.current = false;\n\n document.removeEventListener(\"mousemove\", onMouseMove);\n document.removeEventListener(\"mouseup\", onMouseUp);\n\n if (moveRaf) {\n cancelAnimationFrame(moveRaf);\n moveRaf = 0;\n }\n\n setMarqueeRect(null);\n\n const root = editor.getRootElement();\n if (root && root.querySelector(\"[data-block-selected]\")) {\n hasBlockSelectionRef.current = true;\n }\n };\n\n document.addEventListener(\"mousedown\", onMouseDown);\n\n return () => {\n document.removeEventListener(\"mousedown\", onMouseDown);\n document.removeEventListener(\"mousemove\", onMouseMove);\n document.removeEventListener(\"mouseup\", onMouseUp);\n if (moveRaf) cancelAnimationFrame(moveRaf);\n };\n }, [editor, isDraggingRef, hasBlockSelectionRef]);\n\n return { marqueeRect };\n}\n","\"use client\";\n\nimport { useEffect, useRef } from \"react\";\nimport { useLexicalComposerContext } from \"@lexical/react/LexicalComposerContext\";\nimport { $getRoot } from \"lexical\";\n\n/**\n * Handles dismissing block selection on click and deleting selected blocks\n * on Backspace/Delete. Uses capture-phase listeners to intercept before Lexical.\n */\nexport function useBlockSelectionActions(\n hasBlockSelectionRef: React.RefObject<boolean>,\n isDraggingRef: React.RefObject<boolean>,\n clearHighlights: () => void,\n) {\n const [editor] = useLexicalComposerContext();\n const editorRef = useRef(editor);\n editorRef.current = editor;\n\n useEffect(() => {\n const onMouseDismiss = () => {\n if (hasBlockSelectionRef.current && !isDraggingRef.current) {\n clearHighlights();\n }\n };\n\n const onKeyDown = (e: KeyboardEvent) => {\n if (!hasBlockSelectionRef.current || isDraggingRef.current) return;\n\n if (e.key === \"Backspace\" || e.key === \"Delete\") {\n e.preventDefault();\n e.stopPropagation();\n\n const ed = editorRef.current;\n\n ed.update(() => {\n const rootNode = $getRoot();\n const children = rootNode.getChildren();\n\n for (const child of children) {\n const el = ed.getElementByKey(child.getKey());\n if (el && el.hasAttribute(\"data-block-selected\")) {\n child.remove();\n }\n }\n });\n\n clearHighlights();\n return;\n }\n\n clearHighlights();\n };\n\n document.addEventListener(\"mousedown\", onMouseDismiss, true);\n document.addEventListener(\"keydown\", onKeyDown, true);\n\n return () => {\n document.removeEventListener(\"mousedown\", onMouseDismiss, true);\n document.removeEventListener(\"keydown\", onKeyDown, true);\n };\n }, [clearHighlights, hasBlockSelectionRef, isDraggingRef]);\n}\n"],"mappings":";;;AAGA,SAAS,aAAAA,kBAAiB;AAG1B,SAAS,uBAAuB;AAChC,SAAS,sBAAsB;AAC/B,SAAS,uBAAuB;AAChC,SAAS,qBAAqB;AAC9B,SAAS,uBAAuB;AAChC,SAAS,4BAA4B;AACrC,SAAS,6BAAAC,kCAAiC;AAC1C,SAAS,gBAAgB;;;ACZzB,SAAS,aAAa,iBAAiB;AACvC,SAAS,UAAU,oBAAoB;AACvC,SAAS,UAAU,oBAAoB;AACvC,SAAS,WAAW,cAAc,qBAAqB;;;ACFvD,SAAS,aAAa,WAAW,cAAc;AAa/C;AAAA,EACE;AAAA,EAGA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP,SAAS,iCAAiC;AAC1C,SAAS,+BAA+B;AAkHlC;AA9FC,IAAM,YAAN,MAAM,mBAAkB,cAA4B;AAAA,EACzD;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EAEA,OAAO,UAAkB;AACvB,WAAO;AAAA,EACT;AAAA,EAEA,OAAO,MAAM,MAA4B;AACvC,WAAO,IAAI;AAAA,MACT,KAAK;AAAA,MACL,KAAK;AAAA,MACL,KAAK;AAAA,MACL,KAAK;AAAA,MACL,KAAK;AAAA,IACP;AAAA,EACF;AAAA,EAEA,YACE,KACA,SACA,OACA,QACA,KACA;AACA,UAAM,GAAG;AACT,SAAK,QAAQ;AACb,SAAK,YAAY;AACjB,SAAK,UAAU;AACf,SAAK,WAAW;AAAA,EAClB;AAAA,EAEA,UAAU,SAAoC;AAC5C,UAAM,MAAM,SAAS,cAAc,KAAK;AACxC,QAAI,MAAM,UAAU;AACpB,QAAI,MAAM,WAAW;AACrB,WAAO;AAAA,EACT;AAAA,EAEA,YAAmB;AACjB,WAAO;AAAA,EACT;AAAA,EAEA,YAA6B;AAC3B,UAAM,MAAM,SAAS,cAAc,KAAK;AACxC,QAAI,aAAa,OAAO,KAAK,KAAK;AAClC,QAAI,aAAa,OAAO,KAAK,SAAS;AACtC,QAAI,KAAK,QAAS,KAAI,aAAa,SAAS,OAAO,KAAK,OAAO,CAAC;AAChE,QAAI,KAAK,SAAU,KAAI,aAAa,UAAU,OAAO,KAAK,QAAQ,CAAC;AACnE,WAAO,EAAE,SAAS,IAAI;AAAA,EACxB;AAAA,EAEA,OAAO,YAAqC;AAC1C,WAAO;AAAA,MACL,KAAK,OAAO;AAAA,QACV,YAAY;AAAA,QACZ,UAAU;AAAA,MACZ;AAAA,IACF;AAAA,EACF;AAAA,EAEA,OAAO,WAAW,gBAAgD;AAChE,WAAO,iBAAiB;AAAA,MACtB,KAAK,eAAe;AAAA,MACpB,SAAS,eAAe;AAAA,MACxB,OAAO,eAAe;AAAA,MACtB,QAAQ,eAAe;AAAA,IACzB,CAAC;AAAA,EACH;AAAA,EAEA,aAAkC;AAChC,WAAO;AAAA,MACL,GAAG,MAAM,WAAW;AAAA,MACpB,KAAK,KAAK;AAAA,MACV,SAAS,KAAK;AAAA,MACd,OAAO,KAAK;AAAA,MACZ,QAAQ,KAAK;AAAA,MACb,MAAM;AAAA,MACN,SAAS;AAAA,IACX;AAAA,EACF;AAAA,EAEA,SAAiB;AACf,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,aAAqB;AACnB,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,WAAyB;AACvB,WACE;AAAA,MAAC;AAAA;AAAA,QACC,KAAK,KAAK;AAAA,QACV,SAAS,KAAK;AAAA,QACd,OAAO,KAAK;AAAA,QACZ,QAAQ,KAAK;AAAA,QACb,SAAS,KAAK,OAAO;AAAA;AAAA,IACvB;AAAA,EAEJ;AACF;AAEA,SAAS,oBAAoB,SAA2C;AACtE,MAAI,mBAAmB,kBAAkB;AACvC,UAAM,MAAM,QAAQ,aAAa,KAAK;AACtC,UAAM,MAAM,QAAQ,aAAa,KAAK,KAAK;AAC3C,QAAI,KAAK;AACP,YAAM,OAAO,iBAAiB,EAAE,KAAK,SAAS,IAAI,CAAC;AACnD,aAAO,EAAE,KAAK;AAAA,IAChB;AAAA,EACF;AACA,SAAO;AACT;AAEA,SAAS,eAAe;AAAA,EACtB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAMG;AACD,QAAM,CAAC,MAAM,IAAI,0BAA0B;AAC3C,QAAM,CAAC,YAAY,aAAa,cAAc,IAC5C,wBAAwB,OAAO;AACjC,QAAM,SAAS,OAAuB,IAAI;AAE1C,YAAU,MAAM;AACd,WAAO,OAAO;AAAA,MACZ;AAAA,MACA,CAAC,UAAsB;AACrB,YAAI,OAAO,SAAS,SAAS,MAAM,MAAc,GAAG;AAClD,cAAI,CAAC,MAAM,UAAU;AACnB,2BAAe;AAAA,UACjB;AACA,sBAAY,IAAI;AAChB,iBAAO;AAAA,QACT;AACA,eAAO;AAAA,MACT;AAAA,MACA;AAAA,IACF;AAAA,EACF,GAAG,CAAC,QAAQ,gBAAgB,WAAW,CAAC;AAExC,QAAM,WAAW;AAAA,IACf,CAAC,UAAyB;AACxB,UAAI,YAAY;AACd,cAAM,eAAe;AACrB,eAAO,OAAO,MAAM;AAClB,gBAAM,OAAO,cAAc,OAAO;AAClC,cAAI,MAAM;AACR,iBAAK,OAAO;AAAA,UACd;AAAA,QACF,CAAC;AACD,eAAO;AAAA,MACT;AACA,aAAO;AAAA,IACT;AAAA,IACA,CAAC,QAAQ,YAAY,OAAO;AAAA,EAC9B;AAEA,YAAU,MAAM;AACd,UAAM,sBAAsB,OAAO;AAAA,MACjC;AAAA,MACA;AAAA,MACA;AAAA,IACF;AACA,UAAM,mBAAmB,OAAO;AAAA,MAC9B;AAAA,MACA;AAAA,MACA;AAAA,IACF;AACA,WAAO,MAAM;AACX,0BAAoB;AACpB,uBAAiB;AAAA,IACnB;AAAA,EACF,GAAG,CAAC,QAAQ,QAAQ,CAAC;AAErB,SACE;AAAA,IAAC;AAAA;AAAA,MACC,KAAK;AAAA,MACL,eAAY;AAAA,MACZ,OAAO;AAAA,QACL,SAAS;AAAA,QACT,UAAU;AAAA,QACV,UAAU;AAAA,QACV,QAAQ;AAAA,MACV;AAAA,MACA,MAAK;AAAA,MACL,cAAY;AAAA,MAEZ;AAAA,QAAC;AAAA;AAAA,UACC;AAAA,UACA,KAAK;AAAA,UACL;AAAA,UACA;AAAA,UACA,OAAO;AAAA,YACL,UAAU;AAAA,YACV,cAAc;AAAA,YACd,SAAS,aACL,4CACA;AAAA,YACJ,eAAe;AAAA,UACjB;AAAA,UACA,WAAW;AAAA;AAAA,MACb;AAAA;AAAA,EACF;AAEJ;AAEO,SAAS,iBAAiB,SAAkC;AACjE,SAAO,IAAI;AAAA,IACT,QAAQ;AAAA,IACR,QAAQ;AAAA,IACR,QAAQ;AAAA,IACR,QAAQ;AAAA,IACR,QAAQ;AAAA,EACV;AACF;AAEO,SAAS,aACd,MACmB;AACnB,SAAO,gBAAgB;AACzB;;;AC1QA,SAAS,iBAAAC,sBAAqB;AAiEnB,gBAAAC,MAMP,YANO;AA1DJ,IAAM,mBAAN,MAAM,0BAAyBD,eAA4B;AAAA,EAChE;AAAA,EAEA,OAAO,UAAkB;AACvB,WAAO;AAAA,EACT;AAAA,EAEA,OAAO,MAAM,MAA0C;AACrD,WAAO,IAAI,kBAAiB,KAAK,aAAa,KAAK,KAAK;AAAA,EAC1D;AAAA,EAEA,YAAY,WAAmB,KAAe;AAC5C,UAAM,GAAG;AACT,SAAK,cAAc;AAAA,EACrB;AAAA,EAEA,UAAU,SAAoC;AAC5C,UAAM,MAAM,SAAS,cAAc,KAAK;AACxC,QAAI,MAAM,WAAW;AACrB,QAAI,MAAM,UAAU;AACpB,QAAI,MAAM,WAAW;AACrB,WAAO;AAAA,EACT;AAAA,EAEA,YAAmB;AACjB,WAAO;AAAA,EACT;AAAA,EAEA,YAA6B;AAC3B,UAAM,UAAU,SAAS,cAAc,KAAK;AAC5C,YAAQ,aAAa,sBAAsB,MAAM;AACjD,WAAO,EAAE,QAAQ;AAAA,EACnB;AAAA,EAEA,OAAO,YAAqC;AAC1C,WAAO;AAAA,EACT;AAAA,EAEA,OAAO,WACL,gBACkB;AAClB,WAAO,wBAAwB,eAAe,SAAS;AAAA,EACzD;AAAA,EAEA,aAAyC;AACvC,WAAO;AAAA,MACL,GAAG,MAAM,WAAW;AAAA,MACpB,WAAW,KAAK;AAAA,MAChB,MAAM;AAAA,MACN,SAAS;AAAA,IACX;AAAA,EACF;AAAA,EAEA,eAAuB;AACrB,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,WAAyB;AACvB,WAAO,gBAAAC,KAAC,yBAAsB,WAAW,KAAK,aAAa;AAAA,EAC7D;AACF;AAEA,SAAS,sBAAsB,EAAE,UAAU,GAA0B;AACnE,SACE;AAAA,IAAC;AAAA;AAAA,MACC,eAAY;AAAA,MACZ,OAAO;AAAA,QACL,UAAU;AAAA,QACV,SAAS;AAAA,QACT,UAAU;AAAA,MACZ;AAAA,MAEA;AAAA,wBAAAA;AAAA,UAAC;AAAA;AAAA,YACC,KAAK;AAAA,YACL,KAAI;AAAA,YACJ,OAAO;AAAA,cACL,UAAU;AAAA,cACV,cAAc;AAAA,cACd,SAAS;AAAA,YACX;AAAA;AAAA,QACF;AAAA,QAEA,gBAAAA;AAAA,UAAC;AAAA;AAAA,YACC,eAAY;AAAA,YACZ,OAAO;AAAA,cACL,UAAU;AAAA,cACV,OAAO;AAAA,cACP,SAAS;AAAA,cACT,YAAY;AAAA,cACZ,gBAAgB;AAAA,cAChB,iBAAiB;AAAA,cACjB,cAAc;AAAA,YAChB;AAAA,YAEA,0BAAAA;AAAA,cAAC;AAAA;AAAA,gBACC,OAAO;AAAA,kBACL,OAAO;AAAA,kBACP,QAAQ;AAAA,kBACR,QAAQ;AAAA,kBACR,gBAAgB;AAAA,kBAChB,cAAc;AAAA,kBACd,WAAW;AAAA,gBACb;AAAA;AAAA,YACF;AAAA;AAAA,QACF;AAAA,QACA,gBAAAA,KAAC,WAAO,4EAAiE;AAAA;AAAA;AAAA,EAC3E;AAEJ;AAEO,SAAS,wBAAwB,WAAqC;AAC3E,SAAO,IAAI,iBAAiB,SAAS;AACvC;AAEO,SAAS,oBACd,MAC0B;AAC1B,SAAO,gBAAgB;AACzB;;;ACvIA,SAAS,eAAAC,cAAa,aAAAC,YAAW,UAAAC,SAAQ,gBAAgB;AAYzD,SAAS,iBAAAC,gBAAe,iBAAAC,sBAAqB;AAC7C,SAAS,6BAAAC,kCAAiC;;;ACC1C,IAAM,WAAW,oBAAI,QAAwC;AAEtD,SAAS,mBACd,QACA,UACA,SAAyB,CAAC,GACpB;AACN,WAAS,IAAI,QAAQ,EAAE,UAAU,OAAO,CAAC;AAC3C;AAEO,SAAS,cACd,QACmB;AACnB,SAAO,SAAS,IAAI,MAAM,GAAG,YAAY;AAC3C;AAEO,SAAS,YACd,QACgB;AAChB,SAAO,SAAS,IAAI,MAAM,GAAG,UAAU,CAAC;AAC1C;AAEO,SAAS,qBAAqB,QAA6B;AAChE,WAAS,OAAO,MAAM;AACxB;;;ACvCA;AAAA,EACE,wBAAAC;AAAA,EACA;AAAA,EACA,kBAAAC;AAAA,EACA;AAAA,OACK;AACP,SAAS,oBAAoB,gBAAgB,oBAAoB;AACjE,SAAS,wBAAwB;AACjC;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;;;ACZP,SAAS,eAAAC,cAAa,aAAAC,YAAW,UAAAC,eAAc;AAa/C;AAAA,EACE,iBAAAC;AAAA,EACA,iBAAAC;AAAA,EACA,wBAAAC;AAAA,EACA,iBAAAC;AAAA,EACA,yBAAAC;AAAA,EACA,sBAAAC;AAAA,OACK;AACP,SAAS,6BAAAC,kCAAiC;AAC1C,SAAS,2BAAAC,gCAA+B;AA6IlC,gBAAAC,MAqHF,QAAAC,aArHE;AAzHC,IAAM,YAAN,MAAM,mBAAkBN,eAA4B;AAAA,EACzD;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EAEA,OAAO,UAAkB;AACvB,WAAO;AAAA,EACT;AAAA,EAEA,OAAO,MAAM,MAA4B;AACvC,WAAO,IAAI;AAAA,MACT,KAAK;AAAA,MACL,KAAK;AAAA,MACL,KAAK;AAAA,MACL,KAAK;AAAA,MACL,KAAK;AAAA,IACP;AAAA,EACF;AAAA,EAEA,YACE,KACA,WACA,UACA,OACA,KACA;AACA,UAAM,GAAG;AACT,SAAK,QAAQ;AACb,SAAK,cAAc;AACnB,SAAK,aAAa;AAClB,SAAK,UAAU,SAAS;AAAA,EAC1B;AAAA,EAEA,UAAU,SAAoC;AAC5C,UAAM,MAAM,SAAS,cAAc,KAAK;AACxC,QAAI,MAAM,UAAU;AACpB,QAAI,MAAM,WAAW;AACrB,WAAO;AAAA,EACT;AAAA,EAEA,YAAmB;AACjB,WAAO;AAAA,EACT;AAAA,EAEA,YAA6B;AAC3B,UAAM,MAAM,SAAS,cAAc,KAAK;AACxC,QAAI,aAAa,kBAAkB,KAAK,KAAK;AAC7C,QAAI,aAAa,mBAAmB,KAAK,WAAW;AACpD,QAAI,aAAa,uBAAuB,KAAK,UAAU;AACvD,QAAI,KAAK,SAAS;AAChB,UAAI,aAAa,oBAAoB,KAAK,OAAO;AAAA,IACnD;AACA,WAAO,EAAE,SAAS,IAAI;AAAA,EACxB;AAAA,EAEA,OAAO,YAAqC;AAC1C,WAAO;AAAA,MACL,KAAK,CAAC,YAAyB;AAC7B,YAAI,CAAC,QAAQ,aAAa,gBAAgB,EAAG,QAAO;AACpD,eAAO;AAAA,UACL,YAAY;AAAA,UACZ,UAAU;AAAA,QACZ;AAAA,MACF;AAAA,MACA,QAAQ,CAAC,YAAyB;AAChC,cAAM,MAAM,QAAQ,aAAa,KAAK,KAAK;AAC3C,YACE,IAAI,SAAS,aAAa,KAC1B,IAAI,SAAS,WAAW,KACxB,IAAI,SAAS,UAAU,GACvB;AACA,iBAAO;AAAA,YACL,YAAY;AAAA,YACZ,UAAU;AAAA,UACZ;AAAA,QACF;AACA,eAAO;AAAA,MACT;AAAA,IACF;AAAA,EACF;AAAA,EAEA,OAAO,WAAW,gBAAgD;AAChE,WAAO,iBAAiB;AAAA,MACtB,KAAK,eAAe;AAAA,MACpB,WAAW,eAAe;AAAA,MAC1B,UAAU,eAAe;AAAA,MACzB,OAAO,eAAe;AAAA,IACxB,CAAC;AAAA,EACH;AAAA,EAEA,aAAkC;AAChC,WAAO;AAAA,MACL,GAAG,MAAM,WAAW;AAAA,MACpB,KAAK,KAAK;AAAA,MACV,WAAW,KAAK;AAAA,MAChB,UAAU,KAAK;AAAA,MACf,OAAO,KAAK;AAAA,MACZ,MAAM;AAAA,MACN,SAAS;AAAA,IACX;AAAA,EACF;AAAA,EAEA,SAAiB;AACf,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,eAAiC;AAC/B,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,cAAsB;AACpB,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,WAAmB;AACjB,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,WAAyB;AACvB,WACE,gBAAAK;AAAA,MAAC;AAAA;AAAA,QACC,KAAK,KAAK;AAAA,QACV,WAAW,KAAK;AAAA,QAChB,UAAU,KAAK;AAAA,QACf,OAAO,KAAK;AAAA,QACZ,SAAS,KAAK,OAAO;AAAA;AAAA,IACvB;AAAA,EAEJ;AACF;AAEA,SAAS,oBAAoB,SAA2C;AACtE,MAAI,mBAAmB,aAAa;AAClC,UAAM,MAAM,QAAQ,aAAa,gBAAgB;AACjD,QAAI,CAAC,IAAK,QAAO;AACjB,UAAM,OAAO,iBAAiB;AAAA,MAC5B;AAAA,MACA,WACG,QAAQ,aAAa,iBAAiB,KACvC;AAAA,MACF,UAAU,QAAQ,aAAa,qBAAqB,KAAK;AAAA,MACzD,OAAO,QAAQ,aAAa,kBAAkB,KAAK;AAAA,IACrD,CAAC;AACD,WAAO,EAAE,KAAK;AAAA,EAChB;AACA,SAAO;AACT;AAEA,SAAS,qBAAqB,SAA2C;AACvE,MAAI,mBAAmB,mBAAmB;AACxC,UAAM,MAAM,QAAQ,aAAa,KAAK;AACtC,QAAI,CAAC,IAAK,QAAO;AAEjB,QAAI,WAAW;AACf,QAAI,IAAI,SAAS,aAAa,EAAG,YAAW;AAAA,aACnC,IAAI,SAAS,WAAW,EAAG,YAAW;AAAA,aACtC,IAAI,SAAS,UAAU,EAAG,YAAW;AAE9C,UAAM,OAAO,iBAAiB;AAAA,MAC5B;AAAA,MACA,WAAW;AAAA,MACX;AAAA,MACA,OAAO,QAAQ,aAAa,OAAO,KAAK;AAAA,IAC1C,CAAC;AACD,WAAO,EAAE,KAAK;AAAA,EAChB;AACA,SAAO;AACT;AAEA,SAAS,eAAe;AAAA,EACtB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAMG;AACD,QAAM,CAAC,MAAM,IAAIF,2BAA0B;AAC3C,QAAM,CAAC,YAAY,aAAa,cAAc,IAC5CC,yBAAwB,OAAO;AACjC,QAAM,eAAeR,QAAuB,IAAI;AAEhD,EAAAD,WAAU,MAAM;AACd,WAAO,OAAO;AAAA,MACZG;AAAA,MACA,CAAC,UAAsB;AACrB,YAAI,aAAa,SAAS,SAAS,MAAM,MAAc,GAAG;AACxD,cAAI,CAAC,MAAM,UAAU;AACnB,2BAAe;AAAA,UACjB;AACA,sBAAY,IAAI;AAChB,iBAAO;AAAA,QACT;AACA,eAAO;AAAA,MACT;AAAA,MACAC;AAAA,IACF;AAAA,EACF,GAAG,CAAC,QAAQ,gBAAgB,WAAW,CAAC;AAExC,QAAM,WAAWL;AAAA,IACf,CAAC,UAAyB;AACxB,UAAI,YAAY;AACd,cAAM,eAAe;AACrB,eAAO,OAAO,MAAM;AAClB,gBAAM,OAAOG,eAAc,OAAO;AAClC,cAAI,KAAM,MAAK,OAAO;AAAA,QACxB,CAAC;AACD,eAAO;AAAA,MACT;AACA,aAAO;AAAA,IACT;AAAA,IACA,CAAC,QAAQ,YAAY,OAAO;AAAA,EAC9B;AAEA,EAAAF,WAAU,MAAM;AACd,UAAM,sBAAsB,OAAO;AAAA,MACjCM;AAAA,MACA;AAAA,MACAF;AAAA,IACF;AACA,UAAM,mBAAmB,OAAO;AAAA,MAC9BG;AAAA,MACA;AAAA,MACAH;AAAA,IACF;AACA,WAAO,MAAM;AACX,0BAAoB;AACpB,uBAAiB;AAAA,IACnB;AAAA,EACF,GAAG,CAAC,QAAQ,QAAQ,CAAC;AAErB,SACE,gBAAAO;AAAA,IAAC;AAAA;AAAA,MACC,KAAK;AAAA,MACL,eAAY;AAAA,MACZ,uBAAqB;AAAA,MACrB,OAAO;AAAA,QACL,UAAU;AAAA,QACV,UAAU;AAAA,QACV,QAAQ;AAAA,QACR,cAAc;AAAA,QACd,SAAS,aACL,4CACA;AAAA,QACJ,eAAe;AAAA,MACjB;AAAA,MAEC;AAAA,sBAAc,UACb,gBAAAD;AAAA,UAAC;AAAA;AAAA,YACC;AAAA,YACA,OAAO,SAAS;AAAA,YAChB,OAAM;AAAA,YACN,iBAAe;AAAA,YACf,OAAO;AAAA,cACL,SAAS;AAAA,cACT,OAAO;AAAA,cACP,aAAa;AAAA,cACb,QAAQ;AAAA,cACR,cAAc;AAAA,YAChB;AAAA,YACA,WAAW;AAAA;AAAA,QACb,IAEA,gBAAAA;AAAA,UAAC;AAAA;AAAA,YACC;AAAA,YACA,UAAQ;AAAA,YACR,OAAO;AAAA,cACL,SAAS;AAAA,cACT,OAAO;AAAA,cACP,WAAW;AAAA,cACX,cAAc;AAAA,YAChB;AAAA,YACA,WAAW;AAAA,YAEX,0BAAAA,KAAC,WAAM,MAAK,YAAW;AAAA;AAAA,QACzB;AAAA,QAKD,CAAC,cACA,gBAAAA;AAAA,UAAC;AAAA;AAAA,YACC,eAAY;AAAA,YACZ,OAAO;AAAA,cACL,UAAU;AAAA,cACV,OAAO;AAAA,cACP,QAAQ;AAAA,cACR,cAAc;AAAA,YAChB;AAAA;AAAA,QACF;AAAA;AAAA;AAAA,EAEJ;AAEJ;AAEO,SAAS,iBAAiB,SAAkC;AACjE,SAAO,IAAI;AAAA,IACT,QAAQ;AAAA,IACR,QAAQ;AAAA,IACR,QAAQ;AAAA,IACR,QAAQ;AAAA,IACR,QAAQ;AAAA,EACV;AACF;AAEO,SAAS,aACd,MACmB;AACnB,SAAO,gBAAgB;AACzB;;;ADtVA,SAAS,mBAAmB;AAC5B;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,OACK;;;AETP,SAAS,mBAAmB;AAoBrB,IAAM,cAAN,MAAM,qBAAoB,YAAY;AAAA,EAC3C;AAAA,EACA;AAAA,EAEA,OAAO,UAAkB;AACvB,WAAO;AAAA,EACT;AAAA,EAEA,OAAO,MAAM,MAAgC;AAC3C,WAAO,IAAI,aAAY,KAAK,SAAS,KAAK,eAAe,KAAK,KAAK;AAAA,EACrE;AAAA,EAEA,YAAY,QAAgB,aAAa,cAAsB,WAAW,KAAe;AACvF,UAAM,GAAG;AACT,SAAK,UAAU;AACf,SAAK,gBAAgB;AAAA,EACvB;AAAA;AAAA,EAIA,UAAU,QAAmC;AAC3C,UAAM,MAAM,SAAS,cAAc,KAAK;AACxC,UAAM,aAAa,OAAO,MAAM;AAChC,QAAI,YAAY;AACd,UAAI,YAAY;AAAA,IAClB;AACA,QAAI,KAAK,kBAAkB,WAAW;AACpC,UAAI,UAAU,IAAI,qBAAqB,KAAK,aAAa,EAAE;AAAA,IAC7D;AACA,QAAI,QAAQ,eAAe,KAAK;AAChC,QAAI,QAAQ,eAAe,KAAK;AAGhC,UAAM,YAAY,SAAS,cAAc,MAAM;AAC/C,cAAU,cAAc,KAAK;AAC7B,cAAU,kBAAkB;AAC5B,cAAU,aAAa,8BAA8B,MAAM;AAC3D,QAAI,YAAY,SAAS;AAEzB,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,WAAW,SAAsC;AAC/C,UAAM,YAAY,QAAQ,cAAc,8BAA8B;AACtE,WAAO,MAAM,WAAW,OAAO,EAAE,UAAU,SAAS;AAAA,EACtD;AAAA,EAEA,UAAU,UAAuB,KAA2B;AAE1D,QAAI,SAAS,YAAY,KAAK,SAAS;AACrC,UAAI,QAAQ,eAAe,KAAK;AAChC,YAAM,YAAY,IAAI,cAAc,8BAA8B;AAClE,UAAI,WAAW;AACb,kBAAU,cAAc,KAAK;AAAA,MAC/B;AAAA,IACF;AAGA,QAAI,SAAS,kBAAkB,KAAK,eAAe;AACjD,UAAI,QAAQ,eAAe,KAAK;AAEhC,UAAI,SAAS,kBAAkB,WAAW;AACxC,YAAI,UAAU,OAAO,qBAAqB,SAAS,aAAa,EAAE;AAAA,MACpE;AAEA,UAAI,KAAK,kBAAkB,WAAW;AACpC,YAAI,UAAU,IAAI,qBAAqB,KAAK,aAAa,EAAE;AAAA,MAC7D;AAAA,IACF;AAGA,WAAO;AAAA,EACT;AAAA;AAAA,EAIA,YAA6B;AAC3B,UAAM,MAAM,SAAS,cAAc,KAAK;AACxC,QAAI,QAAQ,eAAe,KAAK;AAChC,QAAI,QAAQ,eAAe,KAAK;AAChC,WAAO,EAAE,SAAS,IAAI;AAAA,EACxB;AAAA,EAEA,OAAO,YAAqC;AAC1C,WAAO;AAAA,MACL,KAAK,CAAC,YAAkB;AACtB,YAAI,mBAAmB,eAAe,QAAQ,QAAQ,cAAc;AAClE,iBAAO;AAAA,YACL,YAAY;AAAA,YACZ,UAAU;AAAA,UACZ;AAAA,QACF;AACA,eAAO;AAAA,MACT;AAAA,IACF;AAAA,EACF;AAAA;AAAA,EAIA,OAAO,WAAW,YAAgD;AAChE,WAAO,mBAAmB;AAAA,MACxB,OAAO,WAAW;AAAA,MAClB,aAAa,WAAW;AAAA,IAC1B,CAAC;AAAA,EACH;AAAA,EAEA,aAAoC;AAClC,WAAO;AAAA,MACL,GAAG,MAAM,WAAW;AAAA,MACpB,OAAO,KAAK;AAAA,MACZ,aAAa,KAAK;AAAA,MAClB,MAAM;AAAA,MACN,SAAS;AAAA,IACX;AAAA,EACF;AAAA;AAAA,EAIA,WAAmB;AACjB,WAAO,KAAK,UAAU,EAAE;AAAA,EAC1B;AAAA,EAEA,SAAS,OAAqB;AAC5B,UAAM,WAAW,KAAK,YAAY;AAClC,aAAS,UAAU;AACnB,WAAO;AAAA,EACT;AAAA,EAEA,iBAAyB;AACvB,WAAO,KAAK,UAAU,EAAE;AAAA,EAC1B;AAAA,EAEA,eAAe,QAAsB;AACnC,UAAM,WAAW,KAAK,YAAY;AAClC,aAAS,gBAAgB;AACzB,WAAO;AAAA,EACT;AACF;AAIA,SAAS,sBAAsB,SAA2C;AACxE,MAAI,mBAAmB,aAAa;AAClC,UAAM,QAAQ,QAAQ,QAAQ,gBAAgB;AAC9C,UAAM,cAAc,QAAQ,QAAQ,gBAAgB;AACpD,UAAM,OAAO,mBAAmB,EAAE,OAAO,YAAY,CAAC;AACtD,WAAO,EAAE,KAAK;AAAA,EAChB;AACA,SAAO;AACT;AAIO,SAAS,mBAAmB,SAAuC;AACxE,SAAO,IAAI;AAAA,IACT,SAAS,SAAS;AAAA,IAClB,SAAS,eAAe;AAAA,IACxB,SAAS;AAAA,EACX;AACF;AAEO,SAAS,eAAe,MAA2D;AACxF,SAAO,gBAAgB;AACzB;;;ACtMA,SAAS,eAAAE,cAAa,aAAAC,YAAW,UAAAC,eAAc;AAa/C;AAAA,EACE,iBAAAC;AAAA,EACA,iBAAAC;AAAA,EACA,wBAAAC;AAAA,EACA,iBAAAC;AAAA,EACA,yBAAAC;AAAA,EACA,sBAAAC;AAAA,OACK;AACP,SAAS,6BAAAC,kCAAiC;AAC1C,SAAS,2BAAAC,gCAA+B;AAsD7B,gBAAAC,YAAA;AAlDJ,IAAM,qBAAN,MAAM,4BAA2BL,eAA4B;AAAA,EAClE,OAAO,UAAkB;AACvB,WAAO;AAAA,EACT;AAAA,EAEA,OAAO,MAAM,MAA8C;AACzD,WAAO,IAAI,oBAAmB,KAAK,KAAK;AAAA,EAC1C;AAAA,EAEA,YAAY,KAAe;AACzB,UAAM,GAAG;AAAA,EACX;AAAA,EAEA,UAAU,SAAoC;AAC5C,UAAM,MAAM,SAAS,cAAc,KAAK;AACxC,QAAI,MAAM,UAAU;AACpB,QAAI,MAAM,QAAQ;AAClB,WAAO;AAAA,EACT;AAAA,EAEA,YAAmB;AACjB,WAAO;AAAA,EACT;AAAA,EAEA,YAA6B;AAC3B,WAAO,EAAE,SAAS,SAAS,cAAc,IAAI,EAAE;AAAA,EACjD;AAAA,EAEA,OAAO,YAAqC;AAC1C,WAAO;AAAA,MACL,IAAI,OAAO;AAAA,QACT,YAAY;AAAA,QACZ,UAAU;AAAA,MACZ;AAAA,IACF;AAAA,EACF;AAAA,EAEA,OAAO,WAAW,iBAA4D;AAC5E,WAAO,0BAA0B;AAAA,EACnC;AAAA,EAEA,aAAoC;AAClC,WAAO;AAAA,MACL,GAAG,MAAM,WAAW;AAAA,MACpB,MAAM;AAAA,MACN,SAAS;AAAA,IACX;AAAA,EACF;AAAA,EAEA,WAAyB;AACvB,WAAO,gBAAAK,KAAC,2BAAwB,SAAS,KAAK,OAAO,GAAG;AAAA,EAC1D;AACF;AAIA,SAAS,+BAAoD;AAC3D,SAAO,EAAE,MAAM,0BAA0B,EAAE;AAC7C;AAIA,SAAS,wBAAwB,EAAE,QAAQ,GAAyB;AAClE,QAAM,CAAC,MAAM,IAAIF,2BAA0B;AAC3C,QAAM,CAAC,YAAY,aAAa,cAAc,IAC5CC,yBAAwB,OAAO;AACjC,QAAM,eAAeR,QAAuB,IAAI;AAGhD,EAAAD,WAAU,MAAM;AACd,WAAO,OAAO;AAAA,MACZG;AAAA,MACA,CAAC,UAAsB;AACrB,YAAI,aAAa,SAAS,SAAS,MAAM,MAAc,GAAG;AACxD,cAAI,CAAC,MAAM,UAAU;AACnB,2BAAe;AAAA,UACjB;AACA,sBAAY,IAAI;AAChB,iBAAO;AAAA,QACT;AACA,eAAO;AAAA,MACT;AAAA,MACAC;AAAA,IACF;AAAA,EACF,GAAG,CAAC,QAAQ,gBAAgB,WAAW,CAAC;AAGxC,QAAM,WAAWL;AAAA,IACf,CAAC,UAAyB;AACxB,UAAI,YAAY;AACd,cAAM,eAAe;AACrB,eAAO,OAAO,MAAM;AAClB,gBAAM,OAAOG,eAAc,OAAO;AAClC,cAAI,KAAM,MAAK,OAAO;AAAA,QACxB,CAAC;AACD,eAAO;AAAA,MACT;AACA,aAAO;AAAA,IACT;AAAA,IACA,CAAC,QAAQ,YAAY,OAAO;AAAA,EAC9B;AAEA,EAAAF,WAAU,MAAM;AACd,UAAM,sBAAsB,OAAO;AAAA,MACjCM;AAAA,MACA;AAAA,MACAF;AAAA,IACF;AACA,UAAM,mBAAmB,OAAO;AAAA,MAC9BG;AAAA,MACA;AAAA,MACAH;AAAA,IACF;AACA,WAAO,MAAM;AACX,0BAAoB;AACpB,uBAAiB;AAAA,IACnB;AAAA,EACF,GAAG,CAAC,QAAQ,QAAQ,CAAC;AAErB,SACE,gBAAAM;AAAA,IAAC;AAAA;AAAA,MACC,KAAK;AAAA,MACL,eAAY;AAAA,MACZ,OAAO;AAAA,QACL,QAAQ;AAAA,QACR,SAAS;AAAA,MACX;AAAA,MAEA,0BAAAA;AAAA,QAAC;AAAA;AAAA,UACC,OAAO;AAAA,YACL,QAAQ;AAAA,YACR,WAAW,aACP,4CACA;AAAA,YACJ,QAAQ;AAAA,YACR,YAAY;AAAA,UACd;AAAA;AAAA,MACF;AAAA;AAAA,EACF;AAEJ;AAIO,SAAS,4BAAgD;AAC9D,SAAO,IAAI,mBAAmB;AAChC;AAEO,SAAS,sBACd,MAC4B;AAC5B,SAAO,gBAAgB;AACzB;;;ACvKA,SAA+B,gBAAgB,eAAAC,oBAAmB;AAClE,SAAS,iBAAiB;AAYnB,IAAM,sBAAN,MAAM,6BAA4BA,aAAY;AAAA,EACnD;AAAA,EAEA,OAAO,UAAkB;AACvB,WAAO;AAAA,EACT;AAAA,EAEA,OAAO,MAAM,MAAgD;AAC3D,WAAO,IAAI,qBAAoB,KAAK,QAAQ,KAAK,KAAK;AAAA,EACxD;AAAA,EAEA,YAAY,OAAgB,MAAM,KAAe;AAC/C,UAAM,GAAG;AACT,SAAK,SAAS;AAAA,EAChB;AAAA;AAAA,EAGA,eAAwB;AACtB,WAAO;AAAA,EACT;AAAA,EAEA,UAAU,QAAsB,QAAoC;AAClE,UAAM,aAAa,OAAO,MAAM;AAChC,QAAI;AAEJ,QAAI,WAAW;AAEb,YAAM,SAAS,cAAc,KAAK;AAClC,UAAI,aAAa,yBAAyB,MAAM;AAChD,UAAI,aAAa,aAAa,KAAK,SAAS,SAAS,OAAO;AAAA,IAC9D,OAAO;AACL,YAAM,UAAU,SAAS,cAAc,SAAS;AAChD,cAAQ,OAAO,KAAK;AACpB,cAAQ,iBAAiB,UAAU,MAAM;AACvC,cAAM,OAAO,OAAO,eAAe,EAAE,KAAK,MAAM,KAAK,QAAQ,CAAC;AAC9D,YAAI,SAAS,QAAQ,MAAM;AACzB,iBAAO,OAAO,MAAM,KAAK,WAAW,CAAC;AAAA,QACvC;AAAA,MACF,CAAC;AACD,YAAM;AAAA,IACR;AAEA,QAAI,YAAY;AACd,UAAI,YAAY;AAAA,IAClB;AAEA,WAAO;AAAA,EACT;AAAA,EAEA,UAAU,UAA+B,KAA2B;AAClE,QAAI,SAAS,WAAW,KAAK,QAAQ;AACnC,UAAI,WAAW;AACb,YAAI,aAAa,aAAa,KAAK,SAAS,SAAS,OAAO;AAAA,MAC9D,OAAO;AACL,QAAC,IAA2B,OAAO,KAAK;AAAA,MAC1C;AAAA,IACF;AACA,WAAO;AAAA,EACT;AAAA;AAAA,EAGA,gBAAgB,YAAqC;AACnD,UAAM,WAAW,KAAK,YAAY;AAClC,UAAM,gBAA+B,CAAC;AACtC,eAAW,SAAS,UAAU;AAC5B,UAAI,eAAe,KAAK,GAAG;AACzB,sBAAc,KAAK,GAAG,MAAM,YAAY,CAAC;AAAA,MAC3C;AAAA,IACF;AACA,eAAW,QAAQ,eAAe;AAChC,WAAK,aAAa,IAAI;AAAA,IACxB;AACA,SAAK,OAAO;AACZ,QAAI,cAAc,SAAS,GAAG;AAC5B,YAAM,QAAQ,cAAc,CAAC;AAC7B,UAAI,eAAe,KAAK,GAAG;AACzB,cAAM,YAAY;AAAA,MACpB;AAAA,IACF;AACA,WAAO;AAAA,EACT;AAAA,EAEA,OAAO,YAAqC;AAC1C,WAAO;AAAA,MACL,SAAS,CAAC,cAAoB;AAAA,QAC5B,YAAY;AAAA,QACZ,UAAU;AAAA,MACZ;AAAA,IACF;AAAA,EACF;AAAA,EAEA,YAA6B;AAC3B,UAAM,UAAU,SAAS,cAAc,SAAS;AAChD,QAAI,KAAK,QAAQ;AACf,cAAQ,aAAa,QAAQ,EAAE;AAAA,IACjC;AACA,WAAO,EAAE,QAAQ;AAAA,EACnB;AAAA,EAEA,OAAO,WACL,YACqB;AACrB,WAAO,2BAA2B,EAAE,MAAM,WAAW,KAAK,CAAC;AAAA,EAC7D;AAAA,EAEA,aAA4C;AAC1C,WAAO;AAAA,MACL,GAAG,MAAM,WAAW;AAAA,MACpB,MAAM,KAAK;AAAA,MACX,MAAM;AAAA,MACN,SAAS;AAAA,IACX;AAAA,EACF;AAAA,EAEA,UAAmB;AACjB,WAAO,KAAK,UAAU,EAAE;AAAA,EAC1B;AAAA,EAEA,QAAQ,MAAqB;AAC3B,UAAM,WAAW,KAAK,YAAY;AAClC,aAAS,SAAS;AAAA,EACpB;AAAA,EAEA,aAAmB;AACjB,SAAK,QAAQ,CAAC,KAAK,QAAQ,CAAC;AAAA,EAC9B;AACF;AAEA,SAAS,sBAAsB,SAA2C;AACxE,MAAI,mBAAmB,aAAa;AAClC,UAAM,SAAU,QAA+B,SAAS;AACxD,WAAO,EAAE,MAAM,2BAA2B,EAAE,MAAM,OAAO,CAAC,EAAE;AAAA,EAC9D;AACA,SAAO;AACT;AAEO,SAAS,2BACd,SACqB;AACrB,SAAO,IAAI,oBAAoB,SAAS,QAAQ,MAAM,SAAS,GAAG;AACpE;AAEO,SAAS,uBACd,MAC6B;AAC7B,SAAO,gBAAgB;AACzB;;;AClKA,SAAS,wBAAAC,uBAAsB,kBAAAC,iBAAgB,eAAAC,oBAAmB;AAClE,SAAS,aAAAC,kBAAiB;;;ACF1B,SAAS,eAAAC,oBAAmB;AAIrB,IAAM,oBAAN,MAAM,2BAA0BA,aAAY;AAAA,EACjD,OAAO,UAAkB;AACvB,WAAO;AAAA,EACT;AAAA,EAEA,OAAO,MAAM,MAA4C;AACvD,WAAO,IAAI,mBAAkB,KAAK,KAAK;AAAA,EACzC;AAAA;AAAA,EAIA,UAAU,QAAmC;AAC3C,UAAM,MAAM,SAAS,cAAc,KAAK;AACxC,UAAM,aAAa,OAAO,MAAM;AAChC,QAAI,YAAY;AACd,UAAI,YAAY;AAAA,IAClB;AACA,QAAI,aAAa,uBAAuB,MAAM;AAC9C,WAAO;AAAA,EACT;AAAA,EAEA,YAAqB;AACnB,WAAO;AAAA,EACT;AAAA;AAAA,EAGA,eAAwB;AACtB,WAAO;AAAA,EACT;AAAA;AAAA,EAIA,OAAO,YAAqC;AAC1C,WAAO;AAAA,MACL,KAAK,CAAC,YAAkB;AACtB,YACE,mBAAmB,eACnB,QAAQ,aAAa,qBAAqB,GAC1C;AACA,iBAAO;AAAA,YACL,YAAY;AAAA,YACZ,UAAU;AAAA,UACZ;AAAA,QACF;AACA,eAAO;AAAA,MACT;AAAA,IACF;AAAA,EACF;AAAA,EAEA,YAA6B;AAC3B,UAAM,UAAU,SAAS,cAAc,KAAK;AAC5C,YAAQ,aAAa,uBAAuB,MAAM;AAClD,WAAO,EAAE,QAAQ;AAAA,EACnB;AAAA;AAAA,EAIA,OAAO,WAAW,aAAuD;AACvE,WAAO,yBAAyB;AAAA,EAClC;AAAA,EAEA,aAAoC;AAClC,WAAO;AAAA,MACL,GAAG,MAAM,WAAW;AAAA,MACpB,MAAM;AAAA,MACN,SAAS;AAAA,IACX;AAAA,EACF;AACF;AAIA,SAAS,4BACP,UAC4B;AAC5B,SAAO,EAAE,MAAM,yBAAyB,EAAE;AAC5C;AAIO,SAAS,2BAA8C;AAC5D,SAAO,IAAI,kBAAkB;AAC/B;AAEO,SAAS,qBACd,MAC2B;AAC3B,SAAO,gBAAgB;AACzB;;;ADtFO,IAAM,kBAAN,MAAM,yBAAwBC,aAAY;AAAA,EAC/C,OAAO,UAAkB;AACvB,WAAO;AAAA,EACT;AAAA,EAEA,OAAO,MAAM,MAAwC;AACnD,WAAO,IAAI,iBAAgB,KAAK,KAAK;AAAA,EACvC;AAAA,EAEA,UAAU,QAAsB,QAAoC;AAClE,UAAM,MAAM,SAAS,cAAc,SAAS;AAC5C,UAAM,aAAa,OAAO,MAAM;AAChC,QAAI,YAAY;AACd,UAAI,YAAY;AAAA,IAClB;AACA,QAAI,aAAa,oBAAoB,gBAAgB;AAErD,QAAIC,YAAW;AAGb,UAAI,iBAAiB,SAAS,CAAC,MAAkB;AAC/C,cAAM,QAAQ,iBAAiB,GAAG,EAAE,cAAc;AAClD,cAAM,oBAAoB,QACtB,EAAE,UAAU,IAAI,cAAc,KAC9B,EAAE,UAAU;AAEhB,YAAI,mBAAmB;AACrB,YAAE,eAAe;AACjB,iBAAO,OAAO,MAAM;AAClB,kBAAM,YAAY,KAAK,UAAU,EAAE,UAAU;AAC7C,gBAAI,uBAAuB,SAAS,GAAG;AACrC,wBAAU,WAAW;AAAA,YACvB;AAAA,UACF,CAAC;AAAA,QACH;AAAA,MACF,CAAC;AAAA,IACH;AAEA,WAAO;AAAA,EACT;AAAA,EAEA,YAAqB;AACnB,WAAO;AAAA,EACT;AAAA;AAAA,EAIA,eACE,YACA,kBACoB;AACpB,UAAM,YAAY,KAAK,UAAU;AAEjC,QAAI,CAAC,uBAAuB,SAAS,GAAG;AACtC,aAAO;AAAA,IACT;AAEA,QAAI,UAAU,QAAQ,GAAG;AAEvB,YAAM,UAAU,KAAK,eAAe;AACpC,UAAI,qBAAqB,OAAO,GAAG;AACjC,cAAM,aAAa,QAAQ,cAAc;AACzC,YAAIC,gBAAe,UAAU,GAAG;AAC9B,iBAAO;AAAA,QACT;AAEA,cAAMC,aAAYC,sBAAqB;AACvC,gBAAQ,OAAOD,UAAS;AACxB,eAAOA;AAAA,MACT;AAAA,IACF;AAGA,UAAM,YAAYC,sBAAqB;AACvC,cAAU,YAAY,WAAW,gBAAgB;AACjD,WAAO;AAAA,EACT;AAAA;AAAA,EAIA,gBAAgB,YAAqC;AACnD,UAAM,YAAY,KAAK,UAAU;AACjC,QAAI,uBAAuB,SAAS,GAAG;AACrC,aAAO,UAAU,gBAAgB,UAAU;AAAA,IAC7C;AACA,WAAO;AAAA,EACT;AAAA,EAEA,OAAO,YAAqC;AAC1C,WAAO;AAAA,MACL,SAAS,CAAC,cAAoB;AAAA,QAC5B,YAAY;AAAA,QACZ,UAAU;AAAA,MACZ;AAAA,IACF;AAAA,EACF;AAAA,EAEA,OAAO,WAAW,aAAqD;AACrE,WAAO,uBAAuB;AAAA,EAChC;AAAA,EAEA,aAAoC;AAClC,WAAO;AAAA,MACL,GAAG,MAAM,WAAW;AAAA,MACpB,MAAM;AAAA,MACN,SAAS;AAAA,IACX;AAAA,EACF;AAAA;AAGF;AAEA,SAAS,sBAAsB,UAA4C;AACzE,SAAO,EAAE,MAAM,uBAAuB,EAAE;AAC1C;AAEO,SAAS,yBAA0C;AACxD,SAAO,IAAI,gBAAgB;AAC7B;AAEO,SAAS,mBACd,MACyB;AACzB,SAAO,gBAAgB;AACzB;;;AL3GO,SAAS,yBAAyB,OAA8B;AACrE,QAAM,QAAkB,CAAC;AAEzB,aAAW,QAAQ,OAAO;AACxB,UAAM,KAAK,cAAc,IAAI,CAAC;AAAA,EAChC;AAEA,SAAO,MAAM,KAAK,MAAM;AAC1B;AAEA,SAAS,cAAc,MAA2B;AAChD,MAAI,eAAe,IAAI,GAAG;AACxB,UAAM,MAAM,KAAK,OAAO;AACxB,UAAM,QAAQ,SAAS,IAAI,QAAQ,KAAK,EAAE,GAAG,EAAE;AAC/C,UAAM,SAAS,IAAI,OAAO,KAAK;AAC/B,WAAO,GAAG,MAAM,IAAI,kBAAkB,IAAI,CAAC;AAAA,EAC7C;AAEA,MAAI,aAAa,IAAI,GAAG;AACtB,WAAO,KAAK,kBAAkB,IAAI,CAAC;AAAA,EACrC;AAEA,MAAI,YAAY,IAAI,GAAG;AACrB,UAAM,WAAW,KAAK,YAAY;AAClC,UAAM,QAAQ,KAAK,YAAY;AAC/B,WAAO,MACJ,IAAI,CAAC,MAAM,MAAM;AAChB,YAAM,UAAUC,gBAAe,IAAI,IAC/B,kBAAkB,IAAI,IACtB,KAAK,eAAe;AACxB,UAAI;AACJ,UAAI,aAAa,UAAU;AACzB,iBAAS,GAAG,IAAI,CAAC;AAAA,MACnB,WAAW,aAAa,WAAW,gBAAgB,IAAI,GAAG;AACxD,iBAAS,KAAK,WAAW,IAAI,WAAW;AAAA,MAC1C,OAAO;AACL,iBAAS;AAAA,MACX;AACA,aAAO,GAAG,MAAM,GAAG,OAAO;AAAA,IAC5B,CAAC,EACA,KAAK,IAAI;AAAA,EACd;AAEA,MAAI,aAAa,IAAI,GAAG;AACtB,WAAO,KAAK,KAAK,WAAW,CAAC,KAAK,KAAK,OAAO,CAAC;AAAA,EACjD;AAEA,MAAI,aAAa,IAAI,GAAG;AACtB,UAAM,QAAQ,KAAK,SAAS,KAAK;AACjC,WAAO,IAAI,KAAK,KAAK,KAAK,OAAO,CAAC;AAAA,EACpC;AAEA,MAAI,sBAAsB,IAAI,GAAG;AAC/B,WAAO;AAAA,EACT;AAEA,MAAI,aAAa,IAAI,GAAG;AACtB,UAAM,OAAO,KAAK,YAAY;AAC9B,UAAM,QAAkB,CAAC;AAEzB,aAAS,SAAS,GAAG,SAAS,KAAK,QAAQ,UAAU;AACnD,YAAM,MAAM,KAAK,MAAM;AACvB,UAAI,CAAC,OAAO,CAAC,gBAAgB,GAAG,EAAG;AAEnC,YAAM,QAAQ,IAAI,YAAY;AAC9B,YAAM,YAAsB,CAAC;AAE7B,iBAAW,QAAQ,OAAO;AACxB,YAAI,iBAAiB,IAAI,GAAG;AAC1B,oBAAU,KAAK,kBAAkB,IAAI,EAAE,QAAQ,OAAO,KAAK,CAAC;AAAA,QAC9D;AAAA,MACF;AAEA,YAAM,KAAK,KAAK,UAAU,KAAK,KAAK,CAAC,IAAI;AAEzC,UAAI,WAAW,GAAG;AAChB,cAAM,KAAK,KAAK,UAAU,IAAI,MAAM,KAAK,EAAE,KAAK,KAAK,CAAC,IAAI;AAAA,MAC5D;AAAA,IACF;AAEA,WAAO,MAAM,KAAK,IAAI;AAAA,EACxB;AAEA,MAAI,uBAAuB,IAAI,GAAG;AAChC,UAAM,WAAW,KAAK,YAAY;AAClC,QAAI,YAAY;AAChB,QAAI,cAAc;AAElB,eAAW,SAAS,UAAU;AAC5B,UAAI,mBAAmB,KAAK,GAAG;AAC7B,oBAAY,kBAAkB,KAAK;AAAA,MACrC,WAAW,qBAAqB,KAAK,GAAG;AACtC,sBAAc,MACX,YAAY,EACZ,IAAI,CAAC,iBAAiB;AACrB,cAAIA,gBAAe,YAAY,GAAG;AAChC,mBAAO,kBAAkB,YAAY;AAAA,UACvC;AACA,iBAAO,aAAa,eAAe;AAAA,QACrC,CAAC,EACA,KAAK,IAAI;AAAA,MACd;AAAA,IACF;AAEA,WAAO;AAAA,WAAuB,SAAS;AAAA;AAAA,EAAiB,WAAW;AAAA;AAAA;AAAA,EACrE;AAEA,MAAI,eAAe,IAAI,GAAG;AACxB,UAAM,QAAQ,KAAK,SAAS;AAC5B,UAAM,eAAe,KAClB,YAAY,EACZ,IAAI,CAAC,UAAU;AACd,UAAIA,gBAAe,KAAK,GAAG;AACzB,eAAO,kBAAkB,KAAK;AAAA,MAChC;AACA,aAAO,MAAM,eAAe;AAAA,IAC9B,CAAC,EACA,KAAK,MAAM;AACd,WAAO,OAAO,KAAK,KAAK,YAAY;AAAA,EACtC;AAEA,MAAIA,gBAAe,IAAI,GAAG;AACxB,WAAO,kBAAkB,IAAI;AAAA,EAC/B;AAEA,SAAO,KAAK,eAAe;AAC7B;AAEA,SAAS,kBAAkB,MAA2B;AACpD,QAAM,WAAW,KAAK,YAAY;AAClC,MAAI,SAAS;AAEb,aAAW,SAAS,UAAU;AAC5B,QAAI,YAAY,KAAK,GAAG;AACtB,UAAI,OAAO,MAAM,eAAe;AAChC,YAAM,SAAS,MAAM,UAAU;AAG/B,UAAI,SAAS,EAAG,QAAO,KAAK,IAAI;AAEhC,UAAI,SAAS,EAAG,QAAO,IAAI,IAAI;AAE/B,UAAI,SAAS,EAAG,QAAO,KAAK,IAAI;AAGhC,UAAI,SAAS,GAAI,QAAO,KAAK,IAAI;AAEjC,gBAAU;AAAA,IACZ,WAAW,YAAY,KAAK,GAAG;AAC7B,YAAM,WAAW,kBAAkB,KAAK;AACxC,YAAM,MAAM,MAAM,OAAO;AACzB,gBAAU,IAAI,QAAQ,KAAK,GAAG;AAAA,IAChC,WAAWA,gBAAe,KAAK,GAAG;AAChC,gBAAU,kBAAkB,KAAK;AAAA,IACnC,OAAO;AACL,gBAAU,MAAM,eAAe;AAAA,IACjC;AAAA,EACF;AAEA,SAAO;AACT;AAOO,SAAS,6BACd,UACe;AACf,QAAM,SAAS,SAAS,MAAM,OAAO;AACrC,QAAM,QAAuB,CAAC;AAE9B,aAAW,SAAS,QAAQ;AAC1B,UAAM,UAAU,MAAM,KAAK;AAC3B,QAAI,CAAC,QAAS;AAEd,UAAM,eAAe,QAAQ,MAAM,mBAAmB;AACtD,QAAI,cAAc;AAChB,YAAM,QAAQ,aAAa,CAAC,EAAG;AAC/B,YAAM,MAAM,IAAI,KAAK,IAAI,OAAO,CAAC,CAAC;AAOlC,YAAM,UAAU,mBAAmB,GAAG;AACtC,cAAQ,OAAO,GAAG,qBAAqB,aAAa,CAAC,CAAE,CAAC;AACxD,YAAM,KAAK,OAAO;AAClB;AAAA,IACF;AAEA,QAAI,QAAQ,WAAW,IAAI,GAAG;AAC5B,YAAM,QAAQ,iBAAiB;AAC/B,YAAM,UAAU,QACb,MAAM,IAAI,EACV,IAAI,CAAC,MAAM,EAAE,QAAQ,SAAS,EAAE,CAAC,EACjC,KAAK,GAAG;AACX,YAAM,OAAO,GAAG,qBAAqB,OAAO,CAAC;AAC7C,YAAM,KAAK,KAAK;AAChB;AAAA,IACF;AAEA,UAAM,QAAQ,QAAQ,MAAM,IAAI;AAChC,UAAM,cAAc,MAAM,MAAM,CAAC,MAAM,iBAAiB,KAAK,CAAC,CAAC;AAC/D,UAAM,WAAW,MAAM,MAAM,CAAC,MAAM,UAAU,KAAK,CAAC,CAAC;AACrD,UAAM,aAAa,MAAM,MAAM,CAAC,MAAM,WAAW,KAAK,CAAC,CAAC;AAExD,QAAI,aAAa;AACf,YAAM,OAAO,gBAAgB,OAAO;AACpC,iBAAW,QAAQ,OAAO;AACxB,cAAM,QAAQ,KAAK,MAAM,qBAAqB;AAC9C,YAAI,CAAC,MAAO;AACZ,cAAM,UAAU,MAAM,CAAC,MAAM;AAC7B,cAAM,UAAU,MAAM,CAAC,KAAK;AAC5B,cAAM,OAAO,oBAAoB,OAAO;AACxC,aAAK,OAAO,GAAG,qBAAqB,OAAO,CAAC;AAC5C,aAAK,OAAO,IAAI;AAAA,MAClB;AACA,YAAM,KAAK,IAAI;AACf;AAAA,IACF;AAEA,QAAI,YAAY,YAAY;AAC1B,YAAM,OAAO,gBAAgB,WAAW,WAAW,QAAQ;AAC3D,iBAAW,QAAQ,OAAO;AACxB,cAAM,UAAU,KAAK,QAAQ,oBAAoB,EAAE;AACnD,cAAM,OAAO,oBAAoB;AACjC,aAAK,OAAO,GAAG,qBAAqB,OAAO,CAAC;AAC5C,aAAK,OAAO,IAAI;AAAA,MAClB;AACA,YAAM,KAAK,IAAI;AACf;AAAA,IACF;AAEA,UAAM,YAAYC,sBAAqB;AACvC,cAAU,OAAO,GAAG,qBAAqB,OAAO,CAAC;AACjD,UAAM,KAAK,SAAS;AAAA,EACtB;AAEA,SAAO;AACT;AAMA,SAAS,qBAAqB,MAA6B;AACzD,QAAM,QAAuB,CAAC;AAI9B,QAAM,UACJ;AAEF,MAAI,YAAY;AAChB,MAAI;AAEJ,UAAQ,QAAQ,QAAQ,KAAK,IAAI,OAAO,MAAM;AAE5C,QAAI,MAAM,QAAQ,WAAW;AAC3B,YAAM,QAAQ,KAAK,MAAM,WAAW,MAAM,KAAK;AAC/C,UAAI,OAAO;AACT,cAAM,KAAK,gBAAgB,KAAK,CAAC;AAAA,MACnC;AAAA,IACF;AAEA,QAAI,MAAM,CAAC,KAAK,MAAM;AAEpB,YAAM,OAAO,gBAAgB,MAAM,CAAC,CAAC;AACrC,WAAK,UAAU,CAAC;AAChB,YAAM,KAAK,IAAI;AAAA,IACjB,WAAW,MAAM,CAAC,KAAK,MAAM;AAE3B,YAAM,OAAO,gBAAgB,MAAM,CAAC,CAAC;AACrC,WAAK,UAAU,CAAC;AAChB,YAAM,KAAK,IAAI;AAAA,IACjB,WAAW,MAAM,CAAC,KAAK,MAAM;AAE3B,YAAM,OAAO,gBAAgB,MAAM,CAAC,CAAC;AACrC,WAAK,UAAU,EAAE;AACjB,YAAM,KAAK,IAAI;AAAA,IACjB,WAAW,MAAM,CAAC,KAAK,MAAM;AAE3B,YAAM,OAAO,gBAAgB,MAAM,CAAC,CAAC;AACrC,WAAK,UAAU,CAAC;AAChB,YAAM,KAAK,IAAI;AAAA,IACjB;AAEA,gBAAY,MAAM,QAAQ,MAAM,CAAC,EAAE;AAAA,EACrC;AAGA,MAAI,YAAY,KAAK,QAAQ;AAC3B,UAAM,YAAY,KAAK,MAAM,SAAS;AACtC,QAAI,WAAW;AACb,YAAM,KAAK,gBAAgB,SAAS,CAAC;AAAA,IACvC;AAAA,EACF;AAGA,MAAI,MAAM,WAAW,GAAG;AACtB,UAAM,KAAK,gBAAgB,IAAI,CAAC;AAAA,EAClC;AAEA,SAAO;AACT;;;AF/TA,SAAS,aAAa,WAAW,OAAO,0BAA0B;AA8E5D,gBAAAC,MAgKA,QAAAC,aAhKA;AA5DC,IAAM,gBAAN,MAAM,uBAAsBC,eAA4B;AAAA,EAC7D;AAAA,EACA;AAAA,EAEA,OAAO,UAAkB;AACvB,WAAO;AAAA,EACT;AAAA,EAEA,OAAO,MAAM,MAAoC;AAC/C,WAAO,IAAI,eAAc,KAAK,UAAU,KAAK,WAAW,KAAK,KAAK;AAAA,EACpE;AAAA,EAEA,YAAY,QAAgB,SAAiB,KAAe;AAC1D,UAAM,GAAG;AACT,SAAK,WAAW;AAChB,SAAK,YAAY;AAAA,EACnB;AAAA,EAEA,UAAU,SAAoC;AAC5C,UAAM,MAAM,SAAS,cAAc,KAAK;AACxC,QAAI,MAAM,UAAU;AACpB,QAAI,MAAM,QAAQ;AAClB,WAAO;AAAA,EACT;AAAA,EAEA,YAAmB;AACjB,WAAO;AAAA,EACT;AAAA,EAEA,YAA6B;AAE3B,UAAM,MAAM,SAAS,cAAc,KAAK;AACxC,QAAI,cAAc;AAClB,WAAO,EAAE,SAAS,IAAI;AAAA,EACxB;AAAA,EAEA,OAAO,YAAqC;AAE1C,WAAO;AAAA,EACT;AAAA,EAEA,OAAO,WAAW,YAAoD;AACpE,WAAO,qBAAqB;AAAA,MAC1B,QAAQ,WAAW;AAAA,MACnB,SAAS,WAAW;AAAA,IACtB,CAAC;AAAA,EACH;AAAA,EAEA,aAAsC;AACpC,WAAO;AAAA,MACL,GAAG,MAAM,WAAW;AAAA,MACpB,QAAQ,KAAK;AAAA,MACb,SAAS,KAAK;AAAA,MACd,MAAM;AAAA,MACN,SAAS;AAAA,IACX;AAAA,EACF;AAAA,EAEA,WAAyB;AACvB,WACE,gBAAAF;AAAA,MAAC;AAAA;AAAA,QACC,SAAS,KAAK,OAAO;AAAA,QACrB,QAAQ,KAAK;AAAA,QACb,SAAS,KAAK;AAAA;AAAA,IAChB;AAAA,EAEJ;AACF;AAEA,SAAS,mBAAmB;AAAA,EAC1B;AAAA,EACA;AAAA,EACA;AACF,GAIG;AACD,QAAM,CAAC,MAAM,IAAIG,2BAA0B;AAC3C,QAAM,CAAC,SAAS,UAAU,IAAI,SAAS,EAAE;AACzC,QAAM,CAAC,QAAQ,SAAS,IAAI,SAAuB,WAAW;AAC9D,QAAM,CAAC,cAAc,eAAe,IAAI,SAAiB,EAAE;AAC3D,QAAM,CAAC,YAAY,aAAa,IAAI,SAAS,CAAC;AAC9C,QAAM,eAAeC,QAAO,KAAK;AACjC,QAAM,YAAYA,QAAmD,IAAI;AACzE,QAAM,YAAYA,QAAuB,CAAC,CAAC;AAG3C,EAAAC,WAAU,MAAM;AACd,cAAU,UAAU,YAAY,MAAM;AAAA,EACxC,GAAG,CAAC,MAAM,CAAC;AAGX,QAAM,SAAS,UAAU,QAAQ,UAAU,CAAC;AAC5C,QAAM,cAAc,OAAO,UAAU;AACrC,QAAM,iBAAiB,OAAO,aAAa;AAC3C,QAAM,cAAc,OAAO,UAAU;AACrC,QAAM,eAAe,OAAO,WAAW;AACvC,QAAM,aAAa,OAAO,SAAS;AACnC,QAAM,eAAe,OAAO,WAAW;AACvC,QAAM,oBAAoB,OAAO,gBAAgB;AAGjD,QAAM,aAAa,UAAU,QAAQ,OAAO,cAAc;AAG1D,EAAAA,WAAU,MAAM;AACd,iBAAa,UAAU;AACvB,eAAW,EAAE;AACb,cAAU,WAAW;AACrB,oBAAgB,EAAE;AAElB,UAAM,WAAW,cAAc,MAAM;AACrC,UAAM,SAAS,YAAY,MAAM;AACjC,cAAU,UAAU;AAEpB,QAAI,CAAC,UAAU;AACb,gBAAU,OAAO;AACjB,sBAAgB,2BAA2B;AAC3C;AAAA,IACF;AAEA,QAAI,cAAc;AAElB,aACG,SAAS,EAAE,QAAQ,SAAS,QAAQ,OAAO,SAAS,CAAC,EACrD,KAAK,OAAO,WAAW;AACtB,YAAM,SAAS,OAAO,UAAU;AAChC,gBAAU,UAAU;AAEpB,aAAO,MAAM;AACX,YAAI,aAAa,SAAS;AACxB,iBAAO,OAAO;AACd;AAAA,QACF;AAEA,cAAM,EAAE,MAAM,MAAM,IAAI,MAAM,OAAO,KAAK;AAC1C,YAAI,KAAM;AAEV,uBAAe;AACf,mBAAW,WAAW;AAAA,MACxB;AAEA,UAAI,CAAC,aAAa,SAAS;AACzB,kBAAU,UAAU;AAAA,MACtB;AAAA,IACF,CAAC,EACA,MAAM,CAAC,QAAiB;AACvB,UAAI,CAAC,aAAa,SAAS;AACzB,cAAM,QAAQ,eAAe,QAAQ,MAAM,IAAI,MAAM,eAAe;AACpE,kBAAU,OAAO;AACjB,wBAAgB,MAAM,OAAO;AAC7B,eAAO,UAAU,KAAK;AAAA,MACxB;AAAA,IACF,CAAC;AAEH,WAAO,MAAM;AACX,mBAAa,UAAU;AACvB,gBAAU,SAAS,OAAO;AAAA,IAC5B;AAAA,EACF,GAAG,CAAC,QAAQ,QAAQ,SAAS,UAAU,CAAC;AAGxC,QAAM,cAAcC,aAAY,MAAM;AACpC,kBAAc,CAAC,MAAM,IAAI,CAAC;AAAA,EAC5B,GAAG,CAAC,CAAC;AAGL,QAAM,eAAeA,aAAY,MAAM;AACrC,cAAU,QAAQ,WAAW,OAAO;AACpC,WAAO,OAAO,MAAM;AAClB,YAAM,OAAOC,eAAc,OAAO;AAClC,UAAI,CAAC,KAAM;AAEX,YAAM,eAAe,6BAA6B,OAAO;AAEzD,UAAI,aAAa,WAAW,GAAG;AAC7B,aAAK,OAAO;AACZ;AAAA,MACF;AAIA,YAAM,YAAY,aAAa,CAAC;AAChC,WAAK,QAAQ,SAAS;AAEtB,UAAI,UAAU;AACd,eAAS,IAAI,GAAG,IAAI,aAAa,QAAQ,KAAK;AAC5C,gBAAQ,YAAY,aAAa,CAAC,CAAE;AACpC,kBAAU,aAAa,CAAC;AAAA,MAC1B;AAAA,IACF,CAAC;AAAA,EACH,GAAG,CAAC,QAAQ,SAAS,OAAO,CAAC;AAG7B,QAAM,gBAAgBD,aAAY,MAAM;AACtC,QAAI,WAAW,SAAS;AACtB,gBAAU,QAAQ,YAAY;AAAA,IAChC;AACA,WAAO,OAAO,MAAM;AAClB,YAAM,OAAOC,eAAc,OAAO;AAClC,UAAI,MAAM;AACR,aAAK,OAAO;AAAA,MACd;AAAA,IACF,CAAC;AAAA,EACH,GAAG,CAAC,QAAQ,SAAS,MAAM,CAAC;AAE5B,SACE,gBAAAN;AAAA,IAAC;AAAA;AAAA,MACC,eAAY;AAAA,MACZ,OAAO;AAAA,QACL,UAAU;AAAA,QACV,mBAAmB;AAAA,QACnB,cAAc;AAAA,QACd,SAAS;AAAA,QACT,QAAQ;AAAA,QACR,iBAAiB;AAAA,QACjB,YAAY;AAAA,MACd;AAAA,MAEA;AAAA,wBAAAA;AAAA,UAAC;AAAA;AAAA,YACC,OAAO;AAAA,cACL,SAAS;AAAA,cACT,YAAY;AAAA,cACZ,KAAK;AAAA,cACL,cAAc;AAAA,cACd,UAAU;AAAA,cACV,YAAY;AAAA,cACZ,OAAO;AAAA,cACP,eAAe;AAAA,cACf,eAAe;AAAA,YACjB;AAAA,YAEA;AAAA,8BAAAD,KAAC,eAAY,MAAM,IAAI,QAAO,QAAO;AAAA,cACrC,gBAAAA,KAAC,UAAM,uBAAY;AAAA,cAClB,WAAW,eACV,gBAAAA;AAAA,gBAAC;AAAA;AAAA,kBACC,OAAO;AAAA,oBACL,UAAU;AAAA,oBACV,YAAY;AAAA,oBACZ,OAAO;AAAA,oBACP,eAAe;AAAA,oBACf,eAAe;AAAA,kBACjB;AAAA,kBAEC;AAAA;AAAA,cACH;AAAA;AAAA;AAAA,QAEJ;AAAA,QAEC,WAAW,UACV,gBAAAA;AAAA,UAAC;AAAA;AAAA,YACC,eAAY;AAAA,YACZ,OAAO;AAAA,cACL,OAAO;AAAA,cACP,UAAU;AAAA,YACZ;AAAA,YAEC,0BAAgB;AAAA;AAAA,QACnB,IAEA,gBAAAC;AAAA,UAAC;AAAA;AAAA,YACC,eAAY;AAAA,YACZ,OAAO;AAAA,cACL,UAAU;AAAA,cACV,YAAY;AAAA,cACZ,OAAO;AAAA,cACP,YAAY;AAAA,YACd;AAAA,YAEC;AAAA;AAAA,cACA,WAAW,eACV,gBAAAD;AAAA,gBAAC;AAAA;AAAA,kBACC,OAAO;AAAA,oBACL,SAAS;AAAA,oBACT,OAAO;AAAA,oBACP,QAAQ;AAAA,oBACR,mBAAmB;AAAA,oBACnB,iBAAiB;AAAA,oBACjB,WAAW;AAAA,oBACX,eAAe;AAAA,kBACjB;AAAA;AAAA,cACF;AAAA;AAAA;AAAA,QAEJ;AAAA,SAGA,WAAW,cAAc,WAAW,YACpC,gBAAAC;AAAA,UAAC;AAAA;AAAA,YACC,OAAO;AAAA,cACL,SAAS;AAAA,cACT,KAAK;AAAA,cACL,WAAW;AAAA,YACb;AAAA,YAEC;AAAA,yBAAW,cACV,gBAAAA;AAAA,gBAAC;AAAA;AAAA,kBACC,MAAK;AAAA,kBACL,eAAY;AAAA,kBACZ,SAAS;AAAA,kBACT,OAAO;AAAA,oBACL,SAAS;AAAA,oBACT,YAAY;AAAA,oBACZ,KAAK;AAAA,oBACL,SAAS;AAAA,oBACT,cAAc;AAAA,oBACd,QAAQ;AAAA,oBACR,UAAU;AAAA,oBACV,YAAY;AAAA,oBACZ,QAAQ;AAAA,oBACR,iBAAiB;AAAA,oBACjB,OAAO;AAAA,oBACP,YAAY;AAAA,kBACd;AAAA,kBAEA;AAAA,oCAAAD,KAAC,aAAU,MAAM,IAAI,QAAO,QAAO;AAAA,oBAClC;AAAA;AAAA;AAAA,cACH;AAAA,cAED,WAAW,WAAW,aAAa,cAClC,gBAAAC;AAAA,gBAAC;AAAA;AAAA,kBACC,MAAK;AAAA,kBACL,eAAY;AAAA,kBACZ,SAAS;AAAA,kBACT,OAAO;AAAA,oBACL,SAAS;AAAA,oBACT,YAAY;AAAA,oBACZ,KAAK;AAAA,oBACL,SAAS;AAAA,oBACT,cAAc;AAAA,oBACd,QAAQ;AAAA,oBACR,UAAU;AAAA,oBACV,YAAY;AAAA,oBACZ,QAAQ;AAAA,oBACR,iBAAiB;AAAA,oBACjB,OAAO;AAAA,oBACP,YAAY;AAAA,kBACd;AAAA,kBAEA;AAAA,oCAAAD;AAAA,sBAAC;AAAA;AAAA,wBACC,OAAO;AAAA,0BACL,SAAS;AAAA,0BACT,WAAW;AAAA,wBACb;AAAA,wBAGA,0BAAAA,KAAC,sBAAmB,MAAM,IAAI,QAAO,QAAO;AAAA;AAAA,sBAFvC;AAAA,oBAGP;AAAA,oBACC;AAAA;AAAA;AAAA,cACH;AAAA,cAEF,gBAAAC;AAAA,gBAAC;AAAA;AAAA,kBACC,MAAK;AAAA,kBACL,eACE,WAAW,UAAU,uBAAuB;AAAA,kBAE9C,SAAS;AAAA,kBACT,OAAO;AAAA,oBACL,SAAS;AAAA,oBACT,YAAY;AAAA,oBACZ,KAAK;AAAA,oBACL,SAAS;AAAA,oBACT,cAAc;AAAA,oBACd,QAAQ;AAAA,oBACR,UAAU;AAAA,oBACV,YAAY;AAAA,oBACZ,QAAQ;AAAA,oBACR,iBAAiB;AAAA,oBACjB,OAAO;AAAA,oBACP,YAAY;AAAA,kBACd;AAAA,kBAEA;AAAA,oCAAAD,KAAC,SAAM,MAAM,IAAI,QAAO,QAAO;AAAA,oBAC9B,WAAW,UAAU,eAAe;AAAA;AAAA;AAAA,cACvC;AAAA;AAAA;AAAA,QACF;AAAA,QAGF,gBAAAA;AAAA,UAAC;AAAA;AAAA,YACC,yBAAyB;AAAA,cACvB,QAAQ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,YAUV;AAAA;AAAA,QACF;AAAA;AAAA;AAAA,EACF;AAEJ;AAEO,SAAS,qBACd,SACe;AACf,SAAO,IAAI,cAAc,QAAQ,QAAQ,QAAQ,SAAS,QAAQ,GAAG;AACvE;AAEO,SAAS,iBACd,MACuB;AACvB,SAAO,gBAAgB;AACzB;;;AS9aA;AAAA,EAEE,iBAAAQ;AAAA,EACA,oBAAAC;AAAA,EACA,iBAAAC;AAAA,EACA,yBAAAC;AAAA,EACA,sBAAAC;AAAA,EACA,wBAAAC;AAAA,OACK;AACP,SAAS,6BAAAC,kCAAiC;AAC1C,SAAS,aAAAC,kBAAiB;AAwHpB,gBAAAC,MAsFF,QAAAC,aAtFE;AAtGC,IAAM,cAAN,MAAM,qBAAoBP,eAA4B;AAAA,EAC3D;AAAA,EACA;AAAA,EACA;AAAA,EAEA,OAAO,UAAkB;AACvB,WAAO;AAAA,EACT;AAAA,EAEA,OAAO,MAAM,MAAgC;AAC3C,WAAO,IAAI;AAAA,MACT,KAAK;AAAA,MACL,KAAK;AAAA,MACL,KAAK;AAAA,MACL,KAAK;AAAA,IACP;AAAA,EACF;AAAA,EAEA,YACE,WACA,OACA,SACA,KACA;AACA,UAAM,GAAG;AACT,SAAK,cAAc;AACnB,SAAK,UAAU;AACf,SAAK,YAAY;AAAA,EACnB;AAAA,EAEA,UAAU,QAAmC;AAC3C,UAAM,OAAO,SAAS,cAAc,MAAM;AAC1C,SAAK,MAAM,UAAU;AACrB,WAAO;AAAA,EACT;AAAA,EAEA,YAAmB;AACjB,WAAO;AAAA,EACT;AAAA,EAEA,YAA6B;AAC3B,UAAM,OAAO,SAAS,cAAc,MAAM;AAC1C,SAAK,aAAa,mBAAmB,KAAK,WAAW;AACrD,SAAK,aAAa,wBAAwB,KAAK,SAAS;AACxD,SAAK,cAAc,GAAG,KAAK,SAAS,GAAG,KAAK,OAAO;AACnD,WAAO,EAAE,SAAS,KAAK;AAAA,EACzB;AAAA,EAEA,OAAO,YAAqC;AAC1C,WAAO;AAAA,MACL,MAAM,CAAC,YAAyB;AAC9B,YAAI,CAAC,QAAQ,aAAa,iBAAiB,EAAG,QAAO;AACrD,eAAO;AAAA,UACL,YAAY,CAAC,YAAqD;AAChE,kBAAM,YAAY,QAAQ,aAAa,iBAAiB;AACxD,kBAAM,UACJ,QAAQ,aAAa,sBAAsB,KAAK;AAClD,kBAAM,QAAQ,QAAQ,aAAa,QAAQ,SAAS,EAAE,KAAK;AAC3D,gBAAI,CAAC,UAAW,QAAO;AACvB,mBAAO;AAAA,cACL,MAAM,mBAAmB;AAAA,gBACvB,IAAI;AAAA,gBACJ;AAAA,gBACA;AAAA,cACF,CAAC;AAAA,YACH;AAAA,UACF;AAAA,UACA,UAAU;AAAA,QACZ;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA,EAEA,OAAO,WAAW,YAAgD;AAChE,WAAO,mBAAmB;AAAA,MACxB,IAAI,WAAW;AAAA,MACf,OAAO,WAAW;AAAA,MAClB,SAAS,WAAW;AAAA,IACtB,CAAC;AAAA,EACH;AAAA,EAEA,aAAoC;AAClC,WAAO;AAAA,MACL,GAAG,MAAM,WAAW;AAAA,MACpB,WAAW,KAAK;AAAA,MAChB,OAAO,KAAK;AAAA,MACZ,SAAS,KAAK;AAAA,MACd,MAAM;AAAA,MACN,SAAS;AAAA,IACX;AAAA,EACF;AAAA,EAEA,WAAiB;AACf,WAAO;AAAA,EACT;AAAA,EAEA,iBAAyB;AACvB,WAAO,GAAG,KAAK,SAAS,GAAG,KAAK,OAAO;AAAA,EACzC;AAAA,EAEA,WAAyB;AACvB,WACE,gBAAAM;AAAA,MAAC;AAAA;AAAA,QACC,SAAS,KAAK,OAAO;AAAA,QACrB,WAAW,KAAK;AAAA,QAChB,OAAO,KAAK;AAAA,QACZ,SAAS,KAAK;AAAA;AAAA,IAChB;AAAA,EAEJ;AACF;AAEA,SAAS,iBAAiB;AAAA,EACxB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAKG;AACD,QAAM,CAAC,MAAM,IAAIF,2BAA0B;AAE3C,EAAAC,WAAU,MAAM;AACd,UAAM,aAAa,MAAM;AACvB,aAAO,OAAO,MAAM;AAClB,cAAM,YAAYP,eAAc;AAChC,YAAI,CAACC,kBAAiB,SAAS,EAAG,QAAO;AACzC,cAAM,QAAQ,UAAU,SAAS;AACjC,mBAAW,QAAQ,OAAO;AACxB,cAAI,KAAK,OAAO,MAAM,SAAS;AAC7B,iBAAK,OAAO;AACZ,mBAAO;AAAA,UACT;AAAA,QACF;AACA,eAAO;AAAA,MACT,CAAC;AACD,aAAO;AAAA,IACT;AAEA,UAAM,sBAAsB,OAAO;AAAA,MACjCE;AAAA,MACA,CAAC,UAAU;AACT,cAAM,YAAYH,eAAc;AAChC,YAAI,CAACC,kBAAiB,SAAS,EAAG,QAAO;AACzC,cAAM,QAAQ,UAAU,SAAS;AACjC,cAAM,aAAa,MAAM,KAAK,CAAC,MAAM,EAAE,OAAO,MAAM,OAAO;AAC3D,YAAI,YAAY;AACd,iBAAO,eAAe;AACtB,qBAAW;AACX,iBAAO;AAAA,QACT;AACA,eAAO;AAAA,MACT;AAAA,MACAI;AAAA,IACF;AAEA,UAAM,mBAAmB,OAAO;AAAA,MAC9BD;AAAA,MACA,CAAC,UAAU;AACT,cAAM,YAAYJ,eAAc;AAChC,YAAI,CAACC,kBAAiB,SAAS,EAAG,QAAO;AACzC,cAAM,QAAQ,UAAU,SAAS;AACjC,cAAM,aAAa,MAAM,KAAK,CAAC,MAAM,EAAE,OAAO,MAAM,OAAO;AAC3D,YAAI,YAAY;AACd,iBAAO,eAAe;AACtB,qBAAW;AACX,iBAAO;AAAA,QACT;AACA,eAAO;AAAA,MACT;AAAA,MACAI;AAAA,IACF;AAEA,WAAO,MAAM;AACX,0BAAoB;AACpB,uBAAiB;AAAA,IACnB;AAAA,EACF,GAAG,CAAC,QAAQ,OAAO,CAAC;AAEpB,QAAM,YACJ,YAAY,MACR,oCACA;AAEN,SACE,gBAAAI;AAAA,IAAC;AAAA;AAAA,MACC,eAAY;AAAA,MACZ,mBAAiB;AAAA,MACjB,wBAAsB;AAAA,MACtB,OAAO;AAAA,QACL,SAAS;AAAA,QACT,YAAY;AAAA,QACZ,KAAK;AAAA,QACL,SAAS;AAAA,QACT,cAAc;AAAA,QACd,iBAAiB,sBAAsB,SAAS;AAAA,QAChD,OAAO;AAAA,QACP,UAAU;AAAA,QACV,YAAY;AAAA,QACZ,YAAY;AAAA,QACZ,QAAQ;AAAA,QACR,YAAY;AAAA,QACZ,YAAY;AAAA,QACZ,eAAe;AAAA,MACjB;AAAA,MAEA;AAAA,wBAAAD,KAAC,UAAK,OAAO,EAAE,SAAS,IAAI,GAAI,mBAAQ;AAAA,QACvC;AAAA;AAAA;AAAA,EACH;AAEJ;AAEO,SAAS,mBACd,SACa;AACb,SAAO,IAAI;AAAA,IACT,QAAQ;AAAA,IACR,QAAQ;AAAA,IACR,QAAQ;AAAA,IACR,QAAQ;AAAA,EACV;AACF;AAEO,SAAS,eACd,MACqB;AACrB,SAAO,gBAAgB;AACzB;;;AC/QA,SAAS,eAAAE,cAAa,aAAAC,YAAW,UAAAC,SAAQ,YAAAC,iBAAgB;AAazD;AAAA,EACE,iBAAAC;AAAA,EACA,iBAAAC;AAAA,EACA,wBAAAC;AAAA,EACA,iBAAAC;AAAA,EACA,yBAAAC;AAAA,EACA,sBAAAC;AAAA,OACK;AACP,SAAS,6BAAAC,kCAAiC;AAC1C,SAAS,2BAAAC,gCAA+B;AAExC,SAAS,UAAU,aAAAC,kBAAiB;AAoH9B,SAwWM,UAxWN,OAAAC,MAwWM,QAAAC,aAxWN;AAlHN,IAAM,sBAAsB;AAAA,EAC1B;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;AACF;AAiBO,IAAM,gBAAN,MAAM,uBAAsBP,eAA4B;AAAA,EAC7D;AAAA,EACA;AAAA,EACA;AAAA,EAEA,OAAO,UAAkB;AACvB,WAAO;AAAA,EACT;AAAA,EAEA,OAAO,MAAM,MAAoC;AAC/C,UAAM,QAAQ,IAAI,eAAc,KAAK,QAAQ,KAAK,YAAY,KAAK,KAAK;AACxE,UAAM,cAAc,KAAK;AACzB,WAAO;AAAA,EACT;AAAA,EAEA,YAAY,MAAc,UAAkB,KAAe;AACzD,UAAM,GAAG;AACT,SAAK,SAAS;AACd,SAAK,aAAa;AAClB,SAAK,cAAc;AAAA,EACrB;AAAA,EAEA,UAAU,SAAoC;AAC5C,UAAM,MAAM,SAAS,cAAc,KAAK;AACxC,QAAI,MAAM,UAAU;AACpB,QAAI,MAAM,QAAQ;AAClB,WAAO;AAAA,EACT;AAAA,EAEA,YAAmB;AACjB,WAAO;AAAA,EACT;AAAA,EAEA,YAA6B;AAC3B,UAAM,MAAM,SAAS,cAAc,KAAK;AACxC,UAAM,OAAO,SAAS,cAAc,MAAM;AAC1C,SAAK,cAAc,KAAK;AACxB,QAAI,KAAK,cAAc,KAAK,eAAe,QAAQ;AACjD,WAAK,YAAY,YAAY,KAAK,UAAU;AAAA,IAC9C;AACA,QAAI,YAAY,IAAI;AACpB,WAAO,EAAE,SAAS,IAAI;AAAA,EACxB;AAAA,EAEA,OAAO,YAAqC;AAC1C,WAAO;AAAA,MACL,KAAK,OAAO;AAAA,QACV,YAAY;AAAA,QACZ,UAAU;AAAA,MACZ;AAAA,IACF;AAAA,EACF;AAAA,EAEA,OAAO,WAAW,YAAoD;AACpE,WAAO,qBAAqB;AAAA,MAC1B,MAAM,WAAW;AAAA,MACjB,UAAU,WAAW;AAAA,IACvB,CAAC;AAAA,EACH;AAAA,EAEA,aAAsC;AACpC,WAAO;AAAA,MACL,GAAG,MAAM,WAAW;AAAA,MACpB,MAAM,KAAK;AAAA,MACX,UAAU,KAAK;AAAA,MACf,MAAM;AAAA,MACN,SAAS;AAAA,IACX;AAAA,EACF;AAAA,EAEA,UAAkB;AAChB,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,cAAsB;AACpB,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,WAAyB;AACvB,WACE,gBAAAM;AAAA,MAAC;AAAA;AAAA,QACC,MAAM,KAAK;AAAA,QACX,UAAU,KAAK;AAAA,QACf,SAAS,KAAK,OAAO;AAAA,QACrB,WAAW,KAAK;AAAA;AAAA,IAClB;AAAA,EAEJ;AACF;AAEA,SAAS,kBAAkB,SAA2C;AACpE,MAAI,mBAAmB,gBAAgB;AACrC,UAAM,SAAS,QAAQ,cAAc,MAAM;AAC3C,UAAM,OAAO,QAAQ,eAAe,QAAQ,eAAe;AAC3D,QAAI,WAAW;AACf,UAAM,YAAY,QAAQ,aAAa;AACvC,UAAM,YAAY,UAAU,MAAM,gBAAgB;AAClD,QAAI,YAAY,CAAC,GAAG;AAClB,iBAAW,UAAU,CAAC;AAAA,IACxB;AACA,UAAM,OAAO,qBAAqB,EAAE,MAAM,SAAS,CAAC;AACpD,WAAO,EAAE,KAAK;AAAA,EAChB;AACA,SAAO;AACT;AAEA,SAAS,mBAAmB;AAAA,EAC1B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAKG;AACD,QAAM,CAAC,MAAM,IAAIH,2BAA0B;AAC3C,QAAM,CAAC,YAAY,aAAa,cAAc,IAC5CC,yBAAwB,OAAO;AACjC,QAAM,eAAeT,QAAuB,IAAI;AAChD,QAAM,cAAcA,QAA4B,IAAI;AACpD,QAAM,CAAC,WAAW,YAAY,IAAIC,UAAS,IAAI;AAC/C,QAAM,CAAC,eAAe,gBAAgB,IAAIA,UAAS,QAAQ;AAC3D,QAAM,CAAC,iBAAiB,kBAAkB,IAAIA,UAAwB,IAAI;AAC1E,QAAM,CAAC,QAAQ,SAAS,IAAIA,UAAS,KAAK;AAC1C,QAAM,CAAC,WAAW,YAAY,IAAIA,UAAS,SAAS;AACpD,QAAM,mBAAmBD,QAA6C,IAAI;AAC1E,QAAM,oBAAoBA,QAA6C,IAAI;AAC3E,QAAM,kBAAkBA,QAAO,KAAK;AAGpC,EAAAD,WAAU,MAAM;AACd,QAAI,aAAa,CAAC,gBAAgB,WAAW,YAAY,SAAS;AAChE,sBAAgB,UAAU;AAC1B,kBAAY,QAAQ,MAAM;AAE1B,aAAO,OAAO,MAAM;AAClB,cAAM,OAAOG,eAAc,OAAO;AAClC,YAAI,QAAQ,gBAAgB,eAAe;AACzC,gBAAM,WAAW,KAAK,YAAY;AAClC,mBAAS,cAAc;AAAA,QACzB;AAAA,MACF,CAAC;AAAA,IACH;AAAA,EACF,GAAG,CAAC,WAAW,QAAQ,OAAO,CAAC;AAG/B,EAAAH,WAAU,MAAM;AACd,iBAAa,IAAI;AAAA,EACnB,GAAG,CAAC,IAAI,CAAC;AAET,EAAAA,WAAU,MAAM;AACd,qBAAiB,QAAQ;AAAA,EAC3B,GAAG,CAAC,QAAQ,CAAC;AAEb,EAAAA,WAAU,MAAM;AACd,WAAO,OAAO;AAAA,MACZI;AAAA,MACA,CAAC,UAAsB;AACrB,YAAI,aAAa,SAAS,SAAS,MAAM,MAAc,GAAG;AAExD,gBAAM,SAAS,MAAM;AACrB,cACE,OAAO,YAAY,cACnB,OAAO,YAAY,YACnB,OAAO,YAAY,YACnB,OAAO,QAAQ,QAAQ,KACvB,OAAO,QAAQ,QAAQ,GACvB;AACA,mBAAO;AAAA,UACT;AACA,cAAI,CAAC,MAAM,UAAU;AACnB,2BAAe;AAAA,UACjB;AACA,sBAAY,IAAI;AAChB,iBAAO;AAAA,QACT;AACA,eAAO;AAAA,MACT;AAAA,MACAC;AAAA,IACF;AAAA,EACF,GAAG,CAAC,QAAQ,gBAAgB,WAAW,CAAC;AAExC,QAAM,WAAWN;AAAA,IACf,CAAC,UAAyB;AACxB,UAAI,cAAc,CAAC,WAAW;AAC5B,cAAM,eAAe;AACrB,eAAO,OAAO,MAAM;AAClB,gBAAM,OAAOI,eAAc,OAAO;AAClC,cAAI,MAAM;AACR,iBAAK,OAAO;AAAA,UACd;AAAA,QACF,CAAC;AACD,eAAO;AAAA,MACT;AACA,aAAO;AAAA,IACT;AAAA,IACA,CAAC,QAAQ,YAAY,WAAW,OAAO;AAAA,EACzC;AAEA,EAAAH,WAAU,MAAM;AACd,UAAM,sBAAsB,OAAO;AAAA,MACjCO;AAAA,MACA;AAAA,MACAF;AAAA,IACF;AACA,UAAM,mBAAmB,OAAO;AAAA,MAC9BG;AAAA,MACA;AAAA,MACAH;AAAA,IACF;AACA,WAAO,MAAM;AACX,0BAAoB;AACpB,uBAAiB;AAAA,IACnB;AAAA,EACF,GAAG,CAAC,QAAQ,QAAQ,CAAC;AAErB,QAAM,iBAAiBN;AAAA,IACrB,CAAC,YAAoB;AACnB,UAAI,iBAAiB,SAAS;AAC5B,qBAAa,iBAAiB,OAAO;AAAA,MACvC;AACA,uBAAiB,UAAU,WAAW,MAAM;AAC1C,eAAO,OAAO,MAAM;AAClB,gBAAM,OAAOI,eAAc,OAAO;AAClC,cAAI,QAAQ,gBAAgB,eAAe;AACzC,kBAAM,WAAW,KAAK,YAAY;AAClC,qBAAS,SAAS;AAAA,UACpB;AAAA,QACF,CAAC;AAAA,MACH,GAAG,GAAG;AAAA,IACR;AAAA,IACA,CAAC,QAAQ,OAAO;AAAA,EAClB;AAEA,QAAM,mBAAmBJ;AAAA,IACvB,CAAC,MAA8C;AAC7C,YAAM,UAAU,EAAE,OAAO;AACzB,mBAAa,OAAO;AACpB,qBAAe,OAAO;AAAA,IACxB;AAAA,IACA,CAAC,cAAc;AAAA,EACjB;AAEA,QAAM,uBAAuBA;AAAA,IAC3B,CAAC,MAA4C;AAC3C,YAAM,cAAc,EAAE,OAAO;AAC7B,uBAAiB,WAAW;AAC5B,aAAO,OAAO,MAAM;AAClB,cAAM,OAAOI,eAAc,OAAO;AAClC,YAAI,QAAQ,gBAAgB,eAAe;AACzC,gBAAM,WAAW,KAAK,YAAY;AAClC,mBAAS,aAAa;AAAA,QACxB;AAAA,MACF,CAAC;AAAA,IACH;AAAA,IACA,CAAC,QAAQ,OAAO;AAAA,EAClB;AAGA,QAAM,qBAAqBJ;AAAA,IACzB,CAAC,SAAiB;AAChB,YAAM,UAAU,KACb,QAAQ,MAAM,OAAO,EACrB,QAAQ,MAAM,MAAM,EACpB,QAAQ,MAAM,MAAM;AACvB,YAAM,YACJ,iBAAiB,kBAAkB,SAC/B,oBAAoB,aAAa,MACjC;AACN,aAAO,aAAa,SAAS,IAAI,OAAO;AAAA,IAC1C;AAAA,IACA,CAAC,aAAa;AAAA,EAChB;AAEA,QAAM,aAAaA,aAAY,MAAM;AACnC,UAAM,OAAO,mBAAmB,SAAS;AACzC,UAAM,WAAW,IAAI,KAAK,CAAC,IAAI,GAAG,EAAE,MAAM,YAAY,CAAC;AACvD,UAAM,WAAW,IAAI,KAAK,CAAC,SAAS,GAAG,EAAE,MAAM,aAAa,CAAC;AAC7D,cAAU,UACP,MAAM,CAAC,IAAI,cAAc,EAAE,aAAa,UAAU,cAAc,SAAS,CAAC,CAAC,CAAC,EAC5E,KAAK,MAAM;AACV,gBAAU,IAAI;AACd,iBAAW,MAAM,UAAU,KAAK,GAAG,GAAI;AAAA,IACzC,CAAC;AAAA,EACL,GAAG,CAAC,WAAW,kBAAkB,CAAC;AAGlC,QAAM,qBAAqBA;AAAA,IACzB,CAAC,MAAiD;AAChD,YAAM,KAAK,EAAE;AACb,YAAM,WAAW,GAAG,MAAM,UAAU,GAAG,gBAAgB,GAAG,YAAY;AACtE,YAAM,OAAO,YAAY;AAEzB,QAAE,eAAe;AACjB,QAAE,cAAc,QAAQ,cAAc,IAAI;AAC1C,QAAE,cAAc,QAAQ,aAAa,mBAAmB,IAAI,CAAC;AAAA,IAC/D;AAAA,IACA,CAAC,WAAW,kBAAkB;AAAA,EAChC;AAEA,QAAM,oBAAoBA;AAAA,IACxB,CAAC,MAAiD;AAChD,YAAM,KAAK,EAAE;AACb,YAAM,WAAW,GAAG,MAAM,UAAU,GAAG,gBAAgB,GAAG,YAAY;AACtE,YAAM,OAAO,YAAY;AAEzB,QAAE,eAAe;AACjB,QAAE,cAAc,QAAQ,cAAc,IAAI;AAC1C,QAAE,cAAc,QAAQ,aAAa,mBAAmB,IAAI,CAAC;AAG7D,UAAI,UAAU;AACZ,cAAM,SAAS,GAAG,MAAM,UAAU,GAAG,GAAG,cAAc;AACtD,cAAM,QAAQ,GAAG,MAAM,UAAU,GAAG,YAAY;AAChD,cAAM,UAAU,SAAS;AACzB,qBAAa,OAAO;AACpB,uBAAe,OAAO;AAAA,MACxB,OAAO;AACL,qBAAa,EAAE;AACf,uBAAe,EAAE;AAAA,MACnB;AAAA,IACF;AAAA,IACA,CAAC,WAAW,oBAAoB,cAAc;AAAA,EAChD;AAGA,EAAAC,WAAU,MAAM;AACd,QAAI,CAAC,UAAU,KAAK,GAAG;AACrB,yBAAmB,IAAI;AACvB;AAAA,IACF;AAEA,QAAI,kBAAkB,SAAS;AAC7B,mBAAa,kBAAkB,OAAO;AAAA,IACxC;AAEA,sBAAkB,UAAU,WAAW,MAAM;AAC3C,YAAM,yBAAyB;AAAA,QAC7B,QAAQ;AAAA,QACR,SAAS,EAAE,gBAAgB,mBAAmB;AAAA,QAC9C,MAAM,KAAK,UAAU,EAAE,MAAM,WAAW,UAAU,cAAc,CAAC;AAAA,MACnE,CAAC,EACE,KAAK,CAAC,QAAQ;AACb,YAAI,CAAC,IAAI,GAAI,OAAM,IAAI,MAAM,kBAAkB;AAC/C,eAAO,IAAI,KAAK;AAAA,MAClB,CAAC,EACA,KAAK,CAAC,SAA2B;AAChC,2BAAmB,KAAK,IAAI;AAAA,MAC9B,CAAC,EACA,MAAM,MAAM;AAEX,2BAAmB,IAAI;AAAA,MACzB,CAAC;AAAA,IACL,GAAG,GAAG;AAEN,WAAO,MAAM;AACX,UAAI,kBAAkB,SAAS;AAC7B,qBAAa,kBAAkB,OAAO;AAAA,MACxC;AAAA,IACF;AAAA,EACF,GAAG,CAAC,WAAW,aAAa,CAAC;AAE7B,EAAAA,WAAU,MAAM;AACd,QAAI,YAAY,WAAW,WAAW;AACpC,YAAM,KAAK,YAAY;AACvB,SAAG,MAAM,SAAS;AAClB,SAAG,MAAM,SAAS,GAAG,GAAG,YAAY;AAAA,IACtC;AAAA,EACF,GAAG,CAAC,WAAW,SAAS,CAAC;AAEzB,SACE,gBAAAa;AAAA,IAAC;AAAA;AAAA,MACC,KAAK;AAAA,MACL,eAAY;AAAA,MACZ,OAAO;AAAA,QACL,UAAU;AAAA,QACV,cAAc;AAAA,QACd,iBAAiB;AAAA,QACjB,QAAQ;AAAA,QACR,UAAU;AAAA,QACV,SAAS,aACL,4CACA;AAAA,QACJ,eAAe;AAAA,MACjB;AAAA,MAEA;AAAA,wBAAAA;AAAA,UAAC;AAAA;AAAA,YACC,OAAO;AAAA,cACL,SAAS;AAAA,cACT,YAAY;AAAA,cACZ,gBAAgB;AAAA,cAChB,SAAS;AAAA,cACT,cAAc;AAAA,cACd,UAAU;AAAA,YACZ;AAAA,YAEA;AAAA,8BAAAD;AAAA,gBAAC;AAAA;AAAA,kBACC,eAAY;AAAA,kBACZ,OAAO;AAAA,kBACP,UAAU;AAAA,kBACV,OAAO;AAAA,oBACL,iBAAiB;AAAA,oBACjB,QAAQ;AAAA,oBACR,UAAU;AAAA,oBACV,YAAY;AAAA,oBACZ,OAAO;AAAA,oBACP,QAAQ;AAAA,oBACR,SAAS;AAAA,oBACT,SAAS;AAAA,kBACX;AAAA,kBAEC,8BAAoB,IAAI,CAAC,SACxB,gBAAAA,KAAC,YAAkB,OAAO,MACvB,kBADU,IAEb,CACD;AAAA;AAAA,cACH;AAAA,cAEA,gBAAAA;AAAA,gBAAC;AAAA;AAAA,kBACC,MAAK;AAAA,kBACL,eAAY;AAAA,kBACZ,SAAS;AAAA,kBACT,OAAO;AAAA,oBACL,SAAS;AAAA,oBACT,YAAY;AAAA,oBACZ,KAAK;AAAA,oBACL,SAAS;AAAA,oBACT,cAAc;AAAA,oBACd,QAAQ;AAAA,oBACR,UAAU;AAAA,oBACV,YAAY;AAAA,oBACZ,QAAQ;AAAA,oBACR,iBAAiB;AAAA,oBACjB,OAAO;AAAA,oBACP,YAAY;AAAA,kBACd;AAAA,kBAEC,mBACC,gBAAAC,MAAA,YACE;AAAA,oCAAAD,KAACD,YAAA,EAAU,MAAM,IAAI,QAAO,QAAO;AAAA,oBAAE;AAAA,qBAEvC,IAEA,gBAAAE,MAAA,YACE;AAAA,oCAAAD,KAAC,YAAS,MAAM,IAAI;AAAA,oBAAE;AAAA,qBAExB;AAAA;AAAA,cAEJ;AAAA;AAAA;AAAA,QACF;AAAA,QAEA,gBAAAC;AAAA,UAAC;AAAA;AAAA,YACC,OAAO;AAAA,cACL,UAAU;AAAA,cACV,WAAW;AAAA,YACb;AAAA,YAEC;AAAA,eAAC,aAAa,kBACb,gBAAAD;AAAA,gBAAC;AAAA;AAAA,kBACC,eAAY;AAAA,kBACZ,SAAS,MAAM;AACb,iCAAa,IAAI;AAEjB,+BAAW,MAAM,YAAY,SAAS,MAAM,GAAG,CAAC;AAAA,kBAClD;AAAA,kBACA,OAAO;AAAA,oBACL,SAAS;AAAA,oBACT,QAAQ;AAAA,oBACR,UAAU;AAAA,kBACZ;AAAA,kBACA,yBAAyB,EAAE,QAAQ,gBAAgB;AAAA;AAAA,cACrD,IACE;AAAA,cAEH,aAAa,CAAC,kBACb,gBAAAA;AAAA,gBAAC;AAAA;AAAA,kBACC,KAAK;AAAA,kBACL,eAAY;AAAA,kBACZ,OAAO;AAAA,kBACP,UAAU;AAAA,kBACV,QAAQ;AAAA,kBACR,OAAO;AAAA,kBACP,SAAS,MAAM,aAAa,IAAI;AAAA,kBAChC,QAAQ,MAAM,aAAa,KAAK;AAAA,kBAChC,aAAY;AAAA,kBACZ,YAAY;AAAA,kBACZ,cAAa;AAAA,kBACb,aAAY;AAAA,kBACZ,gBAAe;AAAA,kBACf,OAAO;AAAA,oBACL,SAAS;AAAA,oBACT,OAAO;AAAA,oBACP,SAAS;AAAA,oBACT,YACE;AAAA,oBACF,UAAU;AAAA,oBACV,YAAY;AAAA,oBACZ,OAAO;AAAA,oBACP,iBAAiB;AAAA,oBACjB,QAAQ;AAAA,oBACR,SAAS;AAAA,oBACT,QAAQ;AAAA,oBACR,UAAU;AAAA,oBACV,YAAY;AAAA,oBACZ,SAAS;AAAA,oBACT,WAAW;AAAA,kBACb;AAAA;AAAA,cACF,IACE;AAAA;AAAA;AAAA,QACN;AAAA;AAAA;AAAA,EACF;AAEJ;AAEO,SAAS,qBAAqB,SAA0C;AAC7E,QAAM,OAAO,IAAI,cAAc,QAAQ,MAAM,QAAQ,UAAU,QAAQ,GAAG;AAC1E,MAAI,QAAQ,WAAW;AACrB,SAAK,cAAc;AAAA,EACrB;AACA,SAAO;AACT;AAEO,SAAS,iBACd,MACuB;AACvB,SAAO,gBAAgB;AACzB;;;AClkBA,SAAS,iBAAAE,sBAAqB;AAgFxB,gBAAAC,MAeF,QAAAC,aAfE;AAzEC,IAAM,mBAAN,MAAM,0BAAyBF,eAA4B;AAAA,EAChE;AAAA,EACA;AAAA,EAEA,OAAO,UAAkB;AACvB,WAAO;AAAA,EACT;AAAA,EAEA,OAAO,MAAM,MAA0C;AACrD,WAAO,IAAI;AAAA,MACT,KAAK;AAAA,MACL,KAAK;AAAA,MACL,KAAK;AAAA,IACP;AAAA,EACF;AAAA,EAEA,YAAY,WAAmB,UAAkB,KAAe;AAC9D,UAAM,GAAG;AACT,SAAK,cAAc;AACnB,SAAK,aAAa;AAAA,EACpB;AAAA,EAEA,UAAU,SAAoC;AAC5C,UAAM,MAAM,SAAS,cAAc,KAAK;AACxC,QAAI,MAAM,WAAW;AACrB,QAAI,MAAM,UAAU;AACpB,QAAI,MAAM,WAAW;AACrB,WAAO;AAAA,EACT;AAAA,EAEA,YAAmB;AACjB,WAAO;AAAA,EACT;AAAA,EAEA,YAA6B;AAC3B,UAAM,UAAU,SAAS,cAAc,KAAK;AAC5C,YAAQ,aAAa,sBAAsB,MAAM;AACjD,WAAO,EAAE,QAAQ;AAAA,EACnB;AAAA,EAEA,OAAO,YAAqC;AAC1C,WAAO;AAAA,EACT;AAAA,EAEA,OAAO,WACL,gBACkB;AAClB,WAAO;AAAA,MACL,eAAe;AAAA,MACf,eAAe;AAAA,IACjB;AAAA,EACF;AAAA,EAEA,aAAyC;AACvC,WAAO;AAAA,MACL,GAAG,MAAM,WAAW;AAAA,MACpB,WAAW,KAAK;AAAA,MAChB,UAAU,KAAK;AAAA,MACf,MAAM;AAAA,MACN,SAAS;AAAA,IACX;AAAA,EACF;AAAA,EAEA,eAAuB;AACrB,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,cAAsB;AACpB,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,WAAyB;AACvB,WACE,gBAAAC;AAAA,MAAC;AAAA;AAAA,QACC,WAAW,KAAK;AAAA,QAChB,UAAU,KAAK;AAAA;AAAA,IACjB;AAAA,EAEJ;AACF;AAEA,SAAS,sBAAsB;AAAA,EAC7B;AACF,GAGG;AACD,SACE,gBAAAC;AAAA,IAAC;AAAA;AAAA,MACC,eAAY;AAAA,MACZ,OAAO;AAAA,QACL,UAAU;AAAA,QACV,OAAO;AAAA,QACP,aAAa;AAAA,QACb,WAAW;AAAA,QACX,iBAAiB;AAAA,QACjB,cAAc;AAAA,QACd,UAAU;AAAA,QACV,SAAS;AAAA,MACX;AAAA,MAGA;AAAA,wBAAAD;AAAA,UAAC;AAAA;AAAA,YACC,OAAO;AAAA,cACL,UAAU;AAAA,cACV,QAAQ;AAAA,cACR,MAAM;AAAA,cACN,OAAO;AAAA,cACP,UAAU;AAAA,cACV,OAAO;AAAA,cACP,YAAY;AAAA,cACZ,UAAU;AAAA,cACV,cAAc;AAAA,cACd,YAAY;AAAA,YACd;AAAA,YAEC;AAAA;AAAA,QACH;AAAA,QAGA,gBAAAA;AAAA,UAAC;AAAA;AAAA,YACC,eAAY;AAAA,YACZ,OAAO;AAAA,cACL,UAAU;AAAA,cACV,OAAO;AAAA,cACP,SAAS;AAAA,cACT,YAAY;AAAA,cACZ,gBAAgB;AAAA,YAClB;AAAA,YAEA,0BAAAA;AAAA,cAAC;AAAA;AAAA,gBACC,OAAO;AAAA,kBACL,OAAO;AAAA,kBACP,QAAQ;AAAA,kBACR,QAAQ;AAAA,kBACR,gBAAgB;AAAA,kBAChB,cAAc;AAAA,kBACd,WAAW;AAAA,gBACb;AAAA;AAAA,YACF;AAAA;AAAA,QACF;AAAA,QACA,gBAAAA,KAAC,WAAO,4EAAiE;AAAA;AAAA;AAAA,EAC3E;AAEJ;AAEO,SAAS,wBACd,WACA,UACkB;AAClB,SAAO,IAAI,iBAAiB,WAAW,QAAQ;AACjD;AAEO,SAAS,oBACd,MAC0B;AAC1B,SAAO,gBAAgB;AACzB;;;Ad9JO,IAAM,YAAuC;AAAA,EAClD;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;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;;;AerCO,IAAM,gBAAoC;AAAA,EAC/C,WAAW;AAAA,EACX,SAAS;AAAA,IACP,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,EACN;AAAA,EACA,OAAO;AAAA,EACP,MAAM;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,UAAU;AAAA,IACV,WAAW;AAAA,IACX,iBAAiB;AAAA,IACjB,mBAAmB;AAAA,IACnB,QAAQ;AAAA,MACN,UAAU;AAAA,IACZ;AAAA,EACF;AAAA,EACA,MAAM;AAAA,IACJ,MAAM;AAAA,IACN,QAAQ;AAAA,IACR,WAAW;AAAA,IACX,eAAe;AAAA,IACf,MAAM;AAAA,EACR;AAAA,EACA,MAAM;AAAA,EACN,MAAM;AAAA,EACN,OAAO;AAAA,EACP,UAAU;AAAA,EACV,WAAW;AAAA,EACX,iBAAiB;AAAA,EACjB,gBAAgB;AAAA,EAChB,SAAS;AAAA,EACT,iBAAiB;AAAA,EACjB,aAAa;AAAA,EACb,eAAe;AACjB;;;AhBqCM,SAQU,OAAAE,MARV,QAAAC,aAAA;AAvCN,SAAS,oBAAoB,EAAE,IAAI,GAA2B;AAC5D,QAAM,CAAC,MAAM,IAAIC,2BAA0B;AAC3C,EAAAC,WAAU,MAAM;AACd,WAAO,OAAO,MAAM;AAClB,eAAS,EAAE,aAAa,GAAG;AAAA,IAC7B,CAAC;AAAA,EAGH,GAAG,CAAC,CAAC;AACL,SAAO;AACT;AAEA,IAAM,iBAAiB,CAAC,UAAiB;AACvC,UAAQ,MAAM,6BAA6B,KAAK;AAChD,QAAM;AACR;AAEO,SAAS,WAAW;AAAA,EACzB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,cAAc;AAAA,EACd,WAAW;AAAA,EACX,YAAY;AAAA,EACZ,UAAU;AACZ,GAAoB;AAClB,QAAM,gBAAgB;AAAA,IACpB;AAAA,IACA,OAAO;AAAA,IACP,OAAO;AAAA,IACP,aAAa,gBAAgB;AAAA,IAC7B;AAAA,IACA;AAAA,EACF;AAEA,SACE,gBAAAH,KAAC,mBAAgB,eACf,0BAAAC,MAAC,SAAI,WAAsB,KAAU,sBAAkB,MAAC,kBAAgB,WACtE;AAAA,oBAAAD;AAAA,MAAC;AAAA;AAAA,QACC,iBACE,gBAAAA;AAAA,UAAC;AAAA;AAAA,YACC,cAAW;AAAA,YACX,oBAAkB;AAAA,YAClB,WAAU;AAAA,YACV,aACE,gBAAAA,KAAC,SAAI,WAAU,wBACZ,uBACH;AAAA;AAAA,QAEJ;AAAA,QAEF,aAAa;AAAA,QACb,eAAe;AAAA;AAAA,IACjB;AAAA,IACA,gBAAAA,KAAC,iBAAc;AAAA,IACd,aAAa,gBAAAA,KAAC,mBAAgB;AAAA,IAC9B,OAAO,QAAQ,UAAU,gBAAAA,KAAC,uBAAoB,KAAU;AAAA,IACxD;AAAA,KACH,GACF;AAEJ;;;AiBvGA,SAAS,6BAAAI,mCAAiC;AAC1C,SAAS,iBAAAC,iBAAe,qBAAAC,qBAAmB,YAAAC,iBAAgB;;;ACC3D,SAAS,eAAAC,cAAa,aAAAC,YAAW,UAAAC,SAAQ,YAAAC,iBAAgB;AAGzD,SAAS,6BAAAC,mCAAiC;AAC1C;AAAA,EACE,iBAAAC;AAAA,EACA;AAAA,EACA,eAAAC;AAAA,EACA,kBAAAC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,wBAAAC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP,SAAS,yBAAyB;AAGlC,SAAS,oBAAoB;AAG7B;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,sBAAAC;AAAA,OACK;AAIP,SAAS,eAAAC,oBAAmB;;;AC3C5B,SAAS,qBAAqB;AAEvB,IAAM,0BAA0B,cAAoB,yBAAyB;AAC7E,IAAM,uBAAuB,cAAoB,sBAAsB;AACvE,IAAM,yBAAyB,cAAoB,wBAAwB;AAC3E,IAAM,4BAA4B,cAAkC,2BAA2B;AAC/F,IAAM,4BAA4B,cAAoB,2BAA2B;AACjF,IAAM,0BAA0B,cAAoB,yBAAyB;AAC7E,IAAM,yBAAyB,cAAsB,wBAAwB;AAC7E,IAAM,8BAA8B,cAAsB,6BAA6B;AACvF,IAAM,gCAAgC,cAAiD,+BAA+B;AACtH,IAAM,yBAAyB,cAAwD,wBAAwB;AAC/G,IAAM,uBAAuB,cAAgD,sBAAsB;AACnG,IAAM,2BAA2B,cAAoB,0BAA0B;AAC/E,IAAM,wBAAwB,cAAgD,uBAAuB;AACrG,IAAM,0BAA0B,cAAsB,yBAAyB;AAC/E,IAAM,8BAA8B,cAA6B,6BAA6B;;;ACPrG,SAAS,WAAW,OAAoC;AACtD,QAAM,MAAM,oBAAI,IAAoB;AACpC,MAAI,CAAC,MAAM,KAAK,EAAG,QAAO;AAE1B,aAAW,eAAe,MAAM,MAAM,GAAG,GAAG;AAC1C,UAAM,aAAa,YAAY,QAAQ,GAAG;AAC1C,QAAI,eAAe,GAAI;AACvB,UAAM,OAAO,YAAY,MAAM,GAAG,UAAU,EAAE,KAAK;AACnD,UAAM,MAAM,YAAY,MAAM,aAAa,CAAC,EAAE,KAAK;AACnD,QAAI,QAAQ,KAAK;AACf,UAAI,IAAI,MAAM,GAAG;AAAA,IACnB;AAAA,EACF;AACA,SAAO;AACT;AAKA,SAAS,eAAe,KAAkC;AACxD,QAAM,QAAkB,CAAC;AACzB,aAAW,CAAC,MAAM,GAAG,KAAK,KAAK;AAC7B,UAAM,KAAK,GAAG,IAAI,KAAK,GAAG,EAAE;AAAA,EAC9B;AACA,SAAO,MAAM,KAAK,IAAI;AACxB;AAOO,SAAS,iBACd,UACA,UACA,OACQ;AACR,QAAM,MAAM,WAAW,QAAQ;AAC/B,MAAI,UAAU,MAAM;AAClB,QAAI,OAAO,QAAQ;AAAA,EACrB,OAAO;AACL,QAAI,IAAI,UAAU,KAAK;AAAA,EACzB;AACA,SAAO,eAAe,GAAG;AAC3B;AAMO,SAAS,uBACd,OACA,UACe;AACf,QAAM,MAAM,WAAW,KAAK;AAC5B,SAAO,IAAI,IAAI,QAAQ,KAAK;AAC9B;;;AChEA,SAAS,eAAAC,oBAAmB;AAC5B,SAAS,6BAAAC,kCAAiC;AAC1C,SAAS,aAAAC,kBAAiB;;;ACiBnB,IAAM,wBAAsC;AAAA,EACjD,MAAM;AAAA,IACJ,EAAE,OAAO,WAAW,OAAO,IAAI,QAAQ,eAAe;AAAA,IACtD,EAAE,OAAO,QAAQ,OAAO,6BAA6B,QAAQ,UAAU;AAAA,IACvE,EAAE,OAAO,SAAS,OAAO,8BAA8B,QAAQ,UAAU;AAAA,IACzE,EAAE,OAAO,UAAU,OAAO,+BAA+B,QAAQ,UAAU;AAAA,IAC3E,EAAE,OAAO,UAAU,OAAO,+BAA+B,QAAQ,UAAU;AAAA,IAC3E,EAAE,OAAO,SAAS,OAAO,8BAA8B,QAAQ,UAAU;AAAA,IACzE,EAAE,OAAO,QAAQ,OAAO,6BAA6B,QAAQ,UAAU;AAAA,IACvE,EAAE,OAAO,UAAU,OAAO,+BAA+B,QAAQ,UAAU;AAAA,IAC3E,EAAE,OAAO,QAAQ,OAAO,6BAA6B,QAAQ,UAAU;AAAA,IACvE,EAAE,OAAO,OAAO,OAAO,4BAA4B,QAAQ,UAAU;AAAA,EACvE;AAAA,EACA,WAAW;AAAA,IACT,EAAE,OAAO,WAAW,OAAO,IAAI,QAAQ,cAAc;AAAA,IACrD,EAAE,OAAO,QAAQ,OAAO,kCAAkC,QAAQ,UAAU;AAAA,IAC5E,EAAE,OAAO,SAAS,OAAO,mCAAmC,QAAQ,UAAU;AAAA,IAC9E,EAAE,OAAO,UAAU,OAAO,oCAAoC,QAAQ,UAAU;AAAA,IAChF,EAAE,OAAO,UAAU,OAAO,oCAAoC,QAAQ,UAAU;AAAA,IAChF,EAAE,OAAO,SAAS,OAAO,mCAAmC,QAAQ,UAAU;AAAA,IAC9E,EAAE,OAAO,QAAQ,OAAO,kCAAkC,QAAQ,UAAU;AAAA,IAC5E,EAAE,OAAO,UAAU,OAAO,oCAAoC,QAAQ,UAAU;AAAA,IAChF,EAAE,OAAO,QAAQ,OAAO,kCAAkC,QAAQ,UAAU;AAAA,IAC5E,EAAE,OAAO,OAAO,OAAO,iCAAiC,QAAQ,UAAU;AAAA,EAC5E;AACF;;;ADSM,gBAAAC,OAmBM,QAAAC,aAnBN;AAtCC,SAAS,YAAY;AAAA,EAC1B,UAAU;AAAA,EACV;AAAA,EACA;AAAA,EACA;AACF,GAAqB;AACnB,QAAM,CAAC,MAAM,IAAIC,2BAA0B;AAE3C,QAAM,kBAAkBC;AAAA,IACtB,CAAC,UAAkB;AACjB,aAAO,gBAAgB,wBAAwB,KAAK;AACpD,aAAO,MAAM;AACb,cAAQ;AAAA,IACV;AAAA,IACA,CAAC,QAAQ,OAAO;AAAA,EAClB;AAEA,QAAM,uBAAuBA;AAAA,IAC3B,CAAC,UAAkB;AACjB,aAAO,gBAAgB,6BAA6B,KAAK;AACzD,aAAO,MAAM;AACb,cAAQ;AAAA,IACV;AAAA,IACA,CAAC,QAAQ,OAAO;AAAA,EAClB;AAEA,SACE,gBAAAF;AAAA,IAAC;AAAA;AAAA,MACC,eAAY;AAAA,MACZ,aAAa,CAAC,MAAM,EAAE,eAAe;AAAA,MACrC,OAAO;AAAA,QACL,SAAS;AAAA,QACT,UAAU;AAAA,QACV,YACE;AAAA,MACJ;AAAA,MAGA;AAAA,wBAAAD;AAAA,UAAC;AAAA;AAAA,YACC,OAAO;AAAA,cACL,UAAU;AAAA,cACV,YAAY;AAAA,cACZ,OAAO;AAAA,cACP,eAAe;AAAA,cACf,eAAe;AAAA,cACf,SAAS;AAAA,cACT,YAAY;AAAA,YACd;AAAA,YACD;AAAA;AAAA,QAED;AAAA,QACA,gBAAAA,MAAC,SAAI,OAAO,EAAE,SAAS,QAAQ,UAAU,QAAQ,KAAK,OAAO,cAAc,MAAM,GAC9E,kBAAQ,KAAK,IAAI,CAAC,UAAU;AAC3B,gBAAM,WACJ,MAAM,UAAU,KAAK,CAAC,kBAAkB,oBAAoB,MAAM;AAEpE,iBACE,gBAAAC;AAAA,YAAC;AAAA;AAAA,cAEC,MAAK;AAAA,cACL,OAAO,MAAM;AAAA,cACb,cAAY,MAAM;AAAA,cAClB,eAAa,cAAc,MAAM,MAAM,YAAY,CAAC;AAAA,cACpD,aAAa,CAAC,MAAM;AAClB,kBAAE,eAAe;AACjB,gCAAgB,MAAM,KAAK;AAAA,cAC7B;AAAA,cACA,OAAO;AAAA,gBACL,OAAO;AAAA,gBACP,QAAQ;AAAA,gBACR,cAAc;AAAA,gBACd,QAAQ;AAAA,gBACR,QAAQ;AAAA,gBACR,SAAS;AAAA,gBACT,YAAY;AAAA,gBACZ,gBAAgB;AAAA,gBAChB,iBAAiB;AAAA,gBACjB,UAAU;AAAA,cACZ;AAAA,cAEA;AAAA,gCAAAD;AAAA,kBAAC;AAAA;AAAA,oBACC,OAAO;AAAA,sBACL,UAAU;AAAA,sBACV,YAAY;AAAA,sBACZ,OACE,MAAM,WAAW,iBACb,wCACA,MAAM;AAAA,sBACZ,YAAY;AAAA,oBACd;AAAA,oBACD;AAAA;AAAA,gBAED;AAAA,gBACC,YACC,gBAAAA;AAAA,kBAACI;AAAA,kBAAA;AAAA,oBACC,MAAM;AAAA,oBACN,QAAO;AAAA,oBACP,OAAO;AAAA,sBACL,UAAU;AAAA,sBACV,QAAQ;AAAA,sBACR,gBAAgB;AAAA,sBAChB,OAAO;AAAA,oBACT;AAAA;AAAA,gBACF;AAAA;AAAA;AAAA,YA7CG,QAAQ,MAAM,KAAK;AAAA,UA+C1B;AAAA,QAEJ,CAAC,GACH;AAAA,QAGA,gBAAAJ;AAAA,UAAC;AAAA;AAAA,YACC,OAAO;AAAA,cACL,QAAQ;AAAA,cACR,iBAAiB;AAAA,cACjB,QAAQ;AAAA,YACV;AAAA;AAAA,QACF;AAAA,QAGA,gBAAAA;AAAA,UAAC;AAAA;AAAA,YACC,OAAO;AAAA,cACL,UAAU;AAAA,cACV,YAAY;AAAA,cACZ,OAAO;AAAA,cACP,eAAe;AAAA,cACf,eAAe;AAAA,cACf,SAAS;AAAA,cACT,YAAY;AAAA,YACd;AAAA,YACD;AAAA;AAAA,QAED;AAAA,QACA,gBAAAA,MAAC,SAAI,OAAO,EAAE,SAAS,QAAQ,UAAU,QAAQ,KAAK,MAAM,GACzD,kBAAQ,UAAU,IAAI,CAAC,UAAU;AAChC,gBAAM,WACJ,MAAM,UAAU,KACZ,CAAC,uBACD,yBAAyB,MAAM;AAErC,iBACE,gBAAAC;AAAA,YAAC;AAAA;AAAA,cAEC,MAAK;AAAA,cACL,OAAO,MAAM;AAAA,cACb,cAAY,MAAM;AAAA,cAClB,eAAa,mBAAmB,MAAM,MAAM,YAAY,CAAC;AAAA,cACzD,aAAa,CAAC,MAAM;AAClB,kBAAE,eAAe;AACjB,qCAAqB,MAAM,KAAK;AAAA,cAClC;AAAA,cACA,OAAO;AAAA,gBACL,OAAO;AAAA,gBACP,QAAQ;AAAA,gBACR,cAAc;AAAA,gBACd,QAAQ;AAAA,gBACR,QAAQ;AAAA,gBACR,SAAS;AAAA,gBACT,YAAY;AAAA,gBACZ,gBAAgB;AAAA,gBAChB,iBACE,MAAM,WAAW,gBAAgB,gBAAgB,MAAM;AAAA,gBACzD,UAAU;AAAA,cACZ;AAAA,cAEC;AAAA,sBAAM,WAAW,iBAChB,gBAAAD;AAAA,kBAAC;AAAA;AAAA,oBACC,OAAO;AAAA,sBACL,UAAU;AAAA,sBACV,OAAO;AAAA,sBACP,YAAY;AAAA,oBACd;AAAA,oBACD;AAAA;AAAA,gBAED;AAAA,gBAED,YACC,gBAAAA;AAAA,kBAACI;AAAA,kBAAA;AAAA,oBACC,MAAM;AAAA,oBACN,QAAO;AAAA,oBACP,OAAO;AAAA,sBACL,OACE,MAAM,WAAW,gBACb,oCACA;AAAA,oBACR;AAAA;AAAA,gBACF;AAAA;AAAA;AAAA,YA5CG,aAAa,MAAM,KAAK;AAAA,UA8C/B;AAAA,QAEJ,CAAC,GACH;AAAA;AAAA;AAAA,EACF;AAEJ;;;AEjNA,SAAS,eAAAC,oBAAmB;AAC5B,SAAS,6BAAAC,kCAAiC;AAC1C,SAAS,aAAAC,kBAAiB;;;ACYnB,IAAM,wBAA2C;AAAA,EACtD,EAAE,OAAO,WAAW,OAAO,IAAI,SAAS,4BAA4B;AAAA,EACpE,EAAE,OAAO,SAAS,OAAO,8BAA8B,SAAS,6BAA6B;AAAA,EAC7F,EAAE,OAAO,QAAQ,OAAO,6BAA6B,SAAS,4BAA4B;AAAA,EAC1F,EAAE,OAAO,QAAQ,OAAO,6BAA6B,SAAS,4BAA4B;AAC5F;;;AD2BU,SA6BE,OAAAC,OA7BF,QAAAC,aAAA;AAhCH,SAAS,WAAW;AAAA,EACzB,QAAQ;AAAA,EACR;AAAA,EACA;AACF,GAAoB;AAClB,QAAM,CAAC,MAAM,IAAIC,2BAA0B;AAE3C,QAAM,eAAeC;AAAA,IACnB,CAAC,UAAkB;AACjB,aAAO,gBAAgB,yBAAyB,KAAK;AACrD,aAAO,MAAM;AACb,cAAQ;AAAA,IACV;AAAA,IACA,CAAC,QAAQ,OAAO;AAAA,EAClB;AAEA,SACE,gBAAAH;AAAA,IAAC;AAAA;AAAA,MACC,eAAY;AAAA,MACZ,aAAa,CAAC,MAAM,EAAE,eAAe;AAAA,MACrC,OAAO;AAAA,QACL,SAAS;AAAA,QACT,UAAU;AAAA,QACV,YACE;AAAA,MACJ;AAAA,MAEC,gBAAM,IAAI,CAAC,UAAU;AACpB,cAAM,WACJ,MAAM,UAAU,KAAK,CAAC,aAAa,eAAe,MAAM;AAE1D,eACE,gBAAAC;AAAA,UAAC;AAAA;AAAA,YAEC,MAAK;AAAA,YACL,cAAY,MAAM;AAAA,YAClB,eAAa,QAAQ,MAAM,MAAM,YAAY,CAAC;AAAA,YAC9C,aAAa,CAAC,MAAM;AAClB,gBAAE,eAAe;AACjB,2BAAa,MAAM,KAAK;AAAA,YAC1B;AAAA,YACA,OAAO;AAAA,cACL,SAAS;AAAA,cACT,YAAY;AAAA,cACZ,gBAAgB;AAAA,cAChB,OAAO;AAAA,cACP,SAAS;AAAA,cACT,cAAc;AAAA,cACd,QAAQ;AAAA,cACR,QAAQ;AAAA,cACR,iBAAiB,WACb,6BACA;AAAA,cACJ,OAAO;AAAA,cACP,YAAY;AAAA,cACZ,YAAY,MAAM;AAAA,cAClB,UAAU;AAAA,cACV,YAAY;AAAA,cACZ,WAAW;AAAA,YACb;AAAA,YAEA;AAAA,8BAAAD,MAAC,UAAM,gBAAM,OAAM;AAAA,cAClB,YACC,gBAAAA;AAAA,gBAACI;AAAA,gBAAA;AAAA,kBACC,MAAM;AAAA,kBACN,QAAO;AAAA,kBACP,OAAO;AAAA,oBACL,OAAO;AAAA,oBACP,YAAY;AAAA,oBACZ,mBAAmB;AAAA,kBACrB;AAAA;AAAA,cACF;AAAA;AAAA;AAAA,UAtCG,MAAM;AAAA,QAwCb;AAAA,MAEJ,CAAC;AAAA;AAAA,EACH;AAEJ;;;ALuRQ,gBAAAC,OA0IA,QAAAC,cA1IA;AA7TR,IAAM,MACJ,OAAO,cAAc,eAAe,uBAAuB,KAAK,UAAU,QAAQ,IAC9E,QACA;AASN,IAAM,kBAAmC;AAAA,EACvC,EAAE,MAAM,WAAW,QAAQ,QAAQ,OAAO,QAAQ,UAAU,GAAG,GAAG,KAAK;AAAA,EACvE,EAAE,MAAM,gBAAgB,QAAQ,UAAU,OAAO,UAAU,UAAU,GAAG,GAAG,KAAK;AAAA,EAChF,EAAE,MAAM,mBAAmB,QAAQ,aAAa,OAAO,aAAa,UAAU,GAAG,GAAG,KAAK;AAAA,EACzF,EAAE,MAAM,uBAAuB,QAAQ,iBAAiB,OAAO,iBAAiB,UAAU,GAAG,GAAG,WAAW;AAAA,EAC3G,EAAE,MAAM,UAAU,QAAQ,QAAQ,OAAO,eAAe,UAAU,GAAG,GAAG,KAAK;AAC/E;AAOO,SAAS,gBAAgB,EAAE,cAAc,aAAa,IAA0B,CAAC,GAAG;AAEzF,QAAM,CAAC,MAAM,IAAIC,4BAA0B;AAG3C,QAAM,CAAC,WAAW,YAAY,IAAIC,UAAkB,KAAK;AACzD,QAAM,CAAC,UAAU,WAAW,IAAIA,UAAwC;AAAA,IACtE,KAAK;AAAA,IACL,MAAM;AAAA,EACR,CAAC;AACD,QAAM,CAAC,eAAe,gBAAgB,IAAIA,UAAsB,oBAAI,IAAI,CAAC;AACzE,QAAM,CAAC,iBAAiB,kBAAkB,IAAIA,UAAwB,IAAI;AAC1E,QAAM,CAAC,sBAAsB,uBAAuB,IAAIA,UAAwB,IAAI;AACpF,QAAM,CAAC,YAAY,aAAa,IAAIA,UAAwB,IAAI;AAChE,QAAM,CAAC,gBAAgB,iBAAiB,IAAIA,UAA+B,IAAI;AAC/E,QAAM,CAAC,iBAAiB,kBAAkB,IAAIA,UAAS,KAAK;AAC5D,QAAM,CAAC,gBAAgB,iBAAiB,IAAIA,UAAS,KAAK;AAC1D,QAAM,CAAC,SAAS,UAAU,IAAIA,UAAS,KAAK;AAC5C,QAAM,CAAC,SAAS,UAAU,IAAIA,UAAS,KAAK;AAC5C,QAAM,aAAaC,QAAuB,IAAI;AAC9C,QAAM,CAAC,iBAAiB,kBAAkB,IAAID;AAAA,IAC5C;AAAA,EACF;AAGA,EAAAE,WAAU,MAAM;AACd,QAAI,OAAO,WAAW,YAAa;AACnC,uBAAmB,SAAS,IAAI;AAAA,EAClC,GAAG,CAAC,CAAC;AAGL,EAAAA,WAAU,MAAM;AACd,UAAM,iBAAiB,OAAO;AAAA,MAC5B;AAAA,MACA,CAAC,YAAY;AACX,mBAAW,OAAO;AAClB,eAAO;AAAA,MACT;AAAA,MACAC;AAAA,IACF;AACA,UAAM,iBAAiB,OAAO;AAAA,MAC5B;AAAA,MACA,CAAC,YAAY;AACX,mBAAW,OAAO;AAClB,eAAO;AAAA,MACT;AAAA,MACAA;AAAA,IACF;AACA,WAAO,MAAM;AACX,qBAAe;AACf,qBAAe;AAAA,IACjB;AAAA,EACF,GAAG,CAAC,MAAM,CAAC;AAGX,QAAM,gBAAgBC,aAAY,MAAM;AAGtC,UAAM,eAAe,OAAO,aAAa;AACzC,QACE,CAAC,gBACD,aAAa,eAAe,KAC5B,aAAa,aACb;AAEA,UAAI,aAAa,SAAS;AACxB,qBAAa,KAAK;AAClB,qBAAa,UAAU;AAAA,MACzB;AACA;AAAA,IACF;AAEA,UAAM,QAAQ,aAAa,WAAW,CAAC;AACvC,UAAM,OAAO,MAAM,sBAAsB;AAEzC,QAAI,KAAK,UAAU,KAAK,KAAK,WAAW,GAAG;AACzC,UAAI,aAAa,SAAS;AACxB,qBAAa,KAAK;AAClB,qBAAa,UAAU;AAAA,MACzB;AACA;AAAA,IACF;AAGA,WAAO,KAAK,MAAM;AAChB,YAAM,YAAYC,eAAc;AAGhC,UAAI,kBAAkB,SAAS,GAAG;AAChC,qBAAa,KAAK;AAClB,qBAAa,UAAU;AACvB;AAAA,MACF;AAEA,UAAI,CAAC,kBAAkB,SAAS,KAAK,UAAU,YAAY,GAAG;AAC5D,qBAAa,KAAK;AAClB,qBAAa,UAAU;AACvB;AAAA,MACF;AAEA,YAAM,UAAU,oBAAI,IAAY;AAChC,UAAI,UAAU,UAAU,MAAM,EAAG,SAAQ,IAAI,MAAM;AACnD,UAAI,UAAU,UAAU,QAAQ,EAAG,SAAQ,IAAI,QAAQ;AACvD,UAAI,UAAU,UAAU,WAAW,EAAG,SAAQ,IAAI,WAAW;AAC7D,UAAI,UAAU,UAAU,eAAe,EAAG,SAAQ,IAAI,eAAe;AACrE,UAAI,UAAU,UAAU,MAAM,EAAG,SAAQ,IAAI,MAAM;AAGnD,YAAM,OAAO,UAAU,OAAO,QAAQ;AACtC,YAAM,SAAS,KAAK,UAAU;AAC9B,UAAIC,aAAY,MAAM,KAAKA,aAAY,IAAI,GAAG;AAC5C,gBAAQ,IAAI,MAAM;AAAA,MACpB;AAGA,YAAM,aAAa,UAAU,OAAO,QAAQ;AAC5C,UAAIC,aAAY,UAAU,GAAG;AAC3B,cAAM,QAAQ,WAAW,SAAS;AAClC,2BAAmB,uBAAuB,OAAO,OAAO,CAAC;AACzD,gCAAwB,uBAAuB,OAAO,kBAAkB,CAAC;AACzE,sBAAc,uBAAuB,OAAO,aAAa,CAAC;AAAA,MAC5D,OAAO;AACL,2BAAmB,IAAI;AACvB,gCAAwB,IAAI;AAC5B,sBAAc,IAAI;AAAA,MACpB;AAGA,UAAI,QAAQC,gBAAe,UAAU,IAAI,aAAa,WAAW,UAAU;AAC3E,aAAO,SAAS,MAAM,UAAU,KAAK,CAAC,YAAY,MAAM,UAAU,CAAC,GAAG;AACpE,gBAAQ,MAAM,UAAU;AAAA,MAC1B;AACA,UAAI,SAASA,gBAAe,KAAK,KAAK,CAAC,YAAY,KAAK,GAAG;AACzD,0BAAkB,MAAM,aAAa,CAAC;AAAA,MACxC,OAAO;AACL,0BAAkB,IAAI;AAAA,MACxB;AAEA,uBAAiB,OAAO;AAAA,IAC1B,CAAC;AAGD,UAAM,gBAAgB;AACtB,UAAM,MAAM;AACZ,UAAMC,aAAY,KAAK,MAAM,gBAAgB;AAE7C,gBAAY;AAAA,MACV,KAAKA,aAAY,KAAK,SAAS,MAAM,KAAK,MAAM;AAAA,MAChD,MAAM,KAAK,OAAO,KAAK,QAAQ;AAAA,IACjC,CAAC;AACD,iBAAa,IAAI;AACjB,iBAAa,UAAU;AAAA,EACzB,GAAG,CAAC,MAAM,CAAC;AAGX,QAAM,kBAAkBR,QAAO,CAAC;AAChC,QAAM,eAAeA,QAAO,KAAK;AAEjC,EAAAC,WAAU,MAAM;AACd,WAAO,OAAO;AAAA,MACZ;AAAA,MACA,MAAM;AAEJ,YAAI,gBAAgB,YAAY,GAAG;AACjC,0BAAgB,UAAU,sBAAsB,MAAM;AACpD,4BAAgB,UAAU;AAC1B,0BAAc;AAAA,UAChB,CAAC;AAAA,QACH;AACA,eAAO;AAAA,MACT;AAAA,MACAC;AAAA,IACF;AAAA,EACF,GAAG,CAAC,QAAQ,aAAa,CAAC;AAG1B,EAAAD,WAAU,MAAM;AACd,QAAI,CAAC,UAAW;AAEhB,WAAO,OAAO;AAAA,MACZ;AAAA,MACA,MAAM;AACJ,qBAAa,KAAK;AAClB,eAAO;AAAA,MACT;AAAA,MACAC;AAAA,IACF;AAAA,EACF,GAAG,CAAC,QAAQ,SAAS,CAAC;AAEtB,QAAM,eAAeC;AAAA,IACnB,CAAC,WAAuB;AACtB,aAAO,gBAAgB,qBAAqB,MAAM;AAElD,aAAO,MAAM;AAAA,IACf;AAAA,IACA,CAAC,MAAM;AAAA,EACT;AAGA,EAAAF,WAAU,MAAM;AACd,UAAM,cAAc,OAAO,eAAe;AAC1C,QAAI,CAAC,YAAa;AAElB,UAAM,gBAAgB,CAAC,MAAqB;AAC1C,YAAM,QAAQ,EAAE,WAAW,EAAE;AAG7B,UAAI,SAAS,EAAE,QAAQ,OAAO,CAAC,EAAE,UAAU;AACzC,UAAE,eAAe;AACjB,eAAO,gBAAgB,qBAAqB,MAAM;AAAA,MACpD;AAGA,UAAI,SAAS,EAAE,YAAY,EAAE,QAAQ,KAAK;AACxC,UAAE,eAAe;AACjB,eAAO,gBAAgB,qBAAqB,eAAe;AAAA,MAC7D;AAAA,IACF;AAEA,gBAAY,iBAAiB,WAAW,aAAa;AACrD,WAAO,MAAM,YAAY,oBAAoB,WAAW,aAAa;AAAA,EACvE,GAAG,CAAC,MAAM,CAAC;AAGX,EAAAA,WAAU,MAAM;AACd,QAAI,CAAC,WAAW;AACd,yBAAmB,KAAK;AACxB,wBAAkB,KAAK;AAAA,IACzB;AAAA,EACF,GAAG,CAAC,SAAS,CAAC;AAEd,MAAI,CAAC,aAAa,CAAC,gBAAiB,QAAO;AAG3C,QAAM,YAAY,SAAS,MAAM;AACjC,QAAM,iBACJ,SAAS,MAAM,KAAK,qBAAqB;AAE3C,SAAO;AAAA,IACL,gBAAAJ;AAAA,MAAC;AAAA;AAAA,QACC,KAAK;AAAA,QACL,MAAK;AAAA,QACL,cAAW;AAAA,QACX,eAAY;AAAA,QACZ,OAAO;AAAA,UACL,UAAU;AAAA,UACV,QAAQ;AAAA,UACR,SAAS;AAAA,UACT,YAAY;AAAA,UACZ,KAAK;AAAA,UACL,SAAS;AAAA,UACT,cAAc;AAAA,UACd,QAAQ;AAAA,UACR,iBAAiB;AAAA,UACjB,gBAAgB;AAAA,UAChB,sBAAsB;AAAA,UACtB,WAAW;AAAA,UACX,KAAK,GAAG,SAAS,GAAG;AAAA,UACpB,MAAM,GAAG,SAAS,IAAI;AAAA,UACtB,WAAW;AAAA,UACX,YACE;AAAA,QACJ;AAAA,QAGA;AAAA,0BAAAD;AAAA,YAAC;AAAA;AAAA,cACC,MAAK;AAAA,cACL,OAAO,SAAS,GAAG;AAAA,cACnB,cAAW;AAAA,cACX,UAAU,CAAC;AAAA,cACX,eAAY;AAAA,cACZ,aAAa,CAAC,MAAM;AAClB,kBAAE,eAAe;AACjB,uBAAO,gBAAgB,cAAc,MAAS;AAC9C,uBAAO,MAAM;AAAA,cACf;AAAA,cACA,OAAO;AAAA,gBACL,SAAS;AAAA,gBACT,YAAY;AAAA,gBACZ,gBAAgB;AAAA,gBAChB,OAAO;AAAA,gBACP,QAAQ;AAAA,gBACR,cAAc;AAAA,gBACd,QAAQ;AAAA,gBACR,QAAQ;AAAA,gBACR,iBAAiB;AAAA,gBACjB,OAAO;AAAA,gBACP,SAAS,UAAU,IAAI;AAAA,gBACvB,eAAe,UAAU,SAAS;AAAA,gBAClC,YAAY;AAAA,cACd;AAAA,cAEA,0BAAAA,MAAC,6BAA0B,MAAM,IAAI,QAAO,WAAU;AAAA;AAAA,UACxD;AAAA,UAGA,gBAAAA;AAAA,YAAC;AAAA;AAAA,cACC,MAAK;AAAA,cACL,OAAO,SAAS,GAAG;AAAA,cACnB,cAAW;AAAA,cACX,UAAU,CAAC;AAAA,cACX,eAAY;AAAA,cACZ,aAAa,CAAC,MAAM;AAClB,kBAAE,eAAe;AACjB,uBAAO,gBAAgB,cAAc,MAAS;AAC9C,uBAAO,MAAM;AAAA,cACf;AAAA,cACA,OAAO;AAAA,gBACL,SAAS;AAAA,gBACT,YAAY;AAAA,gBACZ,gBAAgB;AAAA,gBAChB,OAAO;AAAA,gBACP,QAAQ;AAAA,gBACR,cAAc;AAAA,gBACd,QAAQ;AAAA,gBACR,QAAQ;AAAA,gBACR,iBAAiB;AAAA,gBACjB,OAAO;AAAA,gBACP,SAAS,UAAU,IAAI;AAAA,gBACvB,eAAe,UAAU,SAAS;AAAA,gBAClC,YAAY;AAAA,cACd;AAAA,cAEA,0BAAAA,MAACa,qBAAA,EAAmB,MAAM,IAAI,QAAO,WAAU;AAAA;AAAA,UACjD;AAAA,UAGA,gBAAAb;AAAA,YAAC;AAAA;AAAA,cACC,OAAO;AAAA,gBACL,OAAO;AAAA,gBACP,QAAQ;AAAA,gBACR,iBAAiB;AAAA,gBACjB,QAAQ;AAAA,cACV;AAAA;AAAA,UACF;AAAA,UAEC,gBAAgB,IAAI,CAAC,EAAE,MAAM,MAAM,QAAQ,OAAO,SAAS,MAC1D,gBAAAA;AAAA,YAAC;AAAA;AAAA,cAEC,MAAK;AAAA,cACL,OAAO,GAAG,KAAK,KAAK,QAAQ;AAAA,cAC5B,cAAY;AAAA,cACZ,gBAAc,cAAc,IAAI,MAAM;AAAA,cACtC,eAAa,WAAW,MAAM;AAAA,cAC9B,aAAa,CAAC,MAAM;AAClB,kBAAE,eAAe;AACjB,6BAAa,MAAM;AAAA,cACrB;AAAA,cACA,OAAO;AAAA,gBACL,SAAS;AAAA,gBACT,YAAY;AAAA,gBACZ,gBAAgB;AAAA,gBAChB,OAAO;AAAA,gBACP,QAAQ;AAAA,gBACR,cAAc;AAAA,gBACd,QAAQ;AAAA,gBACR,QAAQ;AAAA,gBACR,iBAAiB,cAAc,IAAI,MAAM,IACrC,oCACA;AAAA,gBACJ,OAAO,cAAc,IAAI,MAAM,IAC3B,4CACA;AAAA,gBACJ,YAAY;AAAA,cACd;AAAA,cAEA,0BAAAA;AAAA,gBAAC;AAAA;AAAA,kBACC,MAAM;AAAA,kBACN,QAAQ,cAAc,IAAI,MAAM,IAAI,SAAS;AAAA;AAAA,cAC/C;AAAA;AAAA,YA/BK;AAAA,UAgCP,CACD;AAAA,UAGD,gBAAAA;AAAA,YAAC;AAAA;AAAA,cACC,OAAO;AAAA,gBACL,OAAO;AAAA,gBACP,QAAQ;AAAA,gBACR,iBAAiB;AAAA,gBACjB,QAAQ;AAAA,cACV;AAAA;AAAA,UACF;AAAA,UAGA,gBAAAA;AAAA,YAAC;AAAA;AAAA,cACC,MAAK;AAAA,cACL,OAAM;AAAA,cACN,cAAW;AAAA,cACX,gBAAc,cAAc,IAAI,MAAM;AAAA,cACtC,eAAY;AAAA,cACZ,aAAa,CAAC,MAAM;AAClB,kBAAE,eAAe;AACjB,uBAAO,gBAAgB,yBAAyB,MAAS;AAAA,cAC3D;AAAA,cACA,OAAO;AAAA,gBACL,SAAS;AAAA,gBACT,YAAY;AAAA,gBACZ,gBAAgB;AAAA,gBAChB,OAAO;AAAA,gBACP,QAAQ;AAAA,gBACR,cAAc;AAAA,gBACd,QAAQ;AAAA,gBACR,QAAQ;AAAA,gBACR,iBAAiB,cAAc,IAAI,MAAM,IACrC,oCACA;AAAA,gBACJ,OAAO,cAAc,IAAI,MAAM,IAC3B,4CACA;AAAA,gBACJ,YAAY;AAAA,cACd;AAAA,cAEA,0BAAAA;AAAA,gBAAC;AAAA;AAAA,kBACC,MAAM;AAAA,kBACN,QAAQ,cAAc,IAAI,MAAM,IAAI,SAAS;AAAA;AAAA,cAC/C;AAAA;AAAA,UACF;AAAA,UAGA,gBAAAA;AAAA,YAAC;AAAA;AAAA,cACC,OAAO;AAAA,gBACL,OAAO;AAAA,gBACP,QAAQ;AAAA,gBACR,iBAAiB;AAAA,gBACjB,QAAQ;AAAA,cACV;AAAA;AAAA,UACF;AAAA,UAGA,gBAAAC,OAAC,SAAI,OAAO,EAAE,UAAU,WAAW,GACjC;AAAA,4BAAAA;AAAA,cAAC;AAAA;AAAA,gBACC,MAAK;AAAA,gBACL,OAAM;AAAA,gBACN,cAAW;AAAA,gBACX,iBAAe;AAAA,gBACf,eAAY;AAAA,gBACZ,aAAa,CAAC,MAAM;AAClB,oBAAE,eAAe;AACjB,qCAAmB,CAAC,SAAS;AAC3B,wBAAI,CAAC,KAAM,mBAAkB,KAAK;AAClC,2BAAO,CAAC;AAAA,kBACV,CAAC;AAAA,gBACH;AAAA,gBACA,OAAO;AAAA,kBACL,SAAS;AAAA,kBACT,YAAY;AAAA,kBACZ,gBAAgB;AAAA,kBAChB,eAAe;AAAA,kBACf,OAAO;AAAA,kBACP,QAAQ;AAAA,kBACR,cAAc;AAAA,kBACd,QAAQ;AAAA,kBACR,QAAQ;AAAA,kBACR,iBAAiB,kBACb,6BACA;AAAA,kBACJ,OAAO;AAAA,kBACP,YAAY;AAAA,kBACZ,KAAK;AAAA,gBACP;AAAA,gBAEA;AAAA,kCAAAD;AAAA,oBAAC;AAAA;AAAA,sBACC,OAAO;AAAA,wBACL,UAAU;AAAA,wBACV,YAAY;AAAA,wBACZ,YAAY;AAAA,wBACZ,OAAO,mBAAmB;AAAA,sBAC5B;AAAA,sBACD;AAAA;AAAA,kBAED;AAAA,kBACA,gBAAAA;AAAA,oBAAC;AAAA;AAAA,sBACC,OAAO;AAAA,wBACL,OAAO;AAAA,wBACP,QAAQ;AAAA,wBACR,cAAc;AAAA,wBACd,iBAAiB,wBAAwB;AAAA,sBAC3C;AAAA;AAAA,kBACF;AAAA;AAAA;AAAA,YACF;AAAA,YAGC,mBACC,gBAAAA;AAAA,cAAC;AAAA;AAAA,gBACC,eAAY;AAAA,gBACZ,OAAO;AAAA,kBACL,UAAU;AAAA,kBACV,KAAK;AAAA,kBACL,MAAM;AAAA,kBACN,WAAW;AAAA,kBACX,cAAc;AAAA,kBACd,QAAQ;AAAA,kBACR,iBAAiB;AAAA,kBACjB,gBAAgB;AAAA,kBAChB,sBAAsB;AAAA,kBACtB,WAAW;AAAA,kBACX,QAAQ;AAAA,gBACV;AAAA,gBAEA,0BAAAA;AAAA,kBAAC;AAAA;AAAA,oBACC,SAAS;AAAA,oBACT;AAAA,oBACA;AAAA,oBACA,SAAS,MAAM,mBAAmB,KAAK;AAAA;AAAA,gBACzC;AAAA;AAAA,YACF;AAAA,aAEJ;AAAA,UAGA,gBAAAC,OAAC,SAAI,OAAO,EAAE,UAAU,WAAW,GACjC;AAAA,4BAAAD;AAAA,cAAC;AAAA;AAAA,gBACC,MAAK;AAAA,gBACL,OAAM;AAAA,gBACN,cAAW;AAAA,gBACX,iBAAe;AAAA,gBACf,eAAY;AAAA,gBACZ,aAAa,CAAC,MAAM;AAClB,oBAAE,eAAe;AACjB,oCAAkB,CAAC,SAAS;AAC1B,wBAAI,CAAC,KAAM,oBAAmB,KAAK;AACnC,2BAAO,CAAC;AAAA,kBACV,CAAC;AAAA,gBACH;AAAA,gBACA,OAAO;AAAA,kBACL,SAAS;AAAA,kBACT,YAAY;AAAA,kBACZ,gBAAgB;AAAA,kBAChB,OAAO;AAAA,kBACP,QAAQ;AAAA,kBACR,cAAc;AAAA,kBACd,QAAQ;AAAA,kBACR,QAAQ;AAAA,kBACR,iBAAiB,iBACb,6BACA;AAAA,kBACJ,OAAO;AAAA,kBACP,YAAY;AAAA,gBACd;AAAA,gBAEA,0BAAAA,MAAC,cAAW,MAAM,IAAI,QAAO,WAAU;AAAA;AAAA,YACzC;AAAA,YAGC,kBACC,gBAAAA;AAAA,cAAC;AAAA;AAAA,gBACC,eAAY;AAAA,gBACZ,OAAO;AAAA,kBACL,UAAU;AAAA,kBACV,KAAK;AAAA,kBACL,MAAM;AAAA,kBACN,WAAW;AAAA,kBACX,cAAc;AAAA,kBACd,QAAQ;AAAA,kBACR,iBAAiB;AAAA,kBACjB,gBAAgB;AAAA,kBAChB,sBAAsB;AAAA,kBACtB,WAAW;AAAA,kBACX,QAAQ;AAAA,gBACV;AAAA,gBAEA,0BAAAA;AAAA,kBAAC;AAAA;AAAA,oBACC,OAAO;AAAA,oBACP;AAAA,oBACA,SAAS,MAAM,kBAAkB,KAAK;AAAA;AAAA,gBACxC;AAAA;AAAA,YACF;AAAA,aAEJ;AAAA,UAGA,gBAAAA;AAAA,YAAC;AAAA;AAAA,cACC,OAAO;AAAA,gBACL,OAAO;AAAA,gBACP,QAAQ;AAAA,gBACR,iBAAiB;AAAA,gBACjB,QAAQ;AAAA,cACV;AAAA;AAAA,UACF;AAAA,UAGA,gBAAAA;AAAA,YAAC;AAAA;AAAA,cACC,MAAK;AAAA,cACL,OAAO,mBAAmB,QAAQ,kBAAkB;AAAA,cACpD,cAAY,mBAAmB,QAAQ,4BAA4B;AAAA,cACnE,eAAY;AAAA,cACZ,aAAa,CAAC,MAAM;AAClB,kBAAE,eAAe;AACjB,sBAAM,SAAS,mBAAmB,QAAQ,QAAQ;AAClD,uBAAO,gBAAgB,6BAA6B,MAAM;AAC1D,kCAAkB,MAAM;AACxB,uBAAO,MAAM;AAAA,cACf;AAAA,cACA,OAAO;AAAA,gBACL,SAAS;AAAA,gBACT,YAAY;AAAA,gBACZ,gBAAgB;AAAA,gBAChB,OAAO;AAAA,gBACP,QAAQ;AAAA,gBACR,cAAc;AAAA,gBACd,QAAQ;AAAA,gBACR,QAAQ;AAAA,gBACR,iBAAiB;AAAA,gBACjB,OAAO;AAAA,gBACP,YAAY;AAAA,cACd;AAAA,cAEC,6BAAmB,QAClB,gBAAAA,MAAC,qBAAkB,MAAM,IAAI,QAAO,WAAU,IAE9C,gBAAAA,MAAC,sBAAmB,MAAM,IAAI,QAAO,WAAU;AAAA;AAAA,UAEnD;AAAA;AAAA;AAAA,IACF;AAAA,IACA;AAAA,EACF;AACF;;;AOtrBA,SAAS,eAAAc,cAAa,aAAAC,YAAW,SAAS,UAAAC,SAAQ,YAAAC,iBAAgB;AAGlE,SAAS,6BAAAC,mCAAiC;AAC1C;AAAA,EACE,wBAAAC;AAAA,EACA,YAAAC;AAAA,EACA,iBAAAC;AAAA,EACA,kBAAAC;AAAA,EACA,qBAAAC;AAAA,EACA,eAAAC;AAAA,EACA,wBAAAC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,sBAAAC;AAAA,EACA;AAAA,OACK;AACP,SAAS,sBAAAC,qBAAoB,oBAAAC,yBAAwB;AACrD,SAAS,mBAAAC,kBAAiB,uBAAAC,4BAA2B;AAGrD,SAAS,gBAAAC,qBAAoB;AAG7B;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,eAAAC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,cAAAC;AAAA,EACA,qBAAAC;AAAA,EACA,sBAAAC;AAAA,OACK;AAcP,SAAS,uBAAuB;AAQ9B,gBAAAC,OAq1Bc,QAAAC,cAr1Bd;AADF,IAAM,SAAS,CAAC,EAAE,KAAK,MACrB,gBAAAD,MAAC,gBAAa,MAAY,QAAO,WAAU;AAE7C,IAAM,SAAS,CAAC,EAAE,KAAK,MACrB,gBAAAA,MAAC,gBAAa,MAAY,QAAO,WAAU;AAE7C,IAAM,SAAS,CAAC,EAAE,KAAK,MACrB,gBAAAA,MAAC,kBAAe,MAAY,QAAO,WAAU;AAE/C,IAAM,YAAY,CAAC,EAAE,KAAK,MACxB,gBAAAA,MAAC,cAAW,MAAY,QAAO,WAAU;AAE3C,IAAM,iBAAiB,CAAC,EAAE,KAAK,MAC7B,gBAAAA,MAAC,mBAAgB,MAAY,QAAO,WAAU;AAEhD,IAAM,mBAAmB,CAAC,EAAE,KAAK,MAC/B,gBAAAA,MAAC,mBAAgB,MAAY,QAAO,WAAU;AAEhD,IAAM,cAAc,CAAC,EAAE,KAAK,MAC1B,gBAAAA,MAAC,mBAAgB,MAAY,QAAO,WAAU;AAEhD,IAAM,YAAY,CAAC,EAAE,KAAK,MACxB,gBAAAA,MAAC,mBAAgB,MAAY,QAAO,WAAU;AAEhD,IAAM,WAAW,CAAC,EAAE,KAAK,MACvB,gBAAAA,MAAC,kBAAe,MAAY,QAAO,WAAU;AAE/C,IAAM,SAAS,CAAC,EAAE,KAAK,MACrB,gBAAAA,MAACE,cAAA,EAAY,MAAY,QAAO,WAAU;AAE5C,IAAM,YAAY,CAAC,EAAE,KAAK,MACxB,gBAAAF,MAAC,aAAU,MAAY,QAAO,WAAU;AAE1C,IAAM,cAAc,CAAC,EAAE,KAAK,MAC1B,gBAAAA,MAAC,YAAS,MAAY,QAAO,WAAU;AAEzC,IAAM,YAAY,CAAC,EAAE,KAAK,MACxB,gBAAAA,MAAC,cAAW,MAAY,QAAO,WAAU;AAE3C,IAAM,YAAY,CAAC,EAAE,KAAK,MACxB,gBAAAA,MAAC,mBAAgB,MAAY,QAAO,WAAU;AAEhD,IAAM,gBAAgB,CAAC,EAAE,KAAK,MAC5B,gBAAAA,MAAC,mBAAgB,MAAY,QAAO,WAAU;AAEhD,IAAM,aAAa,CAAC,EAAE,KAAK,MACzB,gBAAAA,MAAC,uBAAoB,MAAY,QAAO,WAAU;AAEpD,IAAM,WAAW,CAAC,EAAE,KAAK,MACvB,gBAAAA,MAACG,aAAA,EAAW,MAAY,QAAO,WAAU;AAE3C,IAAM,UAAU,CAAC,EAAE,KAAK,MACtB,gBAAAH,MAACI,oBAAA,EAAkB,MAAY,QAAO,WAAU;AAElD,IAAM,UAAU,CAAC,EAAE,KAAK,MACtB,gBAAAJ,MAACK,qBAAA,EAAmB,MAAY,QAAO,WAAU;AAiBnD,IAAM,iBAAyC;AAAA,EAC7C,aAAa;AAAA,EACb,aAAa;AAAA,EACb,aAAa;AAAA,EACb,OAAO;AAAA,EACP,eAAe;AAAA,EACf,iBAAiB;AAAA,EACjB,cAAc;AAAA,EACd,SAAS;AAAA,EACT,MAAM;AACR;AASA,IAAM,kBAAiD;AAAA,EACrD,IAAI,EAAE,IAAI,yBAAyB,MAAM,UAAU;AAAA,EACnD,UAAU,EAAE,IAAI,yBAAyB,MAAM,UAAU;AAAA,EACzD,QAAQ,EAAE,IAAI,yBAAyB,MAAM,UAAU;AAAA,EACvD,OAAO,EAAE,IAAI,yBAAyB,MAAM,UAAU;AAAA,EACtD,OAAO,EAAE,IAAI,yBAAyB,MAAM,UAAU;AAAA,EACtD,QAAQ,EAAE,IAAI,yBAAyB,MAAM,UAAU;AAAA,EACvD,OAAO,EAAE,IAAI,yBAAyB,MAAM,UAAU;AACxD;AAEA,SAAS,iBAAiB,IAAoB;AAC5C,MAAI,OAAO,KAAM,QAAO;AACxB,MAAI,GAAG,WAAW,SAAS,EAAG,QAAO;AACrC,MAAI,OAAO,WAAW,OAAO,aAAa,OAAO,UAAU,OAAO,WAAW,OAAO,aAAa,OAAO,SAAU,QAAO;AACzH,MAAI,OAAO,iBAAiB,OAAO,mBAAmB,OAAO;AAC3D,WAAO;AACT,MAAI,OAAO,WAAW,OAAO,WAAW,OAAO,QAAS,QAAO;AAC/D,MAAI,GAAG,WAAW,OAAO,KAAK,GAAG,WAAW,YAAY,EAAG,QAAO;AAClE,SAAO;AACT;AAIA,IAAM,oBAAoB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAuB1B,SAAS,gBACP,QACiB;AACjB,QAAM,sBAAsB,CAC1B,eACG;AACH,WAAO,OAAO,MAAM;AAClB,YAAM,YAAYC,eAAc;AAChC,UAAI,CAACC,mBAAkB,SAAS,EAAG;AACnC,YAAM,SAAS,UAAU,OAAO,QAAQ;AAGxC,UAAI,QAAuC;AAC3C,aAAO,MAAM,UAAU,KAAK,CAACC,aAAY,MAAM,UAAU,CAAC,GAAG;AAC3D,gBAAQ,MAAM,UAAU;AAAA,MAC1B;AAGA,UAAI,kBAAkB,UAAU;AAC9B,eAAO,OAAO;AAAA,MAChB;AAEA,YAAM,UAAU,WAAW;AAC3B,UAAIA,aAAY,KAAK,GAAG;AACtB,QAAAC,UAAS,EAAE,OAAO,OAAO;AAAA,MAC3B,WACE,qBAAqB,SACrB,OAAO,MAAM,oBAAoB,cAChC,MAAM,gBAAiC,MAAM,GAC9C;AACA,cAAM,QAAQ,OAAO;AAAA,MACvB,OAAO;AACL,cAAM,YAAY,OAAO;AAAA,MAC3B;AACA,cAAQ,UAAU;AAAA,IACpB,CAAC;AAAA,EACH;AAEA,SAAO;AAAA,IACL;AAAA,MACE,IAAI;AAAA,MACJ,OAAO;AAAA,MACP,aAAa;AAAA,MACb,MAAM;AAAA,MACN,UAAU,MAAM;AAEd,eAAO,OAAO,MAAM;AAClB,gBAAM,YAAYH,eAAc;AAChC,cAAI,CAACC,mBAAkB,SAAS,EAAG;AACnC,gBAAM,SAAS,UAAU,OAAO,QAAQ;AACxC,cAAI,kBAAkB,UAAU;AAC9B,mBAAO,OAAO;AAAA,UAChB;AAAA,QACF,CAAC;AAED,eAAO,gBAAgB,wBAAwB,MAAS;AAAA,MAC1D;AAAA,IACF;AAAA,IACA;AAAA,MACE,IAAI;AAAA,MACJ,OAAO;AAAA,MACP,aAAa;AAAA,MACb,UAAU,CAAC,IAAI;AAAA,MACf,MAAM;AAAA,MACN,UAAU,MAAM,oBAAoB,MAAMG,oBAAmB,IAAI,CAAC;AAAA,IACpE;AAAA,IACA;AAAA,MACE,IAAI;AAAA,MACJ,OAAO;AAAA,MACP,aAAa;AAAA,MACb,UAAU,CAAC,IAAI;AAAA,MACf,MAAM;AAAA,MACN,UAAU,MAAM,oBAAoB,MAAMA,oBAAmB,IAAI,CAAC;AAAA,IACpE;AAAA,IACA;AAAA,MACE,IAAI;AAAA,MACJ,OAAO;AAAA,MACP,aAAa;AAAA,MACb,UAAU,CAAC,IAAI;AAAA,MACf,MAAM;AAAA,MACN,UAAU,MAAM,oBAAoB,MAAMA,oBAAmB,IAAI,CAAC;AAAA,IACpE;AAAA,IACA;AAAA,MACE,IAAI;AAAA,MACJ,OAAO;AAAA,MACP,aAAa;AAAA,MACb,MAAM;AAAA,MACN,UAAU,MAAM,oBAAoB,MAAMC,kBAAiB,CAAC;AAAA,IAC9D;AAAA,IACA;AAAA,MACE,IAAI;AAAA,MACJ,OAAO;AAAA,MACP,aAAa;AAAA,MACb,MAAM;AAAA,MACN,UAAU,MACR,oBAAoB,MAAM;AACxB,cAAM,OAAOC,iBAAgB,QAAQ;AACrC,cAAM,OAAOC,qBAAoB;AACjC,aAAK,OAAO,IAAI;AAChB,eAAO;AAAA,MACT,CAAC;AAAA,IACL;AAAA,IACA;AAAA,MACE,IAAI;AAAA,MACJ,OAAO;AAAA,MACP,aAAa;AAAA,MACb,MAAM;AAAA,MACN,UAAU,MACR,oBAAoB,MAAM;AACxB,cAAM,OAAOD,iBAAgB,QAAQ;AACrC,cAAM,OAAOC,qBAAoB;AACjC,aAAK,OAAO,IAAI;AAChB,eAAO;AAAA,MACT,CAAC;AAAA,IACL;AAAA,IACA;AAAA,MACE,IAAI;AAAA,MACJ,OAAO;AAAA,MACP,aAAa;AAAA,MACb,UAAU,CAAC,QAAQ,QAAQ,YAAY,OAAO;AAAA,MAC9C,MAAM;AAAA,MACN,UAAU,MACR,oBAAoB,MAAM;AACxB,cAAM,OAAOD,iBAAgB,OAAO;AACpC,cAAM,OAAOC,qBAAoB;AACjC,aAAK,OAAO,IAAI;AAChB,eAAO;AAAA,MACT,CAAC;AAAA,IACL;AAAA,IACA;AAAA,MACE,IAAI;AAAA,MACJ,OAAO;AAAA,MACP,aAAa;AAAA,MACb,MAAM;AAAA,MACN,UAAU,MAAM;AACd,eAAO,OAAO,MAAM;AAClB,gBAAM,YAAYP,eAAc;AAChC,cAAI,CAACC,mBAAkB,SAAS,EAAG;AACnC,gBAAM,SAAS,UAAU,OAAO,QAAQ;AAExC,cAAI,QAAuC;AAC3C,iBAAO,MAAM,UAAU,KAAK,CAACC,aAAY,MAAM,UAAU,CAAC,GAAG;AAC3D,oBAAQ,MAAM,UAAU;AAAA,UAC1B;AAEA,cAAI,kBAAkB,UAAU;AAC9B,mBAAO,OAAO;AAAA,UAChB;AAEA,gBAAM,OAAO,0BAA0B;AACvC,gBAAM,oBAAoBM,sBAAqB;AAE/C,cAAIN,aAAY,KAAK,GAAG;AACtB,kBAAM,OAAOC,UAAS;AACtB,iBAAK,OAAO,IAAI;AAChB,iBAAK,OAAO,iBAAiB;AAAA,UAC/B,WACE,qBAAqB,SACrB,OAAO,MAAM,oBAAoB,cAChC,MAAM,gBAAiC,MAAM,GAC9C;AACA,kBAAM,QAAQ,IAAI;AAClB,iBAAK,YAAY,iBAAiB;AAAA,UACpC,OAAO;AACL,kBAAM,YAAY,IAAI;AACtB,iBAAK,YAAY,iBAAiB;AAAA,UACpC;AACA,4BAAkB,UAAU;AAAA,QAC9B,CAAC;AAAA,MACH;AAAA,IACF;AAAA,IACA;AAAA,MACE,IAAI;AAAA,MACJ,OAAO;AAAA,MACP,aAAa;AAAA,MACb,MAAM;AAAA,MACN,UAAU,MAAM;AACd,eAAO,OAAO,MAAM;AAClB,gBAAM,YAAYH,eAAc;AAChC,cAAI,CAACC,mBAAkB,SAAS,EAAG;AACnC,gBAAM,SAAS,UAAU,OAAO,QAAQ;AAExC,cAAI,QAAuC;AAC3C,iBAAO,MAAM,UAAU,KAAK,CAACC,aAAY,MAAM,UAAU,CAAC,GAAG;AAC3D,oBAAQ,MAAM,UAAU;AAAA,UAC1B;AAEA,cAAI,kBAAkB,UAAU;AAC9B,mBAAO,OAAO;AAAA,UAChB;AAEA,gBAAM,YAAY,qBAAqB,EAAE,MAAM,IAAI,UAAU,cAAc,WAAW,KAAK,CAAC;AAC5F,gBAAM,oBAAoBM,sBAAqB;AAC/C,cAAIN,aAAY,KAAK,GAAG;AACtB,YAAAC,UAAS,EAAE,OAAO,SAAS;AAAA,UAC7B,WACE,qBAAqB,SACrB,OAAO,MAAM,oBAAoB,cAChC,MAAM,gBAAiC,MAAM,GAC9C;AACA,kBAAM,QAAQ,SAAS;AAAA,UACzB,OAAO;AACL,kBAAM,YAAY,SAAS;AAAA,UAC7B;AACA,oBAAU,YAAY,iBAAiB;AACvC,4BAAkB,UAAU;AAAA,QAC9B,CAAC;AAAA,MACH;AAAA,IACF;AAAA,IACA;AAAA,MACE,IAAI;AAAA,MACJ,OAAO;AAAA,MACP,aAAa;AAAA,MACb,MAAM;AAAA,MACN,UAAU,MAAM;AACd,eAAO,OAAO,MAAM;AAClB,gBAAM,YAAYH,eAAc;AAChC,cAAI,CAACC,mBAAkB,SAAS,EAAG;AACnC,gBAAM,SAAS,UAAU,OAAO,QAAQ;AACxC,cAAI,kBAAkB,UAAU;AAC9B,mBAAO,OAAO;AAAA,UAChB;AAAA,QACF,CAAC;AACD,eAAO,gBAAgB,+BAA+B;AAAA,UACpD,MAAM;AAAA,UACN,SAAS;AAAA,QACX,CAAC;AAAA,MACH;AAAA,IACF;AAAA,IACA;AAAA,MACE,IAAI;AAAA,MACJ,OAAO;AAAA,MACP,aAAa;AAAA,MACb,MAAM;AAAA,MACN,UAAU,MAAM;AACd,eAAO,OAAO,MAAM;AAClB,gBAAM,YAAYD,eAAc;AAChC,cAAI,CAACC,mBAAkB,SAAS,EAAG;AACnC,gBAAM,SAAS,UAAU,OAAO,QAAQ;AACxC,cAAI,kBAAkB,UAAU;AAC9B,mBAAO,OAAO;AAAA,UAChB;AAAA,QACF,CAAC;AACD,eAAO,gBAAgB,wBAAwB,CAAC,CAAC;AAAA,MACnD;AAAA,IACF;AAAA,IACA;AAAA,MACE,IAAI;AAAA,MACJ,OAAO;AAAA,MACP,aAAa;AAAA,MACb,MAAM;AAAA,MACN,UAAU,CAAC,UAAU,YAAY,UAAU,aAAa,YAAY,WAAW,MAAM;AAAA,MACrF,UAAU,MAAM;AACd,eAAO,OAAO,MAAM;AAClB,gBAAM,YAAYD,eAAc;AAChC,cAAI,CAACC,mBAAkB,SAAS,EAAG;AACnC,gBAAM,SAAS,UAAU,OAAO,QAAQ;AACxC,cAAI,kBAAkB,UAAU;AAC9B,mBAAO,OAAO;AAAA,UAChB;AAAA,QACF,CAAC;AACD,eAAO,gBAAgB,uBAAuB,CAAC,CAAC;AAAA,MAClD;AAAA,IACF;AAAA,IACA;AAAA,MACE,IAAI;AAAA,MACJ,OAAO;AAAA,MACP,aAAa;AAAA,MACb,MAAM;AAAA,MACN,UAAU,MAAM;AACd,eAAO,OAAO,MAAM;AAClB,gBAAM,YAAYD,eAAc;AAChC,cAAI,CAACC,mBAAkB,SAAS,EAAG;AACnC,gBAAM,SAAS,UAAU,OAAO,QAAQ;AACxC,cAAI,kBAAkB,UAAU;AAC9B,mBAAO,OAAO;AAAA,UAChB;AAAA,QACF,CAAC;AACD,cAAM,QAAQ,SAAS,cAAc,OAAO;AAC5C,cAAM,OAAO;AACb,cAAM,SAAS;AACf,cAAM,WAAW,MAAM;AACrB,gBAAM,OAAO,MAAM,QAAQ,CAAC;AAC5B,cAAI,MAAM;AACR,mBAAO,gBAAgB,sBAAsB,IAAI;AAAA,UACnD;AAAA,QACF;AACA,cAAM,MAAM;AAAA,MACd;AAAA,IACF;AAAA,IACA;AAAA,MACE,IAAI;AAAA,MACJ,OAAO;AAAA,MACP,aAAa;AAAA,MACb,UAAU,CAAC,UAAU,QAAQ,UAAU;AAAA,MACvC,MAAM;AAAA,MACN,UAAU,MAAM;AAEd,eAAO,OAAO,MAAM;AAClB,gBAAM,YAAYD,eAAc;AAChC,cAAI,CAACC,mBAAkB,SAAS,EAAG;AACnC,gBAAM,SAAS,UAAU,OAAO,QAAQ;AACxC,cAAI,kBAAkB,UAAU;AAC9B,mBAAO,OAAO;AAAA,UAChB;AAAA,QACF,CAAC;AACD,eAAO,gBAAgB,2BAA2B,MAAS;AAAA,MAC7D;AAAA,IACF;AAAA,IACA;AAAA,MACE,IAAI;AAAA,MACJ,OAAO;AAAA,MACP,aAAa;AAAA,MACb,UAAU,CAAC,WAAW,SAAS,QAAQ,SAAS,SAAS,MAAM;AAAA,MAC/D,MAAM;AAAA,MACN,UAAU,MAAM;AACd,eAAO,OAAO,MAAM;AAClB,gBAAM,YAAYD,eAAc;AAChC,cAAI,CAACC,mBAAkB,SAAS,EAAG;AACnC,gBAAM,SAAS,UAAU,OAAO,QAAQ;AACxC,cAAI,kBAAkB,UAAU;AAC9B,mBAAO,OAAO;AAAA,UAChB;AAAA,QACF,CAAC;AACD,eAAO,gBAAgB,0BAA0B,MAAS;AAAA,MAC5D;AAAA,IACF;AAAA;AAAA,IAEA,GAAG,sBAAsB,OAAO,CAAC,MAAM,EAAE,UAAU,EAAE,EAAE,IAAI,CAAC,UAAU;AAAA,MACpE,IAAI,QAAQ,KAAK,MAAM,YAAY,CAAC;AAAA,MACpC,OAAO,GAAG,KAAK,KAAK;AAAA,MACpB,aAAa,aAAa,KAAK,MAAM,YAAY,CAAC;AAAA,MAClD,UAAU,CAAC,QAAQ,YAAY,cAAc,KAAK,MAAM,YAAY,CAAC;AAAA,MACrE,MAAM;AAAA,MACN,UAAU,MAAM;AACd,eAAO,OAAO,MAAM;AAClB,gBAAM,YAAYD,eAAc;AAChC,cAAI,CAACC,mBAAkB,SAAS,EAAG;AACnC,gBAAM,SAAS,UAAU,OAAO,QAAQ;AACxC,cAAI,kBAAkB,UAAU;AAC9B,mBAAO,OAAO;AAAA,UAChB;AAGA,gBAAM,UAAUD,eAAc;AAC9B,cAAIC,mBAAkB,OAAO,GAAG;AAC9B,4BAAgB,SAAS,EAAE,eAAe,KAAK,MAAM,CAAC;AAAA,UACxD;AAAA,QACF,CAAC;AAAA,MACH;AAAA,IACF,EAAE;AAAA;AAAA;AAAA,IAGF;AAAA,MACE,IAAI;AAAA,MACJ,OAAO;AAAA,MACP,aAAa;AAAA,MACb,UAAU,CAAC,OAAO,aAAa,WAAW,OAAO;AAAA,MACjD,MAAM;AAAA,MACN,UAAU,MAAM;AACd,eAAO,OAAO,MAAM;AAClB,gBAAM,YAAYD,eAAc;AAChC,cAAI,CAACC,mBAAkB,SAAS,EAAG;AACnC,gBAAM,SAAS,UAAU,OAAO,QAAQ;AAGxC,cAAI,QAAuC;AAC3C,iBAAO,MAAM,UAAU,KAAK,CAACC,aAAY,MAAM,UAAU,CAAC,GAAG;AAC3D,oBAAQ,MAAM,UAAU;AAAA,UAC1B;AAEA,cAAI,kBAAkB,UAAU;AAC9B,mBAAO,OAAO;AAAA,UAChB;AAEA,cAAIO,gBAAe,KAAK,KAAK,CAACP,aAAY,KAAK,GAAG;AAChD,kBAAM,aAAa,KAAK;AAAA,UAC1B;AAAA,QACF,CAAC;AAAA,MACH;AAAA,IACF;AAAA,IACA;AAAA,MACE,IAAI;AAAA,MACJ,OAAO;AAAA,MACP,aAAa;AAAA,MACb,UAAU,CAAC,OAAO,aAAa,UAAU,QAAQ;AAAA,MACjD,MAAM;AAAA,MACN,UAAU,MAAM;AACd,eAAO,OAAO,MAAM;AAClB,gBAAM,YAAYF,eAAc;AAChC,cAAI,CAACC,mBAAkB,SAAS,EAAG;AACnC,gBAAM,SAAS,UAAU,OAAO,QAAQ;AAGxC,cAAI,QAAuC;AAC3C,iBAAO,MAAM,UAAU,KAAK,CAACC,aAAY,MAAM,UAAU,CAAC,GAAG;AAC3D,oBAAQ,MAAM,UAAU;AAAA,UAC1B;AAEA,cAAI,kBAAkB,UAAU;AAC9B,mBAAO,OAAO;AAAA,UAChB;AAEA,cAAIO,gBAAe,KAAK,KAAK,CAACP,aAAY,KAAK,GAAG;AAChD,kBAAM,aAAa,KAAK;AAAA,UAC1B;AAAA,QACF,CAAC;AAAA,MACH;AAAA,IACF;AAAA,EACF;AACF;AAUA,SAAS,WAAW,OAAqC;AACvD,QAAM,UAA2C,CAAC;AAClD,QAAM,iBAAyC;AAAA,IAC7C,IAAI;AAAA,IACJ,UAAU;AAAA,IACV,QAAQ;AAAA,IACR,OAAO;AAAA,IACP,OAAO;AAAA,IACP,QAAQ;AAAA,IACR,OAAO;AAAA,EACT;AACA,QAAM,QAAQ,CAAC,MAAM,YAAY,UAAU,SAAS,SAAS,UAAU,OAAO;AAE9E,aAAW,QAAQ,OAAO;AACxB,UAAM,MAAM,iBAAiB,KAAK,EAAE;AACpC,QAAI,CAAC,QAAQ,GAAG,EAAG,SAAQ,GAAG,IAAI,CAAC;AACnC,YAAQ,GAAG,EAAG,KAAK,IAAI;AAAA,EACzB;AAEA,QAAM,SAAsB,CAAC;AAC7B,aAAW,OAAO,OAAO;AACvB,UAAM,SAAS,QAAQ,GAAG;AAC1B,QAAI,UAAU,OAAO,SAAS,GAAG;AAC/B,aAAO,KAAK;AAAA,QACV,OAAO,eAAe,GAAG,KAAK;AAAA,QAC9B,UAAU;AAAA,QACV,OAAO;AAAA,MACT,CAAC;AAAA,IACH;AAAA,EACF;AACA,SAAO;AACT;AAQO,SAAS,UAAU,EAAE,OAAO,cAAc,GAAmB;AAClE,QAAM,CAAC,MAAM,IAAIQ,4BAA0B;AAC3C,QAAM,CAAC,QAAQ,SAAS,IAAIC,UAAS,KAAK;AAC1C,QAAM,CAAC,UAAU,WAAW,IAAIA,UAAS,EAAE,KAAK,GAAG,MAAM,EAAE,CAAC;AAC5D,QAAM,CAAC,OAAO,QAAQ,IAAIA,UAAS,EAAE;AACrC,QAAM,CAAC,eAAe,gBAAgB,IAAIA,UAAS,CAAC;AACpD,QAAM,UAAUC,QAAuB,IAAI;AAC3C,QAAM,CAAC,iBAAiB,kBAAkB,IAAID;AAAA,IAC5C;AAAA,EACF;AAEA,EAAAE,WAAU,MAAM;AACd,QAAI,OAAO,WAAW,YAAa;AACnC,uBAAmB,SAAS,IAAI;AAAA,EAClC,GAAG,CAAC,CAAC;AAEL,QAAM,eAAe,QAAQ,MAAM,gBAAgB,MAAM,GAAG,CAAC,MAAM,CAAC;AACpE,QAAM,WAAW,gBACb,CAAC,GAAG,cAAc,GAAG,aAAa,IAClC;AAEJ,QAAM,gBAAgB,QAClB,SAAS,OAAO,CAAC,SAAS;AACxB,UAAM,IAAI,MAAM,YAAY;AAC5B,WACE,KAAK,MAAM,YAAY,EAAE,SAAS,CAAC,KACnC,KAAK,YAAY,YAAY,EAAE,SAAS,CAAC,KACzC,KAAK,UAAU,KAAK,CAAC,OAAO,GAAG,YAAY,EAAE,SAAS,CAAC,CAAC,KACxD;AAAA,EAEJ,CAAC,IACD;AAGJ,QAAM,eAAe,WAAW,aAAa;AAC7C,QAAM,YAA6B,CAAC;AACpC,aAAW,SAAS,cAAc;AAChC,eAAW,QAAQ,MAAM,OAAO;AAC9B,gBAAU,KAAK,IAAI;AAAA,IACrB;AAAA,EACF;AAEA,QAAM,QAAQC,aAAY,MAAM;AAC9B,cAAU,KAAK;AACf,aAAS,EAAE;AACX,qBAAiB,CAAC;AAAA,EACpB,GAAG,CAAC,CAAC;AAEL,QAAM,aAAaA;AAAA,IACjB,CAAC,UAAkB;AACjB,YAAM,OAAO,UAAU,KAAK;AAC5B,UAAI,MAAM;AACR,cAAM;AACN,aAAK,SAAS;AAAA,MAChB;AAAA,IACF;AAAA,IACA,CAAC,WAAW,KAAK;AAAA,EACnB;AAGA,EAAAD,WAAU,MAAM;AACd,WAAO,OAAO;AAAA,MACZ;AAAA,MACA,MAAM;AACJ,cAAM,eAAe,OAAO,aAAa;AACzC,YAAI,CAAC,gBAAgB,aAAa,eAAe,EAAG,QAAO;AAE3D,cAAM,QAAQ,aAAa,WAAW,CAAC;AACvC,cAAM,OAAO,MAAM,sBAAsB;AAEzC,oBAAY;AAAA,UACV,KAAK,KAAK,SAAS;AAAA,UACnB,MAAM,KAAK;AAAA,QACb,CAAC;AACD,kBAAU,IAAI;AACd,iBAAS,EAAE;AACX,yBAAiB,CAAC;AAClB,eAAO;AAAA,MACT;AAAA,MACAE;AAAA,IACF;AAAA,EACF,GAAG,CAAC,MAAM,CAAC;AAGX,EAAAF,WAAU,MAAM;AACd,QAAI,CAAC,OAAQ;AAEb,WAAO,OAAO,uBAAuB,CAAC,EAAE,YAAY,MAAM;AACxD,kBAAY,KAAK,MAAM;AACrB,cAAM,YAAYb,eAAc;AAChC,YAAI,CAACC,mBAAkB,SAAS,GAAG;AACjC,gBAAM;AACN;AAAA,QACF;AACA,cAAM,SAAS,UAAU,OAAO,QAAQ;AACxC,YAAI,kBAAkB,UAAU;AAC9B,gBAAM,OAAO,OAAO,eAAe;AACnC,cAAI,KAAK,WAAW,GAAG,GAAG;AACxB,qBAAS,KAAK,MAAM,CAAC,CAAC;AACtB,6BAAiB,CAAC;AAAA,UACpB,WAAW,SAAS,IAAI;AACtB,kBAAM;AAAA,UACR,OAAO;AACL,kBAAM;AAAA,UACR;AAAA,QACF;AAAA,MACF,CAAC;AAAA,IACH,CAAC;AAAA,EACH,GAAG,CAAC,QAAQ,QAAQ,KAAK,CAAC;AAG1B,EAAAY,WAAU,MAAM;AACd,QAAI,CAAC,OAAQ;AAEb,UAAM,kBAAkB,OAAO;AAAA,MAC7B;AAAA,MACA,CAAC,UAAU;AACT,eAAO,eAAe;AACtB,yBAAiB,CAAC,SAAS,KAAK,IAAI,OAAO,GAAG,UAAU,SAAS,CAAC,CAAC;AACnE,eAAO;AAAA,MACT;AAAA,MACAE;AAAA,IACF;AAEA,UAAM,gBAAgB,OAAO;AAAA,MAC3B;AAAA,MACA,CAAC,UAAU;AACT,eAAO,eAAe;AACtB,yBAAiB,CAAC,SAAS,KAAK,IAAI,OAAO,GAAG,CAAC,CAAC;AAChD,eAAO;AAAA,MACT;AAAA,MACAA;AAAA,IACF;AAEA,UAAM,cAAc,OAAO;AAAA,MACzB;AAAA,MACA,CAAC,UAAU;AACT,eAAO,eAAe;AACtB,mBAAW,aAAa;AACxB,eAAO;AAAA,MACT;AAAA,MACAA;AAAA,IACF;AAEA,UAAM,eAAe,OAAO;AAAA,MAC1BC;AAAA,MACA,MAAM;AACJ,cAAM;AACN,eAAO;AAAA,MACT;AAAA,MACAD;AAAA,IACF;AAEA,WAAO,MAAM;AACX,sBAAgB;AAChB,oBAAc;AACd,kBAAY;AACZ,mBAAa;AAAA,IACf;AAAA,EACF,GAAG,CAAC,QAAQ,QAAQ,UAAU,QAAQ,eAAe,YAAY,KAAK,CAAC;AAGvE,EAAAF,WAAU,MAAM;AACd,QAAI,CAAC,UAAU,CAAC,QAAQ,QAAS;AACjC,UAAM,WAAW,QAAQ,QAAQ;AAAA,MAC/B;AAAA,IACF;AACA,QAAI,UAAU;AACZ,eAAS,eAAe,EAAE,OAAO,UAAU,CAAC;AAAA,IAC9C;AAAA,EACF,GAAG,CAAC,QAAQ,aAAa,CAAC;AAE1B,MAAI,CAAC,UAAU,CAAC,gBAAiB,QAAO;AAExC,MAAI,YAAY;AAEhB,SAAOI;AAAA,IACL,gBAAAtB;AAAA,MAAC;AAAA;AAAA,QACC,KAAK;AAAA,QACL,MAAK;AAAA,QACL,cAAW;AAAA,QACX,eAAY;AAAA,QACZ,OAAO;AAAA,UACL,UAAU;AAAA,UACV,QAAQ;AAAA,UACR,OAAO;AAAA,UACP,WAAW;AAAA,UACX,UAAU;AAAA,UACV,cAAc;AAAA,UACd,QAAQ;AAAA,UACR,iBAAiB;AAAA,UACjB,gBAAgB;AAAA,UAChB,sBAAsB;AAAA,UACtB,SAAS;AAAA,UACT,WAAW;AAAA,UACX,KAAK,GAAG,SAAS,GAAG;AAAA,UACpB,MAAM,GAAG,SAAS,IAAI;AAAA,UACtB,YACE;AAAA,UACF,eAAe;AAAA,UACf,WAAW;AAAA,UACX,gBAAgB;AAAA,UAChB,iBAAiB;AAAA,QACnB;AAAA,QAEA;AAAA,0BAAAD,MAAC,WAAO,6BAAkB;AAAA,UAEzB,UAAU,WAAW,IACpB,gBAAAA;AAAA,YAAC;AAAA;AAAA,cACC,OAAO;AAAA,gBACL,SAAS;AAAA,gBACT,UAAU;AAAA,gBACV,OAAO;AAAA,gBACP,WAAW;AAAA,gBACX,YAAY;AAAA,cACd;AAAA,cACD;AAAA;AAAA,UAED,IAEA,aAAa,IAAI,CAAC,OAAO,aACvB,gBAAAC,OAAC,SAEE;AAAA,uBAAW,KACV,gBAAAD;AAAA,cAAC;AAAA;AAAA,gBACC,OAAO;AAAA,kBACL,QAAQ;AAAA,kBACR,iBAAiB;AAAA,kBACjB,QAAQ;AAAA,gBACV;AAAA;AAAA,YACF;AAAA,YAID,CAAC,SACA,gBAAAA;AAAA,cAAC;AAAA;AAAA,gBACC,OAAO;AAAA,kBACL,SAAS;AAAA,kBACT,UAAU;AAAA,kBACV,YAAY;AAAA,kBACZ,OAAO;AAAA,kBACP,eAAe;AAAA,kBACf,eAAe;AAAA,kBACf,YAAY;AAAA,gBACd;AAAA,gBAEC,gBAAM;AAAA;AAAA,YACT;AAAA,YAGD,MAAM,MAAM,IAAI,CAAC,SAAS;AACzB,oBAAM,MAAM;AACZ,oBAAM,WAAW,QAAQ;AACzB,oBAAM,WAAW,iBAAiB,KAAK,EAAE;AACzC,oBAAM,SAAS,gBAAgB,QAAQ,KAAK,gBAAgB;AAC5D,oBAAM,WAAW,eAAe,KAAK,EAAE;AAEvC,qBACE,gBAAAC;AAAA,gBAAC;AAAA;AAAA,kBAEC,MAAK;AAAA,kBACL,MAAK;AAAA,kBACL,iBAAe;AAAA,kBACf,eAAa,mBAAmB,KAAK,EAAE;AAAA,kBACvC,aAAa,CAAC,MAAM;AAClB,sBAAE,eAAe;AACjB,+BAAW,GAAG;AAAA,kBAChB;AAAA,kBACA,cAAc,MAAM,iBAAiB,GAAG;AAAA,kBACxC,OAAO;AAAA,oBACL,SAAS;AAAA,oBACT,OAAO;AAAA,oBACP,YAAY;AAAA,oBACZ,KAAK;AAAA,oBACL,cAAc;AAAA,oBACd,SAAS;AAAA,oBACT,WAAW;AAAA,oBACX,UAAU;AAAA,oBACV,QAAQ;AAAA,oBACR,QAAQ;AAAA,oBACR,iBAAiB,WACb,oCACA;AAAA,oBACJ,OAAO,WACH,4CACA;AAAA,oBACJ,YAAY;AAAA,kBACd;AAAA,kBAGA;AAAA,oCAAAD;AAAA,sBAAC;AAAA;AAAA,wBACC,OAAO;AAAA,0BACL,OAAO;AAAA,0BACP,QAAQ;AAAA,0BACR,SAAS;AAAA,0BACT,YAAY;AAAA,0BACZ,gBAAgB;AAAA,0BAChB,cAAc;AAAA,0BACd,YAAY,WACR,6BACA,OAAO;AAAA,0BACX,YAAY;AAAA,0BACZ,OAAO,WAAW,4CAA4C,OAAO;AAAA,0BACrE,WAAW,WACP,+DACA;AAAA,wBACN;AAAA,wBAEA,0BAAAA,MAAC,KAAK,MAAL,EAAU,MAAM,IAAI;AAAA;AAAA,oBACvB;AAAA,oBAGA,gBAAAA;AAAA,sBAAC;AAAA;AAAA,wBACC,OAAO;AAAA,0BACL,MAAM;AAAA,0BACN,YAAY;AAAA,0BACZ,YAAY;AAAA,0BACZ,YAAY;AAAA,0BACZ,UAAU;AAAA,0BACV,cAAc;AAAA,wBAChB;AAAA,wBAEC,eAAK;AAAA;AAAA,oBACR;AAAA,oBAGC,YACC,gBAAAA;AAAA,sBAAC;AAAA;AAAA,wBACC,OAAO;AAAA,0BACL,UAAU;AAAA,0BACV,YACE;AAAA,0BACF,YAAY;AAAA,0BACZ,OAAO,WACH,iEACA;AAAA,0BACJ,YAAY;AAAA,0BACZ,kBAAkB;AAAA,wBACpB;AAAA,wBAEC;AAAA;AAAA,oBACH;AAAA;AAAA;AAAA,gBAlFG,KAAK;AAAA,cAoFZ;AAAA,YAEJ,CAAC;AAAA,eA5HO,MAAM,KA6HhB,CACD;AAAA;AAAA;AAAA,IAEL;AAAA,IACA;AAAA,EACF;AACF;;;ACt/BA,SAAS,eAAAwB,eAAa,aAAAC,aAAW,UAAAC,SAAQ,YAAAC,iBAAgB;AAGzD,SAAS,6BAAAC,mCAAiC;AAE1C,SAAS,iBAAAC,gBAAe,YAAAC,iBAAgB;AAKxC,SAAS,gBAAAC,qBAAoB;AAG7B,SAAS,2BAA2B;;;ACbpC,SAAS,eAAAC,eAAa,aAAAC,aAAW,UAAAC,eAAc;AAG/C,SAAS,gBAAAC,qBAAoB;AAI7B;AAAA,EACE,wBAAAC;AAAA,EACA,mBAAAC;AAAA,EACA,iBAAAC;AAAA,EACA,kBAAAC;AAAA,OACK;AACP;AAAA,EACE,sBAAAC;AAAA,EACA,kBAAAC;AAAA,EACA,gBAAAC;AAAA,EACA,oBAAAC;AAAA,OACK;AACP;AAAA,EACE,mBAAAC;AAAA,EACA,uBAAAC;AAAA,EACA,eAAAC;AAAA,OACK;AAUP;AAAA,EACE,qBAAAC;AAAA,EACA,gBAAAC;AAAA,EACA,gBAAAC;AAAA,EACA,kBAAAC;AAAA,EACA,cAAAC;AAAA,EACA,mBAAAC;AAAA,EACA,mBAAAC;AAAA,EACA,mBAAAC;AAAA,EACA,kBAAAC;AAAA,EACA,YAAAC;AAAA,EACA,aAAAC;AAAA,EACA,uBAAAC;AAAA,OACK;AAgUD,gBAAAC,OAkBI,QAAAC,cAlBJ;AAtTN,IAAM,kBAAkC;AAAA,EACtC,EAAE,IAAI,aAAa,OAAO,aAAa,MAAMb,mBAAkB;AAAA,EAC/D,EAAE,IAAI,aAAa,OAAO,aAAa,MAAMC,cAAa;AAAA,EAC1D,EAAE,IAAI,aAAa,OAAO,aAAa,MAAMC,cAAa;AAAA,EAC1D,EAAE,IAAI,aAAa,OAAO,aAAa,MAAMC,gBAAe;AAAA,EAC5D,EAAE,IAAI,SAAS,OAAO,SAAS,MAAMC,YAAW;AAAA,EAChD,EAAE,IAAI,eAAe,OAAO,eAAe,MAAMC,iBAAgB;AAAA,EACjE,EAAE,IAAI,iBAAiB,OAAO,iBAAiB,MAAMC,iBAAgB;AAAA,EACrE,EAAE,IAAI,cAAc,OAAO,aAAa,MAAMC,iBAAgB;AAAA,EAC9D,EAAE,IAAI,QAAQ,OAAO,cAAc,MAAMC,gBAAe;AAAA,EACxD,EAAE,IAAI,WAAW,OAAO,WAAW,MAAMC,UAAS;AAAA,EAClD,EAAE,IAAI,UAAU,OAAO,UAAU,MAAME,qBAAoB;AAC7D;AAIA,SAAS,aACP,QACA,UACe;AACf,MAAI,OAAsB;AAC1B,SAAO,KAAK,MAAM;AAChB,UAAM,OAAOG,eAAc,QAAQ;AACnC,QAAI,CAAC,KAAM;AACX,QAAIC,gBAAe,IAAI,GAAG;AACxB,YAAM,MAAM,KAAK,OAAO;AACxB,aAAO,WAAW,IAAI,QAAQ,KAAK,EAAE,CAAC;AAAA,IACxC,WAAWC,cAAa,IAAI,GAAG;AAC7B,aAAO;AAAA,IACT,WAAWC,aAAY,IAAI,GAAG;AAC5B,YAAM,WAAW,KAAK,YAAY;AAClC,UAAI,aAAa,SAAU,QAAO;AAAA,eACzB,aAAa,SAAU,QAAO;AAAA,eAC9B,aAAa,QAAS,QAAO;AAAA,IACxC,WAAW,iBAAiB,IAAI,GAAG;AACjC,aAAO;AAAA,IACT,WAAW,eAAe,IAAI,GAAG;AAC/B,aAAO;AAAA,IACT,WAAW,uBAAuB,IAAI,GAAG;AACvC,aAAO;AAAA,IACT,WAAW,KAAK,QAAQ,MAAM,aAAa;AACzC,aAAO;AAAA,IACT;AAAA,EACF,CAAC;AACD,SAAO;AACT;AAIA,SAAS,aACP,QACA,UACA,YACM;AACN,SAAO,OAAO,MAAM;AAClB,UAAM,OAAOH,eAAc,QAAQ;AACnC,QAAI,CAAC,KAAM;AAGX,UAAM,kBAAqD,CAAC;AAG5D,UAAM,kBAAkB,MAAM;AAC5B,UAAII,gBAAe,IAAI,GAAG;AACxB,cAAM,WAAW,KAAK,YAAY;AAElC,eAAO;AAAA,MACT;AACA,aAAO,CAAC;AAAA,IACV;AAEA,UAAM,qBAAqB,MAAc;AACvC,aAAO,KAAK,eAAe;AAAA,IAC7B;AAGA,UAAM,iBAAiB,CACrB,WACG;AACH,UAAID,aAAY,IAAI,GAAG;AAGrB,cAAM,QAAQ,KAAK,YAAY;AAC/B,YAAI,UAAU;AACd,mBAAW,QAAQ,OAAO;AACxB,cAAIC,gBAAe,IAAI,GAAG;AACxB,gBAAI,SAAS;AACX,oBAAM,WAAW,KAAK,YAAY;AAClC,yBAAW,SAAS,UAAU;AAC5B,uBAAO,OAAO,KAAK;AAAA,cACrB;AACA,wBAAU;AAAA,YACZ,OAAO;AAGL,oBAAM,IAAIC,sBAAqB;AAC/B,oBAAM,WAAW,KAAK,YAAY;AAClC,yBAAW,SAAS,UAAU;AAC5B,kBAAE,OAAO,KAAK;AAAA,cAChB;AACA,8BAAgB,KAAK,CAAC;AAAA,YACxB;AAAA,UACF;AAAA,QACF;AAAA,MACF,WAAWD,gBAAe,IAAI,GAAG;AAC/B,cAAM,WAAW,KAAK,YAAY;AAClC,mBAAW,SAAS,UAAU;AAC5B,iBAAO,OAAO,KAAK;AAAA,QACrB;AAAA,MACF,OAAO;AAEL,eAAO,OAAOE,iBAAgB,mBAAmB,CAAC,CAAC;AAAA,MACrD;AAAA,IACF;AAGA,UAAM,aAAa,CACjB,aACG;AACH,YAAM,OAAOC,iBAAgB,QAAQ;AACrC,YAAM,OAAOC,qBAAoB;AACjC,UAAIL,aAAY,IAAI,GAAG;AAErB,cAAM,QAAQ,KAAK,YAAY;AAC/B,mBAAW,gBAAgB,OAAO;AAChC,eAAK,OAAO,YAAY;AAAA,QAC1B;AAAA,MACF,OAAO;AACL,uBAAe,IAAI;AACnB,aAAK,OAAO,IAAI;AAAA,MAClB;AACA,aAAO;AAAA,IACT;AAEA,QAAI,UAAgD;AAEpD,YAAQ,YAAY;AAAA,MAClB,KAAK,aAAa;AAChB,cAAM,IAAIE,sBAAqB;AAC/B,uBAAe,CAAC;AAChB,kBAAU;AACV;AAAA,MACF;AAAA,MACA,KAAK,aAAa;AAChB,cAAM,IAAII,oBAAmB,IAAI;AACjC,uBAAe,CAAC;AAChB,kBAAU;AACV;AAAA,MACF;AAAA,MACA,KAAK,aAAa;AAChB,cAAM,IAAIA,oBAAmB,IAAI;AACjC,uBAAe,CAAC;AAChB,kBAAU;AACV;AAAA,MACF;AAAA,MACA,KAAK,aAAa;AAChB,cAAM,IAAIA,oBAAmB,IAAI;AACjC,uBAAe,CAAC;AAChB,kBAAU;AACV;AAAA,MACF;AAAA,MACA,KAAK,SAAS;AACZ,cAAM,IAAIC,kBAAiB;AAC3B,uBAAe,CAAC;AAChB,kBAAU;AACV;AAAA,MACF;AAAA,MACA,KAAK,eAAe;AAClB,kBAAU,WAAW,QAAQ;AAC7B;AAAA,MACF;AAAA,MACA,KAAK,iBAAiB;AACpB,kBAAU,WAAW,QAAQ;AAC7B;AAAA,MACF;AAAA,MACA,KAAK,cAAc;AACjB,kBAAU,WAAW,OAAO;AAC5B;AAAA,MACF;AAAA,MACA,KAAK,QAAQ;AACX,cAAM,OAAO,mBAAmB;AAChC,cAAM,YAAY,qBAAqB;AAAA,UACrC,MAAM;AAAA,UACN,UAAU;AAAA,QACZ,CAAC;AACD,cAAM,WAAWL,sBAAqB;AACtC,aAAK,QAAQ,SAAS;AACtB,kBAAU,YAAY,QAAQ;AAC9B,iBAAS,UAAU;AACnB;AAAA,MACF;AAAA,MACA,KAAK,WAAW;AACd,cAAM,UAAU,mBAAmB;AACnC,uBAAe,OAAO;AACtB,kBAAU;AACV;AAAA,MACF;AAAA,MACA,KAAK,UAAU;AACb,cAAM,YAAY,2BAA2B,EAAE,MAAM,KAAK,CAAC;AAC3D,cAAM,QAAQ,uBAAuB;AACrC,cAAM,UAAU,yBAAyB;AACzC,uBAAe,OAAO;AACtB,kBAAU,OAAO,OAAO,OAAO;AAC/B,kBAAU;AACV;AAAA,MACF;AAAA,IACF;AAEA,QAAI,SAAS;AACX,WAAK,QAAQ,OAAO;AAEpB,UAAI,cAA6C;AACjD,iBAAW,KAAK,iBAAiB;AAC/B,oBAAY,YAAY,CAAC;AACzB,sBAAc;AAAA,MAChB;AACA,UAAID,gBAAe,OAAO,GAAG;AAC3B,gBAAQ,UAAU;AAAA,MACpB;AAAA,IACF;AAAA,EACF,CAAC;AACH;AAWO,SAAS,aAAa;AAAA,EAC3B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAAsB;AACpB,QAAM,eAAeO,QAAuB,IAAI;AAChD,QAAM,cAAc,aAAa,QAAQ,QAAQ;AAGjD,EAAAC,YAAU,MAAM;AACd,UAAM,qBAAqB,CAAC,MAAkB;AAC5C,UACE,aAAa,WACb,CAAC,aAAa,QAAQ,SAAS,EAAE,MAAc,GAC/C;AACA,gBAAQ;AAAA,MACV;AAAA,IACF;AACA,UAAM,MAAM,sBAAsB,MAAM;AACtC,eAAS,iBAAiB,aAAa,kBAAkB;AAAA,IAC3D,CAAC;AACD,WAAO,MAAM;AACX,2BAAqB,GAAG;AACxB,eAAS,oBAAoB,aAAa,kBAAkB;AAAA,IAC9D;AAAA,EACF,GAAG,CAAC,OAAO,CAAC;AAGZ,EAAAA,YAAU,MAAM;AACd,UAAM,gBAAgB,CAAC,MAAqB;AAC1C,UAAI,EAAE,QAAQ,UAAU;AACtB,UAAE,eAAe;AACjB,gBAAQ;AAAA,MACV;AAAA,IACF;AACA,aAAS,iBAAiB,WAAW,aAAa;AAClD,WAAO,MAAM,SAAS,oBAAoB,WAAW,aAAa;AAAA,EACpE,GAAG,CAAC,OAAO,CAAC;AAEZ,QAAM,eAAeC;AAAA,IACnB,CAAC,WAAmB;AAClB,UAAI,WAAW,aAAa;AAC1B,gBAAQ;AACR;AAAA,MACF;AACA,mBAAa,QAAQ,UAAU,MAAM;AACrC,cAAQ;AAAA,IACV;AAAA,IACA,CAAC,QAAQ,UAAU,aAAa,OAAO;AAAA,EACzC;AAEA,SAAOC;AAAA,IACL,gBAAAf;AAAA,MAAC;AAAA;AAAA,QACC,KAAK;AAAA,QACL,eAAY;AAAA,QACZ,OAAO;AAAA,UACL,UAAU;AAAA,UACV,KAAK,GAAG,SAAS,GAAG;AAAA,UACpB,MAAM,GAAG,SAAS,IAAI;AAAA,UACtB,QAAQ;AAAA,UACR,SAAS;AAAA,UACT,eAAe;AAAA,UACf,SAAS;AAAA,UACT,cAAc;AAAA,UACd,QAAQ;AAAA,UACR,iBAAiB;AAAA,UACjB,gBAAgB;AAAA,UAChB,sBAAsB;AAAA,UACtB,WAAW;AAAA,UACX,YAAY;AAAA,UACZ,UAAU;AAAA,UACV,WAAW;AAAA,UACX,WAAW;AAAA,UACX,WAAW;AAAA,QACb;AAAA,QAGA;AAAA,0BAAAD;AAAA,YAAC;AAAA;AAAA,cACC,OAAO;AAAA,gBACL,UAAU;AAAA,gBACV,YAAY;AAAA,gBACZ,eAAe;AAAA,gBACf,eAAe;AAAA,gBACf,OAAO;AAAA,gBACP,SAAS;AAAA,cACX;AAAA,cACD;AAAA;AAAA,UAED;AAAA,UAEC,gBAAgB,IAAI,CAAC,SAAS;AAC7B,kBAAM,WAAW,KAAK,OAAO;AAC7B,kBAAM,OAAO,KAAK;AAElB,mBACE,gBAAAC;AAAA,cAAC;AAAA;AAAA,gBAEC,MAAK;AAAA,gBACL,SAAS,MAAM,aAAa,KAAK,EAAE;AAAA,gBACnC,OAAO;AAAA,kBACL,SAAS;AAAA,kBACT,YAAY;AAAA,kBACZ,KAAK;AAAA,kBACL,OAAO;AAAA,kBACP,SAAS;AAAA,kBACT,cAAc;AAAA,kBACd,QAAQ;AAAA,kBACR,QAAQ;AAAA,kBACR,iBAAiB,WACb,mCACA;AAAA,kBACJ,OAAO;AAAA,kBACP,UAAU;AAAA,kBACV,YAAY;AAAA,kBACZ,WAAW;AAAA,kBACX,YAAY;AAAA,gBACd;AAAA,gBACA,cAAc,CAAC,MAAM;AACnB,sBAAI,CAAC,UAAU;AACb,sBAAE,cAAc,MAAM,kBACpB;AAAA,kBACJ;AAAA,gBACF;AAAA,gBACA,cAAc,CAAC,MAAM;AACnB,oBAAE,cAAc,MAAM,kBAAkB,WACpC,mCACA;AAAA,gBACN;AAAA,gBAEA;AAAA,kCAAAD,MAAC,QAAK,MAAM,IAAI,QAAO,WAAU;AAAA,kBACjC,gBAAAA,MAAC,UAAK,OAAO,EAAE,MAAM,EAAE,GAAI,eAAK,OAAM;AAAA,kBACrC,YACC,gBAAAA;AAAA,oBAACF;AAAA,oBAAA;AAAA,sBACC,MAAM;AAAA,sBACN,QAAO;AAAA,sBACP,OAAO,EAAE,OAAO,kCAAkC;AAAA;AAAA,kBACpD;AAAA;AAAA;AAAA,cAxCG,KAAK;AAAA,YA0CZ;AAAA,UAEJ,CAAC;AAAA,UAED,gBAAAE;AAAA,YAAC;AAAA;AAAA,cACC,yBAAyB;AAAA,gBACvB,QAAQ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,cAYV;AAAA;AAAA,UACF;AAAA;AAAA;AAAA,IACF;AAAA,IACA,SAAS;AAAA,EACX;AACF;;;ADoEQ,qBAAAiB,WAyBI,OAAAC,OAzBJ,QAAAC,cAAA;AAreR,SAAS,aACP,MACA,MACA,SACW;AACX,MAAI,MAA4B;AAChC,MAAI,SAAS;AACX,UAAM,IAAI,QAAQ,aAAa,KAAK,KAAK,QAAQ;AACjD,QAAI,MAAM,OAAO;AACf,YAAM;AAAA,IACR,WAAW,MAAM,OAAO;AACtB,YAAM;AAAA,IACR,OAAO;AAGL,YAAM,WAAW,iBAAiB,OAAO,EAAE;AAC3C,UAAI,aAAa,MAAO,OAAM;AAAA,eACrB,aAAa,MAAO,OAAM;AAAA,IACrC;AAAA,EACF;AACA,SAAO;AAAA,IACL,KAAK,KAAK,OAAO;AAAA,IACjB,KAAK,KAAK;AAAA,IACV,MAAM,KAAK;AAAA,IACX,OAAO,KAAK;AAAA,IACZ,iBAAiB,KAAK,MAAM;AAAA,IAC5B,WAAW;AAAA,EACb;AACF;AAMA,SAAS,0BACP,SACA,eACA,QACkB;AAClB,MAAI,CAAC,uBAAuB,aAAa,EAAG,QAAO;AAEnD,aAAW,OAAO,cAAc,YAAY,GAAG;AAC7C,QAAI,CAAC,qBAAqB,GAAG,EAAG;AAEhC,UAAM,YAAY,OAAO,gBAAgB,IAAI,OAAO,CAAC;AACrD,QAAI,CAAC,UAAW;AAChB,UAAM,cAAc,UAAU,sBAAsB;AACpD,QAAI,UAAU,YAAY,MAAM,KAAK,UAAU,YAAY,SAAS;AAClE;AAEF,UAAM,WAAW,IAAI,YAAY;AAEjC,QAAI,SAAS,WAAW,GAAG;AACzB,aAAO,aAAa,KAAK,aAAa,SAAS;AAAA,IACjD;AAEA,QAAI,cAAc;AAClB,QAAI,QAA0B;AAE9B,eAAW,gBAAgB,UAAU;AACnC,YAAM,KAAK,OAAO,gBAAgB,aAAa,OAAO,CAAC;AACvD,UAAI,CAAC,GAAI;AAET,YAAM,OAAO,GAAG,sBAAsB;AAEtC,UAAI,WAAW,KAAK,MAAM,KAAK,WAAW,KAAK,SAAS,GAAG;AACzD,eAAO,aAAa,cAAc,MAAM,EAAE;AAAA,MAC5C;AAEA,YAAM,OAAO,KAAK;AAAA,QAChB,KAAK,IAAI,UAAU,KAAK,GAAG;AAAA,QAC3B,KAAK,IAAI,UAAU,KAAK,MAAM;AAAA,MAChC;AACA,UAAI,OAAO,aAAa;AACtB,sBAAc;AACd,gBAAQ,aAAa,cAAc,MAAM,EAAE;AAAA,MAC7C;AAAA,IACF;AAEA,QAAI,MAAO,QAAO;AAElB,UAAM,aAAa,SAAS,CAAC;AAC7B,UAAM,eAAe,OAAO,gBAAgB,WAAW,OAAO,CAAC;AAC/D,QAAI;AACF,aAAO,aAAa,YAAY,aAAa,sBAAsB,GAAG,YAAY;AAEpF,WAAO,aAAa,KAAK,aAAa,SAAS;AAAA,EACjD;AAEA,SAAO;AACT;AAMA,SAAS,aACP,SACA,QACkB;AAClB,MAAI,SAA2B;AAE/B,SAAO,KAAK,MAAM;AAChB,UAAM,OAAOC,UAAS;AACtB,UAAM,WAAW,KAAK,YAAY;AAClC,QAAI,cAAc;AAElB,eAAW,SAAS,UAAU;AAC5B,YAAM,KAAK,OAAO,gBAAgB,MAAM,OAAO,CAAC;AAChD,UAAI,CAAC,GAAI;AAET,YAAM,OAAO,GAAG,sBAAsB;AAEtC,UACE,uBAAuB,KAAK,KAC5B,MAAM,QAAQ,KACd,WAAW,KAAK,MAAM,KACtB,WAAW,KAAK,SAAS,GACzB;AACA,cAAM,aAAa;AAAA,UACjB;AAAA,UACA;AAAA,UACA;AAAA,QACF;AACA,YAAI,YAAY;AACd,mBAAS;AACT;AAAA,QACF;AAAA,MACF;AAEA,UAAI,WAAW,KAAK,MAAM,KAAK,WAAW,KAAK,SAAS,GAAG;AACzD,iBAAS,aAAa,OAAO,MAAM,EAAE;AACrC;AAAA,MACF;AAEA,YAAM,OAAO,KAAK;AAAA,QAChB,KAAK,IAAI,UAAU,KAAK,GAAG;AAAA,QAC3B,KAAK,IAAI,UAAU,KAAK,MAAM;AAAA,MAChC;AACA,UAAI,OAAO,aAAa;AACtB,sBAAc;AACd,iBAAS,aAAa,OAAO,MAAM,EAAE;AAAA,MACvC;AAAA,IACF;AAAA,EACF,CAAC;AAED,SAAO;AACT;AAMO,SAAS,cAAc,EAAE,UAAU,GAAuB;AAC/D,QAAM,CAAC,MAAM,IAAIC,4BAA0B;AAC3C,QAAM,CAAC,eAAe,gBAAgB,IAAIC,UAAyB,IAAI;AACvE,QAAM,CAAC,iBAAiB,kBAAkB,IAAIA;AAAA,IAC5C;AAAA,EACF;AAGA,QAAM,YAAYC,QAAuB,IAAI;AAC7C,QAAM,gBAAgBA,QAAsB,IAAI;AAChD,QAAM,uBAAuBA,QAAO,KAAK;AACzC,QAAM,mBAAmBA,QAAO,KAAK;AAGrC,QAAM,gBAAgBA,QAAO,KAAK;AAClC,QAAM,mBAAmBA,QAAsB,IAAI;AACnD,QAAM,kBAAkBA,QAA2B,OAAO;AAC1D,QAAM,mBAAmBA,QAAsB,IAAI;AACnD,QAAM,eAAeA,QAAuB,IAAI;AAGhD,QAAM,mBAAmBA,QAAO,CAAC;AACjC,QAAM,kBAAkBA,QAAO,EAAE,GAAG,GAAG,GAAG,EAAE,CAAC;AAG7C,QAAM,WAAWA,QAAO,CAAC;AAGzB,QAAM,CAAC,WAAW,YAAY,IAAID,UAIxB,IAAI;AAGd,EAAAE,YAAU,MAAM;AACd,QAAI,OAAO,WAAW,YAAa;AACnC,UAAM,UACJ,OAAO,WAAW,mBAAmB,EAAE,WACvC,UAAU,iBAAiB,KAC3B,kBAAkB;AACpB,qBAAiB,OAAO;AAAA,EAC1B,GAAG,CAAC,CAAC;AAGL,EAAAA,YAAU,MAAM;AACd,QAAI,OAAO,WAAW,YAAa;AACnC,uBAAmB,SAAS,IAAI;AAAA,EAClC,GAAG,CAAC,CAAC;AAEL,QAAM,aAAaC;AAAA,IACjB,CAAC,iBAAyB,MAAc,OAAe,cAAoC;AACzF,UAAI,CAAC,UAAU,QAAS;AACxB,gBAAU,QAAQ,MAAM,MAAM,GAAG,kBAAkB,EAAE;AACrD,UAAI,cAAc,OAAO;AACvB,kBAAU,QAAQ,MAAM,OAAO,GAAG,OAAO,QAAQ,CAAC;AAAA,MACpD,OAAO;AACL,kBAAU,QAAQ,MAAM,OAAO,GAAG,OAAO,EAAE;AAAA,MAC7C;AACA,gBAAU,QAAQ,MAAM,aAAa;AACrC,uBAAiB,UAAU;AAAA,IAC7B;AAAA,IACA,CAAC;AAAA,EACH;AAEA,QAAM,aAAaA,cAAY,MAAM;AACnC,QAAI,CAAC,UAAU,QAAS;AACxB,cAAU,QAAQ,MAAM,aAAa;AACrC,qBAAiB,UAAU;AAC3B,kBAAc,UAAU;AAAA,EAC1B,GAAG,CAAC,CAAC;AAEL,QAAM,gBAAgBA;AAAA,IACpB,CAAC,KAAa,MAAc,UAAkB;AAC5C,UAAI,CAAC,aAAa,QAAS;AAC3B,mBAAa,QAAQ,MAAM,MAAM,GAAG,MAAM,CAAC;AAC3C,mBAAa,QAAQ,MAAM,OAAO,GAAG,IAAI;AACzC,mBAAa,QAAQ,MAAM,QAAQ,GAAG,KAAK;AAC3C,mBAAa,QAAQ,MAAM,aAAa;AAAA,IAC1C;AAAA,IACA,CAAC;AAAA,EACH;AAEA,QAAM,gBAAgBA,cAAY,MAAM;AACtC,QAAI,CAAC,aAAa,QAAS;AAC3B,iBAAa,QAAQ,MAAM,aAAa;AAAA,EAC1C,GAAG,CAAC,CAAC;AAGL,EAAAD,YAAU,MAAM;AACd,QAAI,kBAAkB,QAAQ,cAAe;AAE7C,QAAI,cAAc;AAClB,QAAI,cAAc;AAElB,UAAM,uBAAuB,MAAM;AACjC,eAAS,UAAU;AAEnB,UAAI,cAAc,QAAS;AAE3B,YAAM,cAAc,OAAO,eAAe;AAC1C,UAAI,CAAC,YAAa;AAElB,YAAM,iBAAiB,YAAY;AAAA,QACjC;AAAA,MACF;AACA,UAAI,CAAC,eAAgB;AAErB,YAAM,cAAc,eAAe,sBAAsB;AACzD,YAAM,SAAS;AAEf,YAAM,eACJ,eAAe,YAAY,OAC3B,eAAe,YAAY,UAC3B,eAAe,YAAY,OAAO,UAClC,eAAe,YAAY,QAAQ;AAErC,UAAI,CAAC,gBAAgB,CAAC,qBAAqB,SAAS;AAClD,mBAAW;AACX;AAAA,MACF;AAEA,YAAM,QAAQ,aAAa,aAAa,MAAM;AAC9C,UAAI,CAAC,OAAO;AACV,YAAI,CAAC,qBAAqB,SAAS;AACjC,qBAAW;AAAA,QACb;AACA;AAAA,MACF;AAEA,oBAAc,UAAU,MAAM;AAC9B,iBAAW,MAAM,iBAAiB,MAAM,MAAM,MAAM,OAAO,MAAM,SAAS;AAAA,IAC5E;AAEA,UAAM,cAAc,CAAC,MAAkB;AACrC,oBAAc,EAAE;AAChB,oBAAc,EAAE;AAEhB,UAAI,cAAc,QAAS;AAG3B,UAAI,SAAS,YAAY,GAAG;AAC1B,iBAAS,UAAU,sBAAsB,oBAAoB;AAAA,MAC/D;AAAA,IACF;AAEA,aAAS,iBAAiB,aAAa,WAAW;AAClD,WAAO,MAAM;AACX,eAAS,oBAAoB,aAAa,WAAW;AACrD,UAAI,SAAS,SAAS;AACpB,6BAAqB,SAAS,OAAO;AACrC,iBAAS,UAAU;AAAA,MACrB;AAAA,IACF;AAAA,EACF,GAAG,CAAC,QAAQ,eAAe,YAAY,UAAU,CAAC;AAGlD,EAAAA,YAAU,MAAM;AACd,UAAM,SAAS,UAAU;AACzB,QAAI,CAAC,UAAU,cAAe;AAE9B,UAAM,UAAU,MAAM;AACpB,2BAAqB,UAAU;AAC/B,aAAO,MAAM,UAAU;AAAA,IACzB;AAEA,UAAM,UAAU,MAAM;AACpB,2BAAqB,UAAU;AAC/B,UAAI,CAAC,cAAc,SAAS;AAC1B,eAAO,MAAM,UAAU;AAAA,MACzB;AAAA,IACF;AAEA,UAAM,cAAc,CAAC,MAAkB;AACrC,QAAE,eAAe;AACjB,QAAE,gBAAgB;AAElB,YAAM,MAAM,cAAc;AAC1B,UAAI,CAAC,IAAK;AAEV,uBAAiB,UAAU,KAAK,IAAI;AACpC,sBAAgB,UAAU,EAAE,GAAG,EAAE,SAAS,GAAG,EAAE,QAAQ;AAEvD,uBAAiB,UAAU;AAC3B,UAAI,WAAW;AACf,UAAI,YAAY;AAChB,UAAI,mBAAsC;AAE1C,YAAM,kBAAkB,MAAM;AAC5B,oBAAY;AACZ,cAAM,YAAY;AAClB,YAAI,CAAC,UAAW;AAEhB,cAAM,SAAS,aAAa,UAAU,SAAS,MAAM;AACrD,YAAI,CAAC,UAAU,OAAO,QAAQ,iBAAiB,SAAS;AACtD,wBAAc;AACd,2BAAiB,UAAU;AAC3B;AAAA,QACF;AAEA,cAAM,KAAK,OAAO,gBAAgB,OAAO,GAAG;AAC5C,YAAI,CAAC,GAAI;AACT,cAAM,OAAO,GAAG,sBAAsB;AACtC,cAAM,OAAO,KAAK,MAAM,KAAK,SAAS;AACtC,cAAM,WAAW,UAAU,UAAU;AAErC,wBAAgB,UAAU,WAAW,WAAW;AAChD,yBAAiB,UAAU,OAAO;AAElC;AAAA,UACE,WAAW,KAAK,MAAM,KAAK;AAAA,UAC3B,KAAK;AAAA,UACL,KAAK;AAAA,QACP;AAAA,MACF;AAEA,YAAM,aAAa,CAAC,cAA0B;AAC5C,cAAM,KAAK,UAAU,UAAU,gBAAgB,QAAQ;AACvD,cAAM,KAAK,UAAU,UAAU,gBAAgB,QAAQ;AACvD,cAAM,OAAO,KAAK,KAAK,KAAK,KAAK,KAAK,EAAE;AAExC,YAAI,CAAC,YAAY,OAAO,EAAG;AAC3B,mBAAW;AAEX,YAAI,CAAC,cAAc,SAAS;AAC1B,wBAAc,UAAU;AACxB,iBAAO,MAAM,UAAU;AACvB,iBAAO,MAAM,SAAS;AAAA,QACxB;AAEA,2BAAmB;AACnB,YAAI,cAAc,GAAG;AACnB,sBAAY,sBAAsB,eAAe;AAAA,QACnD;AAAA,MACF;AAEA,YAAM,YAAY,MAAM;AACtB,iBAAS,oBAAoB,aAAa,UAAU;AACpD,iBAAS,oBAAoB,WAAW,SAAS;AACjD,YAAI,WAAW;AACb,+BAAqB,SAAS;AAAA,QAChC;AAEA,YAAI,CAAC,UAAU;AACb,wBAAc,UAAU;AACxB,gBAAM,WAAW,iBAAiB;AAClC,cAAI,YAAY,UAAU,SAAS;AACjC,kBAAM,aAAa,UAAU,QAAQ,sBAAsB;AAC3D,yBAAa;AAAA,cACX,MAAM;AAAA,cACN;AAAA,cACA,UAAU;AAAA,gBACR,KAAK,WAAW,SAAS;AAAA,gBACzB,MAAM,WAAW;AAAA,cACnB;AAAA,YACF,CAAC;AAAA,UACH;AACA,2BAAiB,UAAU;AAC3B;AAAA,QACF;AAEA,sBAAc,UAAU;AACxB,sBAAc;AAEd,eAAO,MAAM,UAAU;AACvB,eAAO,MAAM,SAAS;AAEtB,cAAM,YAAY,iBAAiB;AACnC,cAAM,YAAY,iBAAiB;AACnC,cAAM,WAAW,gBAAgB;AAEjC,YAAI,aAAa,aAAa,cAAc,WAAW;AACrD,iBAAO,OAAO,MAAM;AAClB,kBAAM,aAAaE,eAAc,SAAS;AAC1C,kBAAM,aAAaA,eAAc,SAAS;AAE1C,gBAAI,CAAC,cAAc,CAAC,WAAY;AAGhC,gBAAI,WAA+B;AACnC,mBAAO,aAAa,MAAM;AACxB,kBAAI,SAAS,OAAO,MAAM,UAAW;AACrC,yBAAW,SAAS,UAAU;AAAA,YAChC;AAIA,gBAAI,qBAAqB,UAAU,GAAG;AACpC,yBAAW,OAAO;AAClB,yBAAW,OAAO,UAAU;AAC5B;AAAA,YACF;AAEA,uBAAW,OAAO;AAElB,gBAAI,aAAa,UAAU;AACzB,yBAAW,aAAa,UAAU;AAAA,YACpC,OAAO;AACL,yBAAW,YAAY,UAAU;AAAA,YACnC;AAAA,UACF,CAAC;AAAA,QACH;AAEA,yBAAiB,UAAU;AAC3B,yBAAiB,UAAU;AAC3B,mBAAW;AAAA,MACb;AAEA,eAAS,iBAAiB,aAAa,UAAU;AACjD,eAAS,iBAAiB,WAAW,SAAS;AAAA,IAChD;AAEA,WAAO,iBAAiB,cAAc,OAAO;AAC7C,WAAO,iBAAiB,cAAc,OAAO;AAC7C,WAAO,iBAAiB,aAAa,WAAW;AAEhD,WAAO,MAAM;AACX,aAAO,oBAAoB,cAAc,OAAO;AAChD,aAAO,oBAAoB,cAAc,OAAO;AAChD,aAAO,oBAAoB,aAAa,WAAW;AAAA,IACrD;AAAA,EACF,GAAG,CAAC,QAAQ,eAAe,YAAY,eAAe,aAAa,CAAC;AAEpE,QAAM,YAAYD,cAAY,MAAM;AAClC,iBAAa,IAAI;AAAA,EACnB,GAAG,CAAC,CAAC;AAEL,MAAI,kBAAkB,QAAQ,iBAAiB,CAAC,gBAAiB,QAAO;AAExE,SACE,gBAAAN,OAAAF,WAAA,EACG;AAAA,IAAAU;AAAA,MACC,gBAAAR,OAAAF,WAAA,EAEE;AAAA,wBAAAC;AAAA,UAAC;AAAA;AAAA,YACC,KAAK;AAAA,YACL,eAAY;AAAA,YACZ,kBAAgB;AAAA,YAChB,OAAO;AAAA,cACL,UAAU;AAAA,cACV,KAAK;AAAA,cACL,MAAM;AAAA,cACN,OAAO;AAAA,cACP,QAAQ;AAAA,cACR,SAAS;AAAA,cACT,YAAY;AAAA,cACZ,gBAAgB;AAAA,cAChB,QAAQ;AAAA,cACR,cAAc;AAAA,cACd,OAAO;AAAA,cACP,SAAS;AAAA,cACT,YAAY;AAAA,cACZ,YAAY;AAAA,cACZ,QAAQ;AAAA,cACR,YAAY;AAAA,YACd;AAAA,YAEA,0BAAAA,MAAC,uBAAoB,MAAM,IAAI,QAAO,QAAO;AAAA;AAAA,QAC/C;AAAA,QAGA,gBAAAA;AAAA,UAAC;AAAA;AAAA,YACC,KAAK;AAAA,YACL,eAAY;AAAA,YACZ,OAAO;AAAA,cACL,UAAU;AAAA,cACV,KAAK;AAAA,cACL,MAAM;AAAA,cACN,OAAO;AAAA,cACP,QAAQ;AAAA,cACR,iBAAiB;AAAA,cACjB,eAAe;AAAA,cACf,QAAQ;AAAA,cACR,YAAY;AAAA,YACd;AAAA;AAAA,QACF;AAAA,SACF;AAAA,MACA;AAAA,IACF;AAAA,IAGC,WAAW,QACV,gBAAAA;AAAA,MAAC;AAAA;AAAA,QACC;AAAA,QACA,UAAU,UAAU;AAAA,QACpB,UAAU,UAAU;AAAA,QACpB,SAAS;AAAA;AAAA,IACX;AAAA,KAEJ;AAEJ;;;AEjkBA,SAAS,aAAAU,mBAAiB;AAG1B,SAAS,6BAAAC,mCAAiC;AAC1C,SAAS,YAAAC,WAAU,wBAAAC,6BAA4B;AAC/C,SAAS,sBAAAC,qBAAoB,oBAAAC,yBAAwB;AACrD,SAAS,mBAAAC,kBAAiB,uBAAAC,4BAA2B;AAerD,IAAM,gBAA6B;AAAA,EACjC;AAAA,IACE,SAAS;AAAA,IACT,MAAM;AAAA,IACN,SAAS,CAAC,QAAQ,SAAS;AACzB,YAAM,SAAS,KAAK,UAAU;AAC9B,UAAI,CAAC,OAAQ;AACb,YAAM,UAAUC,oBAAmB,IAAI;AACvC,aAAO,QAAQ,OAAO;AACtB,cAAQ,UAAU;AAAA,IACpB;AAAA,EACF;AAAA,EACA;AAAA,IACE,SAAS;AAAA,IACT,MAAM;AAAA,IACN,SAAS,CAAC,QAAQ,SAAS;AACzB,YAAM,SAAS,KAAK,UAAU;AAC9B,UAAI,CAAC,OAAQ;AACb,YAAM,UAAUA,oBAAmB,IAAI;AACvC,aAAO,QAAQ,OAAO;AACtB,cAAQ,UAAU;AAAA,IACpB;AAAA,EACF;AAAA,EACA;AAAA,IACE,SAAS;AAAA,IACT,MAAM;AAAA,IACN,SAAS,CAAC,QAAQ,SAAS;AACzB,YAAM,SAAS,KAAK,UAAU;AAC9B,UAAI,CAAC,OAAQ;AACb,YAAM,UAAUA,oBAAmB,IAAI;AACvC,aAAO,QAAQ,OAAO;AACtB,cAAQ,UAAU;AAAA,IACpB;AAAA,EACF;AAAA,EACA;AAAA,IACE,SAAS;AAAA,IACT,MAAM;AAAA,IACN,SAAS,CAAC,QAAQ,SAAS;AACzB,YAAM,SAAS,KAAK,UAAU;AAC9B,UAAI,CAAC,OAAQ;AACb,YAAM,QAAQC,kBAAiB;AAC/B,aAAO,QAAQ,KAAK;AACpB,YAAM,UAAU;AAAA,IAClB;AAAA,EACF;AAAA,EACA;AAAA,IACE,SAAS;AAAA,IACT,MAAM;AAAA,IACN,SAAS,CAAC,QAAQ,SAAS;AACzB,YAAM,SAAS,KAAK,UAAU;AAC9B,UAAI,CAAC,OAAQ;AACb,YAAM,OAAOC,iBAAgB,QAAQ;AACrC,YAAM,OAAOC,qBAAoB;AACjC,WAAK,OAAO,IAAI;AAChB,aAAO,QAAQ,IAAI;AACnB,WAAK,UAAU;AAAA,IACjB;AAAA,EACF;AAAA,EACA;AAAA,IACE,SAAS;AAAA,IACT,MAAM;AAAA,IACN,SAAS,CAAC,QAAQ,SAAS;AACzB,YAAM,SAAS,KAAK,UAAU;AAC9B,UAAI,CAAC,OAAQ;AACb,YAAM,OAAOD,iBAAgB,QAAQ;AACrC,YAAM,OAAOC,qBAAoB;AACjC,WAAK,OAAO,IAAI;AAChB,aAAO,QAAQ,IAAI;AACnB,WAAK,UAAU;AAAA,IACjB;AAAA,EACF;AAAA,EACA;AAAA,IACE,SAAS;AAAA,IACT,MAAM;AAAA,IACN,SAAS,CAAC,QAAQ,SAAS;AACzB,YAAM,SAAS,KAAK,UAAU;AAC9B,UAAI,CAAC,OAAQ;AACb,YAAM,OAAOD,iBAAgB,OAAO;AACpC,YAAM,OAAOC,qBAAoB;AACjC,WAAK,OAAO,IAAI;AAChB,aAAO,QAAQ,IAAI;AACnB,WAAK,UAAU;AAAA,IACjB;AAAA,EACF;AAAA,EACA;AAAA,IACE,SAAS;AAAA,IACT,MAAM;AAAA,IACN,SAAS,CAAC,QAAQ,SAAS;AACzB,YAAM,SAAS,KAAK,UAAU;AAC9B,UAAI,CAAC,OAAQ;AACb,YAAM,OAAOD,iBAAgB,OAAO;AACpC,YAAM,OAAOC,qBAAoB,IAAI;AACrC,WAAK,OAAO,IAAI;AAChB,aAAO,QAAQ,IAAI;AACnB,WAAK,UAAU;AAAA,IACjB;AAAA,EACF;AAAA,EACA;AAAA,IACE,SAAS;AAAA,IACT,MAAM;AAAA,IACN,SAAS,CAAC,QAAQ,SAAS;AACzB,YAAM,SAAS,KAAK,UAAU;AAC9B,UAAI,CAAC,OAAQ;AACb,YAAM,OAAO,0BAA0B;AACvC,YAAM,oBAAoBC,sBAAqB;AAC/C,aAAO,QAAQ,IAAI;AACnB,WAAK,YAAY,iBAAiB;AAClC,wBAAkB,UAAU;AAAA,IAC9B;AAAA,EACF;AAAA,EACA;AAAA,IACE,SAAS;AAAA,IACT,MAAM;AAAA,IACN,SAAS,CAAC,QAAQ,SAAS;AACzB,YAAM,SAAS,KAAK,UAAU;AAC9B,UAAI,CAAC,OAAQ;AACb,YAAM,YAAY,qBAAqB,EAAE,MAAM,IAAI,UAAU,cAAc,WAAW,KAAK,CAAC;AAI5F,YAAM,oBAAoBA,sBAAqB;AAC/C,aAAO,QAAQ,SAAS;AACxB,gBAAU,YAAY,iBAAiB;AACvC,wBAAkB,UAAU;AAAA,IAC9B;AAAA,EACF;AACF;AAMO,SAAS,gBAAgB,EAAE,QAAQ,CAAC,EAAE,GAAyB;AACpE,QAAM,CAAC,MAAM,IAAIC,4BAA0B;AAE3C,EAAAC,YAAU,MAAM;AACd,UAAM,WAAW,CAAC,GAAG,eAAe,GAAG,KAAK;AAI5C,UAAM,oBAAoB,oBAAI,IAAY;AAC1C,eAAW,QAAQ,UAAU;AAG3B,YAAM,MAAM,KAAK,QAAQ;AAEzB,YAAM,QAAQ,IAAI,WAAW,GAAG,IAAI,IAAI;AACxC,YAAM,KAAK,IAAI,KAAK;AACpB,UAAI,MAAM,OAAO,OAAO,OAAO,OAAO,OAAO,MAAM;AACjD,0BAAkB,IAAI,EAAE;AAAA,MAC1B,WAAW,OAAO,KAAK;AAErB,iBAAS,IAAI,QAAQ,GAAG,IAAI,IAAI,QAAQ,KAAK;AAC3C,cAAI,IAAI,CAAC,MAAM,IAAK;AACpB,cAAI,IAAI,CAAC,MAAM,OAAO,MAAM,QAAQ,EAAG,mBAAkB,IAAI,IAAI,CAAC,CAAE;AAAA,QACtE;AAAA,MACF,WAAW,OAAO,MAAM;AAEtB,cAAM,OAAO,IAAI,QAAQ,CAAC;AAC1B,YAAI,KAAM,mBAAkB,IAAI,IAAI;AAAA,MACtC;AAAA,IACF;AAEA,WAAO,OAAO,sBAAsBC,WAAU,CAAC,aAAa;AAE1D,YAAM,wBAAwB;AAG9B,UAAI,sBAAsB,oBAAoB,KAAM;AAEpD,YAAM,OAAO,SAAS,eAAe;AAIrC,UAAI,KAAK,SAAS,EAAG;AAGrB,UAAI,SAAS,KAAK;AAChB,cAAM,SAAS,SAAS,UAAU;AAClC,YAAI,UAAU,OAAO,gBAAgB,MAAM,GAAG;AAE5C,yBAAe,MAAM;AACnB,mBAAO,gBAAgB,yBAAyB,MAAS;AAAA,UAC3D,CAAC;AACD;AAAA,QACF;AAAA,MACF;AAGA,YAAM,YAAY,KAAK,CAAC;AACxB,UAAI,CAAC,aAAa,CAAC,kBAAkB,IAAI,SAAS,EAAG;AAGrD,iBAAW,QAAQ,UAAU;AAC3B,cAAM,QAAQ,KAAK,MAAM,KAAK,OAAO;AACrC,YAAI,OAAO;AAET,mBAAS,eAAe,EAAE;AAC1B,eAAK,QAAQ,OAAO,UAAU,MAAM;AACpC;AAAA,QACF;AAAA,MACF;AAAA,IACF,CAAC;AAAA,EACH,GAAG,CAAC,QAAQ,KAAK,CAAC;AAElB,SAAO;AACT;;;ACpOA,SAAS,aAAAC,aAAW,UAAAC,gBAAc;AAElC,SAAS,6BAAAC,mCAAiC;AAC1C;AAAA,EACE,iBAAAC;AAAA,EACA,YAAAC;AAAA,EACA,iBAAAC;AAAA,EACA,qBAAAC;AAAA,EACA,eAAAC;AAAA,EACA,wBAAAC;AAAA,OACK;AAYP,IAAM,wBAAwB,KAAK,OAAO;AAC1C,IAAM,0BAA0B;AAAA,EAC9B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAcO,SAAS,YAAY;AAAA,EAC1B;AAAA,EACA,cAAc;AAAA,EACd,iBAAiB;AAAA,EACjB;AAAA,EACA;AACF,GAAqB;AACnB,QAAM,CAAC,MAAM,IAAIC,4BAA0B;AAC3C,QAAM,mBAAmBC,SAAO,aAAa;AAC7C,mBAAiB,UAAU;AAC3B,QAAM,mBAAmBA,SAAO,aAAa;AAC7C,mBAAiB,UAAU;AAE3B,QAAM,eAAe,CAAC,SAAwB;AAC5C,QAAI,CAAC,eAAe,KAAK,CAAC,QAAQ,KAAK,SAAS,GAAG,GAAG;AACpD,uBAAiB,MAAM,QAAQ;AAC/B,aAAO;AAAA,IACT;AACA,QAAI,KAAK,OAAO,aAAa;AAC3B,uBAAiB,MAAM,MAAM;AAC7B,aAAO;AAAA,IACT;AACA,WAAO;AAAA,EACT;AAEA,EAAAC,YAAU,MAAM;AACd,WAAO,OAAO;AAAA,MACZ;AAAA,MACA,CAAC,SAAe;AACd,YAAI,CAAC,aAAa,IAAI,EAAG,QAAO;AAChC,0BAAkB,MAAM,QAAQ,iBAAiB,SAAS,iBAAiB,OAAO;AAClF,eAAO;AAAA,MACT;AAAA,MACAC;AAAA,IACF;AAAA,EACF,GAAG,CAAC,QAAQ,aAAa,gBAAgB,cAAc,CAAC;AAExD,EAAAD,YAAU,MAAM;AACd,UAAM,cAAc,OAAO,eAAe;AAC1C,QAAI,CAAC,YAAa;AAElB,UAAM,SAAS,CAAC,MAAiB;AAC/B,YAAM,QAAQ,EAAE,cAAc;AAC9B,UAAI,CAAC,SAAS,MAAM,WAAW,EAAG;AAElC,YAAM,aAAa,MAAM,KAAK,KAAK,EAAE;AAAA,QAAO,CAAC,MAC3C,EAAE,KAAK,WAAW,QAAQ;AAAA,MAC5B;AACA,UAAI,WAAW,WAAW,EAAG;AAE7B,QAAE,eAAe;AACjB,QAAE,gBAAgB;AAElB,iBAAW,QAAQ,YAAY;AAC7B,YAAI,CAAC,aAAa,IAAI,EAAG;AACzB,0BAAkB,MAAM,QAAQ,iBAAiB,SAAS,iBAAiB,OAAO;AAAA,MACpF;AAAA,IACF;AAEA,gBAAY,iBAAiB,QAAQ,MAAM;AAC3C,WAAO,MAAM,YAAY,oBAAoB,QAAQ,MAAM;AAAA,EAC7D,GAAG,CAAC,QAAQ,aAAa,gBAAgB,cAAc,CAAC;AAExD,EAAAA,YAAU,MAAM;AACd,UAAM,cAAc,OAAO,eAAe;AAC1C,QAAI,CAAC,YAAa;AAElB,UAAM,UAAU,CAAC,MAAsB;AACrC,YAAM,QAAQ,EAAE,eAAe;AAC/B,UAAI,CAAC,SAAS,MAAM,WAAW,EAAG;AAElC,YAAM,aAAa,MAAM,KAAK,KAAK,EAAE;AAAA,QAAO,CAAC,MAC3C,EAAE,KAAK,WAAW,QAAQ;AAAA,MAC5B;AACA,UAAI,WAAW,WAAW,EAAG;AAE7B,QAAE,eAAe;AAEjB,iBAAW,QAAQ,YAAY;AAC7B,YAAI,CAAC,aAAa,IAAI,EAAG;AACzB,0BAAkB,MAAM,QAAQ,iBAAiB,SAAS,iBAAiB,OAAO;AAAA,MACpF;AAAA,IACF;AAEA,gBAAY,iBAAiB,SAAS,OAAO;AAC7C,WAAO,MAAM,YAAY,oBAAoB,SAAS,OAAO;AAAA,EAC/D,GAAG,CAAC,QAAQ,aAAa,gBAAgB,cAAc,CAAC;AAExD,SAAO;AACT;AAEA,SAAS,kBACP,MACA,QACA,eACA,eACA;AAEA,QAAM,YAAY,IAAI,gBAAgB,IAAI;AAG1C,MAAI,iBAAgC;AAEpC,SAAO,OAAO,MAAM;AAClB,UAAM,cAAc,wBAAwB,SAAS;AACrD,qBAAiB,YAAY,OAAO;AAEpC,UAAM,OAAOE,UAAS;AACtB,UAAM,YAAYC,eAAc;AAGhC,QAAI,cAAoD;AAExD,QAAIC,mBAAkB,SAAS,GAAG;AAChC,UAAI,OAAsC,UAAU,OAAO,QAAQ;AAEnE,aAAO,CAACC,aAAY,IAAI,GAAG;AACzB,cAAM,SAAS,KAAK,UAAU;AAC9B,YAAI,CAAC,UAAUA,aAAY,MAAM,GAAG;AAElC,cAAI,OAAQ,eAAc;AAC1B;AAAA,QACF;AACA,eAAO;AAAA,MACT;AAAA,IACF;AAEA,QAAI,eAAe,CAACA,aAAY,WAAW,GAAG;AAC5C,kBAAY,YAAY,WAAW;AAAA,IACrC,OAAO;AACL,WAAK,OAAO,WAAW;AAAA,IACzB;AAAA,EACF,CAAC;AAGD,gBAAc,IAAI,EACf,KAAK,CAAC,cAAc;AAEnB,QAAI;AACF,aAAO,OAAO,MAAM;AAClB,YAAI,CAAC,eAAgB;AAErB,cAAM,cAAcC,eAAc,cAAc;AAChD,YAAI,CAAC,eAAe,CAAC,oBAAoB,WAAW,EAAG;AAEvD,cAAM,YAAY,iBAAiB;AAAA,UACjC,KAAK;AAAA,UACL,SAAS,KAAK;AAAA,QAChB,CAAC;AAED,oBAAY,QAAQ,SAAS;AAAA,MAC/B,CAAC;AAAA,IACH,QAAQ;AAAA,IAER;AAEA,QAAI,gBAAgB,SAAS;AAAA,EAC/B,CAAC,EACA,MAAM,CAAC,UAAmB;AAEzB,QAAI;AACF,aAAO,OAAO,MAAM;AAClB,YAAI,CAAC,eAAgB;AAErB,cAAM,cAAcA,eAAc,cAAc;AAChD,YAAI,CAAC,YAAa;AAElB,oBAAY,OAAO;AAAA,MACrB,CAAC;AAAA,IACH,QAAQ;AAAA,IAER;AAEA,oBAAgB,MAAM,KAAK;AAC3B,QAAI,gBAAgB,SAAS;AAAA,EAC/B,CAAC;AACL;;;AC3NA,SAAS,eAAAC,eAAa,aAAAC,aAAW,UAAAC,UAAQ,YAAAC,iBAAgB;AAEzD,SAAS,gBAAAC,qBAAoB;AAE7B,SAAS,6BAAAC,mCAAiC;AAC1C;AAAA,EACE,YAAAC;AAAA,EACA,iBAAAC;AAAA,EACA,qBAAAC;AAAA,EACA,eAAAC;AAAA,EACA,wBAAAC;AAAA,OACK;AAcP,SAAS,2BAA2B;AAmKpC,SAAS,kBAAkB;AAnBvB,qBAAAC,WAMQ,OAAAC,OA+DN,QAAAC,cArEF;AAnIG,SAAS,SAAS,EAAE,UAAU,SAAS,CAAC,EAAE,GAAkB;AACjE,QAAM,CAAC,MAAM,IAAIC,4BAA0B;AAC3C,QAAM,CAAC,cAAc,eAAe,IAAIC,UAAS,KAAK;AACtD,QAAM,CAAC,gBAAgB,iBAAiB,IAAIA,UAAS,EAAE,KAAK,GAAG,MAAM,EAAE,CAAC;AACxE,QAAM,CAAC,iBAAiB,kBAAkB,IAAIA;AAAA,IAC5C;AAAA,EACF;AACA,QAAM,WAAWC,SAAyB,IAAI;AAG9C,QAAM,oBAAoB,OAAO,qBAAqB;AAEtD,EAAAC,YAAU,MAAM;AACd,QAAI,OAAO,WAAW,YAAa;AACnC,uBAAmB,SAAS,IAAI;AAAA,EAClC,GAAG,CAAC,CAAC;AAGL,EAAAA,YAAU,MAAM;AACd,uBAAmB,QAAQ,UAAU,MAAM;AAC3C,WAAO,MAAM;AACX,2BAAqB,MAAM;AAAA,IAC7B;AAAA,EACF,GAAG,CAAC,QAAQ,UAAU,MAAM,CAAC;AAE7B,EAAAA,YAAU,MAAM;AACd,WAAO,OAAO;AAAA,MACZ;AAAA,MACA,MAAM;AAEJ,cAAM,eAAe,OAAO,aAAa;AACzC,YAAI,gBAAgB,aAAa,aAAa,GAAG;AAC/C,gBAAM,QAAQ,aAAa,WAAW,CAAC;AACvC,gBAAM,OAAO,MAAM,sBAAsB;AACzC,4BAAkB;AAAA,YAChB,KAAK,KAAK;AAAA,YACV,MAAM,KAAK;AAAA,UACb,CAAC;AAAA,QACH;AAEA,wBAAgB,IAAI;AAEpB,eAAO;AAAA,MACT;AAAA,MACAC;AAAA,IACF;AAAA,EACF,GAAG,CAAC,QAAQ,OAAO,YAAY,CAAC;AAEhC,EAAAD,YAAU,MAAM;AACd,WAAO,OAAO;AAAA,MACZ;AAAA,MACA,CAAC,YAAY;AAEX,YAAI,kBAAkB;AACtB,eAAO,KAAK,MAAM;AAChB,gBAAM,OAAOE,UAAS;AACtB,gBAAM,WAAW,KAAK,YAAY;AAClC,gBAAM,eAAe,SAAS,MAAM,CAAC,iBAAiB;AACtD,4BAAkB,yBAAyB,YAAY;AAAA,QACzD,CAAC;AAGD,eAAO,OAAO,MAAM;AAClB,gBAAM,YAAYC,eAAc;AAChC,cAAI,cAAoD;AAExD,cAAIC,mBAAkB,SAAS,GAAG;AAChC,gBAAI,OACF,UAAU,OAAO,QAAQ;AAC3B,mBAAO,CAACC,aAAY,IAAI,GAAG;AACzB,oBAAM,SAAS,KAAK,UAAU;AAC9B,kBAAI,CAAC,UAAUA,aAAY,MAAM,GAAG;AAClC,oBAAI,OAAQ,eAAc;AAC1B;AAAA,cACF;AACA,qBAAO;AAAA,YACT;AAAA,UACF;AAEA,gBAAM,SAAS,qBAAqB;AAAA,YAClC,QAAQ,QAAQ;AAAA,YAChB,SAAS;AAAA,UACX,CAAC;AAED,cAAI,eAAe,CAACA,aAAY,WAAW,GAAG;AAE5C,kBAAM,cAAc,YAAY,eAAe;AAC/C,gBAAI,YAAY,KAAK,MAAM,IAAI;AAC7B,0BAAY,QAAQ,MAAM;AAAA,YAC5B,OAAO;AACL,0BAAY,YAAY,MAAM;AAAA,YAChC;AAAA,UACF,OAAO;AACL,kBAAM,OAAOH,UAAS;AACtB,iBAAK,OAAO,MAAM;AAAA,UACpB;AAAA,QACF,CAAC;AAED,eAAO;AAAA,MACT;AAAA,MACAD;AAAA,IACF;AAAA,EACF,GAAG,CAAC,QAAQ,iBAAiB,CAAC;AAE9B,QAAM,eAAeK;AAAA,IACnB,CAAC,eAAuB;AACtB,UAAI,CAAC,WAAW,KAAK,EAAG;AAExB,sBAAgB,KAAK;AACrB,aAAO,gBAAgB,2BAA2B;AAAA,QAChD,QAAQ,WAAW,KAAK;AAAA,MAC1B,CAAC;AAAA,IACH;AAAA,IACA,CAAC,MAAM;AAAA,EACT;AAEA,QAAM,cAAcA,cAAY,MAAM;AACpC,oBAAgB,KAAK;AACrB,WAAO,MAAM;AAAA,EACf,GAAG,CAAC,MAAM,CAAC;AAEX,MAAI,CAAC,gBAAiB,QAAO;AAG7B,QAAM,oBAA8C;AAAA,IAClD,UAAU;AAAA,IACV,UAAU;AAAA,IACV,SAAS;AAAA,EACX;AAEA,SACE,gBAAAX,MAAAD,WAAA,EACG,0BACCa;AAAA,IACE,OAAO,eACL,OAAO,aAAa,iBAAiB,IAErC,gBAAAZ;AAAA,MAAC;AAAA;AAAA,QACC,KAAK;AAAA,QACL,UAAU;AAAA,QACV,UAAU;AAAA,QACV,SAAS;AAAA;AAAA,IACX;AAAA,IAEF;AAAA,EACF,GACJ;AAEJ;AAUA,IAAM,gBAAgB;AAAA,EACpB,SAASa,eAAc,EAAE,UAAU,UAAU,QAAQ,GAAG,KAAK;AAC3D,UAAM,CAAC,OAAO,QAAQ,IAAIV,UAAS,EAAE;AACrC,UAAM,eAAeC,SAAuB,IAAI;AAEhD,IAAAC,YAAU,MAAM;AACd,YAAM,qBAAqB,CAAC,MAAkB;AAC5C,YACE,aAAa,WACb,CAAC,aAAa,QAAQ,SAAS,EAAE,MAAc,GAC/C;AACA,kBAAQ;AAAA,QACV;AAAA,MACF;AAIA,YAAM,MAAM,sBAAsB,MAAM;AACtC,iBAAS,iBAAiB,aAAa,kBAAkB;AAAA,MAC3D,CAAC;AACD,aAAO,MAAM;AACX,6BAAqB,GAAG;AACxB,iBAAS,oBAAoB,aAAa,kBAAkB;AAAA,MAC9D;AAAA,IACF,GAAG,CAAC,OAAO,CAAC;AAEZ,UAAM,gBAAgB,CAAC,MAA6C;AAGlE,QAAE,gBAAgB;AAElB,UAAI,EAAE,QAAQ,WAAW,CAAC,EAAE,UAAU;AACpC,UAAE,eAAe;AACjB,iBAAS,KAAK;AAAA,MAChB;AACA,UAAI,EAAE,QAAQ,UAAU;AACtB,UAAE,eAAe;AACjB,gBAAQ;AAAA,MACV;AAAA,IACF;AAEA,WACE,gBAAAJ;AAAA,MAAC;AAAA;AAAA,QACC,KAAK;AAAA,QACL,eAAY;AAAA,QACZ,OAAO;AAAA,UACL,UAAU;AAAA,UACV,KAAK,GAAG,SAAS,GAAG;AAAA,UACpB,MAAM,GAAG,SAAS,IAAI;AAAA,UACtB,QAAQ;AAAA,UACR,SAAS;AAAA,UACT,YAAY;AAAA,UACZ,KAAK;AAAA,UACL,SAAS;AAAA,UACT,cAAc;AAAA,UACd,QAAQ;AAAA,UACR,iBAAiB;AAAA,UACjB,gBAAgB;AAAA,UAChB,sBAAsB;AAAA,UACtB,WAAW;AAAA,UACX,YACE;AAAA,UACF,WAAW;AAAA,UACX,UAAU;AAAA,QACZ;AAAA,QAEA;AAAA,0BAAAD;AAAA,YAAC;AAAA;AAAA,cACC,KAAK,CAAC,OAAO;AACX,oBAAI,GAAI,IAAG,MAAM;AACjB,oBAAI,OAAO,QAAQ,WAAY,KAAI,EAAE;AAAA,yBAC5B,IAAK,KAAI,UAAU;AAAA,cAC9B;AAAA,cACA,MAAK;AAAA,cACL;AAAA,cACA,UAAU,CAAC,MAAM,SAAS,EAAE,OAAO,KAAK;AAAA,cACxC,WAAW;AAAA,cACX,aAAY;AAAA,cACZ,OAAO;AAAA,gBACL,MAAM;AAAA,gBACN,QAAQ;AAAA,gBACR,SAAS;AAAA,gBACT,YAAY;AAAA,gBACZ,UAAU;AAAA,gBACV,OAAO;AAAA,gBACP,YAAY;AAAA,cACd;AAAA;AAAA,UACF;AAAA,UACA,gBAAAA;AAAA,YAAC;AAAA;AAAA,cACC,MAAK;AAAA,cACL,eAAY;AAAA,cACZ,SAAS,MAAM,SAAS,KAAK;AAAA,cAC7B,UAAU,CAAC,MAAM,KAAK;AAAA,cACtB,OAAO;AAAA,gBACL,SAAS;AAAA,gBACT,YAAY;AAAA,gBACZ,gBAAgB;AAAA,gBAChB,OAAO;AAAA,gBACP,QAAQ;AAAA,gBACR,cAAc;AAAA,gBACd,QAAQ;AAAA,gBACR,QAAQ,MAAM,KAAK,IAAI,YAAY;AAAA,gBACnC,iBAAiB,MAAM,KAAK,IACxB,uCACA;AAAA,gBACJ,OAAO,MAAM,KAAK,IAAI,4CAA4C;AAAA,gBAClE,YAAY;AAAA,cACd;AAAA,cAEA,0BAAAA,MAAC,uBAAoB,MAAM,IAAI,QAAO,QAAO;AAAA;AAAA,UAC/C;AAAA,UAEA,gBAAAA;AAAA,YAAC;AAAA;AAAA,cACC,yBAAyB;AAAA,gBACvB,QAAQ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,cAYV;AAAA;AAAA,UACF;AAAA;AAAA;AAAA,IACF;AAAA,EAEJ;AACF;;;ACrUA,SAAS,eAAAc,eAAa,aAAAC,aAAW,UAAAC,UAAQ,YAAAC,iBAAgB;AAGzD,SAAS,gBAAAC,qBAAoB;AAG7B,SAAS,6BAAAC,mCAAiC;AAC1C;AAAA,EACE,iBAAAC;AAAA,EACA,qBAAAC;AAAA,EACA,eAAAC;AAAA,EACA;AAAA,EACA,0BAAAC;AAAA,EACA,wBAAAC;AAAA,EACA,qBAAAC;AAAA,EACA,sBAAAC;AAAA,EACA;AAAA,EACA,YAAAC;AAAA,OACK;AAkRH,gBAAAC,OAoIM,QAAAC,cApIN;AApQG,SAAS,cAAc,EAAE,UAAU,GAAuB;AAC/D,QAAM,CAAC,MAAM,IAAIV,4BAA0B;AAC3C,QAAM,CAAC,QAAQ,SAAS,IAAIF,UAAS,KAAK;AAC1C,QAAM,CAAC,OAAO,QAAQ,IAAIA,UAAS,EAAE;AACrC,QAAM,CAAC,OAAO,QAAQ,IAAIA,UAAwB,CAAC,CAAC;AACpD,QAAM,CAAC,eAAe,gBAAgB,IAAIA,UAAS,CAAC;AACpD,QAAM,CAAC,UAAU,WAAW,IAAIA,UAAS,EAAE,KAAK,GAAG,MAAM,EAAE,CAAC;AAC5D,QAAM,CAAC,iBAAiB,kBAAkB,IAAIA;AAAA,IAC5C;AAAA,EACF;AACA,QAAM,oBAAoBD,SAA+B,IAAI;AAC7D,QAAM,mBAAmBA,SAAe,CAAC;AACzC,QAAM,mBAAmBA,SAA6C,IAAI;AAG1E,EAAAD,YAAU,MAAM;AACd,QAAI,OAAO,WAAW,YAAa;AACnC,uBAAmB,SAAS,IAAI;AAAA,EAClC,GAAG,CAAC,CAAC;AAGL,QAAM,WAAW,UAAU,IAAI,CAAC,MAAM,EAAE,OAAO;AAG/C,QAAM,QAAQD,cAAY,MAAM;AAC9B,cAAU,KAAK;AACf,aAAS,EAAE;AACX,aAAS,CAAC,CAAC;AACX,qBAAiB,CAAC;AAClB,sBAAkB,UAAU;AAAA,EAC9B,GAAG,CAAC,CAAC;AAGL,EAAAC,YAAU,MAAM;AACd,QAAI,eAAe;AAEnB,UAAM,aAAa,OAAO,uBAAuB,CAAC,EAAE,YAAY,MAAM;AAEpE,UAAI,iBAAiB,EAAG,sBAAqB,YAAY;AACzD,qBAAe,sBAAsB,MAAM;AACzC,uBAAe;AACf,oBAAY,KAAK,MAAM;AACvB,gBAAM,YAAYK,eAAc;AAChC,cAAI,CAACC,mBAAkB,SAAS,KAAK,CAAC,UAAU,YAAY,GAAG;AAC7D,gBAAI,OAAQ,OAAM;AAClB;AAAA,UACF;AAEA,gBAAM,SAAS,UAAU;AACzB,gBAAM,OAAO,OAAO,QAAQ;AAC5B,cAAI,CAACC,aAAY,IAAI,GAAG;AACtB,gBAAI,OAAQ,OAAM;AAClB;AAAA,UACF;AAEA,gBAAM,OAAO,KAAK,eAAe;AACjC,gBAAM,SAAS,OAAO;AAGtB,cAAI,CAAC,UAAU,CAAC,SAAS,KAAK,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,GAAG;AACtD;AAAA,UACF;AAGA,cAAI,eAAe;AACnB,cAAI,iBAAiB;AAErB,mBAAS,IAAI,SAAS,GAAG,KAAK,GAAG,KAAK;AACpC,kBAAM,OAAO,KAAK,CAAC;AACnB,gBAAI,SAAS,OAAW;AAExB,gBAAI,SAAS,SAAS,IAAI,GAAG;AAC3B,kBAAI,MAAM,KAAK,KAAK,IAAI,CAAC,MAAM,OAAO,KAAK,IAAI,CAAC,MAAM,MAAM;AAC1D,+BAAe;AACf,iCAAiB;AAAA,cACnB;AACA;AAAA,YACF;AAEA,gBAAI,SAAS,OAAO,SAAS,MAAM;AACjC;AAAA,YACF;AAAA,UACF;AAEA,cAAI,iBAAiB,MAAM,CAAC,gBAAgB;AAC1C,gBAAI,OAAQ,OAAM;AAClB;AAAA,UACF;AAEA,gBAAM,YAAY,KAAK,MAAM,eAAe,GAAG,MAAM;AAErD,gBAAM,WAAW,UAAU,KAAK,CAAC,MAAM,EAAE,YAAY,cAAc;AACnE,cAAI,CAAC,UAAU;AACb,gBAAI,OAAQ,OAAM;AAClB;AAAA,UACF;AAGA,gBAAM,eAAe,OAAO,aAAa;AACzC,cAAI,gBAAgB,aAAa,aAAa,GAAG;AAC/C,kBAAM,QAAQ,aAAa,WAAW,CAAC;AACvC,kBAAM,OAAO,MAAM,sBAAsB;AACzC,wBAAY;AAAA,cACV,KAAK,KAAK,SAAS;AAAA,cACnB,MAAM,KAAK;AAAA,YACb,CAAC;AAAA,UACH;AAEA,4BAAkB,UAAU;AAC5B,2BAAiB,UAAU;AAC3B,mBAAS,SAAS;AAClB,oBAAU,IAAI;AAEd,cAAI,iBAAiB,SAAS;AAC5B,yBAAa,iBAAiB,OAAO;AAAA,UACvC;AACA,2BAAiB,UAAU,WAAW,MAAM;AAC1C,qBAAS,SAAS,SAAS,EAAE,KAAK,CAAC,YAAY;AAC7C,uBAAS,OAAO;AAChB,+BAAiB,CAAC;AAAA,YACpB,CAAC;AAAA,UACH,GAAG,EAAE;AAAA,QACP,CAAC;AAAA,MACD,CAAC;AAAA,IACH,CAAC;AAED,WAAO,MAAM;AACX,iBAAW;AACX,UAAI,iBAAiB,EAAG,sBAAqB,YAAY;AAAA,IAC3D;AAAA,EACF,GAAG,CAAC,QAAQ,QAAQ,OAAO,UAAU,SAAS,CAAC;AAG/C,QAAM,aAAaR;AAAA,IACjB,CAAC,SAAsB;AACrB,YAAM,WAAW,kBAAkB;AACnC,UAAI,CAAC,SAAU;AAEf,aAAO,OAAO,MAAM;AAClB,cAAM,YAAYM,eAAc;AAChC,YAAI,CAACC,mBAAkB,SAAS,EAAG;AAEnC,cAAM,SAAS,UAAU;AACzB,cAAM,OAAO,OAAO,QAAQ;AAC5B,YAAI,CAACC,aAAY,IAAI,EAAG;AAExB,cAAM,OAAO,KAAK,eAAe;AACjC,cAAM,SAAS,OAAO;AAGtB,cAAM,eAAe,iBAAiB;AACtC,cAAM,UAAU,SAAS;AAGzB,cAAM,SAAS,KAAK,MAAM,GAAG,YAAY;AAEzC,cAAM,QAAQ,KAAK,MAAM,MAAM;AAG/B,cAAM,cAAc,SAAS,SAAS,IAAI;AAE1C,YAAI,WAAW,MAAM,UAAU,IAAI;AAEjC,eAAK,QAAQ,WAAW;AAAA,QAC1B,OAAO;AAEL,eAAK,eAAe,MAAM;AAG1B,eAAK,YAAY,WAAW;AAG5B,cAAI,OAAO;AACT,kBAAM,YAAY,IAAIK,UAAS,KAAK;AACpC,wBAAY,YAAY,SAAS;AAAA,UACnC;AAAA,QACF;AAGA,oBAAY,WAAW,GAAG,CAAC;AAAA,MAC7B,CAAC;AAED,YAAM;AAAA,IACR;AAAA,IACA,CAAC,QAAQ,KAAK;AAAA,EAChB;AAGA,EAAAZ,YAAU,MAAM;AACd,QAAI,CAAC,OAAQ;AAEb,UAAM,iBAAiB,OAAO;AAAA,MAC5BQ;AAAA,MACA,CAAC,UAAU;AACT,YAAI,CAAC,UAAU,MAAM,WAAW,EAAG,QAAO;AAC1C,eAAO,eAAe;AACtB,yBAAiB,CAAC,UAAU,OAAO,KAAK,MAAM,MAAM;AACpD,eAAO;AAAA,MACT;AAAA,MACA;AAAA,IACF;AAEA,UAAM,eAAe,OAAO;AAAA,MAC1BC;AAAA,MACA,CAAC,UAAU;AACT,YAAI,CAAC,UAAU,MAAM,WAAW,EAAG,QAAO;AAC1C,eAAO,eAAe;AACtB,yBAAiB,CAAC,UAAU,OAAO,IAAI,MAAM,UAAU,MAAM,MAAM;AACnE,eAAO;AAAA,MACT;AAAA,MACA;AAAA,IACF;AAEA,UAAM,kBAAkB,OAAO;AAAA,MAC7BC;AAAA,MACA,CAAC,UAAU;AACT,YAAI,CAAC,UAAU,MAAM,WAAW,EAAG,QAAO;AAC1C,eAAO,eAAe;AACtB,cAAM,OAAO,MAAM,aAAa;AAChC,YAAI,KAAM,YAAW,IAAI;AACzB,eAAO;AAAA,MACT;AAAA,MACA;AAAA,IACF;AAEA,UAAM,gBAAgB,OAAO;AAAA,MAC3B;AAAA,MACA,CAAC,UAAU;AACT,YAAI,CAAC,UAAU,MAAM,WAAW,EAAG,QAAO;AAC1C,eAAO,eAAe;AACtB,cAAM,OAAO,MAAM,aAAa;AAChC,YAAI,KAAM,YAAW,IAAI;AACzB,eAAO;AAAA,MACT;AAAA,MACA;AAAA,IACF;AAEA,UAAM,mBAAmB,OAAO;AAAA,MAC9BC;AAAA,MACA,CAAC,UAAU;AACT,YAAI,CAAC,OAAQ,QAAO;AACpB,eAAO,eAAe;AACtB,cAAM;AACN,eAAO;AAAA,MACT;AAAA,MACA;AAAA,IACF;AAEA,WAAO,MAAM;AACX,qBAAe;AACf,mBAAa;AACb,sBAAgB;AAChB,oBAAc;AACd,uBAAiB;AAAA,IACnB;AAAA,EACF,GAAG,CAAC,QAAQ,QAAQ,OAAO,eAAe,YAAY,KAAK,CAAC;AAE5D,MAAI,CAAC,mBAAmB,CAAC,UAAU,MAAM,WAAW,EAAG,QAAO;AAE9D,SAAOR;AAAA,IACL,gBAAAU;AAAA,MAAC;AAAA;AAAA,QACC;AAAA,QACA;AAAA,QACA;AAAA,QACA,UAAU,kBAAkB;AAAA,QAC5B,UAAU;AAAA,QACV,SAAS;AAAA;AAAA,IACX;AAAA,IACA;AAAA,EACF;AACF;AAIA,SAAS,gBAAgB;AAAA,EACvB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAOG;AACD,QAAM,UAAUZ,SAAuB,IAAI;AAG3C,EAAAD,YAAU,MAAM;AACd,UAAM,OAAO,QAAQ;AACrB,QAAI,CAAC,KAAM;AACX,UAAM,WAAW,KAAK,SAAS,aAAa;AAC5C,QAAI,UAAU;AACZ,eAAS,eAAe,EAAE,OAAO,UAAU,CAAC;AAAA,IAC9C;AAAA,EACF,GAAG,CAAC,aAAa,CAAC;AAGlB,QAAM,UAAU,UAAU,WAAW;AACrC,QAAM,cACJ,YAAY,MACR,oCACA;AAEN,SACE,gBAAAc;AAAA,IAAC;AAAA;AAAA,MACC,eAAY;AAAA,MACZ,OAAO;AAAA,QACL,UAAU;AAAA,QACV,KAAK,GAAG,SAAS,GAAG;AAAA,QACpB,MAAM,GAAG,SAAS,IAAI;AAAA,QACtB,QAAQ;AAAA,QACR,UAAU;AAAA,QACV,UAAU;AAAA,QACV,WAAW;AAAA,QACX,WAAW;AAAA,QACX,cAAc;AAAA,QACd,QAAQ;AAAA,QACR,iBAAiB;AAAA,QACjB,gBAAgB;AAAA,QAChB,sBAAsB;AAAA,QACtB,WAAW;AAAA,QACX,YAAY;AAAA,QACZ,WAAW;AAAA,QACX,SAAS;AAAA,MACX;AAAA,MACA,KAAK;AAAA,MAEJ;AAAA,cAAM,IAAI,CAAC,MAAM,UAChB,gBAAAA;AAAA,UAAC;AAAA;AAAA,YAEC,eAAa,gBAAgB,KAAK,EAAE;AAAA,YACpC,MAAK;AAAA,YACL,iBAAe,UAAU;AAAA,YACzB,aAAa,CAAC,MAAM;AAClB,gBAAE,eAAe;AACjB,uBAAS,IAAI;AAAA,YACf;AAAA,YACA,cAAc,MAAM,QAAQ,KAAK;AAAA,YACjC,OAAO;AAAA,cACL,SAAS;AAAA,cACT,YAAY;AAAA,cACZ,KAAK;AAAA,cACL,SAAS;AAAA,cACT,cAAc;AAAA,cACd,QAAQ;AAAA,cACR,iBACE,UAAU,gBACN,sBAAsB,WAAW,sBACjC;AAAA,cACN,YAAY;AAAA,YACd;AAAA,YAGC;AAAA,mBAAK,QACJ,gBAAAD;AAAA,gBAAC;AAAA;AAAA,kBACC,KAAK,KAAK;AAAA,kBACV,KAAI;AAAA,kBACJ,OAAO;AAAA,oBACL,OAAO;AAAA,oBACP,QAAQ;AAAA,oBACR,cAAc;AAAA,oBACd,WAAW;AAAA,oBACX,YAAY;AAAA,kBACd;AAAA;AAAA,cACF;AAAA,cAED,CAAC,KAAK,QACL,gBAAAA;AAAA,gBAAC;AAAA;AAAA,kBACC,OAAO;AAAA,oBACL,OAAO;AAAA,oBACP,QAAQ;AAAA,oBACR,cAAc;AAAA,oBACd,iBAAiB,sBAAsB,WAAW;AAAA,oBAClD,OAAO;AAAA,oBACP,SAAS;AAAA,oBACT,YAAY;AAAA,oBACZ,gBAAgB;AAAA,oBAChB,UAAU;AAAA,oBACV,YAAY;AAAA,oBACZ,YAAY;AAAA,kBACd;AAAA,kBAEC,eAAK,MAAM,OAAO,CAAC,EAAE,YAAY;AAAA;AAAA,cACpC;AAAA,cAIF,gBAAAC,OAAC,SAAI,OAAO,EAAE,MAAM,GAAG,UAAU,EAAE,GACjC;AAAA,gCAAAD;AAAA,kBAAC;AAAA;AAAA,oBACC,OAAO;AAAA,sBACL,UAAU;AAAA,sBACV,YAAY;AAAA,sBACZ,OAAO;AAAA,sBACP,YAAY;AAAA,sBACZ,UAAU;AAAA,sBACV,cAAc;AAAA,oBAChB;AAAA,oBAEC,qBAAW,SAAS,WAAW,IAAI,IAAI,KAAK;AAAA;AAAA,gBAC/C;AAAA,gBACC,KAAK,QACJ,gBAAAA;AAAA,kBAAC;AAAA;AAAA,oBACC,OAAO;AAAA,sBACL,UAAU;AAAA,sBACV,OAAO;AAAA,sBACP,YAAY;AAAA,sBACZ,UAAU;AAAA,sBACV,cAAc;AAAA,oBAChB;AAAA,oBAEC,eAAK;AAAA;AAAA,gBACR;AAAA,iBAEJ;AAAA;AAAA;AAAA,UApFK,KAAK;AAAA,QAqFZ,CACD;AAAA,QAGD,gBAAAA;AAAA,UAAC;AAAA;AAAA,YACC,yBAAyB;AAAA,cACvB,QAAQ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,YAYV;AAAA;AAAA,QACF;AAAA;AAAA;AAAA,EACF;AAEJ;;;AC1dA,SAAS,aAAAE,mBAAiB;AAE1B,SAAS,6BAAAC,mCAAiC;AAC1C;AAAA,EACE,iBAAAC;AAAA,EACA,qBAAAC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP,SAAS,6BAA6B;;;ACCtC,IAAM,eAAe,oBAAI,IAAI;AAAA,EAC3B;AAAA,EAAK;AAAA,EAAM;AAAA,EAAM;AAAA,EAAM;AAAA,EAAM;AAAA,EAAM;AAAA,EAAM;AAAA,EACzC;AAAA,EAAU;AAAA,EAAK;AAAA,EAAM;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAO;AAAA,EAC3C;AAAA,EAAQ;AAAA,EAAO;AAAA,EACf;AAAA,EAAM;AAAA,EAAM;AAAA,EACZ;AAAA,EAAK;AAAA,EACL;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAM;AAAA,EAAM;AAAA,EACvC;AACF,CAAC;AAKD,IAAM,sBAAsB,oBAAI,IAAI,CAAC,UAAU,SAAS,UAAU,UAAU,UAAU,CAAC;AAMvF,IAAM,qBAAkD;AAAA,EACtD,GAAG,oBAAI,IAAI,CAAC,MAAM,CAAC;AAAA,EACnB,KAAK,oBAAI,IAAI,CAAC,OAAO,KAAK,CAAC;AAC7B;AAKA,SAAS,iBAAiB,SAAgC;AACxD,UAAQ,SAAS;AAAA,IACf,KAAK;AAAK,aAAO;AAAA,IACjB,KAAK;AAAK,aAAO;AAAA,IACjB,KAAK;AAAO,aAAO;AAAA,IACnB,KAAK;AAAU,aAAO;AAAA,IACtB;AAAS,aAAO;AAAA,EAClB;AACF;AAOA,SAAS,uBAAuB,UAAiC;AAC/D,QAAM,QAAQ,SAAS,MAAM,8BAA8B;AAC3D,MAAI,CAAC,MAAO,QAAO;AAEnB,QAAM,QAAQ,WAAW,MAAM,CAAC,CAAE;AAClC,QAAM,OAAO,MAAM,CAAC,KAAK;AAGzB,MAAI;AACJ,UAAQ,MAAM;AAAA,IACZ,KAAK;AAAM,WAAK,SAAS,IAAI;AAAI;AAAA,IACjC,KAAK;AAAA,IACL,KAAK;AAAO,WAAK,QAAQ;AAAI;AAAA,IAC7B;AAAS,WAAK;AAAA,EAChB;AAGA,MAAI,MAAM,GAAI,QAAO;AACrB,MAAI,MAAM,GAAI,QAAO;AACrB,MAAI,MAAM,GAAI,QAAO;AACrB,SAAO;AACT;AAKA,SAAS,gBAAgB,IAAmB;AAC1C,QAAM,UAAU,mBAAmB,GAAG,OAAO;AAC7C,QAAM,QAAQ,MAAM,KAAK,GAAG,UAAU;AAEtC,aAAW,QAAQ,OAAO;AACxB,QAAI,CAAC,WAAW,CAAC,QAAQ,IAAI,KAAK,IAAI,GAAG;AACvC,SAAG,gBAAgB,KAAK,IAAI;AAAA,IAC9B;AAAA,EACF;AACF;AAOA,SAAS,aAAa,MAAY,KAAqB;AACrD,MAAI,KAAK,aAAa,GAAmB;AACvC;AAAA,EACF;AAEA,MAAI,KAAK,aAAa,GAAsB;AAE1C,SAAK,YAAY,YAAY,IAAI;AACjC;AAAA,EACF;AAEA,QAAM,KAAK;AACX,QAAM,UAAU,GAAG;AAGnB,MAAI,oBAAoB,IAAI,OAAO,GAAG;AACpC,OAAG,YAAY,YAAY,EAAE;AAC7B;AAAA,EACF;AAGA,QAAM,cAAc,GAAG,aAAa,OAAO;AAC3C,MAAI,eAA8B;AAElC,MAAI,aAAa;AACf,UAAM,gBAAgB,YAAY,MAAM,0BAA0B;AAClE,QAAI,eAAe;AACjB,qBAAe,uBAAuB,cAAc,CAAC,EAAG,KAAK,CAAC;AAAA,IAChE;AAAA,EACF;AAGA,QAAM,WAAW,MAAM,KAAK,GAAG,UAAU;AACzC,aAAW,SAAS,UAAU;AAC5B,iBAAa,OAAO,GAAG;AAAA,EACzB;AAGA,MAAI,YAAY,UAAU,YAAY,QAAQ;AAE5C,QAAI,iBAAiB,QAAQ,gBAAgB,KAAK,gBAAgB,GAAG;AACnE,YAAM,UAAU,IAAI,cAAc,IAAI,YAAY,EAAE;AACpD,aAAO,GAAG,YAAY;AACpB,gBAAQ,YAAY,GAAG,UAAU;AAAA,MACnC;AACA,SAAG,YAAY,aAAa,SAAS,EAAE;AACvC;AAAA,IACF;AAGA,kBAAc,EAAE;AAChB;AAAA,EACF;AAGA,MAAI,YAAY,OAAO;AAErB,QAAI,iBAAiB,QAAQ,gBAAgB,KAAK,gBAAgB,GAAG;AACnE,YAAM,UAAU,IAAI,cAAc,IAAI,YAAY,EAAE;AACpD,aAAO,GAAG,YAAY;AACpB,gBAAQ,YAAY,GAAG,UAAU;AAAA,MACnC;AACA,SAAG,YAAY,aAAa,SAAS,EAAE;AACvC;AAAA,IACF;AAGA,UAAM,IAAI,IAAI,cAAc,GAAG;AAC/B,WAAO,GAAG,YAAY;AACpB,QAAE,YAAY,GAAG,UAAU;AAAA,IAC7B;AACA,OAAG,YAAY,aAAa,GAAG,EAAE;AACjC;AAAA,EACF;AAGA,MAAI,CAAC,aAAa,IAAI,OAAO,GAAG;AAE9B,UAAMC,cAAa,iBAAiB,OAAO;AAC3C,QAAIA,eAAc,aAAa,IAAIA,WAAU,GAAG;AAC9C,YAAM,cAAc,IAAI,cAAcA,WAAU;AAChD,aAAO,GAAG,YAAY;AACpB,oBAAY,YAAY,GAAG,UAAU;AAAA,MACvC;AACA,SAAG,YAAY,aAAa,aAAa,EAAE;AAC3C,sBAAgB,WAAW;AAC3B;AAAA,IACF;AAGA,kBAAc,EAAE;AAChB;AAAA,EACF;AAGA,QAAM,aAAa,iBAAiB,OAAO;AAC3C,MAAI,YAAY;AACd,UAAM,cAAc,IAAI,cAAc,UAAU;AAChD,WAAO,GAAG,YAAY;AACpB,kBAAY,YAAY,GAAG,UAAU;AAAA,IACvC;AACA,OAAG,YAAY,aAAa,aAAa,EAAE;AAC3C,oBAAgB,WAAW;AAC3B;AAAA,EACF;AAGA,kBAAgB,EAAE;AACpB;AAKA,SAAS,cAAc,IAAmB;AACxC,QAAM,SAAS,GAAG;AAClB,MAAI,CAAC,OAAQ;AAEb,SAAO,GAAG,YAAY;AACpB,WAAO,aAAa,GAAG,YAAY,EAAE;AAAA,EACvC;AACA,SAAO,YAAY,EAAE;AACvB;AAYO,SAAS,mBAAmB,MAAsB;AACvD,QAAM,SAAS,IAAI,UAAU;AAC7B,QAAM,MAAM,OAAO,gBAAgB,MAAM,WAAW;AAGpD,QAAM,OAAO,IAAI;AAGjB,QAAM,WAAW,MAAM,KAAK,KAAK,UAAU;AAC3C,aAAW,SAAS,UAAU;AAC5B,iBAAa,OAAO,GAAG;AAAA,EACzB;AAEA,SAAO,KAAK;AACd;;;AD9NO,SAAS,cAAc;AAC5B,QAAM,CAAC,MAAM,IAAIC,4BAA0B;AAE3C,EAAAC,YAAU,MAAM;AACd,WAAO,OAAO;AAAA,MACZ;AAAA,MACA,CAAC,UAA0B;AACzB,cAAM,gBAAgB,MAAM;AAC5B,YAAI,CAAC,cAAe,QAAO;AAE3B,cAAM,gBAAgB,MAAM,KAAK,cAAc,KAAK,EAAE;AAAA,UAAK,CAAC,SAC1D,KAAK,KAAK,WAAW,QAAQ;AAAA,QAC/B;AACA,YAAI,cAAe,QAAO;AAE1B,cAAM,OAAO,cAAc,QAAQ,WAAW;AAC9C,YAAI,CAAC,KAAM,QAAO;AAElB,cAAM,gBAAgB,mBAAmB,IAAI;AAE7C,cAAM,SAAS,IAAI,UAAU;AAC7B,cAAM,MAAM,OAAO,gBAAgB,eAAe,WAAW;AAE7D,cAAM,QAAQ,sBAAsB,QAAQ,GAAG;AAE/C,YAAI,MAAM,WAAW,EAAG,QAAO;AAE/B,cAAM,YAAYC,eAAc;AAChC,YAAIC,mBAAkB,SAAS,GAAG;AAChC,oBAAU,WAAW;AAAA,QACvB;AACA,qBAAa,KAAK;AAElB,cAAM,eAAe;AACrB,eAAO;AAAA,MACT;AAAA,MACA;AAAA,IACF;AAAA,EACF,GAAG,CAAC,MAAM,CAAC;AAEX,SAAO;AACT;;;AE7DA,SAAS,eAAAC,eAAa,aAAAC,aAAW,UAAAC,UAAQ,YAAAC,iBAAgB;AAEzD,SAAS,gBAAAC,qBAAoB;AAE7B,SAAS,6BAAAC,mCAAiC;AAC1C;AAAA,EACE,iBAAAC;AAAA,EACA,qBAAAC;AAAA,EACA,eAAAC;AAAA,EACA,yBAAAC;AAAA,EACA,wBAAAC;AAAA,EACA,0BAAAC;AAAA,EACA,wBAAAC;AAAA,EACA,qBAAAC;AAAA,EACA,sBAAAC;AAAA,EACA,mBAAAC;AAAA,OAEK;;;ACbA,IAAM,iBAA8B;AAAA,EACzC,EAAE,OAAO,aAAa,MAAM,iBAAiB,UAAU,CAAC,SAAS,SAAS,OAAO,MAAM,EAAE;AAAA,EACzF,EAAE,OAAO,aAAa,MAAM,+BAA+B,UAAU,CAAC,SAAS,SAAS,OAAO,SAAS,EAAE;AAAA,EAC1G,EAAE,OAAO,aAAa,MAAM,mCAAmC,UAAU,CAAC,SAAS,SAAS,OAAO,OAAO,EAAE;AAAA,EAC5G,EAAE,OAAO,aAAa,MAAM,kCAAkC,UAAU,CAAC,SAAS,SAAS,QAAQ,MAAM,EAAE;AAAA,EAC3G,EAAE,OAAO,aAAa,MAAM,2BAA2B,UAAU,CAAC,SAAS,SAAS,aAAa,MAAM,EAAE;AAAA,EACzG,EAAE,OAAO,aAAa,MAAM,4BAA4B,UAAU,CAAC,SAAS,SAAS,SAAS,UAAU,SAAS,EAAE;AAAA,EACnH,EAAE,OAAO,aAAa,MAAM,iCAAiC,UAAU,CAAC,SAAS,QAAQ,QAAQ,aAAa,OAAO,EAAE;AAAA,EACvH,EAAE,OAAO,aAAa,MAAM,0BAA0B,UAAU,CAAC,SAAS,OAAO,SAAS,SAAS,OAAO,OAAO,EAAE;AAAA,EACnH,EAAE,OAAO,aAAa,MAAM,yBAAyB,UAAU,CAAC,SAAS,SAAS,WAAW,SAAS,EAAE;AAAA,EACxG,EAAE,OAAO,aAAa,MAAM,oBAAoB,UAAU,CAAC,SAAS,WAAW,SAAS,SAAS,EAAE;AAAA,EACnG,EAAE,OAAO,aAAa,MAAM,gBAAgB,UAAU,CAAC,QAAQ,OAAO,eAAe,WAAW,WAAW,EAAE;AAAA,EAC7G,EAAE,OAAO,aAAa,MAAM,gBAAgB,UAAU,CAAC,QAAQ,SAAS,WAAW,MAAM,EAAE;AAAA,EAC3F,EAAE,OAAO,aAAa,MAAM,kCAAkC,UAAU,CAAC,SAAS,SAAS,QAAQ,SAAS,EAAE;AAAA,EAC9G,EAAE,OAAO,aAAa,MAAM,0BAA0B,UAAU,CAAC,SAAS,YAAY,QAAQ,SAAS,EAAE;AAAA,EACzG,EAAE,OAAO,aAAa,MAAM,4BAA4B,UAAU,CAAC,QAAQ,SAAS,SAAS,aAAa,QAAQ,EAAE;AAAA,EACpH,EAAE,OAAO,aAAa,MAAM,gCAAgC,UAAU,CAAC,QAAQ,SAAS,SAAS,SAAS,aAAa,EAAE;AAAA,EACzH,EAAE,OAAO,aAAa,MAAM,eAAe,UAAU,CAAC,QAAQ,QAAQ,UAAU,OAAO,WAAW,KAAK,EAAE;AAAA,EACzG,EAAE,OAAO,aAAa,MAAM,uBAAuB,UAAU,CAAC,QAAQ,QAAQ,SAAS,WAAW,EAAE;AAAA,EACpG,EAAE,OAAO,aAAa,MAAM,gBAAgB,UAAU,CAAC,QAAQ,QAAQ,MAAM,EAAE;AAAA,EAC/E,EAAE,OAAO,gBAAoB,MAAM,gBAAgB,UAAU,CAAC,SAAS,QAAQ,SAAS,SAAS,EAAE;AAAA,EACnG,EAAE,OAAO,aAAa,MAAM,iCAAiC,UAAU,CAAC,QAAQ,QAAQ,WAAW,EAAE;AAAA,EACrG,EAAE,OAAO,aAAa,MAAM,kCAAkC,UAAU,CAAC,QAAQ,QAAQ,OAAO,EAAE;AAAA,EAClG,EAAE,OAAO,aAAa,MAAM,0BAA0B,UAAU,CAAC,SAAS,OAAO,YAAY,SAAS,aAAa,EAAE;AAAA,EACrH,EAAE,OAAO,aAAa,MAAM,sBAAsB,UAAU,CAAC,SAAS,aAAa,UAAU,SAAS,MAAM,EAAE;AAAA,EAC9G,EAAE,OAAO,aAAa,MAAM,oBAAoB,UAAU,CAAC,UAAU,WAAW,SAAS,MAAM,EAAE;AAAA,EACjG,EAAE,OAAO,aAAa,MAAM,4BAA4B,UAAU,CAAC,UAAU,QAAQ,WAAW,SAAS,MAAM,EAAE;AAAA,EACjH,EAAE,OAAO,aAAa,MAAM,aAAa,UAAU,CAAC,SAAS,QAAQ,SAAS,SAAS,OAAO,EAAE;AAAA,EAChG,EAAE,OAAO,aAAa,MAAM,8BAA8B,UAAU,CAAC,UAAU,WAAW,SAAS,OAAO,EAAE;AAAA,EAC5G,EAAE,OAAO,aAAa,MAAM,oBAAoB,UAAU,CAAC,SAAS,QAAQ,UAAU,QAAQ,QAAQ,EAAE;AAAA,EACxG,EAAE,OAAO,aAAa,MAAM,gBAAgB,UAAU,CAAC,OAAO,WAAW,QAAQ,QAAQ,MAAM,EAAE;AAAA,EACjG,EAAE,OAAO,aAAa,MAAM,6BAA6B,UAAU,CAAC,QAAQ,UAAU,UAAU,OAAO,QAAQ,EAAE;AAAA,EACjH,EAAE,OAAO,aAAa,MAAM,2CAA2C,UAAU,CAAC,SAAS,YAAY,QAAQ,MAAM,EAAE;AAAA,EACvH,EAAE,OAAO,aAAa,MAAM,yBAAyB,UAAU,CAAC,QAAQ,OAAO,UAAU,WAAW,QAAQ,EAAE;AAAA,EAC9G,EAAE,OAAO,aAAa,MAAM,qBAAqB,UAAU,CAAC,SAAS,UAAU,QAAQ,WAAW,KAAK,EAAE;AAAA,EACzG,EAAE,OAAO,aAAa,MAAM,iBAAiB,UAAU,CAAC,SAAS,OAAO,UAAU,YAAY,WAAW,EAAE;AAAA,EAC3G,EAAE,OAAO,aAAa,MAAM,4BAA4B,UAAU,CAAC,aAAa,cAAc,SAAS,QAAQ,EAAE;AAAA,EACjH,EAAE,OAAO,aAAa,MAAM,gBAAgB,UAAU,CAAC,OAAO,SAAS,eAAe,SAAS,EAAE;AAAA,EACjG,EAAE,OAAO,aAAa,MAAM,uBAAuB,UAAU,CAAC,SAAS,eAAe,WAAW,SAAS,EAAE;AAAA,EAC5G,EAAE,OAAO,aAAa,MAAM,sBAAsB,UAAU,CAAC,UAAU,cAAc,QAAQ,OAAO,EAAE;AAAA,EACtG,EAAE,OAAO,aAAa,MAAM,oBAAoB,UAAU,CAAC,aAAa,UAAU,OAAO,WAAW,EAAE;AAAA,EACtG,EAAE,OAAO,kCAAsC,MAAM,kBAAkB,UAAU,CAAC,UAAU,SAAS,YAAY,MAAM,EAAE;AAAA,EACzH,EAAE,OAAO,aAAa,MAAM,iBAAiB,UAAU,CAAC,SAAS,QAAQ,OAAO,SAAS,OAAO,EAAE;AAAA,EAClG,EAAE,OAAO,aAAa,MAAM,iBAAiB,UAAU,CAAC,WAAW,eAAe,SAAS,OAAO,cAAc,EAAE;AAAA,EAClH,EAAE,OAAO,aAAa,MAAM,0BAA0B,UAAU,CAAC,WAAW,WAAW,YAAY,SAAS,YAAY,EAAE;AAAA,EAC1H,EAAE,OAAO,aAAa,MAAM,kBAAkB,UAAU,CAAC,WAAW,WAAW,WAAW,UAAU,OAAO,EAAE;AAAA,EAC7G,EAAE,OAAO,4BAA8B,MAAM,iBAAiB,UAAU,CAAC,UAAU,QAAQ,UAAU,SAAS,QAAQ,EAAE;AAAA,EACxH,EAAE,OAAO,aAAa,MAAM,cAAc,UAAU,CAAC,OAAO,aAAa,aAAa,MAAM,EAAE;AAAA,EAC9F,EAAE,OAAO,aAAa,MAAM,iBAAiB,UAAU,CAAC,YAAY,WAAW,QAAQ,WAAW,OAAO,EAAE;AAAA,EAC3G,EAAE,OAAO,aAAa,MAAM,gBAAgB,UAAU,CAAC,OAAO,WAAW,cAAc,cAAc,EAAE;AAAA,EACvG,EAAE,OAAO,aAAa,MAAM,eAAe,UAAU,CAAC,UAAU,SAAS,aAAa,MAAM,EAAE;AAAA,EAC9F,EAAE,OAAO,aAAa,MAAM,iBAAiB,UAAU,CAAC,SAAS,UAAU,SAAS,MAAM,EAAE;AAAA,EAC5F,EAAE,OAAO,aAAa,MAAM,iBAAiB,UAAU,CAAC,SAAS,OAAO,SAAS,QAAQ,KAAK,EAAE;AAAA,EAChG,EAAE,OAAO,aAAa,MAAM,0BAA0B,UAAU,CAAC,QAAQ,QAAQ,SAAS,OAAO,QAAQ,EAAE;AAAA,EAC3G,EAAE,OAAO,aAAa,MAAM,yBAAyB,UAAU,CAAC,QAAQ,SAAS,OAAO,aAAa,EAAE;AAAA,EACvG,EAAE,OAAO,aAAa,MAAM,0BAA0B,UAAU,CAAC,QAAQ,WAAW,WAAW,QAAQ,QAAQ,EAAE;AAAA,EACjH,EAAE,OAAO,aAAa,MAAM,kBAAkB,UAAU,CAAC,QAAQ,YAAY,SAAS,SAAS,OAAO,EAAE;AAAA,EACxG,EAAE,OAAO,aAAa,MAAM,iBAAiB,UAAU,CAAC,QAAQ,SAAS,SAAS,aAAa,MAAM,EAAE;AAAA,EACvG,EAAE,OAAO,aAAa,MAAM,iBAAiB,UAAU,CAAC,UAAU,QAAQ,QAAQ,UAAU,WAAW,EAAE;AAAA,EACzG,EAAE,OAAO,aAAa,MAAM,YAAY,UAAU,CAAC,OAAO,QAAQ,SAAS,QAAQ,QAAQ,EAAE;AAAA,EAC7F,EAAE,OAAO,aAAa,MAAM,aAAa,UAAU,CAAC,QAAQ,UAAU,UAAU,OAAO,KAAK,EAAE;AAAA,EAC9F,EAAE,OAAO,aAAa,MAAM,cAAc,UAAU,CAAC,SAAS,SAAS,SAAS,SAAS,aAAa,EAAE;AAAA,EACxG,EAAE,OAAO,aAAa,MAAM,8BAA8B,UAAU,CAAC,QAAQ,SAAS,eAAe,aAAa,EAAE;AAAA,EACpH,EAAE,OAAO,aAAa,MAAM,kBAAkB,UAAU,CAAC,cAAc,WAAW,UAAU,aAAa,KAAK,EAAE;AAAA,EAChH,EAAE,OAAO,aAAa,MAAM,mBAAmB,UAAU,CAAC,UAAU,WAAW,OAAO,QAAQ,EAAE;AAAA,EAChG,EAAE,OAAO,aAAa,MAAM,iBAAiB,UAAU,CAAC,SAAS,aAAa,YAAY,OAAO,UAAU,EAAE;AAAA,EAC7G,EAAE,OAAO,aAAa,MAAM,kBAAkB,UAAU,CAAC,YAAY,OAAO,aAAa,WAAW,UAAU,EAAE;AAAA,EAChH,EAAE,OAAO,aAAa,MAAM,gCAAgC,UAAU,CAAC,QAAQ,cAAc,aAAa,SAAS,EAAE;AAAA,EACrH,EAAE,OAAO,aAAa,MAAM,aAAa,UAAU,CAAC,QAAQ,QAAQ,SAAS,WAAW,OAAO,EAAE;AAAA,EACjG,EAAE,OAAO,aAAa,MAAM,qBAAqB,UAAU,CAAC,WAAW,UAAU,aAAa,WAAW,OAAO,EAAE;AAAA,EAClH,EAAE,OAAO,aAAa,MAAM,iBAAiB,UAAU,CAAC,YAAY,WAAW,QAAQ,QAAQ,EAAE;AAAA,EACjG,EAAE,OAAO,aAAa,MAAM,4BAA4B,UAAU,CAAC,aAAa,UAAU,OAAO,KAAK,EAAE;AAAA,EACxG,EAAE,OAAO,aAAa,MAAM,gBAAgB,UAAU,CAAC,WAAW,WAAW,WAAW,WAAW,EAAE;AAAA,EACrG,EAAE,OAAO,aAAa,MAAM,0BAA0B,UAAU,CAAC,OAAO,SAAS,gBAAgB,SAAS,EAAE;AAAA,EAC5G,EAAE,OAAO,gBAAoB,MAAM,iBAAiB,UAAU,CAAC,OAAO,SAAS,WAAW,cAAc,EAAE;AAAA,EAC1G,EAAE,OAAO,aAAa,MAAM,wBAAwB,UAAU,CAAC,YAAY,SAAS,OAAO,MAAM,EAAE;AAAA,EACnG,EAAE,OAAO,aAAa,MAAM,eAAe,UAAU,CAAC,YAAY,SAAS,WAAW,KAAK,EAAE;AAAA,EAC7F,EAAE,OAAO,aAAa,MAAM,mBAAmB,UAAU,CAAC,cAAc,WAAW,UAAU,UAAU,EAAE;AAAA,EACzG,EAAE,OAAO,aAAa,MAAM,gBAAgB,UAAU,CAAC,SAAS,eAAe,OAAO,SAAS,EAAE;AAAA,EACjG,EAAE,OAAO,aAAa,MAAM,iBAAiB,UAAU,CAAC,UAAU,cAAc,OAAO,QAAQ,UAAU,EAAE;AAAA,EAC3G,EAAE,OAAO,aAAa,MAAM,2BAA2B,UAAU,CAAC,OAAO,OAAO,gBAAgB,aAAa,OAAO,EAAE;AAAA,EACtH,EAAE,OAAO,aAAa,MAAM,iCAAiC,UAAU,CAAC,SAAS,YAAY,SAAS,EAAE;AAAA,EACxG,EAAE,OAAO,aAAa,MAAM,kBAAkB,UAAU,CAAC,WAAW,QAAQ,YAAY,OAAO,EAAE;AAAA,EACjG,EAAE,OAAO,aAAa,MAAM,gBAAgB,UAAU,CAAC,QAAQ,UAAU,SAAS,WAAW,EAAE;AAAA,EAC/F,EAAE,OAAO,aAAa,MAAM,2BAA2B,UAAU,CAAC,WAAW,WAAW,SAAS,SAAS,EAAE;AAAA,EAC5G,EAAE,OAAO,aAAa,MAAM,yBAAyB,UAAU,CAAC,OAAO,YAAY,gBAAgB,MAAM,EAAE;AAAA,EAC3G,EAAE,OAAO,aAAa,MAAM,eAAe,UAAU,CAAC,OAAO,OAAO,SAAS,OAAO,EAAE;AAAA,EACtF,EAAE,OAAO,aAAa,MAAM,sBAAsB,UAAU,CAAC,OAAO,OAAO,OAAO,SAAS,MAAM,EAAE;AAAA,EACnG,EAAE,OAAO,aAAa,MAAM,0BAA0B,UAAU,CAAC,UAAU,QAAQ,UAAU,UAAU,KAAK,EAAE;AAAA,EAC9G,EAAE,OAAO,aAAa,MAAM,mBAAmB,UAAU,CAAC,YAAY,cAAc,WAAW,EAAE;AAAA,EACjG,EAAE,OAAO,aAAa,MAAM,oBAAoB,UAAU,CAAC,aAAa,YAAY,cAAc,QAAQ,EAAE;AAAA,EAC5G,EAAE,OAAO,aAAa,MAAM,qBAAqB,UAAU,CAAC,OAAO,gBAAgB,WAAW,MAAM,EAAE;AAAA,EACtG,EAAE,OAAO,aAAa,MAAM,4BAA4B,UAAU,CAAC,OAAO,SAAS,SAAS,WAAW,EAAE;AAAA,EACzG,EAAE,OAAO,aAAa,MAAM,cAAc,UAAU,CAAC,SAAS,SAAS,aAAa,YAAY,EAAE;AAAA,EAClG,EAAE,OAAO,aAAa,MAAM,cAAc,UAAU,CAAC,SAAS,aAAa,cAAc,OAAO,EAAE;AAAA,EAClG,EAAE,OAAO,aAAa,MAAM,gBAAgB,UAAU,CAAC,QAAQ,SAAS,SAAS,QAAQ,EAAE;AAAA,EAC3F,EAAE,OAAO,aAAa,MAAM,6BAA6B,UAAU,CAAC,SAAS,cAAc,WAAW,SAAS,EAAE;AAAA,EACjH,EAAE,OAAO,aAAa,MAAM,gBAAgB,UAAU,CAAC,SAAS,OAAO,QAAQ,WAAW,KAAK,EAAE;AAAA,EACjG,EAAE,OAAO,aAAa,MAAM,cAAc,UAAU,CAAC,SAAS,OAAO,WAAW,QAAQ,EAAE;AAAA,EAC1F,EAAE,OAAO,aAAa,MAAM,8BAA8B,UAAU,CAAC,SAAS,WAAW,SAAS,WAAW,EAAE;AAAA,EAC/G,EAAE,OAAO,aAAa,MAAM,2BAA2B,UAAU,CAAC,SAAS,QAAQ,YAAY,SAAS,EAAE;AAAA,EAC1G,EAAE,OAAO,aAAa,MAAM,yBAAyB,UAAU,CAAC,SAAS,QAAQ,SAAS,OAAO,EAAE;AAAA,EACnG,EAAE,OAAO,aAAa,MAAM,SAAS,UAAU,CAAC,SAAS,QAAQ,YAAY,UAAU,gBAAgB,EAAE;AAAA,EACzG,EAAE,OAAO,gBAAoB,MAAM,wBAAwB,UAAU,CAAC,SAAS,UAAU,UAAU,QAAQ,EAAE;AAAA,EAC7G,EAAE,OAAO,aAAa,MAAM,eAAe,UAAU,CAAC,QAAQ,QAAQ,QAAQ,OAAO,EAAE;AAAA,EACvF,EAAE,OAAO,aAAa,MAAM,cAAc,UAAU,CAAC,SAAS,SAAS,SAAS,QAAQ,QAAQ,EAAE;AAAA,EAClG,EAAE,OAAO,aAAa,MAAM,SAAS,UAAU,CAAC,SAAS,aAAa,UAAU,SAAS,KAAK,EAAE;AAAA,EAChG,EAAE,OAAO,aAAa,MAAM,SAAS,UAAU,CAAC,SAAS,SAAS,OAAO,kBAAkB,EAAE;AAAA,EAC7F,EAAE,OAAO,aAAa,MAAM,SAAS,UAAU,CAAC,SAAS,OAAO,WAAW,MAAM,YAAY,EAAE;AAAA,EAC/F,EAAE,OAAO,aAAa,MAAM,gBAAgB,UAAU,CAAC,OAAO,SAAS,SAAS,MAAM,EAAE;AAAA,EACxF,EAAE,OAAO,aAAa,MAAM,yBAAyB,UAAU,CAAC,OAAO,SAAS,SAAS,OAAO,EAAE;AAAA,EAClG,EAAE,OAAO,aAAa,MAAM,+BAA+B,UAAU,CAAC,OAAO,QAAQ,SAAS,OAAO,EAAE;AAAA,EACvG,EAAE,OAAO,aAAa,MAAM,eAAe,UAAU,CAAC,OAAO,QAAQ,QAAQ,WAAW,EAAE;AAAA,EAC1F,EAAE,OAAO,aAAa,MAAM,aAAa,UAAU,CAAC,OAAO,SAAS,WAAW,QAAQ,EAAE;AAAA,EACzF,EAAE,OAAO,aAAa,MAAM,cAAc,UAAU,CAAC,OAAO,OAAO,OAAO,OAAO,EAAE;AAAA,EACnF,EAAE,OAAO,aAAa,MAAM,eAAe,UAAU,CAAC,OAAO,SAAS,QAAQ,QAAQ,EAAE;AAAA,EACxF,EAAE,OAAO,aAAa,MAAM,iBAAiB,UAAU,CAAC,UAAU,WAAW,WAAW,OAAO,EAAE;AAAA,EACjG,EAAE,OAAO,aAAa,MAAM,gBAAgB,UAAU,CAAC,SAAS,SAAS,cAAc,SAAS,EAAE;AAAA,EAElG,EAAE,OAAO,aAAa,MAAM,aAAa,UAAU,CAAC,YAAY,OAAO,WAAW,QAAQ,QAAQ,IAAI,EAAE;AAAA,EACxG,EAAE,OAAO,aAAa,MAAM,eAAe,UAAU,CAAC,cAAc,MAAM,WAAW,OAAO,YAAY,EAAE;AAAA,EAC1G,EAAE,OAAO,aAAa,MAAM,kBAAkB,UAAU,CAAC,QAAQ,YAAY,SAAS,mBAAmB,WAAW,EAAE;AAAA,EACtH,EAAE,OAAO,aAAa,MAAM,iBAAiB,UAAU,CAAC,aAAa,UAAU,UAAU,cAAc,KAAK,EAAE;AAAA,EAC9G,EAAE,OAAO,aAAa,MAAM,eAAe,UAAU,CAAC,QAAQ,SAAS,MAAM,OAAO,WAAW,OAAO,EAAE;AAAA,EACxG,EAAE,OAAO,aAAa,MAAM,uBAAuB,UAAU,CAAC,QAAQ,YAAY,UAAU,MAAM,EAAE;AAAA,EACpG,EAAE,OAAO,mBAAqB,MAAM,6BAA6B,UAAU,CAAC,QAAQ,WAAW,aAAa,QAAQ,MAAM,EAAE;AAAA,EAC5H,EAAE,OAAO,UAAY,MAAM,eAAe,UAAU,CAAC,QAAQ,QAAQ,aAAa,MAAM,EAAE;AAAA,EAC1F,EAAE,OAAO,aAAa,MAAM,iBAAiB,UAAU,CAAC,SAAS,aAAa,UAAU,WAAW,EAAE;AAAA,EACrG,EAAE,OAAO,aAAa,MAAM,mBAAmB,UAAU,CAAC,QAAQ,SAAS,SAAS,WAAW,EAAE;AAAA,EACjG,EAAE,OAAO,aAAa,MAAM,kBAAkB,UAAU,CAAC,QAAQ,QAAQ,SAAS,WAAW,EAAE;AAAA,EAC/F,EAAE,OAAO,aAAa,MAAM,kBAAkB,UAAU,CAAC,QAAQ,QAAQ,SAAS,MAAM,EAAE;AAAA,EAC1F,EAAE,OAAO,aAAa,MAAM,gBAAgB,UAAU,CAAC,QAAQ,MAAM,SAAS,WAAW,QAAQ,EAAE;AAAA,EACnG,EAAE,OAAO,aAAa,MAAM,WAAW,UAAU,CAAC,MAAM,WAAW,QAAQ,QAAQ,QAAQ,WAAW,EAAE;AAAA,EACxG,EAAE,OAAO,aAAa,MAAM,mBAAmB,UAAU,CAAC,WAAW,WAAW,QAAQ,UAAU,EAAE;AAAA,EACpG,EAAE,OAAO,aAAa,MAAM,iBAAiB,UAAU,CAAC,SAAS,QAAQ,UAAU,OAAO,EAAE;AAAA,EAC5F,EAAE,OAAO,gBAAoB,MAAM,gBAAgB,UAAU,CAAC,SAAS,WAAW,OAAO,GAAG,EAAE;AAAA,EAC9F,EAAE,OAAO,aAAa,MAAM,mBAAmB,UAAU,CAAC,QAAQ,QAAQ,mBAAmB,MAAM,EAAE;AAAA,EACrG,EAAE,OAAO,aAAa,MAAM,4CAA4C,UAAU,CAAC,SAAS,QAAQ,QAAQ,OAAO,EAAE;AAAA,EACrH,EAAE,OAAO,aAAa,MAAM,oBAAoB,UAAU,CAAC,QAAQ,OAAO,QAAQ,eAAe,EAAE;AAAA,EACnG,EAAE,OAAO,aAAa,MAAM,qBAAqB,UAAU,CAAC,QAAQ,SAAS,SAAS,OAAO,EAAE;AAAA,EAC/F,EAAE,OAAO,aAAa,MAAM,gBAAgB,UAAU,CAAC,QAAQ,SAAS,cAAc,OAAO,EAAE;AAAA,EAC/F,EAAE,OAAO,aAAa,MAAM,gCAAgC,UAAU,CAAC,QAAQ,SAAS,aAAa,MAAM,EAAE;AAAA,EAC7G,EAAE,OAAO,aAAa,MAAM,iCAAiC,UAAU,CAAC,SAAS,SAAS,aAAa,MAAM,EAAE;AAAA,EAC/G,EAAE,OAAO,aAAa,MAAM,8BAA8B,UAAU,CAAC,MAAM,SAAS,SAAS,MAAM,EAAE;AAAA,EACrG,EAAE,OAAO,aAAa,MAAM,gCAAgC,UAAU,CAAC,QAAQ,SAAS,SAAS,MAAM,EAAE;AAAA,EACzG,EAAE,OAAO,gBAAoB,MAAM,qBAAqB,UAAU,CAAC,MAAM,SAAS,OAAO,SAAS,WAAW,EAAE;AAAA,EAC/G,EAAE,OAAO,aAAa,MAAM,gCAAgC,UAAU,CAAC,SAAS,OAAO,OAAO,MAAM,EAAE;AAAA,EACtG,EAAE,OAAO,aAAa,MAAM,iBAAiB,UAAU,CAAC,UAAU,UAAU,QAAQ,SAAS,SAAS,EAAE;AAAA,EACxG,EAAE,OAAO,aAAa,MAAM,kBAAkB,UAAU,CAAC,cAAc,SAAS,OAAO,YAAY,EAAE;AAAA,EACrG,EAAE,OAAO,aAAa,MAAM,gBAAgB,UAAU,CAAC,QAAQ,UAAU,aAAa,QAAQ,WAAW,WAAW,EAAE;AAAA,EACtH,EAAE,OAAO,aAAa,MAAM,aAAa,UAAU,CAAC,aAAa,QAAQ,SAAS,WAAW,UAAU,EAAE;AAAA,EACzG,EAAE,OAAO,aAAa,MAAM,oBAAoB,UAAU,CAAC,QAAQ,QAAQ,SAAS,MAAM,EAAE;AAAA,EAC5F,EAAE,OAAO,aAAa,MAAM,qBAAqB,UAAU,CAAC,QAAQ,QAAQ,SAAS,OAAO,EAAE;AAAA,EAC9F,EAAE,OAAO,aAAa,MAAM,iBAAiB,UAAU,CAAC,QAAQ,SAAS,QAAQ,QAAQ,EAAE;AAAA,EAC3F,EAAE,OAAO,gBAAoB,MAAM,gBAAgB,UAAU,CAAC,SAAS,OAAO,QAAQ,SAAS,EAAE;AAAA,EACjG,EAAE,OAAO,aAAa,MAAM,eAAe,UAAU,CAAC,SAAS,UAAU,YAAY,YAAY,OAAO,EAAE;AAAA,EAC1G,EAAE,OAAO,aAAa,MAAM,UAAU,UAAU,CAAC,UAAU,SAAS,UAAU,OAAO,EAAE;AAAA,EACvF,EAAE,OAAO,aAAa,MAAM,sBAAsB,UAAU,CAAC,YAAY,cAAc,gBAAgB,KAAK,EAAE;AAAA,EAC9G,EAAE,OAAO,aAAa,MAAM,oBAAoB,UAAU,CAAC,SAAS,SAAS,OAAO,YAAY,WAAW,EAAE;AAAA,EAC7G,EAAE,OAAO,aAAa,MAAM,uBAAuB,UAAU,CAAC,MAAM,QAAQ,aAAa,aAAa,EAAE;AAAA,EACxG,EAAE,OAAO,aAAa,MAAM,uBAAuB,UAAU,CAAC,MAAM,OAAO,WAAW,UAAU,EAAE;AAAA,EAClG,EAAE,OAAO,aAAa,MAAM,uBAAuB,UAAU,CAAC,QAAQ,SAAS,YAAY,aAAa,IAAI,EAAE;AAAA,EAC9G,EAAE,OAAO,aAAa,MAAM,iBAAiB,UAAU,CAAC,OAAO,WAAW,SAAS,aAAa,SAAS,EAAE;AAAA,EAC3G,EAAE,OAAO,aAAa,MAAM,eAAe,UAAU,CAAC,SAAS,SAAS,QAAQ,WAAW,YAAY,EAAE;AAAA,EACzG,EAAE,OAAO,aAAa,MAAM,OAAO,UAAU,CAAC,OAAO,QAAQ,MAAM,EAAE;AAAA,EACrE,EAAE,OAAO,aAAa,MAAM,QAAQ,UAAU,CAAC,QAAQ,QAAQ,OAAO,EAAE;AAAA,EACxE,EAAE,OAAO,aAAa,MAAM,SAAS,UAAU,CAAC,SAAS,WAAW,OAAO,EAAE;AAAA,EAC7E,EAAE,OAAO,aAAa,MAAM,QAAQ,UAAU,CAAC,QAAQ,YAAY,MAAM,EAAE;AAAA,EAC3E,EAAE,OAAO,aAAa,MAAM,QAAQ,UAAU,CAAC,QAAQ,QAAQ,OAAO,SAAS,SAAS,MAAM,EAAE;AAAA,EAChG,EAAE,OAAO,mBAAqB,MAAM,OAAO,UAAU,CAAC,OAAO,QAAQ,OAAO,QAAQ,EAAE;AAAA,EACtF,EAAE,OAAO,aAAa,MAAM,OAAO,UAAU,CAAC,OAAO,QAAQ,UAAU,OAAO,EAAE;AAAA,EAChF,EAAE,OAAO,aAAa,MAAM,QAAQ,UAAU,CAAC,QAAQ,SAAS,OAAO,EAAE;AAAA,EACzE,EAAE,OAAO,aAAa,MAAM,SAAS,UAAU,CAAC,SAAS,QAAQ,MAAM,EAAE;AAAA,EACzE,EAAE,OAAO,aAAa,MAAM,UAAU,UAAU,CAAC,UAAU,SAAS,MAAM,EAAE;AAAA,EAC5E,EAAE,OAAO,aAAa,MAAM,SAAS,UAAU,CAAC,SAAS,SAAS,SAAS,QAAQ,cAAc,EAAE;AAAA,EACnG,EAAE,OAAO,aAAa,MAAM,oBAAoB,UAAU,CAAC,SAAS,SAAS,WAAW,MAAM,EAAE;AAAA,EAChG,EAAE,OAAO,aAAa,MAAM,SAAS,UAAU,CAAC,SAAS,WAAW,SAAS,MAAM,EAAE;AAAA,EACrF,EAAE,OAAO,aAAa,MAAM,QAAQ,UAAU,CAAC,QAAQ,SAAS,UAAU,SAAS,EAAE;AAAA,EACrF,EAAE,OAAO,aAAa,MAAM,OAAO,UAAU,CAAC,OAAO,SAAS,QAAQ,KAAK,EAAE;AAAA,EAC7E,EAAE,OAAO,aAAa,MAAM,QAAQ,UAAU,CAAC,QAAQ,SAAS,UAAU,KAAK,EAAE;AAAA,EACjF,EAAE,OAAO,aAAa,MAAM,OAAO,UAAU,CAAC,OAAO,QAAQ,SAAS,QAAQ,EAAE;AAAA,EAChF,EAAE,OAAO,aAAa,MAAM,SAAS,UAAU,CAAC,SAAS,UAAU,SAAS,QAAQ,EAAE;AAAA,EACtF,EAAE,OAAO,aAAa,MAAM,WAAW,UAAU,CAAC,OAAO,OAAO,WAAW,SAAS,EAAE;AAAA,EACtF,EAAE,OAAO,aAAa,MAAM,aAAa,UAAU,CAAC,OAAO,SAAS,WAAW,SAAS,EAAE;AAAA,EAC1F,EAAE,OAAO,4BAA8B,MAAM,gBAAgB,UAAU,CAAC,aAAa,cAAc,SAAS,YAAY,MAAM,EAAE;AAAA,EAChI,EAAE,OAAO,4BAA8B,MAAM,UAAU,UAAU,CAAC,UAAU,WAAW,YAAY,KAAK,EAAE;AAAA,EAC1G,EAAE,OAAO,4BAA8B,MAAM,aAAa,UAAU,CAAC,aAAa,YAAY,OAAO,SAAS,EAAE;AAAA,EAChH,EAAE,OAAO,4BAA8B,MAAM,aAAa,UAAU,CAAC,aAAa,SAAS,UAAU,MAAM,EAAE;AAAA,EAC7G,EAAE,OAAO,4BAA8B,MAAM,eAAe,UAAU,CAAC,eAAe,QAAQ,UAAU,WAAW,EAAE;AAAA,EACrH,EAAE,OAAO,+BAAqC,MAAM,SAAS,UAAU,CAAC,SAAS,OAAO,SAAS,SAAS,EAAE;AAAA,EAC5G,EAAE,OAAO,4BAA8B,MAAM,WAAW,UAAU,CAAC,WAAW,UAAU,aAAa,WAAW,EAAE;AAAA,EAClH,EAAE,OAAO,4BAA8B,MAAM,QAAQ,UAAU,CAAC,QAAQ,QAAQ,QAAQ,SAAS,EAAE;AAAA,EAEnG,EAAE,OAAO,gBAAoB,MAAM,aAAa,UAAU,CAAC,QAAQ,SAAS,OAAO,WAAW,QAAQ,YAAY,EAAE;AAAA,EACpH,EAAE,OAAO,aAAa,MAAM,gBAAgB,UAAU,CAAC,QAAQ,SAAS,UAAU,MAAM,EAAE;AAAA,EAC1F,EAAE,OAAO,aAAa,MAAM,gBAAgB,UAAU,CAAC,QAAQ,SAAS,UAAU,YAAY,EAAE;AAAA,EAChG,EAAE,OAAO,aAAa,MAAM,eAAe,UAAU,CAAC,QAAQ,SAAS,SAAS,UAAU,MAAM,EAAE;AAAA,EAClG,EAAE,OAAO,aAAa,MAAM,cAAc,UAAU,CAAC,QAAQ,SAAS,QAAQ,SAAS,MAAM,EAAE;AAAA,EAC/F,EAAE,OAAO,aAAa,MAAM,gBAAgB,UAAU,CAAC,QAAQ,SAAS,UAAU,OAAO,EAAE;AAAA,EAC3F,EAAE,OAAO,aAAa,MAAM,eAAe,UAAU,CAAC,QAAQ,SAAS,SAAS,OAAO,EAAE;AAAA,EACzF,EAAE,OAAO,aAAa,MAAM,eAAe,UAAU,CAAC,QAAQ,SAAS,SAAS,QAAQ,QAAQ,MAAM,EAAE;AAAA,EACxG,EAAE,OAAO,aAAa,MAAM,oBAAoB,UAAU,CAAC,QAAQ,SAAS,cAAc,KAAK,EAAE;AAAA,EACjG,EAAE,OAAO,aAAa,MAAM,cAAc,UAAU,CAAC,QAAQ,SAAS,QAAQ,QAAQ,SAAS,EAAE;AAAA,EACjG,EAAE,OAAO,aAAa,MAAM,cAAc,UAAU,CAAC,QAAQ,SAAS,QAAQ,QAAQ,SAAS,EAAE;AAAA,EACjG,EAAE,OAAO,aAAa,MAAM,eAAe,UAAU,CAAC,QAAQ,SAAS,SAAS,QAAQ,OAAO,EAAE;AAAA,EACjG,EAAE,OAAO,aAAa,MAAM,gBAAgB,UAAU,CAAC,cAAc,OAAO,WAAW,QAAQ,MAAM,EAAE;AAAA,EACvG,EAAE,OAAO,+BAAqC,MAAM,iBAAiB,UAAU,CAAC,QAAQ,WAAW,QAAQ,QAAQ,EAAE;AAAA,EACrH,EAAE,OAAO,+BAAqC,MAAM,iBAAiB,UAAU,CAAC,SAAS,QAAQ,WAAW,SAAS,EAAE;AAAA,EACvH,EAAE,OAAO,aAAa,MAAM,mBAAmB,UAAU,CAAC,QAAQ,WAAW,SAAS,SAAS,MAAM,EAAE;AAAA,EACvG,EAAE,OAAO,aAAa,MAAM,iBAAiB,UAAU,CAAC,QAAQ,SAAS,WAAW,QAAQ,EAAE;AAAA,EAC9F,EAAE,OAAO,aAAa,MAAM,iBAAiB,UAAU,CAAC,QAAQ,SAAS,QAAQ,SAAS,OAAO,EAAE;AAAA,EACnG,EAAE,OAAO,aAAa,MAAM,oBAAoB,UAAU,CAAC,QAAQ,UAAU,aAAa,SAAS,EAAE;AAAA,EACrG,EAAE,OAAO,aAAa,MAAM,cAAc,UAAU,CAAC,QAAQ,UAAU,QAAQ,SAAS,EAAE;AAAA,EAC1F,EAAE,OAAO,aAAa,MAAM,eAAe,UAAU,CAAC,UAAU,QAAQ,QAAQ,WAAW,UAAU,EAAE;AAAA,EACvG,EAAE,OAAO,aAAa,MAAM,aAAa,UAAU,CAAC,QAAQ,QAAQ,QAAQ,QAAQ,EAAE;AAAA,EACtF,EAAE,OAAO,aAAa,MAAM,QAAQ,UAAU,CAAC,QAAQ,cAAc,WAAW,YAAY,SAAS,EAAE;AAAA,EACvG,EAAE,OAAO,aAAa,MAAM,WAAW,UAAU,CAAC,WAAW,WAAW,WAAW,QAAQ,MAAM,EAAE;AAAA,EAEnG,EAAE,OAAO,aAAa,MAAM,YAAY,UAAU,CAAC,OAAO,SAAS,OAAO,UAAU,QAAQ,MAAM,EAAE;AAAA,EACpG,EAAE,OAAO,aAAa,MAAM,YAAY,UAAU,CAAC,OAAO,UAAU,OAAO,UAAU,QAAQ,MAAM,EAAE;AAAA,EACrG,EAAE,OAAO,aAAa,MAAM,cAAc,UAAU,CAAC,SAAS,UAAU,UAAU,OAAO,EAAE;AAAA,EAC3F,EAAE,OAAO,aAAa,MAAM,WAAW,UAAU,CAAC,WAAW,OAAO,UAAU,MAAM,EAAE;AAAA,EACtF,EAAE,OAAO,aAAa,MAAM,eAAe,UAAU,CAAC,UAAU,SAAS,UAAU,QAAQ,QAAQ,EAAE;AAAA,EACrG,EAAE,OAAO,aAAa,MAAM,QAAQ,UAAU,CAAC,QAAQ,UAAU,UAAU,SAAS,EAAE;AAAA,EACtF,EAAE,OAAO,aAAa,MAAM,SAAS,UAAU,CAAC,SAAS,QAAQ,UAAU,QAAQ,QAAQ,EAAE;AAAA,EAC7F,EAAE,OAAO,aAAa,MAAM,SAAS,UAAU,CAAC,SAAS,UAAU,aAAa,MAAM,EAAE;AAAA,EACxF,EAAE,OAAO,aAAa,MAAM,cAAc,UAAU,CAAC,SAAS,UAAU,OAAO,QAAQ,QAAQ,EAAE;AAAA,EACjG,EAAE,OAAO,aAAa,MAAM,QAAQ,UAAU,CAAC,QAAQ,UAAU,QAAQ,QAAQ,MAAM,EAAE;AAAA,EACzF,EAAE,OAAO,aAAa,MAAM,YAAY,UAAU,CAAC,OAAO,UAAU,QAAQ,KAAK,EAAE;AAAA,EACnF,EAAE,OAAO,aAAa,MAAM,YAAY,UAAU,CAAC,OAAO,UAAU,QAAQ,MAAM,EAAE;AAAA,EACpF,EAAE,OAAO,aAAa,MAAM,QAAQ,UAAU,CAAC,QAAQ,UAAU,QAAQ,QAAQ,EAAE;AAAA,EACnF,EAAE,OAAO,aAAa,MAAM,eAAe,UAAU,CAAC,UAAU,UAAU,WAAW,KAAK,EAAE;AAAA,EAC5F,EAAE,OAAO,aAAa,MAAM,sBAAsB,UAAU,CAAC,UAAU,eAAe,OAAO,MAAM,EAAE;AAAA,EACrG,EAAE,OAAO,aAAa,MAAM,uBAAuB,UAAU,CAAC,UAAU,gBAAgB,QAAQ,EAAE;AAAA,EAClG,EAAE,OAAO,aAAa,MAAM,wBAAwB,UAAU,CAAC,UAAU,iBAAiB,UAAU,OAAO,EAAE;AAAA,EAC7G,EAAE,OAAO,aAAa,MAAM,WAAW,UAAU,CAAC,WAAW,QAAQ,WAAW,QAAQ,KAAK,EAAE;AAAA,EAC/F,EAAE,OAAO,aAAa,MAAM,WAAW,UAAU,CAAC,WAAW,QAAQ,UAAU,QAAQ,QAAQ,EAAE;AAAA,EACjG,EAAE,OAAO,aAAa,MAAM,QAAQ,UAAU,CAAC,QAAQ,UAAU,OAAO,SAAS,OAAO,EAAE;AAAA,EAC1F,EAAE,OAAO,aAAa,MAAM,SAAS,UAAU,CAAC,SAAS,QAAQ,WAAW,WAAW,UAAU,EAAE;AAAA,EACnG,EAAE,OAAO,aAAa,MAAM,aAAa,UAAU,CAAC,aAAa,UAAU,UAAU,aAAa,QAAQ,EAAE;AAAA,EAC5G,EAAE,OAAO,aAAa,MAAM,OAAO,UAAU,CAAC,OAAO,UAAU,eAAe,QAAQ,EAAE;AAAA,EACxF,EAAE,OAAO,aAAa,MAAM,YAAY,UAAU,CAAC,OAAO,UAAU,SAAS,QAAQ,OAAO,EAAE;AAAA,EAC9F,EAAE,OAAO,aAAa,MAAM,UAAU,UAAU,CAAC,UAAU,YAAY,QAAQ,UAAU,OAAO,EAAE;AAAA,EAClG,EAAE,OAAO,aAAa,MAAM,SAAS,UAAU,CAAC,SAAS,WAAW,UAAU,SAAS,EAAE;AAAA,EACzF,EAAE,OAAO,aAAa,MAAM,kBAAkB,UAAU,CAAC,SAAS,SAAS,OAAO,UAAU,OAAO,EAAE;AAAA,EACrG,EAAE,OAAO,aAAa,MAAM,WAAW,UAAU,CAAC,WAAW,SAAS,OAAO,UAAU,OAAO,EAAE;AAAA,EAChG,EAAE,OAAO,aAAa,MAAM,QAAQ,UAAU,CAAC,QAAQ,SAAS,OAAO,UAAU,MAAM,EAAE;AAAA,EACzF,EAAE,OAAO,aAAa,MAAM,WAAW,UAAU,CAAC,WAAW,SAAS,OAAO,UAAU,EAAE;AAAA,EACzF,EAAE,OAAO,aAAa,MAAM,SAAS,UAAU,CAAC,SAAS,QAAQ,UAAU,OAAO,EAAE;AAAA,EACpF,EAAE,OAAO,aAAa,MAAM,WAAW,UAAU,CAAC,WAAW,WAAW,WAAW,SAAS,SAAS,EAAE;AAAA,EACvG,EAAE,OAAO,aAAa,MAAM,UAAU,UAAU,CAAC,UAAU,WAAW,QAAQ,UAAU,EAAE;AAAA,EAC1F,EAAE,OAAO,aAAa,MAAM,aAAa,UAAU,CAAC,aAAa,SAAS,OAAO,SAAS,UAAU,EAAE;AAAA,EACtG,EAAE,OAAO,aAAa,MAAM,SAAS,UAAU,CAAC,SAAS,UAAU,OAAO,SAAS,EAAE;AAAA,EACrF,EAAE,OAAO,aAAa,MAAM,UAAU,UAAU,CAAC,UAAU,UAAU,QAAQ,OAAO,EAAE;AAAA,EACtF,EAAE,OAAO,aAAa,MAAM,SAAS,UAAU,CAAC,SAAS,QAAQ,QAAQ,QAAQ,EAAE;AAAA,EACnF,EAAE,OAAO,4BAA8B,MAAM,WAAW,UAAU,CAAC,WAAW,QAAQ,QAAQ,YAAY,SAAS,EAAE;AAAA,EACrH,EAAE,OAAO,aAAa,MAAM,SAAS,UAAU,CAAC,SAAS,UAAU,QAAQ,QAAQ,MAAM,EAAE;AAAA,EAC3F,EAAE,OAAO,aAAa,MAAM,SAAS,UAAU,CAAC,SAAS,UAAU,QAAQ,SAAS,SAAS,EAAE;AAAA,EAC/F,EAAE,OAAO,aAAa,MAAM,aAAa,UAAU,CAAC,aAAa,UAAU,WAAW,KAAK,EAAE;AAAA,EAC7F,EAAE,OAAO,aAAa,MAAM,WAAW,UAAU,CAAC,WAAW,UAAU,eAAe,MAAM,EAAE;AAAA,EAC9F,EAAE,OAAO,aAAa,MAAM,SAAS,UAAU,CAAC,SAAS,UAAU,UAAU,MAAM,EAAE;AAAA,EACrF,EAAE,OAAO,aAAa,MAAM,YAAY,UAAU,CAAC,YAAY,QAAQ,QAAQ,UAAU,EAAE;AAAA,EAC3F,EAAE,OAAO,aAAa,MAAM,WAAW,UAAU,CAAC,WAAW,QAAQ,YAAY,WAAW,EAAE;AAAA,EAC9F,EAAE,OAAO,aAAa,MAAM,UAAU,UAAU,CAAC,UAAU,QAAQ,YAAY,QAAQ,UAAU,EAAE;AAAA,EACnG,EAAE,OAAO,aAAa,MAAM,WAAW,UAAU,CAAC,WAAW,WAAW,SAAS,QAAQ,MAAM,EAAE;AAAA,EACjG,EAAE,OAAO,aAAa,MAAM,YAAY,UAAU,CAAC,YAAY,OAAO,UAAU,MAAM,EAAE;AAAA,EACxF,EAAE,OAAO,aAAa,MAAM,WAAW,UAAU,CAAC,WAAW,QAAQ,SAAS,SAAS,OAAO,EAAE;AAAA,EAChG,EAAE,OAAO,aAAa,MAAM,SAAS,UAAU,CAAC,SAAS,SAAS,QAAQ,OAAO,QAAQ,EAAE;AAAA,EAC3F,EAAE,OAAO,aAAa,MAAM,SAAS,UAAU,CAAC,SAAS,UAAU,QAAQ,cAAc,QAAQ,EAAE;AAAA,EACnG,EAAE,OAAO,aAAa,MAAM,OAAO,UAAU,CAAC,OAAO,UAAU,UAAU,QAAQ,MAAM,EAAE;AAAA,EACzF,EAAE,OAAO,aAAa,MAAM,UAAU,UAAU,CAAC,UAAU,WAAW,UAAU,OAAO,EAAE;AAAA,EACzF,EAAE,OAAO,aAAa,MAAM,WAAW,UAAU,CAAC,WAAW,UAAU,WAAW,OAAO,QAAQ,EAAE;AAAA,EACnG,EAAE,OAAO,aAAa,MAAM,QAAQ,UAAU,CAAC,QAAQ,UAAU,UAAU,SAAS,KAAK,EAAE;AAAA,EAC3F,EAAE,OAAO,aAAa,MAAM,aAAa,UAAU,CAAC,aAAa,aAAa,WAAW,QAAQ,EAAE;AAAA,EACnG,EAAE,OAAO,aAAa,MAAM,SAAS,UAAU,CAAC,SAAS,SAAS,QAAQ,QAAQ,UAAU,EAAE;AAAA,EAC9F,EAAE,OAAO,aAAa,MAAM,OAAO,UAAU,CAAC,OAAO,QAAQ,SAAS,QAAQ,MAAM,EAAE;AAAA,EACtF,EAAE,OAAO,aAAa,MAAM,cAAc,UAAU,CAAC,SAAS,UAAU,QAAQ,MAAM,EAAE;AAAA,EACxF,EAAE,OAAO,aAAa,MAAM,WAAW,UAAU,CAAC,WAAW,UAAU,QAAQ,UAAU,OAAO,EAAE;AAAA,EAClG,EAAE,OAAO,aAAa,MAAM,SAAS,UAAU,CAAC,SAAS,UAAU,WAAW,QAAQ,EAAE;AAAA,EACxF,EAAE,OAAO,aAAa,MAAM,YAAY,UAAU,CAAC,YAAY,UAAU,SAAS,MAAM,EAAE;AAAA,EAC1F,EAAE,OAAO,aAAa,MAAM,YAAY,UAAU,CAAC,YAAY,YAAY,WAAW,aAAa,EAAE;AAAA,EACrG,EAAE,OAAO,aAAa,MAAM,SAAS,UAAU,CAAC,YAAY,QAAQ,WAAW,eAAe,MAAM,EAAE;AAAA,EACtG,EAAE,OAAO,aAAa,MAAM,SAAS,UAAU,CAAC,SAAS,SAAS,UAAU,OAAO,KAAK,EAAE;AAAA,EAC1F,EAAE,OAAO,aAAa,MAAM,YAAY,UAAU,CAAC,YAAY,UAAU,OAAO,UAAU,OAAO,EAAE;AAAA,EACnG,EAAE,OAAO,aAAa,MAAM,QAAQ,UAAU,CAAC,QAAQ,OAAO,QAAQ,QAAQ,EAAE;AAAA,EAChF,EAAE,OAAO,aAAa,MAAM,UAAU,UAAU,CAAC,UAAU,UAAU,WAAW,KAAK,EAAE;AAAA,EACvF,EAAE,OAAO,aAAa,MAAM,OAAO,UAAU,CAAC,OAAO,SAAS,UAAU,UAAU,OAAO,EAAE;AAAA,EAC3F,EAAE,OAAO,aAAa,MAAM,QAAQ,UAAU,CAAC,QAAQ,UAAU,YAAY,YAAY,EAAE;AAAA,EAC3F,EAAE,OAAO,aAAa,MAAM,OAAO,UAAU,CAAC,OAAO,OAAO,UAAU,SAAS,UAAU,EAAE;AAAA,EAC3F,EAAE,OAAO,aAAa,MAAM,OAAO,UAAU,CAAC,OAAO,OAAO,UAAU,OAAO,EAAE;AAAA,EAC/E,EAAE,OAAO,aAAa,MAAM,UAAU,UAAU,CAAC,UAAU,SAAS,UAAU,QAAQ,EAAE;AAAA,EACxF,EAAE,OAAO,aAAa,MAAM,kBAAkB,UAAU,CAAC,QAAQ,QAAQ,UAAU,UAAU,WAAW,EAAE;AAAA,EAC1G,EAAE,OAAO,aAAa,MAAM,kBAAkB,UAAU,CAAC,QAAQ,UAAU,UAAU,MAAM,EAAE;AAAA,EAC7F,EAAE,OAAO,aAAa,MAAM,aAAa,UAAU,CAAC,QAAQ,QAAQ,SAAS,YAAY,UAAU,EAAE;AAAA,EACrG,EAAE,OAAO,aAAa,MAAM,aAAa,UAAU,CAAC,UAAU,aAAa,UAAU,UAAU,KAAK,EAAE;AAAA,EACtG,EAAE,OAAO,aAAa,MAAM,QAAQ,UAAU,CAAC,UAAU,QAAQ,QAAQ,WAAW,OAAO,QAAQ,EAAE;AAAA,EACrG,EAAE,OAAO,aAAa,MAAM,YAAY,UAAU,CAAC,UAAU,YAAY,YAAY,UAAU,WAAW,EAAE;AAAA,EAC5G,EAAE,OAAO,aAAa,MAAM,SAAS,UAAU,CAAC,UAAU,SAAS,UAAU,UAAU,QAAQ,EAAE;AAAA,EACjG,EAAE,OAAO,aAAa,MAAM,kBAAkB,UAAU,CAAC,UAAU,WAAW,UAAU,UAAU,OAAO,EAAE;AAAA,EAC3G,EAAE,OAAO,aAAa,MAAM,oBAAoB,UAAU,CAAC,UAAU,QAAQ,SAAS,UAAU,OAAO,EAAE;AAAA,EACzG,EAAE,OAAO,aAAa,MAAM,cAAc,UAAU,CAAC,QAAQ,SAAS,QAAQ,UAAU,QAAQ,EAAE;AAAA,EAClG,EAAE,OAAO,aAAa,MAAM,2BAA2B,UAAU,CAAC,QAAQ,QAAQ,UAAU,QAAQ,QAAQ,EAAE;AAAA,EAC9G,EAAE,OAAO,aAAa,MAAM,YAAY,UAAU,CAAC,YAAY,SAAS,QAAQ,UAAU,UAAU,KAAK,EAAE;AAAA,EAC3G,EAAE,OAAO,aAAa,MAAM,gBAAgB,UAAU,CAAC,SAAS,OAAO,cAAc,UAAU,SAAS,MAAM,EAAE;AAAA,EAChH,EAAE,OAAO,aAAa,MAAM,iBAAiB,UAAU,CAAC,QAAQ,SAAS,WAAW,QAAQ,QAAQ,EAAE;AAAA,EACtG,EAAE,OAAO,aAAa,MAAM,QAAQ,UAAU,CAAC,QAAQ,QAAQ,SAAS,SAAS,QAAQ,EAAE;AAAA,EAC3F,EAAE,OAAO,gBAAoB,MAAM,YAAY,UAAU,CAAC,YAAY,UAAU,SAAS,QAAQ,OAAO,EAAE;AAAA,EAC1G,EAAE,OAAO,aAAa,MAAM,cAAc,UAAU,CAAC,QAAQ,SAAS,QAAQ,MAAM,EAAE;AAAA,EACtF,EAAE,OAAO,aAAa,MAAM,kBAAkB,UAAU,CAAC,QAAQ,QAAQ,QAAQ,QAAQ,QAAQ,EAAE;AAAA,EACnG,EAAE,OAAO,aAAa,MAAM,QAAQ,UAAU,CAAC,QAAQ,OAAO,UAAU,UAAU,QAAQ,EAAE;AAAA,EAE5F,EAAE,OAAO,gBAAoB,MAAM,OAAO,UAAU,CAAC,OAAO,SAAS,WAAW,OAAO,UAAU,QAAQ,EAAE;AAAA,EAC3G,EAAE,OAAO,mBAAqB,MAAM,0BAA0B,UAAU,CAAC,OAAO,SAAS,iBAAiB,SAAS,EAAE;AAAA,EACrH,EAAE,OAAO,UAAY,MAAM,oBAAoB,UAAU,CAAC,OAAO,SAAS,iBAAiB,SAAS,EAAE;AAAA,EACtG,EAAE,OAAO,gBAAoB,MAAM,SAAS,UAAU,CAAC,SAAS,WAAW,YAAY,KAAK,EAAE;AAAA,EAC9F,EAAE,OAAO,mBAAqB,MAAM,mBAAmB,UAAU,CAAC,QAAQ,SAAS,WAAW,OAAO,EAAE;AAAA,EACvG,EAAE,OAAO,gBAAoB,MAAM,iCAAiC,UAAU,CAAC,SAAS,WAAW,aAAa,MAAM,EAAE;AAAA,EACxH,EAAE,OAAO,mBAAqB,MAAM,wBAAwB,UAAU,CAAC,aAAa,WAAW,SAAS,SAAS,EAAE;AAAA,EACnH,EAAE,OAAO,gBAAoB,MAAM,aAAa,UAAU,CAAC,QAAQ,QAAQ,UAAU,OAAO,QAAQ,EAAE;AAAA,EACtG,EAAE,OAAO,mBAAqB,MAAM,mBAAmB,UAAU,CAAC,QAAQ,SAAS,WAAW,UAAU,MAAM,EAAE;AAAA,EAChH,EAAE,OAAO,aAAa,MAAM,WAAW,UAAU,CAAC,WAAW,WAAW,YAAY,SAAS,KAAK,EAAE;AAAA,EACpG,EAAE,OAAO,UAAY,MAAM,QAAQ,UAAU,CAAC,QAAQ,SAAS,OAAO,UAAU,UAAU,EAAE;AAAA,EAC5F,EAAE,OAAO,aAAa,MAAM,gBAAgB,UAAU,CAAC,QAAQ,QAAQ,WAAW,SAAS,SAAS,EAAE;AAAA,EACtG,EAAE,OAAO,aAAa,MAAM,iBAAiB,UAAU,CAAC,QAAQ,YAAY,SAAS,OAAO,OAAO,EAAE;AAAA,EACrG,EAAE,OAAO,aAAa,MAAM,iBAAiB,UAAU,CAAC,OAAO,QAAQ,SAAS,QAAQ,SAAS,EAAE;AAAA,EACnG,EAAE,OAAO,aAAa,MAAM,kBAAkB,UAAU,CAAC,QAAQ,QAAQ,QAAQ,SAAS,QAAQ,EAAE;AAAA,EACpG,EAAE,OAAO,aAAa,MAAM,QAAQ,UAAU,CAAC,QAAQ,SAAS,OAAO,OAAO,QAAQ,UAAU,EAAE;AAAA,EAClG,EAAE,OAAO,aAAa,MAAM,WAAW,UAAU,CAAC,SAAS,QAAQ,SAAS,QAAQ,MAAM,EAAE;AAAA,EAC5F,EAAE,OAAO,aAAa,MAAM,cAAc,UAAU,CAAC,QAAQ,SAAS,SAAS,OAAO,MAAM,EAAE;AAAA,EAE9F,EAAE,OAAO,aAAa,MAAM,aAAa,UAAU,CAAC,SAAS,SAAS,OAAO,WAAW,MAAM,EAAE;AAAA,EAChG,EAAE,OAAO,aAAa,MAAM,aAAa,UAAU,CAAC,UAAU,aAAa,SAAS,QAAQ,EAAE;AAAA,EAC9F,EAAE,OAAO,aAAa,MAAM,SAAS,UAAU,CAAC,SAAS,SAAS,UAAU,UAAU,MAAM,EAAE;AAAA,EAC9F,EAAE,OAAO,aAAa,MAAM,UAAU,UAAU,CAAC,UAAU,SAAS,UAAU,MAAM,EAAE;AAAA,EACtF,EAAE,OAAO,aAAa,MAAM,cAAc,UAAU,CAAC,cAAc,SAAS,UAAU,MAAM,EAAE;AAAA,EAC9F,EAAE,OAAO,aAAa,MAAM,UAAU,UAAU,CAAC,UAAU,SAAS,QAAQ,QAAQ,EAAE;AAAA,EACtF,EAAE,OAAO,aAAa,MAAM,cAAc,UAAU,CAAC,cAAc,SAAS,SAAS,KAAK,EAAE;AAAA,EAC5F,EAAE,OAAO,aAAa,MAAM,eAAe,UAAU,CAAC,aAAa,SAAS,SAAS,MAAM,EAAE;AAAA,EAC7F,EAAE,OAAO,aAAa,MAAM,SAAS,UAAU,CAAC,SAAS,SAAS,QAAQ,MAAM,EAAE;AAAA,EAClF,EAAE,OAAO,aAAa,MAAM,YAAY,UAAU,CAAC,UAAU,YAAY,SAAS,KAAK,EAAE;AAAA,EACzF,EAAE,OAAO,aAAa,MAAM,SAAS,UAAU,CAAC,SAAS,SAAS,SAAS,MAAM,EAAE;AAAA,EACnF,EAAE,OAAO,aAAa,MAAM,QAAQ,UAAU,CAAC,QAAQ,SAAS,SAAS,MAAM,EAAE;AAAA,EACjF,EAAE,OAAO,aAAa,MAAM,aAAa,UAAU,CAAC,aAAa,SAAS,YAAY,MAAM,EAAE;AAAA,EAC9F,EAAE,OAAO,aAAa,MAAM,SAAS,UAAU,CAAC,SAAS,SAAS,YAAY,MAAM,EAAE;AAAA,EACtF,EAAE,OAAO,aAAa,MAAM,WAAW,UAAU,CAAC,WAAW,QAAQ,aAAa,WAAW,OAAO,EAAE;AAAA,EACtG,EAAE,OAAO,aAAa,MAAM,UAAU,UAAU,CAAC,UAAU,aAAa,QAAQ,QAAQ,EAAE;AAAA,EAC1F,EAAE,OAAO,aAAa,MAAM,eAAe,UAAU,CAAC,QAAQ,aAAa,QAAQ,OAAO,EAAE;AAAA,EAC5F,EAAE,OAAO,mBAAqB,MAAM,cAAc,UAAU,CAAC,UAAU,OAAO,SAAS,OAAO,EAAE;AAAA,EAChG,EAAE,OAAO,aAAa,MAAM,YAAY,UAAU,CAAC,YAAY,aAAa,SAAS,WAAW,MAAM,EAAE;AAAA,EACxG,EAAE,OAAO,aAAa,MAAM,SAAS,UAAU,CAAC,SAAS,aAAa,QAAQ,KAAK,EAAE;AAAA,EACrF,EAAE,OAAO,aAAa,MAAM,YAAY,UAAU,CAAC,YAAY,UAAU,QAAQ,QAAQ,EAAE;AAAA,EAC3F,EAAE,OAAO,aAAa,MAAM,WAAW,UAAU,CAAC,UAAU,OAAO,QAAQ,OAAO,EAAE;AAAA,EACpF,EAAE,OAAO,aAAa,MAAM,SAAS,UAAU,CAAC,SAAS,QAAQ,UAAU,SAAS,MAAM,EAAE;AAAA,EAC5F,EAAE,OAAO,aAAa,MAAM,aAAa,UAAU,CAAC,aAAa,SAAS,UAAU,UAAU,WAAW,EAAE;AAAA,EAC3G,EAAE,OAAO,aAAa,MAAM,kBAAkB,UAAU,CAAC,YAAY,SAAS,UAAU,MAAM,EAAE;AAAA,EAChG,EAAE,OAAO,aAAa,MAAM,WAAW,UAAU,CAAC,WAAW,SAAS,QAAQ,OAAO,EAAE;AAAA,EACvF,EAAE,OAAO,aAAa,MAAM,gBAAgB,UAAU,CAAC,UAAU,QAAQ,SAAS,SAAS,EAAE;AAAA,EAC7F,EAAE,OAAO,aAAa,MAAM,gBAAgB,UAAU,CAAC,QAAQ,QAAQ,QAAQ,KAAK,EAAE;AAAA,EACtF,EAAE,OAAO,aAAa,MAAM,aAAa,UAAU,CAAC,UAAU,aAAa,aAAa,QAAQ,cAAc,EAAE;AAAA,EAChH,EAAE,OAAO,aAAa,MAAM,gBAAgB,UAAU,CAAC,SAAS,gBAAgB,aAAa,QAAQ,OAAO,EAAE;AAAA,EAC9G,EAAE,OAAO,aAAa,MAAM,SAAS,UAAU,CAAC,SAAS,QAAQ,WAAW,SAAS,QAAQ,EAAE;AAAA,EAC/F,EAAE,OAAO,aAAa,MAAM,QAAQ,UAAU,CAAC,QAAQ,QAAQ,WAAW,SAAS,EAAE;AAAA,EACrF,EAAE,OAAO,aAAa,MAAM,WAAW,UAAU,CAAC,WAAW,QAAQ,WAAW,MAAM,EAAE;AAAA,EACxF,EAAE,OAAO,aAAa,MAAM,SAAS,UAAU,CAAC,SAAS,QAAQ,YAAY,QAAQ,MAAM,EAAE;AAAA,EAC7F,EAAE,OAAO,aAAa,MAAM,iBAAiB,UAAU,CAAC,SAAS,WAAW,QAAQ,QAAQ,YAAY,KAAK,EAAE;AAAA,EAC/G,EAAE,OAAO,aAAa,MAAM,aAAa,UAAU,CAAC,aAAa,SAAS,QAAQ,WAAW,SAAS,EAAE;AAAA,EACxG,EAAE,OAAO,aAAa,MAAM,cAAc,UAAU,CAAC,SAAS,QAAQ,QAAQ,UAAU,UAAU,EAAE;AAAA,EACpG,EAAE,OAAO,aAAa,MAAM,gBAAgB,UAAU,CAAC,UAAU,WAAW,SAAS,QAAQ,SAAS,EAAE;AAAA,EACxG,EAAE,OAAO,aAAa,MAAM,WAAW,UAAU,CAAC,OAAO,UAAU,WAAW,aAAa,MAAM,EAAE;AAAA,EACnG,EAAE,OAAO,aAAa,MAAM,iBAAiB,UAAU,CAAC,QAAQ,YAAY,eAAe,WAAW,OAAO,EAAE;AAAA,EAC/G,EAAE,OAAO,aAAa,MAAM,aAAa,UAAU,CAAC,QAAQ,WAAW,cAAc,OAAO,EAAE;AAAA,EAC9F,EAAE,OAAO,aAAa,MAAM,iBAAiB,UAAU,CAAC,aAAa,SAAS,SAAS,SAAS,EAAE;AAAA,EAClG,EAAE,OAAO,aAAa,MAAM,SAAS,UAAU,CAAC,SAAS,SAAS,SAAS,OAAO,EAAE;AAAA,EACpF,EAAE,OAAO,aAAa,MAAM,YAAY,UAAU,CAAC,SAAS,YAAY,WAAW,SAAS,MAAM,EAAE;AAAA,EACpG,EAAE,OAAO,aAAa,MAAM,kBAAkB,UAAU,CAAC,aAAa,WAAW,SAAS,QAAQ,QAAQ,EAAE;AAAA,EAC5G,EAAE,OAAO,aAAa,MAAM,UAAU,UAAU,CAAC,UAAU,WAAW,SAAS,WAAW,OAAO,EAAE;AAAA,EACnG,EAAE,OAAO,UAAY,MAAM,gBAAgB,UAAU,CAAC,UAAU,OAAO,OAAO,SAAS,QAAQ,KAAK,EAAE;AAAA,EACtG,EAAE,OAAO,aAAa,MAAM,yBAAyB,UAAU,CAAC,OAAO,aAAa,SAAS,OAAO,QAAQ,EAAE;AAAA,EAC9G,EAAE,OAAO,aAAa,MAAM,YAAY,UAAU,CAAC,QAAQ,SAAS,WAAW,OAAO,QAAQ,EAAE;AAAA,EAChG,EAAE,OAAO,aAAa,MAAM,sBAAsB,UAAU,CAAC,QAAQ,UAAU,SAAS,aAAa,OAAO,EAAE;AAAA,EAC9G,EAAE,OAAO,aAAa,MAAM,cAAc,UAAU,CAAC,QAAQ,SAAS,WAAW,SAAS,KAAK,EAAE;AAAA,EACjG,EAAE,OAAO,aAAa,MAAM,kBAAkB,UAAU,CAAC,YAAY,SAAS,WAAW,WAAW,KAAK,EAAE;AAAA,EAC3G,EAAE,OAAO,aAAa,MAAM,kBAAkB,UAAU,CAAC,YAAY,SAAS,YAAY,YAAY,OAAO,EAAE;AAAA,EAC/G,EAAE,OAAO,aAAa,MAAM,cAAc,UAAU,CAAC,cAAc,QAAQ,SAAS,OAAO,UAAU,EAAE;AAAA,EACvG,EAAE,OAAO,aAAa,MAAM,gBAAgB,UAAU,CAAC,SAAS,OAAO,SAAS,OAAO,EAAE;AAAA,EACzF,EAAE,OAAO,aAAa,MAAM,iBAAiB,UAAU,CAAC,QAAQ,SAAS,SAAS,OAAO,EAAE;AAAA,EAC3F,EAAE,OAAO,aAAa,MAAM,SAAS,UAAU,CAAC,SAAS,SAAS,aAAa,MAAM,EAAE;AAAA,EACvF,EAAE,OAAO,aAAa,MAAM,UAAU,UAAU,CAAC,UAAU,aAAa,QAAQ,OAAO,EAAE;AAAA,EACzF,EAAE,OAAO,aAAa,MAAM,YAAY,UAAU,CAAC,YAAY,QAAQ,SAAS,OAAO,EAAE;AAAA,EACzF,EAAE,OAAO,aAAa,MAAM,eAAe,UAAU,CAAC,OAAO,QAAQ,UAAU,QAAQ,EAAE;AAAA,EACzF,EAAE,OAAO,aAAa,MAAM,WAAW,UAAU,CAAC,WAAW,QAAQ,kBAAkB,YAAY,EAAE;AAAA,EACrG,EAAE,OAAO,aAAa,MAAM,UAAU,UAAU,CAAC,UAAU,QAAQ,WAAW,QAAQ,EAAE;AAAA,EACxF,EAAE,OAAO,aAAa,MAAM,eAAe,UAAU,CAAC,SAAS,WAAW,QAAQ,aAAa,SAAS,EAAE;AAAA,EAC1G,EAAE,OAAO,aAAa,MAAM,SAAS,UAAU,CAAC,SAAS,QAAQ,OAAO,eAAe,EAAE;AAAA,EACzF,EAAE,OAAO,aAAa,MAAM,SAAS,UAAU,CAAC,SAAS,QAAQ,UAAU,QAAQ,EAAE;AAAA,EACrF,EAAE,OAAO,aAAa,MAAM,WAAW,UAAU,CAAC,WAAW,QAAQ,WAAW,SAAS,OAAO,EAAE;AAAA,EAClG,EAAE,OAAO,aAAa,MAAM,QAAQ,UAAU,CAAC,QAAQ,aAAa,QAAQ,OAAO,EAAE;AAAA,EACrF,EAAE,OAAO,aAAa,MAAM,UAAU,UAAU,CAAC,UAAU,OAAO,SAAS,MAAM,EAAE;AAAA,EACnF,EAAE,OAAO,aAAa,MAAM,QAAQ,UAAU,CAAC,QAAQ,SAAS,OAAO,SAAS,WAAW,EAAE;AAAA,EAC7F,EAAE,OAAO,aAAa,MAAM,OAAO,UAAU,CAAC,OAAO,QAAQ,QAAQ,UAAU,OAAO,EAAE;AAAA,EACxF,EAAE,OAAO,aAAa,MAAM,kBAAkB,UAAU,CAAC,QAAQ,UAAU,SAAS,SAAS,OAAO,EAAE;AAAA,EACtG,EAAE,OAAO,aAAa,MAAM,iBAAiB,UAAU,CAAC,WAAW,SAAS,SAAS,WAAW,SAAS,EAAE;AAAA,EAC3G,EAAE,OAAO,aAAa,MAAM,oBAAoB,UAAU,CAAC,aAAa,UAAU,SAAS,aAAa,OAAO,EAAE;AAAA,EACjH,EAAE,OAAO,aAAa,MAAM,4BAA4B,UAAU,CAAC,aAAa,UAAU,aAAa,SAAS,KAAK,EAAE;AAAA,EACvH,EAAE,OAAO,aAAa,MAAM,aAAa,UAAU,CAAC,QAAQ,aAAa,SAAS,UAAU,KAAK,EAAE;AAAA,EAEnG,EAAE,OAAO,aAAa,MAAM,cAAc,UAAU,CAAC,OAAO,SAAS,WAAW,aAAa,MAAM,EAAE;AAAA,EACrG,EAAE,OAAO,aAAa,MAAM,QAAQ,UAAU,CAAC,QAAQ,OAAO,OAAO,QAAQ,WAAW,EAAE;AAAA,EAC1F,EAAE,OAAO,aAAa,MAAM,OAAO,UAAU,CAAC,OAAO,aAAa,UAAU,SAAS,EAAE;AAAA,EACvF,EAAE,OAAO,aAAa,MAAM,aAAa,UAAU,CAAC,aAAa,aAAa,YAAY,SAAS,EAAE;AAAA,EACrG,EAAE,OAAO,aAAa,MAAM,eAAe,UAAU,CAAC,QAAQ,UAAU,SAAS,aAAa,SAAS,EAAE;AAAA,EACzG,EAAE,OAAO,aAAa,MAAM,cAAc,UAAU,CAAC,UAAU,OAAO,OAAO,aAAa,SAAS,EAAE;AAAA,EACrG,EAAE,OAAO,mBAAqB,MAAM,cAAc,UAAU,CAAC,cAAc,QAAQ,WAAW,QAAQ,EAAE;AAAA,EACxG,EAAE,OAAO,aAAa,MAAM,WAAW,UAAU,CAAC,WAAW,QAAQ,WAAW,SAAS,MAAM,EAAE;AAAA,EACjG,EAAE,OAAO,gBAAoB,MAAM,YAAY,UAAU,CAAC,YAAY,SAAS,UAAU,UAAU,KAAK,EAAE;AAAA,EAC1G,EAAE,OAAO,aAAa,MAAM,sBAAsB,UAAU,CAAC,YAAY,aAAa,UAAU,UAAU,SAAS,EAAE;AAAA,EACrH,EAAE,OAAO,aAAa,MAAM,oBAAoB,UAAU,CAAC,YAAY,WAAW,UAAU,UAAU,SAAS,EAAE;AAAA,EACjH,EAAE,OAAO,aAAa,MAAM,UAAU,UAAU,CAAC,UAAU,SAAS,UAAU,QAAQ,QAAQ,MAAM,EAAE;AAAA,EACtG,EAAE,OAAO,aAAa,MAAM,iBAAiB,UAAU,CAAC,OAAO,SAAS,SAAS,eAAe,EAAE;AAAA,EAClG,EAAE,OAAO,aAAa,MAAM,QAAQ,UAAU,CAAC,QAAQ,QAAQ,UAAU,SAAS,QAAQ,EAAE;AAAA,EAC5F,EAAE,OAAO,aAAa,MAAM,aAAa,UAAU,CAAC,aAAa,QAAQ,QAAQ,OAAO,EAAE;AAAA,EAC1F,EAAE,OAAO,aAAa,MAAM,WAAW,UAAU,CAAC,WAAW,SAAS,WAAW,WAAW,EAAE;AAAA,EAC9F,EAAE,OAAO,aAAa,MAAM,oBAAoB,UAAU,CAAC,SAAS,QAAQ,UAAU,aAAa,SAAS,EAAE;AAAA,EAC9G,EAAE,OAAO,aAAa,MAAM,SAAS,UAAU,CAAC,SAAS,QAAQ,YAAY,WAAW,EAAE;AAAA,EAC1F,EAAE,OAAO,aAAa,MAAM,mBAAmB,UAAU,CAAC,UAAU,YAAY,QAAQ,UAAU,EAAE;AAAA,EACpG,EAAE,OAAO,aAAa,MAAM,YAAY,UAAU,CAAC,YAAY,UAAU,WAAW,YAAY,QAAQ,EAAE;AAAA,EAC1G,EAAE,OAAO,aAAa,MAAM,UAAU,UAAU,CAAC,UAAU,aAAa,YAAY,OAAO,EAAE;AAAA,EAC7F,EAAE,OAAO,mBAAqB,MAAM,uBAAuB,UAAU,CAAC,SAAS,YAAY,QAAQ,SAAS,QAAQ,EAAE;AAAA,EACtH,EAAE,OAAO,mBAAqB,MAAM,wBAAwB,UAAU,CAAC,YAAY,QAAQ,UAAU,UAAU,MAAM,EAAE;AAAA,EACvH,EAAE,OAAO,gBAAoB,MAAM,YAAY,UAAU,CAAC,YAAY,UAAU,UAAU,OAAO,EAAE;AAAA,EACnG,EAAE,OAAO,aAAa,MAAM,WAAW,UAAU,CAAC,WAAW,YAAY,QAAQ,UAAU,UAAU,EAAE;AAAA,EACvG,EAAE,OAAO,aAAa,MAAM,eAAe,UAAU,CAAC,SAAS,SAAS,SAAS,UAAU,EAAE;AAAA,EAC7F,EAAE,OAAO,aAAa,MAAM,qBAAqB,UAAU,CAAC,UAAU,WAAW,OAAO,WAAW,UAAU,EAAE;AAAA,EAC/G,EAAE,OAAO,aAAa,MAAM,UAAU,UAAU,CAAC,UAAU,YAAY,cAAc,SAAS,EAAE;AAAA,EAChG,EAAE,OAAO,UAAY,MAAM,QAAQ,UAAU,CAAC,QAAQ,WAAW,WAAW,UAAU,MAAM,EAAE;AAAA,EAC9F,EAAE,OAAO,mBAAqB,MAAM,iBAAiB,UAAU,CAAC,UAAU,UAAU,YAAY,SAAS,MAAM,EAAE;AAAA,EACjH,EAAE,OAAO,aAAa,MAAM,+BAA+B,UAAU,CAAC,SAAS,SAAS,SAAS,UAAU,UAAU,eAAe,EAAE;AAAA,EACtI,EAAE,OAAO,aAAa,MAAM,0BAA0B,UAAU,CAAC,SAAS,SAAS,SAAS,YAAY,eAAe,EAAE;AAAA,EACzH,EAAE,OAAO,aAAa,MAAM,gCAAgC,UAAU,CAAC,SAAS,SAAS,SAAS,QAAQ,aAAa,eAAe,EAAE;AAAA,EACxI,EAAE,OAAO,aAAa,MAAM,wBAAwB,UAAU,CAAC,SAAS,SAAS,SAAS,YAAY,OAAO,iBAAiB,WAAW,EAAE;AAAA,EAC3I,EAAE,OAAO,mBAAqB,MAAM,aAAa,UAAU,CAAC,OAAO,SAAS,SAAS,aAAa,QAAQ,EAAE;AAAA,EAC5G,EAAE,OAAO,aAAa,MAAM,WAAW,UAAU,CAAC,WAAW,YAAY,aAAa,UAAU,SAAS,EAAE;AAAA,EAC3G,EAAE,OAAO,mBAAqB,MAAM,yBAAyB,UAAU,CAAC,gBAAgB,YAAY,SAAS,OAAO,EAAE;AAAA,EACtH,EAAE,OAAO,mBAAqB,MAAM,UAAU,UAAU,CAAC,UAAU,gBAAgB,aAAa,UAAU,MAAM,EAAE;AAAA,EAClH,EAAE,OAAO,mBAAqB,MAAM,kBAAkB,UAAU,CAAC,SAAS,aAAa,YAAY,KAAK,EAAE;AAAA,EAC1G,EAAE,OAAO,aAAa,MAAM,wBAAwB,UAAU,CAAC,QAAQ,UAAU,YAAY,MAAM,EAAE;AAAA,EACrG,EAAE,OAAO,aAAa,MAAM,SAAS,UAAU,CAAC,SAAS,YAAY,UAAU,iBAAiB,MAAM,EAAE;AAAA,EACxG,EAAE,OAAO,aAAa,MAAM,qBAAqB,UAAU,CAAC,SAAS,QAAQ,YAAY,aAAa,EAAE;AAAA,EACxG,EAAE,OAAO,UAAY,MAAM,YAAY,UAAU,CAAC,YAAY,QAAQ,SAAS,UAAU,EAAE;AAAA,EAC3F,EAAE,OAAO,UAAY,MAAM,YAAY,UAAU,CAAC,YAAY,QAAQ,WAAW,SAAS,OAAO,EAAE;AAAA,EACnG,EAAE,OAAO,mBAAqB,MAAM,kBAAkB,UAAU,CAAC,QAAQ,UAAU,QAAQ,UAAU,OAAO,EAAE;AAAA,EAC9G,EAAE,OAAO,aAAa,MAAM,cAAc,UAAU,CAAC,SAAS,cAAc,WAAW,SAAS,QAAQ,EAAE;AAAA,EAC1G,EAAE,OAAO,aAAa,MAAM,eAAe,UAAU,CAAC,SAAS,WAAW,OAAO,WAAW,EAAE;AAAA,EAC9F,EAAE,OAAO,aAAa,MAAM,yBAAyB,UAAU,CAAC,OAAO,OAAO,WAAW,QAAQ,OAAO,EAAE;AAAA,EAC1G,EAAE,OAAO,aAAa,MAAM,gBAAgB,UAAU,CAAC,SAAS,UAAU,WAAW,OAAO,EAAE;AAAA,EAC9F,EAAE,OAAO,aAAa,MAAM,gBAAgB,UAAU,CAAC,WAAW,QAAQ,QAAQ,WAAW,EAAE;AAAA,EAC/F,EAAE,OAAO,aAAa,MAAM,iBAAiB,UAAU,CAAC,WAAW,SAAS,QAAQ,OAAO,EAAE;AAAA,EAC7F,EAAE,OAAO,aAAa,MAAM,iBAAiB,UAAU,CAAC,YAAY,QAAQ,WAAW,WAAW,EAAE;AAAA,EACpG,EAAE,OAAO,aAAa,MAAM,SAAS,UAAU,CAAC,SAAS,SAAS,QAAQ,UAAU,OAAO,EAAE;AAAA,EAC7F,EAAE,OAAO,aAAa,MAAM,cAAc,UAAU,CAAC,cAAc,OAAO,WAAW,WAAW,EAAE;AAAA,EAClG,EAAE,OAAO,aAAa,MAAM,0BAA0B,UAAU,CAAC,WAAW,SAAS,UAAU,MAAM,EAAE;AAAA,EACvG,EAAE,OAAO,aAAa,MAAM,oBAAoB,UAAU,CAAC,UAAU,SAAS,SAAS,aAAa,OAAO,EAAE;AAAA,EAC7G,EAAE,OAAO,UAAY,MAAM,aAAa,UAAU,CAAC,QAAQ,OAAO,UAAU,WAAW,MAAM,EAAE;AAAA,EAC/F,EAAE,OAAO,aAAa,MAAM,QAAQ,UAAU,CAAC,QAAQ,UAAU,iBAAiB,SAAS,MAAM,EAAE;AAAA,EAEnG,EAAE,OAAO,UAAY,MAAM,eAAe,UAAU,CAAC,UAAU,YAAY,SAAS,QAAQ,MAAM,EAAE;AAAA,EACpG,EAAE,OAAO,aAAa,MAAM,cAAc,UAAU,CAAC,cAAc,SAAS,QAAQ,QAAQ,KAAK,EAAE;AAAA,EACnG,EAAE,OAAO,aAAa,MAAM,qBAAqB,UAAU,CAAC,YAAY,YAAY,SAAS,KAAK,EAAE;AAAA,EACpG,EAAE,OAAO,UAAY,MAAM,YAAY,UAAU,CAAC,YAAY,SAAS,QAAQ,MAAM,EAAE;AAAA,EACvF,EAAE,OAAO,aAAa,MAAM,UAAU,UAAU,CAAC,UAAU,SAAS,QAAQ,QAAQ,EAAE;AAAA,EACtF,EAAE,OAAO,aAAa,MAAM,cAAc,UAAU,CAAC,cAAc,SAAS,QAAQ,MAAM,EAAE;AAAA,EAC5F,EAAE,OAAO,aAAa,MAAM,kBAAkB,UAAU,CAAC,SAAS,SAAS,QAAQ,UAAU,EAAE;AAAA,EAC/F,EAAE,OAAO,aAAa,MAAM,WAAW,UAAU,CAAC,WAAW,SAAS,QAAQ,OAAO,MAAM,EAAE;AAAA,EAC7F,EAAE,OAAO,aAAa,MAAM,gBAAgB,UAAU,CAAC,WAAW,SAAS,OAAO,MAAM,EAAE;AAAA,EAC1F,EAAE,OAAO,UAAY,MAAM,gBAAgB,UAAU,CAAC,QAAQ,SAAS,QAAQ,MAAM,EAAE;AAAA,EACvF,EAAE,OAAO,aAAa,MAAM,UAAU,UAAU,CAAC,UAAU,SAAS,UAAU,YAAY,SAAS,MAAM,EAAE;AAAA,EAC3G,EAAE,OAAO,aAAa,MAAM,gBAAgB,UAAU,CAAC,SAAS,SAAS,SAAS,QAAQ,EAAE;AAAA,EAC5F,EAAE,OAAO,aAAa,MAAM,qBAAqB,UAAU,CAAC,QAAQ,SAAS,SAAS,UAAU,UAAU,EAAE;AAAA,EAC5G,EAAE,OAAO,aAAa,MAAM,sBAAsB,UAAU,CAAC,UAAU,SAAS,UAAU,WAAW,EAAE;AAAA,EACvG,EAAE,OAAO,aAAa,MAAM,qBAAqB,UAAU,CAAC,UAAU,SAAS,OAAO,EAAE;AAAA,EACxF,EAAE,OAAO,aAAa,MAAM,cAAc,UAAU,CAAC,QAAQ,UAAU,cAAc,QAAQ,SAAS,EAAE;AAAA,EACxG,EAAE,OAAO,aAAa,MAAM,YAAY,UAAU,CAAC,QAAQ,QAAQ,QAAQ,UAAU,QAAQ,EAAE;AAAA,EAC/F,EAAE,OAAO,gBAAoB,MAAM,cAAc,UAAU,CAAC,SAAS,QAAQ,YAAY,MAAM,EAAE;AAAA,EACjG,EAAE,OAAO,aAAa,MAAM,YAAY,UAAU,CAAC,UAAU,QAAQ,YAAY,OAAO,MAAM,EAAE;AAAA,EAChG,EAAE,OAAO,aAAa,MAAM,gBAAgB,UAAU,CAAC,SAAS,QAAQ,SAAS,QAAQ,MAAM,EAAE;AAAA,EACjG,EAAE,OAAO,aAAa,MAAM,iBAAiB,UAAU,CAAC,SAAS,SAAS,SAAS,UAAU,MAAM,EAAE;AAAA,EACrG,EAAE,OAAO,aAAa,MAAM,UAAU,UAAU,CAAC,UAAU,SAAS,cAAc,MAAM,EAAE;AAAA,EAC1F,EAAE,OAAO,aAAa,MAAM,oBAAoB,UAAU,CAAC,SAAS,YAAY,SAAS,YAAY,EAAE;AAAA,EACvG,EAAE,OAAO,aAAa,MAAM,cAAc,UAAU,CAAC,cAAc,SAAS,QAAQ,WAAW,KAAK,EAAE;AAAA,EACtG,EAAE,OAAO,aAAa,MAAM,iBAAiB,UAAU,CAAC,SAAS,QAAQ,UAAU,UAAU,SAAS,EAAE;AAAA,EACxG,EAAE,OAAO,aAAa,MAAM,kBAAkB,UAAU,CAAC,OAAO,SAAS,WAAW,YAAY,MAAM,EAAE;AAAA,EACxG,EAAE,OAAO,aAAa,MAAM,mBAAmB,UAAU,CAAC,QAAQ,YAAY,QAAQ,SAAS,OAAO,EAAE;AAAA,EACxG,EAAE,OAAO,aAAa,MAAM,kBAAkB,UAAU,CAAC,QAAQ,WAAW,QAAQ,SAAS,OAAO,EAAE;AAAA,EACtG,EAAE,OAAO,aAAa,MAAM,iBAAiB,UAAU,CAAC,QAAQ,WAAW,WAAW,QAAQ,OAAO,EAAE;AAAA,EACvG,EAAE,OAAO,mBAAqB,MAAM,0BAA0B,UAAU,CAAC,OAAO,WAAW,WAAW,YAAY,QAAQ,EAAE;AAAA,EAC5H,EAAE,OAAO,aAAa,MAAM,kBAAkB,UAAU,CAAC,WAAW,SAAS,SAAS,MAAM,EAAE;AAAA,EAC9F,EAAE,OAAO,aAAa,MAAM,oBAAoB,UAAU,CAAC,aAAa,SAAS,SAAS,SAAS,EAAE;AAAA,EACrG,EAAE,OAAO,aAAa,MAAM,6BAA6B,UAAU,CAAC,cAAc,SAAS,QAAQ,MAAM,EAAE;AAAA,EAC3G,EAAE,OAAO,aAAa,MAAM,2BAA2B,UAAU,CAAC,YAAY,SAAS,QAAQ,OAAO,EAAE;AAAA,EACxG,EAAE,OAAO,aAAa,MAAM,gBAAgB,UAAU,CAAC,UAAU,SAAS,SAAS,SAAS,OAAO,EAAE;AAAA,EACrG,EAAE,OAAO,aAAa,MAAM,wBAAwB,UAAU,CAAC,UAAU,gBAAgB,QAAQ,OAAO,EAAE;AAAA,EAC1G,EAAE,OAAO,aAAa,MAAM,iBAAiB,UAAU,CAAC,WAAW,SAAS,UAAU,KAAK,EAAE;AAAA,EAC7F,EAAE,OAAO,aAAa,MAAM,YAAY,UAAU,CAAC,YAAY,SAAS,SAAS,MAAM,EAAE;AAAA,EACzF,EAAE,OAAO,aAAa,MAAM,eAAe,UAAU,CAAC,QAAQ,aAAa,SAAS,MAAM,EAAE;AAAA,EAC5F,EAAE,OAAO,aAAa,MAAM,aAAa,UAAU,CAAC,aAAa,gBAAgB,SAAS,QAAQ,EAAE;AAAA,EACpG,EAAE,OAAO,aAAa,MAAM,aAAa,UAAU,CAAC,aAAa,SAAS,UAAU,aAAa,EAAE;AAAA,EACnG,EAAE,OAAO,aAAa,MAAM,SAAS,UAAU,CAAC,SAAS,OAAO,QAAQ,OAAO,EAAE;AAAA,EACjF,EAAE,OAAO,aAAa,MAAM,QAAQ,UAAU,CAAC,QAAQ,OAAO,QAAQ,OAAO,SAAS,EAAE;AAAA,EACxF,EAAE,OAAO,aAAa,MAAM,aAAa,UAAU,CAAC,aAAa,SAAS,UAAU,WAAW,EAAE;AAAA,EACjG,EAAE,OAAO,aAAa,MAAM,eAAe,UAAU,CAAC,UAAU,QAAQ,QAAQ,YAAY,KAAK,EAAE;AAAA,EACnG,EAAE,OAAO,aAAa,MAAM,kBAAkB,UAAU,CAAC,YAAY,SAAS,QAAQ,aAAa,MAAM,EAAE;AAAA,EAC3G,EAAE,OAAO,aAAa,MAAM,gBAAgB,UAAU,CAAC,UAAU,SAAS,aAAa,QAAQ,MAAM,EAAE;AAAA,EACvG,EAAE,OAAO,aAAa,MAAM,kBAAkB,UAAU,CAAC,kBAAkB,aAAa,QAAQ,QAAQ,QAAQ,EAAE;AAAA,EAClH,EAAE,OAAO,mBAAqB,MAAM,eAAe,UAAU,CAAC,QAAQ,SAAS,UAAU,UAAU,MAAM,EAAE;AAAA,EAC3G,EAAE,OAAO,mBAAqB,MAAM,qBAAqB,UAAU,CAAC,UAAU,aAAa,SAAS,QAAQ,SAAS,EAAE;AAAA,EACvH,EAAE,OAAO,aAAa,MAAM,WAAW,UAAU,CAAC,WAAW,SAAS,SAAS,cAAc,OAAO,EAAE;AAAA,EACtG,EAAE,OAAO,aAAa,MAAM,aAAa,UAAU,CAAC,QAAQ,SAAS,cAAc,QAAQ,YAAY,EAAE;AAAA,EACzG,EAAE,OAAO,aAAa,MAAM,WAAW,UAAU,CAAC,WAAW,SAAS,cAAc,SAAS,MAAM,EAAE;AAAA,EACrG,EAAE,OAAO,aAAa,MAAM,UAAU,UAAU,CAAC,UAAU,SAAS,cAAc,UAAU,WAAW,EAAE;AAAA,EACzG,EAAE,OAAO,aAAa,MAAM,SAAS,UAAU,CAAC,SAAS,SAAS,cAAc,UAAU,SAAS,EAAE;AAAA,EACrG,EAAE,OAAO,aAAa,MAAM,QAAQ,UAAU,CAAC,QAAQ,SAAS,cAAc,QAAQ,YAAY,EAAE;AAAA,EAEpG,EAAE,OAAO,aAAa,MAAM,gBAAgB,UAAU,CAAC,SAAS,UAAU,QAAQ,cAAc,QAAQ,EAAE;AAAA,EAC1G,EAAE,OAAO,aAAa,MAAM,2BAA2B,UAAU,CAAC,SAAS,QAAQ,YAAY,QAAQ,EAAE;AAAA,EACzG,EAAE,OAAO,gBAAoB,MAAM,aAAa,UAAU,CAAC,SAAS,QAAQ,aAAa,UAAU,EAAE;AAAA,EACrG,EAAE,OAAO,aAAa,MAAM,UAAU,UAAU,CAAC,UAAU,YAAY,MAAM,QAAQ,QAAQ,EAAE;AAAA,EAC/F,EAAE,OAAO,mBAAqB,MAAM,oBAAoB,UAAU,CAAC,YAAY,WAAW,WAAW,UAAU,IAAI,EAAE;AAAA,EACrH,EAAE,OAAO,gBAAoB,MAAM,YAAY,UAAU,CAAC,YAAY,QAAQ,YAAY,OAAO,EAAE;AAAA,EACnG,EAAE,OAAO,mBAAqB,MAAM,WAAW,UAAU,CAAC,WAAW,SAAS,SAAS,QAAQ,EAAE;AAAA,EACjG,EAAE,OAAO,aAAa,MAAM,UAAU,UAAU,CAAC,UAAU,SAAS,WAAW,aAAa,EAAE;AAAA,EAC9F,EAAE,OAAO,aAAa,MAAM,gBAAgB,UAAU,CAAC,SAAS,UAAU,QAAQ,QAAQ,EAAE;AAAA,EAC5F,EAAE,OAAO,aAAa,MAAM,cAAc,UAAU,CAAC,MAAM,cAAc,UAAU,SAAS,MAAM,EAAE;AAAA,EACpG,EAAE,OAAO,aAAa,MAAM,SAAS,UAAU,CAAC,SAAS,SAAS,aAAa,QAAQ,EAAE;AAAA,EACzF,EAAE,OAAO,aAAa,MAAM,WAAW,UAAU,CAAC,WAAW,SAAS,UAAU,QAAQ,EAAE;AAAA,EAC1F,EAAE,OAAO,aAAa,MAAM,iBAAiB,UAAU,CAAC,QAAQ,YAAY,SAAS,UAAU,QAAQ,EAAE;AAAA,EACzG,EAAE,OAAO,aAAa,MAAM,cAAc,UAAU,CAAC,QAAQ,SAAS,QAAQ,UAAU,SAAS,YAAY,EAAE;AAAA,EAC/G,EAAE,OAAO,aAAa,MAAM,cAAc,UAAU,CAAC,cAAc,SAAS,SAAS,MAAM,EAAE;AAAA,EAC7F,EAAE,OAAO,mBAAqB,MAAM,UAAU,UAAU,CAAC,UAAU,SAAS,QAAQ,SAAS,UAAU,EAAE;AAAA,EACzG,EAAE,OAAO,aAAa,MAAM,aAAa,UAAU,CAAC,QAAQ,QAAQ,QAAQ,SAAS,YAAY,EAAE;AAAA,EACnG,EAAE,OAAO,aAAa,MAAM,eAAe,UAAU,CAAC,QAAQ,UAAU,OAAO,MAAM,EAAE;AAAA,EACvF,EAAE,OAAO,aAAa,MAAM,SAAS,UAAU,CAAC,SAAS,WAAW,SAAS,QAAQ,OAAO,EAAE;AAAA,EAC9F,EAAE,OAAO,aAAa,MAAM,YAAY,UAAU,CAAC,YAAY,SAAS,WAAW,OAAO,EAAE;AAAA,EAC5F,EAAE,OAAO,aAAa,MAAM,QAAQ,UAAU,CAAC,QAAQ,QAAQ,SAAS,UAAU,UAAU,EAAE;AAAA,EAC9F,EAAE,OAAO,aAAa,MAAM,kBAAkB,UAAU,CAAC,QAAQ,YAAY,QAAQ,OAAO,EAAE;AAAA,EAC9F,EAAE,OAAO,aAAa,MAAM,aAAa,UAAU,CAAC,aAAa,QAAQ,UAAU,QAAQ,EAAE;AAAA,EAC7F,EAAE,OAAO,aAAa,MAAM,aAAa,UAAU,CAAC,aAAa,QAAQ,SAAS,OAAO,EAAE;AAAA,EAC3F,EAAE,OAAO,aAAa,MAAM,YAAY,UAAU,CAAC,YAAY,QAAQ,YAAY,SAAS,KAAK,EAAE;AAAA,EACnG,EAAE,OAAO,aAAa,MAAM,qBAAqB,UAAU,CAAC,YAAY,QAAQ,YAAY,KAAK,EAAE;AAAA,EACnG,EAAE,OAAO,aAAa,MAAM,oBAAoB,UAAU,CAAC,SAAS,SAAS,MAAM,UAAU,YAAY,UAAU,EAAE;AAAA,EACrH,EAAE,OAAO,aAAa,MAAM,oBAAoB,UAAU,CAAC,SAAS,SAAS,QAAQ,YAAY,MAAM,EAAE;AAAA,EACzG,EAAE,OAAO,aAAa,MAAM,aAAa,UAAU,CAAC,SAAS,SAAS,OAAO,SAAS,WAAW,EAAE;AAAA,EACnG,EAAE,OAAO,aAAa,MAAM,WAAW,UAAU,CAAC,OAAO,WAAW,YAAY,MAAM,EAAE;AAAA,EACxF,EAAE,OAAO,aAAa,MAAM,iBAAiB,UAAU,CAAC,OAAO,YAAY,OAAO,MAAM,EAAE;AAAA,EAC1F,EAAE,OAAO,gBAAoB,MAAM,YAAY,UAAU,CAAC,YAAY,OAAO,QAAQ,MAAM,EAAE;AAAA,EAC7F,EAAE,OAAO,aAAa,MAAM,kBAAkB,UAAU,CAAC,SAAS,WAAW,YAAY,MAAM,EAAE;AAAA,EACjG,EAAE,OAAO,aAAa,MAAM,UAAU,UAAU,CAAC,QAAQ,UAAU,YAAY,WAAW,QAAQ,EAAE;AAAA,EACpG,EAAE,OAAO,aAAa,MAAM,YAAY,UAAU,CAAC,UAAU,QAAQ,YAAY,QAAQ,EAAE;AAAA,EAC3F,EAAE,OAAO,aAAa,MAAM,OAAO,UAAU,CAAC,OAAO,QAAQ,UAAU,YAAY,QAAQ,EAAE;AAAA,EAC7F,EAAE,OAAO,aAAa,MAAM,UAAU,UAAU,CAAC,UAAU,QAAQ,SAAS,OAAO,cAAc,EAAE;AAAA,EACnG,EAAE,OAAO,aAAa,MAAM,eAAe,UAAU,CAAC,eAAe,QAAQ,OAAO,QAAQ,EAAE;AAAA,EAC9F,EAAE,OAAO,aAAa,MAAM,UAAU,UAAU,CAAC,UAAU,QAAQ,OAAO,UAAU,UAAU,EAAE;AAAA,EAChG,EAAE,OAAO,mBAAqB,MAAM,qBAAqB,UAAU,CAAC,SAAS,OAAO,UAAU,SAAS,UAAU,EAAE;AAAA,EACnH,EAAE,OAAO,gBAAoB,MAAM,QAAQ,UAAU,CAAC,QAAQ,YAAY,OAAO,aAAa,YAAY,EAAE;AAAA,EAC5G,EAAE,OAAO,aAAa,MAAM,UAAU,UAAU,CAAC,UAAU,WAAW,YAAY,MAAM,EAAE;AAAA,EAC1F,EAAE,OAAO,aAAa,MAAM,gCAAgC,UAAU,CAAC,UAAU,WAAW,QAAQ,QAAQ,QAAQ,aAAa,EAAE;AAAA,EACnI,EAAE,OAAO,aAAa,MAAM,iCAAiC,UAAU,CAAC,UAAU,WAAW,QAAQ,QAAQ,MAAM,EAAE;AAAA,EACrH,EAAE,OAAO,aAAa,MAAM,aAAa,UAAU,CAAC,SAAS,OAAO,UAAU,QAAQ,UAAU,MAAM,EAAE;AAAA,EACxG,EAAE,OAAO,aAAa,MAAM,mBAAmB,UAAU,CAAC,SAAS,UAAU,QAAQ,QAAQ,KAAK,EAAE;AAAA,EACpG,EAAE,OAAO,aAAa,MAAM,eAAe,UAAU,CAAC,UAAU,QAAQ,WAAW,SAAS,KAAK,EAAE;AAAA,EACnG,EAAE,OAAO,aAAa,MAAM,oBAAoB,UAAU,CAAC,SAAS,UAAU,YAAY,aAAa,MAAM,EAAE;AAAA,EAC/G,EAAE,OAAO,aAAa,MAAM,SAAS,UAAU,CAAC,SAAS,QAAQ,UAAU,YAAY,SAAS,EAAE;AAAA,EAClG,EAAE,OAAO,aAAa,MAAM,qBAAqB,UAAU,CAAC,SAAS,YAAY,YAAY,QAAQ,QAAQ,EAAE;AAAA,EAC/G,EAAE,OAAO,aAAa,MAAM,uBAAuB,UAAU,CAAC,SAAS,YAAY,QAAQ,UAAU,EAAE;AAAA,EACvG,EAAE,OAAO,aAAa,MAAM,WAAW,UAAU,CAAC,WAAW,OAAO,YAAY,YAAY,QAAQ,EAAE;AAAA,EACtG,EAAE,OAAO,mBAAqB,MAAM,SAAS,UAAU,CAAC,SAAS,OAAO,SAAS,MAAM,EAAE;AAAA,EACzF,EAAE,OAAO,UAAY,MAAM,SAAS,UAAU,CAAC,SAAS,QAAQ,SAAS,OAAO,EAAE;AAAA,EAClF,EAAE,OAAO,UAAY,MAAM,eAAe,UAAU,CAAC,SAAS,SAAS,QAAQ,QAAQ,SAAS,EAAE;AAAA,EAClG,EAAE,OAAO,UAAY,MAAM,0BAA0B,UAAU,CAAC,aAAa,QAAQ,WAAW,QAAQ,OAAO,EAAE;AAAA,EACjH,EAAE,OAAO,mBAAqB,MAAM,qBAAqB,UAAU,CAAC,SAAS,QAAQ,WAAW,SAAS,EAAE;AAAA,EAC3G,EAAE,OAAO,aAAa,MAAM,eAAe,UAAU,CAAC,WAAW,QAAQ,gBAAgB,WAAW,EAAE;AAAA,EACtG,EAAE,OAAO,aAAa,MAAM,QAAQ,UAAU,CAAC,QAAQ,gBAAgB,QAAQ,SAAS,OAAO,EAAE;AAAA,EACjG,EAAE,OAAO,aAAa,MAAM,mBAAmB,UAAU,CAAC,QAAQ,QAAQ,UAAU,mBAAmB,OAAO,EAAE;AAAA,EAChH,EAAE,OAAO,aAAa,MAAM,gBAAgB,UAAU,CAAC,QAAQ,UAAU,YAAY,QAAQ,SAAS,EAAE;AAAA,EACxG,EAAE,OAAO,aAAa,MAAM,SAAS,UAAU,CAAC,SAAS,QAAQ,SAAS,SAAS,QAAQ,QAAQ,EAAE;AAAA,EACrG,EAAE,OAAO,aAAa,MAAM,aAAa,UAAU,CAAC,OAAO,WAAW,SAAS,WAAW,YAAY,MAAM,EAAE;AAAA,EAC9G,EAAE,OAAO,UAAY,MAAM,YAAY,UAAU,CAAC,YAAY,SAAS,SAAS,WAAW,SAAS,OAAO,OAAO,EAAE;AAAA,EACpH,EAAE,OAAO,aAAa,MAAM,SAAS,UAAU,CAAC,SAAS,QAAQ,WAAW,SAAS,OAAO,EAAE;AAAA,EAC9F,EAAE,OAAO,mBAAqB,MAAM,UAAU,UAAU,CAAC,UAAU,WAAW,WAAW,YAAY,OAAO,EAAE;AAAA,EAC9G,EAAE,OAAO,gBAAoB,MAAM,kBAAkB,UAAU,CAAC,UAAU,UAAU,SAAS,UAAU,OAAO,SAAS,EAAE;AAAA,EACzH,EAAE,OAAO,aAAa,MAAM,gBAAgB,UAAU,CAAC,WAAW,QAAQ,WAAW,SAAS,WAAW,QAAQ,EAAE;AAAA,EACnH,EAAE,OAAO,aAAa,MAAM,cAAc,UAAU,CAAC,SAAS,QAAQ,UAAU,SAAS,SAAS,EAAE;AAAA,EACpG,EAAE,OAAO,aAAa,MAAM,gBAAgB,UAAU,CAAC,SAAS,YAAY,UAAU,SAAS,YAAY,EAAE;AAAA,EAC7G,EAAE,OAAO,aAAa,MAAM,SAAS,UAAU,CAAC,SAAS,SAAS,SAAS,OAAO,EAAE;AAAA,EACpF,EAAE,OAAO,aAAa,MAAM,UAAU,UAAU,CAAC,UAAU,SAAS,SAAS,MAAM,EAAE;AAAA,EACrF,EAAE,OAAO,mBAAqB,MAAM,eAAe,UAAU,CAAC,SAAS,UAAU,OAAO,SAAS,WAAW,SAAS,EAAE;AAAA,EACvH,EAAE,OAAO,aAAa,MAAM,WAAW,UAAU,CAAC,WAAW,YAAY,UAAU,OAAO,MAAM,EAAE;AAAA,EAClG,EAAE,OAAO,aAAa,MAAM,YAAY,UAAU,CAAC,YAAY,OAAO,UAAU,UAAU,QAAQ,EAAE;AAAA,EACpG,EAAE,OAAO,aAAa,MAAM,kBAAkB,UAAU,CAAC,cAAc,OAAO,UAAU,aAAa,UAAU,KAAK,EAAE;AAAA,EACtH,EAAE,OAAO,aAAa,MAAM,aAAa,UAAU,CAAC,aAAa,QAAQ,SAAS,SAAS,SAAS,EAAE;AAAA,EACtG,EAAE,OAAO,aAAa,MAAM,UAAU,UAAU,CAAC,UAAU,YAAY,WAAW,SAAS,WAAW,EAAE;AAAA,EACxG,EAAE,OAAO,aAAa,MAAM,iBAAiB,UAAU,CAAC,YAAY,QAAQ,QAAQ,MAAM,EAAE;AAAA,EAC5F,EAAE,OAAO,aAAa,MAAM,YAAY,UAAU,CAAC,YAAY,QAAQ,QAAQ,QAAQ,UAAU,EAAE;AAAA,EACnG,EAAE,OAAO,aAAa,MAAM,mBAAmB,UAAU,CAAC,WAAW,SAAS,SAAS,UAAU,aAAa,EAAE;AAAA,EAChH,EAAE,OAAO,aAAa,MAAM,gBAAgB,UAAU,CAAC,UAAU,SAAS,UAAU,OAAO,SAAS,MAAM,EAAE;AAAA,EAC5G,EAAE,OAAO,aAAa,MAAM,SAAS,UAAU,CAAC,SAAS,SAAS,QAAQ,gBAAgB,OAAO,EAAE;AAAA,EACnG,EAAE,OAAO,aAAa,MAAM,QAAQ,UAAU,CAAC,QAAQ,SAAS,QAAQ,YAAY,KAAK,EAAE;AAAA,EAC3F,EAAE,OAAO,aAAa,MAAM,gBAAgB,UAAU,CAAC,SAAS,OAAO,SAAS,QAAQ,MAAM,EAAE;AAAA,EAChG,EAAE,OAAO,aAAa,MAAM,iBAAiB,UAAU,CAAC,SAAS,QAAQ,UAAU,QAAQ,MAAM,EAAE;AAAA,EACnG,EAAE,OAAO,aAAa,MAAM,kBAAkB,UAAU,CAAC,SAAS,SAAS,WAAW,QAAQ,MAAM,EAAE;AAAA,EACtG,EAAE,OAAO,aAAa,MAAM,eAAe,UAAU,CAAC,UAAU,QAAQ,QAAQ,SAAS,QAAQ,EAAE;AAAA,EACnG,EAAE,OAAO,aAAa,MAAM,cAAc,UAAU,CAAC,SAAS,WAAW,QAAQ,SAAS,UAAU,EAAE;AAAA,EACtG,EAAE,OAAO,aAAa,MAAM,iCAAiC,UAAU,CAAC,WAAW,QAAQ,UAAU,MAAM,EAAE;AAAA,EAC7G,EAAE,OAAO,mBAAqB,MAAM,iBAAiB,UAAU,CAAC,QAAQ,OAAO,WAAW,WAAW,UAAU,EAAE;AAAA,EACjH,EAAE,OAAO,mBAAqB,MAAM,gBAAgB,UAAU,CAAC,QAAQ,WAAW,WAAW,WAAW,QAAQ,EAAE;AAAA,EAClH,EAAE,OAAO,mBAAqB,MAAM,uBAAuB,UAAU,CAAC,YAAY,SAAS,QAAQ,YAAY,MAAM,EAAE;AAAA,EACvH,EAAE,OAAO,aAAa,MAAM,eAAe,UAAU,CAAC,UAAU,QAAQ,aAAa,UAAU,EAAE;AAAA,EACjG,EAAE,OAAO,aAAa,MAAM,oBAAoB,UAAU,CAAC,UAAU,QAAQ,QAAQ,WAAW,EAAE;AAAA,EAClG,EAAE,OAAO,mBAAqB,MAAM,0BAA0B,UAAU,CAAC,UAAU,QAAQ,YAAY,OAAO,WAAW,EAAE;AAAA,EAC3H,EAAE,OAAO,aAAa,MAAM,cAAc,UAAU,CAAC,QAAQ,SAAS,WAAW,UAAU,EAAE;AAAA,EAC7F,EAAE,OAAO,aAAa,MAAM,aAAa,UAAU,CAAC,aAAa,QAAQ,YAAY,OAAO,QAAQ,EAAE;AAAA,EACtG,EAAE,OAAO,aAAa,MAAM,WAAW,UAAU,CAAC,WAAW,WAAW,aAAa,WAAW,UAAU,QAAQ,EAAE;AAAA,EACpH,EAAE,OAAO,aAAa,MAAM,eAAe,UAAU,CAAC,eAAe,WAAW,UAAU,UAAU,UAAU,EAAE;AAAA,EAChH,EAAE,OAAO,aAAa,MAAM,QAAQ,UAAU,CAAC,QAAQ,YAAY,QAAQ,UAAU,UAAU,EAAE;AAAA,EACjG,EAAE,OAAO,aAAa,MAAM,aAAa,UAAU,CAAC,aAAa,WAAW,cAAc,aAAa,KAAK,EAAE;AAAA,EAC9G,EAAE,OAAO,aAAa,MAAM,cAAc,UAAU,CAAC,cAAc,WAAW,YAAY,OAAO,SAAS,EAAE;AAAA,EAC5G,EAAE,OAAO,aAAa,MAAM,aAAa,UAAU,CAAC,aAAa,SAAS,aAAa,SAAS,MAAM,EAAE;AAAA,EACxG,EAAE,OAAO,aAAa,MAAM,qBAAqB,UAAU,CAAC,aAAa,WAAW,UAAU,aAAa,eAAe,EAAE;AAAA,EAC5H,EAAE,OAAO,aAAa,MAAM,mBAAmB,UAAU,CAAC,QAAQ,OAAO,UAAU,WAAW,OAAO,EAAE;AAAA,EACvG,EAAE,OAAO,aAAa,MAAM,mBAAmB,UAAU,CAAC,QAAQ,OAAO,UAAU,WAAW,QAAQ,EAAE;AAAA,EACxG,EAAE,OAAO,aAAa,MAAM,UAAU,UAAU,CAAC,UAAU,YAAY,SAAS,cAAc,QAAQ,EAAE;AAAA,EACxG,EAAE,OAAO,aAAa,MAAM,kCAAkC,UAAU,CAAC,YAAY,cAAc,SAAS,OAAO,EAAE;AAAA,EACrH,EAAE,OAAO,aAAa,MAAM,cAAc,UAAU,CAAC,QAAQ,SAAS,QAAQ,OAAO,EAAE;AAAA,EACvF,EAAE,OAAO,aAAa,MAAM,aAAa,UAAU,CAAC,QAAQ,QAAQ,QAAQ,OAAO,EAAE;AAAA,EACrF,EAAE,OAAO,aAAa,MAAM,eAAe,UAAU,CAAC,QAAQ,UAAU,QAAQ,OAAO,EAAE;AAAA,EACzF,EAAE,OAAO,gBAAoB,MAAM,aAAa,UAAU,CAAC,aAAa,QAAQ,SAAS,SAAS,MAAM,EAAE;AAAA,EAC1G,EAAE,OAAO,gBAAoB,MAAM,eAAe,UAAU,CAAC,SAAS,SAAS,aAAa,MAAM,EAAE;AAAA,EACpG,EAAE,OAAO,UAAY,MAAM,kBAAkB,UAAU,CAAC,aAAa,QAAQ,QAAQ,YAAY,MAAM,EAAE;AAAA,EACzG,EAAE,OAAO,aAAa,MAAM,gBAAgB,UAAU,CAAC,MAAM,QAAQ,OAAO,SAAS,MAAM,EAAE;AAAA,EAC7F,EAAE,OAAO,aAAa,MAAM,eAAe,UAAU,CAAC,UAAU,QAAQ,QAAQ,QAAQ,OAAO,EAAE;AAAA,EACjG,EAAE,OAAO,aAAa,MAAM,YAAY,UAAU,CAAC,QAAQ,QAAQ,WAAW,OAAO,EAAE;AAAA,EACvF,EAAE,OAAO,aAAa,MAAM,OAAO,UAAU,CAAC,OAAO,QAAQ,SAAS,QAAQ,OAAO,EAAE;AAAA,EACvF,EAAE,OAAO,aAAa,MAAM,iBAAiB,UAAU,CAAC,SAAS,QAAQ,WAAW,UAAU,QAAQ,EAAE;AAAA,EACxG,EAAE,OAAO,aAAa,MAAM,UAAU,UAAU,CAAC,UAAU,WAAW,UAAU,QAAQ,SAAS,EAAE;AAAA,EACnG,EAAE,OAAO,aAAa,MAAM,SAAS,UAAU,CAAC,QAAQ,WAAW,SAAS,UAAU,MAAM,EAAE;AAAA,EAC9F,EAAE,OAAO,aAAa,MAAM,iBAAiB,UAAU,CAAC,QAAQ,YAAY,OAAO,SAAS,SAAS,EAAE;AAAA,EACvG,EAAE,OAAO,aAAa,MAAM,gBAAgB,UAAU,CAAC,QAAQ,WAAW,YAAY,aAAa,MAAM,EAAE;AAAA,EAC3G,EAAE,OAAO,aAAa,MAAM,UAAU,UAAU,CAAC,UAAU,OAAO,QAAQ,cAAc,MAAM,EAAE;AAAA,EAChG,EAAE,OAAO,aAAa,MAAM,WAAW,UAAU,CAAC,WAAW,SAAS,aAAa,YAAY,OAAO,EAAE;AAAA,EACxG,EAAE,OAAO,aAAa,MAAM,gBAAgB,UAAU,CAAC,SAAS,aAAa,YAAY,QAAQ,iBAAiB,EAAE;AAAA,EACpH,EAAE,OAAO,aAAa,MAAM,iBAAiB,UAAU,CAAC,YAAY,SAAS,aAAa,MAAM,EAAE;AAAA,EAClG,EAAE,OAAO,aAAa,MAAM,kBAAkB,UAAU,CAAC,SAAS,YAAY,YAAY,aAAa,EAAE;AAAA,EACzG,EAAE,OAAO,aAAa,MAAM,qBAAqB,UAAU,CAAC,WAAW,OAAO,YAAY,SAAS,SAAS,EAAE;AAAA,EAC9G,EAAE,OAAO,aAAa,MAAM,eAAe,UAAU,CAAC,eAAe,YAAY,eAAe,YAAY,MAAM,EAAE;AAAA,EACpH,EAAE,OAAO,aAAa,MAAM,aAAa,UAAU,CAAC,aAAa,aAAa,SAAS,WAAW,UAAU,EAAE;AAAA,EAC9G,EAAE,OAAO,aAAa,MAAM,YAAY,UAAU,CAAC,YAAY,YAAY,aAAa,OAAO,EAAE;AAAA,EACjG,EAAE,OAAO,aAAa,MAAM,UAAU,UAAU,CAAC,UAAU,cAAc,QAAQ,QAAQ,EAAE;AAAA,EAC3F,EAAE,OAAO,aAAa,MAAM,UAAU,UAAU,CAAC,UAAU,QAAQ,SAAS,SAAS,OAAO,EAAE;AAAA,EAC9F,EAAE,OAAO,aAAa,MAAM,QAAQ,UAAU,CAAC,QAAQ,YAAY,QAAQ,QAAQ,OAAO,EAAE;AAAA,EAC5F,EAAE,OAAO,aAAa,MAAM,SAAS,UAAU,CAAC,SAAS,QAAQ,OAAO,WAAW,EAAE;AAAA,EACrF,EAAE,OAAO,mBAAqB,MAAM,kBAAkB,UAAU,CAAC,SAAS,QAAQ,QAAQ,aAAa,aAAa,EAAE;AAAA,EACtH,EAAE,OAAO,mBAAqB,MAAM,OAAO,UAAU,CAAC,OAAO,SAAS,WAAW,aAAa,MAAM,EAAE;AAAA,EACtG,EAAE,OAAO,aAAa,MAAM,WAAW,UAAU,CAAC,WAAW,QAAQ,SAAS,SAAS,UAAU,EAAE;AAAA,EACnG,EAAE,OAAO,aAAa,MAAM,UAAU,UAAU,CAAC,UAAU,QAAQ,SAAS,SAAS,UAAU,EAAE;AAAA,EACjG,EAAE,OAAO,aAAa,MAAM,iBAAiB,UAAU,CAAC,UAAU,SAAS,eAAe,WAAW,EAAE;AAAA,EACvG,EAAE,OAAO,aAAa,MAAM,cAAc,UAAU,CAAC,cAAc,OAAO,UAAU,KAAK,EAAE;AAAA,EAC3F,EAAE,OAAO,aAAa,MAAM,UAAU,UAAU,CAAC,UAAU,UAAU,UAAU,QAAQ,EAAE;AAAA,EACzF,EAAE,OAAO,aAAa,MAAM,QAAQ,UAAU,CAAC,QAAQ,YAAY,WAAW,QAAQ,OAAO,EAAE;AAAA,EAC/F,EAAE,OAAO,aAAa,MAAM,WAAW,UAAU,CAAC,WAAW,cAAc,UAAU,WAAW,MAAM,EAAE;AAAA,EACxG,EAAE,OAAO,mBAAqB,MAAM,cAAc,UAAU,CAAC,cAAc,QAAQ,OAAO,UAAU,QAAQ,EAAE;AAAA,EAC9G,EAAE,OAAO,aAAa,MAAM,mBAAmB,UAAU,CAAC,YAAY,QAAQ,WAAW,QAAQ,EAAE;AAAA,EACnG,EAAE,OAAO,gBAAoB,MAAM,YAAY,UAAU,CAAC,YAAY,QAAQ,WAAW,KAAK,EAAE;AAAA,EAChG,EAAE,OAAO,aAAa,MAAM,WAAW,UAAU,CAAC,WAAW,SAAS,OAAO,SAAS,EAAE;AAAA,EACxF,EAAE,OAAO,aAAa,MAAM,cAAc,UAAU,CAAC,OAAO,WAAW,OAAO,WAAW,EAAE;AAAA,EAC3F,EAAE,OAAO,aAAa,MAAM,WAAW,UAAU,CAAC,OAAO,WAAW,UAAU,aAAa,OAAO,EAAE;AAAA,EACpG,EAAE,OAAO,aAAa,MAAM,WAAW,UAAU,CAAC,UAAU,SAAS,WAAW,OAAO,SAAS,EAAE;AAAA,EAClG,EAAE,OAAO,aAAa,MAAM,SAAS,UAAU,CAAC,SAAS,WAAW,WAAW,QAAQ,EAAE;AAAA,EACzF,EAAE,OAAO,aAAa,MAAM,gBAAgB,UAAU,CAAC,QAAQ,WAAW,WAAW,SAAS,MAAM,EAAE;AAAA,EACtG,EAAE,OAAO,aAAa,MAAM,oBAAoB,UAAU,CAAC,QAAQ,QAAQ,WAAW,UAAU,EAAE;AAAA,EAElG,EAAE,OAAO,UAAY,MAAM,qBAAqB,UAAU,CAAC,SAAS,QAAQ,OAAO,YAAY,WAAW,OAAO,EAAE;AAAA,EACnH,EAAE,OAAO,gBAAoB,MAAM,cAAc,UAAU,CAAC,SAAS,QAAQ,OAAO,QAAQ,SAAS,EAAE;AAAA,EACvG,EAAE,OAAO,UAAY,MAAM,cAAc,UAAU,CAAC,KAAK,MAAM,SAAS,UAAU,UAAU,KAAK,EAAE;AAAA,EACnG,EAAE,OAAO,UAAY,MAAM,qBAAqB,UAAU,CAAC,KAAK,MAAM,SAAS,UAAU,OAAO,EAAE;AAAA,EAClG,EAAE,OAAO,UAAY,MAAM,qBAAqB,UAAU,CAAC,UAAU,OAAO,KAAK,MAAM,EAAE;AAAA,EACzF,EAAE,OAAO,gBAAoB,MAAM,WAAW,UAAU,CAAC,WAAW,WAAW,SAAS,UAAU,WAAW,EAAE;AAAA,EAC/G,EAAE,OAAO,aAAa,MAAM,cAAc,UAAU,CAAC,cAAc,aAAa,MAAM,UAAU,MAAM,EAAE;AAAA,EACxG,EAAE,OAAO,gBAAoB,MAAM,eAAe,UAAU,CAAC,QAAQ,eAAe,QAAQ,SAAS,EAAE;AAAA,EACvG,EAAE,OAAO,UAAY,MAAM,wBAAwB,UAAU,CAAC,eAAe,aAAa,WAAW,SAAS,MAAM,EAAE;AAAA,EACtH,EAAE,OAAO,UAAY,MAAM,qBAAqB,UAAU,CAAC,YAAY,QAAQ,YAAY,MAAM,EAAE;AAAA,EACnG,EAAE,OAAO,gBAAoB,MAAM,6BAA6B,UAAU,CAAC,eAAe,YAAY,YAAY,aAAa,EAAE;AAAA,EACjI,EAAE,OAAO,aAAa,MAAM,cAAc,UAAU,CAAC,OAAO,QAAQ,aAAa,QAAQ,EAAE;AAAA,EAC3F,EAAE,OAAO,aAAa,MAAM,cAAc,UAAU,CAAC,OAAO,SAAS,UAAU,SAAS,EAAE;AAAA,EAC1F,EAAE,OAAO,aAAa,MAAM,aAAa,UAAU,CAAC,MAAM,UAAU,WAAW,OAAO,EAAE;AAAA,EACxF,EAAE,OAAO,aAAa,MAAM,aAAa,UAAU,CAAC,MAAM,WAAW,UAAU,MAAM,EAAE;AAAA,EACvF,EAAE,OAAO,aAAa,MAAM,eAAe,UAAU,CAAC,QAAQ,WAAW,SAAS,MAAM,EAAE;AAAA,EAC1F,EAAE,OAAO,aAAa,MAAM,eAAe,UAAU,CAAC,QAAQ,UAAU,WAAW,EAAE;AAAA,EACrF,EAAE,OAAO,gBAAoB,MAAM,eAAe,UAAU,CAAC,SAAS,SAAS,aAAa,QAAQ,SAAS,EAAE;AAAA,EAC/G,EAAE,OAAO,gBAAoB,MAAM,cAAc,UAAU,CAAC,SAAS,QAAQ,aAAa,QAAQ,UAAU,EAAE;AAAA,EAC9G,EAAE,OAAO,gBAAoB,MAAM,YAAY,UAAU,CAAC,SAAS,MAAM,aAAa,KAAK,EAAE;AAAA,EAC7F,EAAE,OAAO,gBAAoB,MAAM,cAAc,UAAU,CAAC,SAAS,QAAQ,aAAa,QAAQ,EAAE;AAAA,EACpG,EAAE,OAAO,gBAAoB,MAAM,4BAA4B,UAAU,CAAC,SAAS,UAAU,QAAQ,SAAS,MAAM,EAAE;AAAA,EACtH,EAAE,OAAO,gBAAoB,MAAM,4BAA4B,UAAU,CAAC,SAAS,WAAW,QAAQ,UAAU,EAAE;AAAA,EAClH,EAAE,OAAO,aAAa,MAAM,kCAAkC,UAAU,CAAC,WAAW,UAAU,QAAQ,UAAU,MAAM,EAAE;AAAA,EACxH,EAAE,OAAO,aAAa,MAAM,6BAA6B,UAAU,CAAC,WAAW,UAAU,QAAQ,OAAO,EAAE;AAAA,EAC1G,EAAE,OAAO,gBAAoB,MAAM,oBAAoB,UAAU,CAAC,WAAW,SAAS,eAAe,KAAK,EAAE;AAAA,EAC5G,EAAE,OAAO,aAAa,MAAM,kBAAkB,UAAU,CAAC,OAAO,WAAW,WAAW,SAAS,MAAM,EAAE;AAAA,EACvG,EAAE,OAAO,aAAa,MAAM,gBAAgB,UAAU,CAAC,SAAS,SAAS,OAAO,OAAO,EAAE;AAAA,EACzF,EAAE,OAAO,aAAa,MAAM,kBAAkB,UAAU,CAAC,UAAU,UAAU,QAAQ,QAAQ,WAAW,SAAS,EAAE;AAAA,EACnH,EAAE,OAAO,aAAa,MAAM,mBAAmB,UAAU,CAAC,WAAW,YAAY,UAAU,OAAO,EAAE;AAAA,EACpG,EAAE,OAAO,aAAa,MAAM,OAAO,UAAU,CAAC,SAAS,OAAO,SAAS,QAAQ,OAAO,EAAE;AAAA,EACxF,EAAE,OAAO,aAAa,MAAM,sBAAsB,UAAU,CAAC,WAAW,UAAU,OAAO,SAAS,OAAO,EAAE;AAAA,EAC3G,EAAE,OAAO,aAAa,MAAM,yBAAyB,UAAU,CAAC,WAAW,UAAU,UAAU,OAAO,EAAE;AAAA,EACxG,EAAE,OAAO,aAAa,MAAM,uBAAuB,UAAU,CAAC,WAAW,UAAU,QAAQ,QAAQ,OAAO,EAAE;AAAA,EAC5G,EAAE,OAAO,aAAa,MAAM,iBAAiB,UAAU,CAAC,QAAQ,UAAU,WAAW,YAAY,OAAO,EAAE;AAAA,EAC1G,EAAE,OAAO,UAAY,MAAM,QAAQ,UAAU,CAAC,QAAQ,OAAO,YAAY,YAAY,MAAM,EAAE;AAAA,EAC7F,EAAE,OAAO,UAAY,MAAM,SAAS,UAAU,CAAC,SAAS,YAAY,YAAY,YAAY,MAAM,EAAE;AAAA,EACpG,EAAE,OAAO,gBAAoB,MAAM,YAAY,UAAU,CAAC,YAAY,SAAS,KAAK,QAAQ,QAAQ,EAAE;AAAA,EACtG,EAAE,OAAO,UAAY,MAAM,UAAU,UAAU,CAAC,UAAU,YAAY,QAAQ,OAAO,EAAE;AAAA,EACvF,EAAE,OAAO,gBAAoB,MAAM,YAAY,UAAU,CAAC,YAAY,WAAW,aAAa,QAAQ,SAAS,EAAE;AAAA,EACjH,EAAE,OAAO,aAAa,MAAM,oBAAoB,UAAU,CAAC,SAAS,OAAO,UAAU,eAAe,EAAE;AAAA,EACtG,EAAE,OAAO,aAAa,MAAM,gBAAgB,UAAU,CAAC,UAAU,QAAQ,QAAQ,aAAa,SAAS,EAAE;AAAA,EACzG,EAAE,OAAO,aAAa,MAAM,aAAa,UAAU,CAAC,aAAa,YAAY,SAAS,QAAQ,SAAS,EAAE;AAAA,EACzG,EAAE,OAAO,gBAAoB,MAAM,eAAe,UAAU,CAAC,QAAQ,WAAW,WAAW,WAAW,QAAQ,EAAE;AAAA,EAChH,EAAE,OAAO,gBAAoB,MAAM,eAAe,UAAU,CAAC,eAAe,WAAW,UAAU,UAAU,WAAW,EAAE;AAAA,EACxH,EAAE,OAAO,gBAAoB,MAAM,aAAa,UAAU,CAAC,aAAa,UAAU,SAAS,UAAU,OAAO,EAAE;AAAA,EAC9G,EAAE,OAAO,gBAAoB,MAAM,YAAY,UAAU,CAAC,YAAY,WAAW,WAAW,OAAO,KAAK,EAAE;AAAA,EAC1G,EAAE,OAAO,gBAAoB,MAAM,eAAe,UAAU,CAAC,SAAS,aAAa,YAAY,QAAQ,EAAE;AAAA,EACzG,EAAE,OAAO,gBAAoB,MAAM,gBAAgB,UAAU,CAAC,SAAS,UAAU,UAAU,QAAQ,SAAS,EAAE;AAAA,EAC9G,EAAE,OAAO,UAAY,MAAM,SAAS,UAAU,CAAC,SAAS,UAAU,aAAa,WAAW,EAAE;AAAA,EAC5F,EAAE,OAAO,UAAY,MAAM,UAAU,UAAU,CAAC,UAAU,UAAU,aAAa,WAAW,EAAE;AAAA,EAC9F,EAAE,OAAO,UAAY,MAAM,UAAU,UAAU,CAAC,UAAU,UAAU,aAAa,WAAW,EAAE;AAAA,EAC9F,EAAE,OAAO,UAAY,MAAM,UAAU,UAAU,CAAC,UAAU,UAAU,aAAa,WAAW,EAAE;AAAA,EAC9F,EAAE,OAAO,UAAY,MAAM,OAAO,UAAU,CAAC,OAAO,UAAU,aAAa,WAAW,EAAE;AAAA,EACxF,EAAE,OAAO,UAAY,MAAM,SAAS,UAAU,CAAC,SAAS,UAAU,aAAa,WAAW,EAAE;AAAA,EAC5F,EAAE,OAAO,UAAY,MAAM,SAAS,UAAU,CAAC,SAAS,UAAU,aAAa,WAAW,EAAE;AAAA,EAC5F,EAAE,OAAO,UAAY,MAAM,WAAW,UAAU,CAAC,WAAW,UAAU,aAAa,WAAW,EAAE;AAAA,EAChG,EAAE,OAAO,UAAY,MAAM,eAAe,UAAU,CAAC,eAAe,UAAU,aAAa,WAAW,EAAE;AAAA,EACxG,EAAE,OAAO,UAAY,MAAM,aAAa,UAAU,CAAC,aAAa,UAAU,aAAa,WAAW,EAAE;AAAA,EACpG,EAAE,OAAO,UAAY,MAAM,YAAY,UAAU,CAAC,YAAY,UAAU,aAAa,WAAW,EAAE;AAAA,EAClG,EAAE,OAAO,UAAY,MAAM,UAAU,UAAU,CAAC,UAAU,UAAU,aAAa,WAAW,EAAE;AAAA,EAC9F,EAAE,OAAO,aAAa,MAAM,gBAAgB,UAAU,CAAC,UAAU,SAAS,YAAY,SAAS,WAAW,EAAE;AAAA,EAC5G,EAAE,OAAO,aAAa,MAAM,qBAAqB,UAAU,CAAC,UAAU,SAAS,YAAY,QAAQ,OAAO,EAAE;AAAA,EAC5G,EAAE,OAAO,cAAoB,MAAM,aAAa,UAAU,CAAC,aAAa,MAAM,SAAS,UAAU,EAAE;AAAA,EACnG,EAAE,OAAO,cAAoB,MAAM,cAAc,UAAU,CAAC,cAAc,aAAa,SAAS,OAAO,EAAE;AAAA,EACzG,EAAE,OAAO,gBAAoB,MAAM,cAAc,UAAU,CAAC,aAAa,MAAM,SAAS,OAAO,EAAE;AAAA,EACjG,EAAE,OAAO,iBAA4B,MAAM,eAAe,UAAU,CAAC,QAAQ,UAAU,WAAW,OAAO,EAAE;AAAA,EAC3G,EAAE,OAAO,iBAA4B,MAAM,mBAAmB,UAAU,CAAC,YAAY,QAAQ,UAAU,KAAK,EAAE;AAAA,EAC9G,EAAE,OAAO,iBAA4B,MAAM,YAAY,UAAU,CAAC,QAAQ,KAAK,UAAU,KAAK,EAAE;AAAA,EAChG,EAAE,OAAO,iBAA4B,MAAM,YAAY,UAAU,CAAC,OAAO,KAAK,UAAU,KAAK,EAAE;AAAA,EAC/F,EAAE,OAAO,iBAA4B,MAAM,YAAY,UAAU,CAAC,OAAO,KAAK,UAAU,KAAK,EAAE;AAAA,EAC/F,EAAE,OAAO,iBAA4B,MAAM,YAAY,UAAU,CAAC,SAAS,KAAK,UAAU,KAAK,EAAE;AAAA,EACjG,EAAE,OAAO,aAAa,MAAM,wBAAwB,UAAU,CAAC,SAAS,QAAQ,YAAY,UAAU,EAAE;AAAA,EACxG,EAAE,OAAO,aAAa,MAAM,SAAS,UAAU,CAAC,SAAS,QAAQ,QAAQ,QAAQ,SAAS,EAAE;AAAA,EAC5F,EAAE,OAAO,gBAAoB,MAAM,cAAc,UAAU,CAAC,SAAS,QAAQ,QAAQ,OAAO,EAAE;AAAA,EAC9F,EAAE,OAAO,gBAAoB,MAAM,cAAc,UAAU,CAAC,SAAS,QAAQ,QAAQ,SAAS,MAAM,EAAE;AAAA,EACtG,EAAE,OAAO,gBAAoB,MAAM,gBAAgB,UAAU,CAAC,WAAW,QAAQ,QAAQ,OAAO,EAAE;AAAA,EAClG,EAAE,OAAO,gBAAoB,MAAM,aAAa,UAAU,CAAC,QAAQ,QAAQ,QAAQ,OAAO,EAAE;AAAA,EAC5F,EAAE,OAAO,aAAa,MAAM,yBAAyB,UAAU,CAAC,WAAW,UAAU,OAAO,OAAO,EAAE;AAAA,EACrG,EAAE,OAAO,aAAa,MAAM,iBAAiB,UAAU,CAAC,UAAU,QAAQ,SAAS,OAAO,EAAE;AAAA,EAC5F,EAAE,OAAO,gBAAoB,MAAM,eAAe,UAAU,CAAC,QAAQ,SAAS,SAAS,SAAS,IAAI,EAAE;AAAA,EACtG,EAAE,OAAO,gBAAoB,MAAM,gBAAgB,UAAU,CAAC,SAAS,QAAQ,QAAQ,MAAM,EAAE;AAAA,EAC/F,EAAE,OAAO,gBAAoB,MAAM,eAAe,UAAU,CAAC,QAAQ,OAAO,QAAQ,QAAQ,EAAE;AAAA,EAC9F,EAAE,OAAO,gBAAoB,MAAM,qBAAqB,UAAU,CAAC,QAAQ,QAAQ,WAAW,OAAO,EAAE;AAAA,EACvG,EAAE,OAAO,gBAAoB,MAAM,yBAAyB,UAAU,CAAC,YAAY,QAAQ,UAAU,OAAO,EAAE;AAAA,EAC9G,EAAE,OAAO,gBAAoB,MAAM,iBAAiB,UAAU,CAAC,UAAU,OAAO,UAAU,WAAW,EAAE;AAAA,EACvG,EAAE,OAAO,aAAa,MAAM,cAAc,UAAU,CAAC,cAAc,OAAO,OAAO,MAAM,EAAE;AAAA,EACzF,EAAE,OAAO,aAAa,MAAM,iBAAiB,UAAU,CAAC,cAAc,UAAU,QAAQ,OAAO,EAAE;AAAA,EACjG,EAAE,OAAO,mBAAqB,MAAM,uBAAuB,UAAU,CAAC,KAAK,SAAS,QAAQ,QAAQ,EAAE;AAAA,EACtG,EAAE,OAAO,mBAAqB,MAAM,uBAAuB,UAAU,CAAC,KAAK,SAAS,QAAQ,QAAQ,EAAE;AAAA,EACtG,EAAE,OAAO,mBAAqB,MAAM,uBAAuB,UAAU,CAAC,KAAK,SAAS,QAAQ,QAAQ,EAAE;AAAA,EAEtG,EAAE,OAAO,sBAAsB,MAAM,sBAAsB,UAAU,CAAC,QAAQ,MAAM,OAAO,WAAW,eAAe,EAAE;AAAA,EACvH,EAAE,OAAO,sBAAsB,MAAM,uBAAuB,UAAU,CAAC,QAAQ,MAAM,WAAW,WAAW,gBAAgB,EAAE;AAAA,EAC7H,EAAE,OAAO,sBAAsB,MAAM,eAAe,UAAU,CAAC,QAAQ,UAAU,UAAU,OAAO,EAAE;AAAA,EACpG,EAAE,OAAO,sBAAsB,MAAM,gBAAgB,UAAU,CAAC,QAAQ,WAAW,UAAU,QAAQ,EAAE;AAAA,EACvG,EAAE,OAAO,sBAAsB,MAAM,cAAc,UAAU,CAAC,QAAQ,SAAS,WAAW,MAAM,EAAE;AAAA,EAClG,EAAE,OAAO,sBAAsB,MAAM,cAAc,UAAU,CAAC,QAAQ,SAAS,WAAW,QAAQ,EAAE;AAAA,EACpG,EAAE,OAAO,sBAAsB,MAAM,iBAAiB,UAAU,CAAC,QAAQ,YAAY,cAAc,QAAQ,EAAE;AAAA,EAC7G,EAAE,OAAO,sBAAsB,MAAM,cAAc,UAAU,CAAC,QAAQ,SAAS,YAAY,OAAO,EAAE;AAAA,EACpG,EAAE,OAAO,sBAAsB,MAAM,oBAAoB,UAAU,CAAC,QAAQ,SAAS,eAAe,UAAU,OAAO,EAAE;AAAA,EACvH,EAAE,OAAO,sBAAsB,MAAM,cAAc,UAAU,CAAC,QAAQ,SAAS,WAAW,SAAS,EAAE;AAAA,EACrG,EAAE,OAAO,sBAAsB,MAAM,cAAc,UAAU,CAAC,QAAQ,SAAS,UAAU,OAAO,EAAE;AAAA,EAClG,EAAE,OAAO,sBAAsB,MAAM,eAAe,UAAU,CAAC,QAAQ,UAAU,WAAW,EAAE;AAAA,EAC9F,EAAE,OAAO,sBAAsB,MAAM,eAAe,UAAU,CAAC,QAAQ,UAAU,YAAY,OAAO,EAAE;AAAA,EACtG,EAAE,OAAO,sBAAsB,MAAM,kBAAkB,UAAU,CAAC,QAAQ,aAAa,YAAY,EAAE;AAAA,EACrG,EAAE,OAAO,sBAAsB,MAAM,eAAe,UAAU,CAAC,QAAQ,UAAU,WAAW,QAAQ,EAAE;AAAA,EACtG,EAAE,OAAO,sBAAsB,MAAM,eAAe,UAAU,CAAC,QAAQ,UAAU,SAAS,EAAE;AAAA,EAC5F,EAAE,OAAO,sBAAsB,MAAM,kBAAkB,UAAU,CAAC,QAAQ,aAAa,WAAW,EAAE;AAAA,EACpG,EAAE,OAAO,sBAAsB,MAAM,gBAAgB,UAAU,CAAC,QAAQ,WAAW,UAAU,EAAE;AAAA,EAC/F,EAAE,OAAO,sBAAsB,MAAM,qBAAqB,UAAU,CAAC,QAAQ,gBAAgB,OAAO,EAAE;AAAA,EACtG,EAAE,OAAO,sBAAsB,MAAM,eAAe,UAAU,CAAC,QAAQ,UAAU,SAAS,EAAE;AAAA,EAC5F,EAAE,OAAO,sBAAsB,MAAM,eAAe,UAAU,CAAC,QAAQ,UAAU,WAAW,WAAW,EAAE;AAAA,EACzG,EAAE,OAAO,aAAa,MAAM,kBAAkB,UAAU,CAAC,QAAQ,aAAa,QAAQ,UAAU,QAAQ,EAAE;AAAA,EAC1G,EAAE,OAAO,aAAa,MAAM,mBAAmB,UAAU,CAAC,QAAQ,YAAY,OAAO,MAAM,EAAE;AAAA,EAC7F,EAAE,OAAO,mBAAqB,MAAM,cAAc,UAAU,CAAC,QAAQ,SAAS,aAAa,OAAO,EAAE;AAAA,EACpG,EAAE,OAAO,aAAa,MAAM,cAAc,UAAU,CAAC,QAAQ,SAAS,QAAQ,EAAE;AAAA,EAChF,EAAE,OAAO,kCAAsC,MAAM,gBAAgB,UAAU,CAAC,QAAQ,WAAW,SAAS,SAAS,KAAK,EAAE;AAC9H;;;ADnac,gBAAAC,OA8BV,QAAAC,cA9BU;AAxVP,SAAS,kBAAkB;AAAA,EAChC;AAAA,EACA,aAAa;AAAA,EACb;AAAA,EACA;AACF,IAA4B,CAAC,GAAG;AAC9B,QAAM,CAAC,MAAM,IAAIC,4BAA0B;AAC3C,QAAM,CAAC,QAAQ,SAAS,IAAIC,UAAS,KAAK;AAC1C,QAAM,CAAC,OAAO,QAAQ,IAAIA,UAAS,EAAE;AACrC,QAAM,CAAC,SAAS,UAAU,IAAIA,UAAsB,CAAC,CAAC;AACtD,QAAM,CAAC,eAAe,gBAAgB,IAAIA,UAAS,CAAC;AACpD,QAAM,CAAC,UAAU,WAAW,IAAIA,UAAS,EAAE,KAAK,GAAG,MAAM,EAAE,CAAC;AAC5D,QAAM,CAAC,iBAAiB,kBAAkB,IAAIA;AAAA,IAC5C;AAAA,EACF;AACA,QAAM,mBAAmBC,SAAe,CAAC;AACzC,QAAM,sBAAsBA,SAAO,KAAK;AACxC,QAAM,YAAY,UAAU;AAE5B,EAAAC,YAAU,MAAM;AACd,QAAI,OAAO,WAAW,YAAa;AACnC,uBAAmB,SAAS,IAAI;AAAA,EAClC,GAAG,CAAC,CAAC;AAEL,QAAM,QAAQC,cAAY,MAAM;AAC9B,cAAU,KAAK;AACf,aAAS,EAAE;AACX,eAAW,CAAC,CAAC;AACb,qBAAiB,CAAC;AAClB,wBAAoB,UAAU;AAAA,EAChC,GAAG,CAAC,CAAC;AAEL,QAAM,eAAeA;AAAA,IACnB,CAAC,MAA2B;AAC1B,UAAI,CAAC,EAAG,QAAO,CAAC;AAChB,YAAM,QAAQ,EAAE,YAAY;AAC5B,aAAO,UACJ;AAAA,QACC,CAAC,MACC,EAAE,KAAK,SAAS,KAAK,KACrB,EAAE,SAAS,KAAK,CAAC,MAAM,EAAE,SAAS,KAAK,CAAC;AAAA,MAC5C,EACC,MAAM,GAAG,UAAU;AAAA,IACxB;AAAA,IACA,CAAC,WAAW,UAAU;AAAA,EACxB;AAGA,EAAAD,YAAU,MAAM;AACd,WAAO,OAAO;AAAA,MACZ;AAAA,MACA,MAAM;AACJ,cAAM,eAAe,OAAO,aAAa;AACzC,YAAI,gBAAgB,aAAa,aAAa,GAAG;AAC/C,gBAAM,QAAQ,aAAa,WAAW,CAAC;AACvC,gBAAM,OAAO,MAAM,sBAAsB;AACzC,sBAAY,EAAE,KAAK,KAAK,SAAS,GAAG,MAAM,KAAK,KAAK,CAAC;AAAA,QACvD;AAEA,4BAAoB,UAAU;AAC9B,iBAAS,EAAE;AACX,mBAAW,UAAU,MAAM,GAAG,UAAU,CAAC;AACzC,yBAAiB,CAAC;AAClB,kBAAU,IAAI;AACd,eAAO;AAAA,MACT;AAAA,MACAE;AAAA,IACF;AAAA,EACF,GAAG,CAAC,QAAQ,WAAW,UAAU,CAAC;AAGlC,EAAAF,YAAU,MAAM;AACd,QAAI,aAAa;AAEjB,UAAM,aAAa,OAAO,uBAAuB,CAAC,EAAE,YAAY,MAAM;AAEpE,UAAI,eAAe,EAAG,sBAAqB,UAAU;AACrD,mBAAa,sBAAsB,MAAM;AACvC,qBAAa;AAGf,YAAI,oBAAoB,SAAS;AAC/B,sBAAY,KAAK,MAAM;AACrB,kBAAM,YAAYG,eAAc;AAChC,gBAAI,CAACC,mBAAkB,SAAS,KAAK,CAAC,UAAU,YAAY,GAAG;AAC7D,kBAAI,OAAQ,OAAM;AAClB;AAAA,YACF;AAEA,kBAAM,SAAS,UAAU;AACzB,kBAAM,OAAO,OAAO,QAAQ;AAG5B,kBAAM,YAAYC,aAAY,IAAI,IAC9B,KAAK,eAAe,EAAE,MAAM,GAAG,OAAO,MAAM,IAC5C;AAEJ,gBAAI,UAAU,WAAW,GAAG;AAE1B,yBAAW,UAAU,MAAM,GAAG,UAAU,CAAC;AACzC,+BAAiB,CAAC;AAClB;AAAA,YACF;AAGA,kBAAM,WAAW,aAAa,SAAS;AACvC,qBAAS,SAAS;AAClB,uBAAW,QAAQ;AACnB,6BAAiB,CAAC;AAAA,UACpB,CAAC;AACD;AAAA,QACF;AAEA,oBAAY,KAAK,MAAM;AACrB,gBAAM,YAAYF,eAAc;AAChC,cAAI,CAACC,mBAAkB,SAAS,KAAK,CAAC,UAAU,YAAY,GAAG;AAC7D,gBAAI,OAAQ,OAAM;AAClB;AAAA,UACF;AAEA,gBAAM,SAAS,UAAU;AACzB,gBAAM,OAAO,OAAO,QAAQ;AAC5B,cAAI,CAACC,aAAY,IAAI,GAAG;AACtB,gBAAI,OAAQ,OAAM;AAClB;AAAA,UACF;AAEA,gBAAM,OAAO,KAAK,eAAe;AACjC,gBAAM,SAAS,OAAO;AAGtB,cAAI,CAAC,UAAU,CAAC,KAAK,SAAS,GAAG,GAAG;AAClC;AAAA,UACF;AAGA,cAAI,aAAa;AAEjB,mBAAS,IAAI,SAAS,GAAG,KAAK,GAAG,KAAK;AACpC,kBAAM,OAAO,KAAK,CAAC;AACnB,gBAAI,SAAS,OAAW;AAExB,gBAAI,SAAS,KAAK;AAChB,kBAAI,MAAM,KAAK,KAAK,IAAI,CAAC,MAAM,OAAO,KAAK,IAAI,CAAC,MAAM,MAAM;AAC1D,6BAAa;AAAA,cACf;AACA;AAAA,YACF;AAEA,gBAAI,SAAS,OAAO,SAAS,MAAM;AACjC;AAAA,YACF;AAAA,UACF;AAEA,cAAI,eAAe,IAAI;AACrB,gBAAI,OAAQ,OAAM;AAClB;AAAA,UACF;AAEA,gBAAM,YAAY,KAAK,MAAM,aAAa,GAAG,MAAM;AAEnD,cAAI,UAAU,SAAS,GAAG;AACxB,gBAAI,OAAQ,OAAM;AAClB;AAAA,UACF;AAEA,gBAAM,WAAW,aAAa,SAAS;AACvC,cAAI,SAAS,WAAW,GAAG;AACzB,gBAAI,OAAQ,OAAM;AAClB;AAAA,UACF;AAGA,gBAAM,eAAe,OAAO,aAAa;AACzC,cAAI,gBAAgB,aAAa,aAAa,GAAG;AAC/C,kBAAM,QAAQ,aAAa,WAAW,CAAC;AACvC,kBAAM,OAAO,MAAM,sBAAsB;AACzC,wBAAY;AAAA,cACV,KAAK,KAAK,SAAS;AAAA,cACnB,MAAM,KAAK;AAAA,YACb,CAAC;AAAA,UACH;AAEA,2BAAiB,UAAU;AAC3B,mBAAS,SAAS;AAClB,qBAAW,QAAQ;AACnB,2BAAiB,CAAC;AAClB,oBAAU,IAAI;AAAA,QAChB,CAAC;AAAA,MAED,CAAC;AAAA,IACH,CAAC;AAED,WAAO,MAAM;AACX,iBAAW;AACX,UAAI,eAAe,EAAG,sBAAqB,UAAU;AAAA,IACvD;AAAA,EACF,GAAG,CAAC,QAAQ,QAAQ,OAAO,YAAY,CAAC;AAGxC,QAAM,aAAaJ;AAAA,IACjB,CAAC,SAAoB;AACnB,UAAI,oBAAoB,SAAS;AAE/B,eAAO,MAAM,MAAM;AACjB,iBAAO,OAAO,MAAM;AAClB,kBAAM,YAAYE,eAAc;AAChC,gBAAI,CAACC,mBAAkB,SAAS,EAAG;AAEnC,kBAAM,SAAS,UAAU;AACzB,kBAAM,OAAO,OAAO,QAAQ;AAG5B,gBAAIC,aAAY,IAAI,GAAG;AACrB,oBAAM,OAAO,KAAK,eAAe;AACjC,oBAAM,SAAS,OAAO;AACtB,oBAAM,QAAQ,KAAK,MAAM,MAAM;AAC/B,mBAAK,eAAe,KAAK,QAAQ,KAAK;AACtC,mBAAK,OAAO,KAAK,MAAM,QAAQ,KAAK,MAAM,MAAM;AAAA,YAClD,OAAO;AACL,wBAAU,cAAc,KAAK,KAAK;AAAA,YACpC;AAAA,UACF,CAAC;AAAA,QACH,CAAC;AAAA,MACH,OAAO;AAEL,eAAO,OAAO,MAAM;AAClB,gBAAM,YAAYF,eAAc;AAChC,cAAI,CAACC,mBAAkB,SAAS,EAAG;AAEnC,gBAAM,SAAS,UAAU;AACzB,gBAAM,OAAO,OAAO,QAAQ;AAC5B,cAAI,CAACC,aAAY,IAAI,EAAG;AAExB,gBAAM,OAAO,KAAK,eAAe;AACjC,gBAAM,SAAS,OAAO;AACtB,gBAAM,eAAe,iBAAiB;AAEtC,gBAAM,SAAS,KAAK,MAAM,GAAG,YAAY;AACzC,gBAAM,QAAQ,KAAK,MAAM,MAAM;AAE/B,eAAK,eAAe,SAAS,KAAK,QAAQ,KAAK;AAE/C,gBAAM,YAAY,OAAO,SAAS,KAAK,MAAM;AAC7C,eAAK,OAAO,WAAW,SAAS;AAAA,QAClC,CAAC;AAAA,MACH;AAEA,YAAM;AAAA,IACR;AAAA,IACA,CAAC,QAAQ,KAAK;AAAA,EAChB;AAEA,EAAAL,YAAU,MAAM;AACd,QAAI,CAAC,OAAQ;AAEb,UAAM,iBAAiB,OAAO;AAAA,MAC5BM;AAAA,MACA,CAAC,UAAU;AACT,YAAI,CAAC,UAAU,QAAQ,WAAW,EAAG,QAAO;AAC5C,eAAO,eAAe;AACtB,yBAAiB,CAAC,UAAU,OAAO,KAAK,QAAQ,MAAM;AACtD,eAAO;AAAA,MACT;AAAA,MACAC;AAAA,IACF;AAEA,UAAM,eAAe,OAAO;AAAA,MAC1BC;AAAA,MACA,CAAC,UAAU;AACT,YAAI,CAAC,UAAU,QAAQ,WAAW,EAAG,QAAO;AAC5C,eAAO,eAAe;AACtB;AAAA,UACE,CAAC,UAAU,OAAO,IAAI,QAAQ,UAAU,QAAQ;AAAA,QAClD;AACA,eAAO;AAAA,MACT;AAAA,MACAD;AAAA,IACF;AAEA,UAAM,kBAAkB,OAAO;AAAA,MAC7BE;AAAA,MACA,CAAC,UAAU;AACT,YAAI,CAAC,UAAU,QAAQ,WAAW,EAAG,QAAO;AAC5C,eAAO,eAAe;AACtB,cAAM,OAAO,QAAQ,aAAa;AAClC,YAAI,KAAM,YAAW,IAAI;AACzB,eAAO;AAAA,MACT;AAAA,MACAF;AAAA,IACF;AAEA,UAAM,gBAAgB,OAAO;AAAA,MAC3BG;AAAA,MACA,CAAC,UAAU;AACT,YAAI,CAAC,UAAU,QAAQ,WAAW,EAAG,QAAO;AAC5C,eAAO,eAAe;AACtB,cAAM,OAAO,QAAQ,aAAa;AAClC,YAAI,KAAM,YAAW,IAAI;AACzB,eAAO;AAAA,MACT;AAAA,MACAH;AAAA,IACF;AAEA,UAAM,mBAAmB,OAAO;AAAA,MAC9BI;AAAA,MACA,CAAC,UAAU;AACT,YAAI,CAAC,OAAQ,QAAO;AACpB,eAAO,eAAe;AACtB,cAAM;AACN,eAAO;AAAA,MACT;AAAA,MACAJ;AAAA,IACF;AAEA,WAAO,MAAM;AACX,qBAAe;AACf,mBAAa;AACb,sBAAgB;AAChB,oBAAc;AACd,uBAAiB;AAAA,IACnB;AAAA,EACF,GAAG,CAAC,QAAQ,QAAQ,SAAS,eAAe,YAAY,KAAK,CAAC;AAE9D,MAAI,CAAC,mBAAmB,CAAC,OAAQ,QAAO;AACxC,MAAI,QAAQ,WAAW,KAAK,CAAC,oBAAoB,QAAS,QAAO;AAGjE,MAAI,gBAAgB;AAClB,WAAOK;AAAA,MACL,eAAe;AAAA,QACb;AAAA,QACA,UAAU,QAAQ,IAAI,CAAC,MAAM,UAC3B,gBAAAjB;AAAA,UAAC;AAAA;AAAA,YAEC,aAAa,CAAC,MAAM;AAClB,gBAAE,eAAe;AACjB,yBAAW,IAAI;AAAA,YACjB;AAAA,YACA,cAAc,MAAM,iBAAiB,KAAK;AAAA,YAEzC,uBACC,WAAW,MAAM,UAAU,aAAa,IAExC,gBAAAA,MAAC,mBAAgB,MAAY,YAAY,UAAU,eAAe;AAAA;AAAA,UAV/D,KAAK;AAAA,QAYZ,CACD;AAAA,MACH,CAAC;AAAA,MACD;AAAA,IACF;AAAA,EACF;AAEA,SAAOiB;AAAA,IACL,gBAAAjB;AAAA,MAAC;AAAA;AAAA,QACC,OAAO;AAAA,QACP;AAAA,QACA;AAAA,QACA,UAAU;AAAA,QACV,SAAS;AAAA,QACT;AAAA;AAAA,IACF;AAAA,IACA;AAAA,EACF;AACF;AAEA,SAAS,gBAAgB;AAAA,EACvB;AAAA,EACA;AACF,GAGG;AACD,SACE,gBAAAC;AAAA,IAAC;AAAA;AAAA,MACC,OAAO;AAAA,QACL,SAAS;AAAA,QACT,YAAY;AAAA,QACZ,KAAK;AAAA,QACL,SAAS;AAAA,QACT,cAAc;AAAA,QACd,QAAQ;AAAA,QACR,iBAAiB,aACb,6BACA;AAAA,QACJ,YAAY;AAAA,MACd;AAAA,MAEA;AAAA,wBAAAD,MAAC,UAAK,OAAO,EAAE,UAAU,QAAQ,YAAY,EAAE,GAAI,eAAK,OAAM;AAAA,QAC9D,gBAAAA;AAAA,UAAC;AAAA;AAAA,YACC,OAAO;AAAA,cACL,UAAU;AAAA,cACV,OAAO;AAAA,cACP,YAAY,aAAa,MAAM;AAAA,YACjC;AAAA,YAEC,eAAK,KAAK,QAAQ,MAAM,GAAG;AAAA;AAAA,QAC9B;AAAA;AAAA;AAAA,EACF;AAEJ;AAEA,SAAS,cAAc;AAAA,EACrB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAOG;AACD,QAAM,UAAUI,SAAuB,IAAI;AAE3C,EAAAC,YAAU,MAAM;AACd,UAAM,OAAO,QAAQ;AACrB,QAAI,CAAC,KAAM;AACX,UAAM,WAAW,KAAK,SAAS,aAAa;AAC5C,QAAI,UAAU;AACZ,eAAS,eAAe,EAAE,OAAO,UAAU,CAAC;AAAA,IAC9C;AAAA,EACF,GAAG,CAAC,aAAa,CAAC;AAElB,SACE,gBAAAJ;AAAA,IAAC;AAAA;AAAA,MACC,KAAK;AAAA,MACL,eAAY;AAAA,MACZ,OAAO;AAAA,QACL,UAAU;AAAA,QACV,KAAK,GAAG,SAAS,GAAG;AAAA,QACpB,MAAM,GAAG,SAAS,IAAI;AAAA,QACtB,QAAQ;AAAA,QACR,UAAU;AAAA,QACV,UAAU;AAAA,QACV,WAAW;AAAA,QACX,WAAW;AAAA,QACX,cAAc;AAAA,QACd,QAAQ;AAAA,QACR,iBAAiB;AAAA,QACjB,gBAAgB;AAAA,QAChB,sBAAsB;AAAA,QACtB,WAAW;AAAA,QACX,YAAY;AAAA,QACZ,WAAW;AAAA,QACX,SAAS;AAAA,MACX;AAAA,MAEC;AAAA,cAAM,WAAW,IAChB,gBAAAD;AAAA,UAAC;AAAA;AAAA,YACC,OAAO;AAAA,cACL,SAAS;AAAA,cACT,UAAU;AAAA,cACV,OAAO;AAAA,cACP,WAAW;AAAA,YACb;AAAA,YACD;AAAA;AAAA,QAED,IAEA,MAAM,IAAI,CAAC,MAAM,UACf,gBAAAA;AAAA,UAAC;AAAA;AAAA,YAEC,eAAa,cAAc,KAAK,IAAI;AAAA,YACpC,MAAK;AAAA,YACL,iBAAe,UAAU;AAAA,YACzB,aAAa,CAAC,MAAM;AAClB,gBAAE,eAAe;AACjB,uBAAS,IAAI;AAAA,YACf;AAAA,YACA,cAAc,MAAM,QAAQ,KAAK;AAAA,YAEhC,uBACC,WAAW,MAAM,UAAU,aAAa,IAExC,gBAAAA,MAAC,mBAAgB,MAAY,YAAY,UAAU,eAAe;AAAA;AAAA,UAb/D,KAAK;AAAA,QAeZ,CACD;AAAA,QAGH,gBAAAA;AAAA,UAAC;AAAA;AAAA,YACC,yBAAyB;AAAA,cACvB,QAAQ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,YAYV;AAAA;AAAA,QACF;AAAA;AAAA;AAAA,EACF;AAEJ;;;AE7hBA,SAAS,eAAAkB,eAAa,aAAAC,aAAW,UAAAC,UAAQ,YAAAC,iBAAgB;AAEzD,SAAS,gBAAAC,qBAAoB;AAE7B,SAAS,6BAAAC,mCAAiC;AAC1C;AAAA,EACE,iBAAAC;AAAA,EACA,qBAAAC;AAAA,EACA,wBAAAC;AAAA,EACA,4BAAAC;AAAA,OACK;AAIP;AAAA,EACE,eAAAC;AAAA,EACA;AAAA,EACA;AAAA,OAEK;AAEP;AAAA,EACE,YAAAC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AA4VP,SAAS,cAAAC,mBAAkB;AAxCjB,SAiCN,YAAAC,WAjCM,OAAAC,OAiCN,QAAAC,cAjCM;AArRH,SAAS,WAAW,EAAE,SAAS,CAAC,EAAE,IAAmC,CAAC,GAAG;AAC9E,QAAM,CAAC,MAAM,IAAIC,4BAA0B;AAC3C,QAAM,CAAC,iBAAiB,kBAAkB,IAAIC;AAAA,IAC5C;AAAA,EACF;AACA,QAAM,CAAC,WAAW,YAAY,IAAIA,UAAS,KAAK;AAChD,QAAM,CAAC,aAAa,cAAc,IAAIA,UAAS,KAAK;AACpD,QAAM,CAAC,eAAe,gBAAgB,IAAIA,UAAS,EAAE,KAAK,GAAG,MAAM,EAAE,CAAC;AACtE,QAAM,CAAC,iBAAiB,kBAAkB,IAAIA,UAAS,EAAE,KAAK,GAAG,MAAM,EAAE,CAAC;AAC1E,QAAM,CAAC,YAAY,aAAa,IAAIA,UAAS,EAAE;AAC/C,QAAM,CAAC,YAAY,aAAa,IAAIA,UAAS,EAAE;AAC/C,QAAM,WAAWC,SAAyB,IAAI;AAE9C,QAAM,SAAS,OAAO,UAAU;AAChC,QAAM,MAAM,OAAO,OAAO;AAE1B,QAAM,cACJ,OAAO,gBACN,CAAC,QAAgB;AAChB,QAAI;AAEF,YAAM,eAAe,IAAI,MAAM,cAAc,IAAI,MAAM,WAAW,GAAG;AACrE,UAAI,IAAI,YAAY;AACpB,aAAO;AAAA,IACT,QAAQ;AACN,aAAO;AAAA,IACT;AAAA,EACF;AAEF,EAAAC,YAAU,MAAM;AACd,QAAI,OAAO,WAAW,YAAa;AACnC,uBAAmB,SAAS,IAAI;AAAA,EAClC,GAAG,CAAC,CAAC;AAGL,EAAAA,YAAU,MAAM;AACd,WAAO,OAAO;AAAA,MACZ;AAAA,MACA,CAAC,YAAY;AACX,YAAI,YAAY,MAAM;AACpB,sBAAY,IAAI;AAAA,QAClB,WAAW,OAAO,YAAY,UAAU;AACtC,sBAAY,SAAS,EAAE,QAAQ,IAAI,CAAC;AAAA,QACtC,OAAO;AACL,sBAAY,QAAQ,KAAK;AAAA,YACvB,QAAQ,QAAQ,UAAU;AAAA,YAC1B,KAAK,QAAQ,OAAO;AAAA,YACpB,OAAO,QAAQ,SAAS;AAAA,UAC1B,CAAC;AAAA,QACH;AACA,eAAO;AAAA,MACT;AAAA,MACAC;AAAA,IACF;AAAA,EACF,GAAG,CAAC,QAAQ,QAAQ,GAAG,CAAC;AAExB,QAAM,uBAAuBC,cAAY,MAAM;AAC7C,UAAM,eAAe,OAAO,aAAa;AACzC,QAAI,gBAAgB,aAAa,aAAa,GAAG;AAC/C,YAAM,QAAQ,aAAa,WAAW,CAAC;AACvC,YAAM,OAAO,MAAM,sBAAsB;AACzC,aAAO;AAAA,QACL,KAAK,KAAK,SAAS;AAAA,QACnB,MAAM,KAAK,OAAO,KAAK,QAAQ;AAAA,MACjC;AAAA,IACF;AACA,WAAO,EAAE,KAAK,GAAG,MAAM,EAAE;AAAA,EAC3B,GAAG,CAAC,CAAC;AAEL,QAAM,eAAeA,cAAY,MAAuB;AACtD,QAAI,WAA4B;AAChC,WAAO,KAAK,MAAM;AAChB,YAAM,YAAYC,gBAAc;AAChC,UAAI,CAACC,mBAAkB,SAAS,EAAG;AACnC,YAAM,OAAO,UAAU,OAAO,QAAQ;AACtC,YAAM,SAAS,KAAK,UAAU;AAC9B,UAAIb,aAAY,MAAM,GAAG;AACvB,mBAAW;AAAA,MACb,WAAWA,aAAY,IAAI,GAAG;AAC5B,mBAAW;AAAA,MACb;AAAA,IACF,CAAC;AACD,WAAO;AAAA,EACT,GAAG,CAAC,MAAM,CAAC;AAEX,QAAM,YAAYW;AAAA,IAChB,CAAC,aAAa,OAAO;AACnB,oBAAc,UAAU;AACxB,uBAAiB,qBAAqB,CAAC;AACvC,qBAAe,KAAK;AACpB,mBAAa,IAAI;AAGjB,UAAI,CAAC,OAAO,iBAAiB;AAC3B,8BAAsB,MAAM;AAC1B,mBAAS,SAAS,MAAM;AACxB,mBAAS,SAAS,OAAO;AAAA,QAC3B,CAAC;AAAA,MACH;AAAA,IACF;AAAA,IACA,CAAC,sBAAsB,OAAO,eAAe;AAAA,EAC/C;AAEA,QAAM,WAAWA,cAAY,MAAM;AACjC,iBAAa,KAAK;AAClB,mBAAe,KAAK;AACpB,kBAAc,EAAE;AAChB,kBAAc,EAAE;AAChB,WAAO,MAAM;AAAA,EACf,GAAG,CAAC,MAAM,CAAC;AAEX,QAAM,aAAaA;AAAA,IACjB,CAAC,QAAgB;AACf,YAAM,UAAU,IAAI,KAAK;AACzB,UAAI,CAAC,SAAS;AACZ,iBAAS;AACT;AAAA,MACF;AAGA,YAAM,WAAW,QAAQ,MAAM,cAAc,IACzC,UACA,WAAW,OAAO;AAEtB,UAAI,CAAC,YAAY,QAAQ,GAAG;AAC1B,iBAAS;AACT;AAAA,MACF;AAEA,aAAO,gBAAgB,qBAAqB;AAAA,QAC1C,KAAK;AAAA,QACL;AAAA,QACA;AAAA,MACF,CAAC;AACD,eAAS;AAAA,IACX;AAAA,IACA,CAAC,QAAQ,aAAa,QAAQ,KAAK,QAAQ;AAAA,EAC7C;AAEA,QAAM,aAAaA,cAAY,MAAM;AACnC,WAAO,gBAAgB,qBAAqB,IAAI;AAChD,aAAS;AAAA,EACX,GAAG,CAAC,QAAQ,QAAQ,CAAC;AAErB,QAAM,mBAAmBA,cAAY,MAAM;AACzC,UAAM,WAAW,aAAa;AAC9B,QAAI,UAAU;AACZ,gBAAU,SAAS,OAAO,CAAC;AAAA,IAC7B,OAAO;AACL,UAAI,eAAe;AACnB,aAAO,KAAK,MAAM;AAChB,cAAM,YAAYC,gBAAc;AAChC,YACEC,mBAAkB,SAAS,KAC3B,CAAC,UAAU,YAAY,GACvB;AACA,yBAAe;AAAA,QACjB;AAAA,MACF,CAAC;AAED,UAAI,cAAc;AAChB,kBAAU;AAAA,MACZ;AAAA,IACF;AAAA,EACF,GAAG,CAAC,QAAQ,cAAc,SAAS,CAAC;AAGpC,EAAAJ,YAAU,MAAM;AACd,UAAM,cAAc,OAAO,eAAe;AAC1C,QAAI,CAAC,YAAa;AAElB,UAAM,iBAAiB,CAAC,UAAsB;AAC5C,YAAMK,UAAS,MAAM;AACrB,YAAM,SAASA,QAAO,QAAQ,GAAG;AACjC,UAAI,CAAC,UAAU,CAAC,YAAY,SAAS,MAAM,EAAG;AAE9C,YAAM,OAAO,OAAO,aAAa,MAAM;AACvC,UAAI,MAAM;AACR,cAAM,eAAe;AACrB,eAAO,KAAK,MAAM,UAAU,qBAAqB;AAAA,MACnD;AAAA,IACF;AAEA,gBAAY,iBAAiB,YAAY,cAAc;AACvD,WAAO,MAAM,YAAY,oBAAoB,YAAY,cAAc;AAAA,EACzE,GAAG,CAAC,MAAM,CAAC;AAGX,EAAAL,YAAU,MAAM;AACd,UAAM,gBAAgB,CAAC,UAAyB;AAC9C,WAAK,MAAM,WAAW,MAAM,YAAY,MAAM,QAAQ,KAAK;AAEzD,cAAMM,eAAc,OAAO,eAAe;AAC1C,YAAI,CAACA,aAAa;AAClB,cAAM,gBAAgB,SAAS;AAC/B,YAAI,CAACA,aAAY,SAAS,aAAa,KAAK,kBAAkBA,aAAa;AAE3E,cAAM,eAAe;AACrB,cAAM,gBAAgB;AACtB,yBAAiB;AAAA,MACnB;AAAA,IACF;AAEA,aAAS,iBAAiB,WAAW,aAAa;AAGlD,UAAM,cAAc,OAAO,eAAe;AAC1C,QAAI,aAAa;AACf,kBAAY,aAAa,0BAA0B,MAAM;AAAA,IAC3D;AAEA,WAAO,MAAM;AACX,eAAS,oBAAoB,WAAW,aAAa;AACrD,YAAM,KAAK,OAAO,eAAe;AACjC,UAAI,IAAI;AACN,WAAG,gBAAgB,wBAAwB;AAAA,MAC7C;AAAA,IACF;AAAA,EACF,GAAG,CAAC,QAAQ,gBAAgB,CAAC;AAG7B,EAAAN,YAAU,MAAM;AACd,WAAO,OAAO;AAAA,MACZ;AAAA,MACA,MAAM;AACJ,yBAAiB;AACjB,eAAO;AAAA,MACT;AAAA,MACAC;AAAA,IACF;AAAA,EACF,GAAG,CAAC,QAAQ,gBAAgB,CAAC;AAE7B,QAAM,gBAAgBF,SAAO,CAAC;AAC9B,EAAAC,YAAU,MAAM;AACd,WAAO,OAAO;AAAA,MACZO;AAAA,MACA,MAAM;AACJ,YAAI,cAAc,YAAY,GAAG;AAC/B,wBAAc,UAAU,sBAAsB,MAAM;AAClD,0BAAc,UAAU;AAExB,gBAAI,UAAW;AAEf,kBAAM,WAAW,aAAa;AAC9B,gBAAI,UAAU;AACZ,4BAAc,SAAS,OAAO,CAAC;AAC/B,iCAAmB,qBAAqB,CAAC;AACzC,6BAAe,IAAI;AAAA,YACrB,OAAO;AACL,kBAAI,aAAa;AACf,+BAAe,KAAK;AACpB,8BAAc,EAAE;AAAA,cAClB;AAAA,YACF;AAAA,UACF,CAAC;AAAA,QACH;AACA,eAAO;AAAA,MACT;AAAA,MACAN;AAAA,IACF;AAAA,EACF,GAAG,CAAC,QAAQ,cAAc,sBAAsB,WAAW,WAAW,CAAC;AAEvE,MAAI,CAAC,gBAAiB,QAAO;AAE7B,QAAM,mBAAyC;AAAA,IAC7C,YAAY;AAAA,IACZ,UAAU;AAAA,IACV,UAAU;AAAA,IACV,SAAS;AAAA,IACT,UAAU;AAAA,EACZ;AAEA,QAAM,eAAe,YACjBO;AAAA,IACE,OAAO,kBACL,OAAO,gBAAgB,gBAAgB,IAEvC,gBAAAb;AAAA,MAAC;AAAA;AAAA,QACC,KAAK;AAAA,QACJ,GAAG;AAAA;AAAA,IACN;AAAA,IAEF;AAAA,EACF,IACA;AAEJ,QAAM,qBAA6C;AAAA,IACjD,KAAK;AAAA,IACL,QAAQ,MAAM,UAAU,UAAU;AAAA,IAClC,UAAU;AAAA,IACV,SAAS,MAAM;AACb,qBAAe,KAAK;AACpB,oBAAc,EAAE;AAAA,IAClB;AAAA,IACA,UAAU;AAAA,EACZ;AAEA,QAAM,iBACJ,eAAe,CAAC,YACZa;AAAA,IACE,OAAO,oBACL,OAAO,kBAAkB,kBAAkB,IAE3C,gBAAAb,MAAC,sBAAoB,GAAG,oBAAoB;AAAA,IAE9C;AAAA,EACF,IACA;AAEN,SACE,gBAAAC,OAAAF,WAAA,EACG;AAAA;AAAA,IACA;AAAA,KACH;AAEJ;AAIA,IAAM,mBAAmBD;AAAA,EACvB,SAASgB,kBACP,EAAE,YAAY,UAAU,UAAU,SAAS,SAAS,GACpD,KACA;AACA,UAAM,CAAC,OAAO,QAAQ,IAAIX,UAAS,UAAU;AAC7C,UAAM,eAAeC,SAAuB,IAAI;AAChD,UAAM,YAAY,eAAe;AAGjC,IAAAC,YAAU,MAAM;AACd,eAAS,UAAU;AAAA,IACrB,GAAG,CAAC,UAAU,CAAC;AAGf,IAAAA,YAAU,MAAM;AACd,YAAM,qBAAqB,CAAC,MAAkB;AAC5C,YACE,aAAa,WACb,CAAC,aAAa,QAAQ,SAAS,EAAE,MAAc,GAC/C;AACA,kBAAQ;AAAA,QACV;AAAA,MACF;AAEA,YAAM,MAAM,sBAAsB,MAAM;AACtC,iBAAS,iBAAiB,aAAa,kBAAkB;AAAA,MAC3D,CAAC;AACD,aAAO,MAAM;AACX,6BAAqB,GAAG;AACxB,iBAAS,oBAAoB,aAAa,kBAAkB;AAAA,MAC9D;AAAA,IACF,GAAG,CAAC,OAAO,CAAC;AAEZ,UAAM,gBAAgB,CAAC,MAA6C;AAClE,QAAE,gBAAgB;AAElB,UAAI,EAAE,QAAQ,WAAW,CAAC,EAAE,UAAU;AACpC,UAAE,eAAe;AACjB,iBAAS,KAAK;AAAA,MAChB;AACA,UAAI,EAAE,QAAQ,UAAU;AACtB,UAAE,eAAe;AACjB,gBAAQ;AAAA,MACV;AAAA,IACF;AAEA,WACE,gBAAAJ;AAAA,MAAC;AAAA;AAAA,QACC,KAAK;AAAA,QACL,eAAY;AAAA,QACZ,OAAO;AAAA,UACL,UAAU;AAAA,UACV,KAAK,GAAG,SAAS,GAAG;AAAA,UACpB,MAAM,GAAG,SAAS,IAAI;AAAA,UACtB,WAAW;AAAA,UACX,QAAQ;AAAA,UACR,SAAS;AAAA,UACT,YAAY;AAAA,UACZ,KAAK;AAAA,UACL,SAAS;AAAA,UACT,cAAc;AAAA,UACd,QAAQ;AAAA,UACR,iBAAiB;AAAA,UACjB,gBAAgB;AAAA,UAChB,sBAAsB;AAAA,UACtB,WAAW;AAAA,UACX,YACE;AAAA,UACF,WAAW;AAAA,UACX,UAAU;AAAA,QACZ;AAAA,QAEA;AAAA,0BAAAD,MAACH,WAAA,EAAS,MAAM,IAAI,OAAO,EAAE,OAAO,iCAAiC,YAAY,EAAE,GAAG;AAAA,UACtF,gBAAAG;AAAA,YAAC;AAAA;AAAA,cACC;AAAA,cACA,MAAK;AAAA,cACL;AAAA,cACA,UAAU,CAAC,MAAM,SAAS,EAAE,OAAO,KAAK;AAAA,cACxC,WAAW;AAAA,cACX,aAAY;AAAA,cACZ,OAAO;AAAA,gBACL,MAAM;AAAA,gBACN,QAAQ;AAAA,gBACR,SAAS;AAAA,gBACT,YAAY;AAAA,gBACZ,UAAU;AAAA,gBACV,OAAO;AAAA,gBACP,YAAY;AAAA,cACd;AAAA;AAAA,UACF;AAAA,UACA,gBAAAA;AAAA,YAAC;AAAA;AAAA,cACC,MAAK;AAAA,cACL,eAAY;AAAA,cACZ,aAAa,CAAC,MAAM;AAClB,kBAAE,eAAe;AACjB,yBAAS,KAAK;AAAA,cAChB;AAAA,cACA,UAAU,CAAC,MAAM,KAAK;AAAA,cACtB,OAAO;AAAA,gBACL,SAAS;AAAA,gBACT,YAAY;AAAA,gBACZ,gBAAgB;AAAA,gBAChB,SAAS;AAAA,gBACT,cAAc;AAAA,gBACd,QAAQ;AAAA,gBACR,QAAQ,MAAM,KAAK,IAAI,YAAY;AAAA,gBACnC,iBAAiB,MAAM,KAAK,IACxB,oCACA;AAAA,gBACJ,OAAO,MAAM,KAAK,IAAI,4CAA4C;AAAA,gBAClE,UAAU;AAAA,gBACV,YAAY;AAAA,gBACZ,YAAY;AAAA,gBACZ,YAAY;AAAA,cACd;AAAA,cAEC,sBAAY,WAAW;AAAA;AAAA,UAC1B;AAAA,UACC,aACC,gBAAAA;AAAA,YAAC;AAAA;AAAA,cACC,MAAK;AAAA,cACL,eAAY;AAAA,cACZ,aAAa,CAAC,MAAM;AAClB,kBAAE,eAAe;AACjB,yBAAS;AAAA,cACX;AAAA,cACA,OAAM;AAAA,cACN,OAAO;AAAA,gBACL,SAAS;AAAA,gBACT,YAAY;AAAA,gBACZ,gBAAgB;AAAA,gBAChB,OAAO;AAAA,gBACP,QAAQ;AAAA,gBACR,cAAc;AAAA,gBACd,QAAQ;AAAA,gBACR,QAAQ;AAAA,gBACR,iBAAiB;AAAA,gBACjB,OAAO;AAAA,gBACP,YAAY;AAAA,cACd;AAAA,cAEA,0BAAAA,MAAC,aAAU,MAAM,IAAI;AAAA;AAAA,UACvB;AAAA,UAGF,gBAAAA;AAAA,YAAC;AAAA;AAAA,cACC,yBAAyB;AAAA,gBACvB,QAAQ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,cAYV;AAAA;AAAA,UACF;AAAA;AAAA;AAAA,IACF;AAAA,EAEJ;AACF;AAEA,SAAS,mBAAmB;AAAA,EAC1B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAA2B;AACzB,QAAM,eAAeI,SAAuB,IAAI;AAGhD,EAAAC,YAAU,MAAM;AACd,UAAM,qBAAqB,CAAC,MAAkB;AAC5C,UACE,aAAa,WACb,CAAC,aAAa,QAAQ,SAAS,EAAE,MAAc,GAC/C;AACA,gBAAQ;AAAA,MACV;AAAA,IACF;AAEA,UAAM,MAAM,sBAAsB,MAAM;AACtC,eAAS,iBAAiB,aAAa,kBAAkB;AAAA,IAC3D,CAAC;AACD,WAAO,MAAM;AACX,2BAAqB,GAAG;AACxB,eAAS,oBAAoB,aAAa,kBAAkB;AAAA,IAC9D;AAAA,EACF,GAAG,CAAC,OAAO,CAAC;AAGZ,QAAM,aACJ,IAAI,SAAS,KAAK,IAAI,MAAM,GAAG,EAAE,IAAI,QAAQ;AAE/C,SACE,gBAAAJ;AAAA,IAAC;AAAA;AAAA,MACC,KAAK;AAAA,MACL,eAAY;AAAA,MACZ,OAAO;AAAA,QACL,UAAU;AAAA,QACV,KAAK,GAAG,SAAS,GAAG;AAAA,QACpB,MAAM,GAAG,SAAS,IAAI;AAAA,QACtB,WAAW;AAAA,QACX,QAAQ;AAAA,QACR,SAAS;AAAA,QACT,YAAY;AAAA,QACZ,KAAK;AAAA,QACL,SAAS;AAAA,QACT,cAAc;AAAA,QACd,QAAQ;AAAA,QACR,iBAAiB;AAAA,QACjB,gBAAgB;AAAA,QAChB,sBAAsB;AAAA,QACtB,WAAW;AAAA,QACX,YACE;AAAA,QACF,WAAW;AAAA,MACb;AAAA,MAEA;AAAA,wBAAAD;AAAA,UAAC;AAAA;AAAA,YACC,MAAM;AAAA,YACN,QAAO;AAAA,YACP,KAAI;AAAA,YACJ,OAAO;AAAA,cACL,UAAU;AAAA,cACV,OAAO;AAAA,cACP,gBAAgB;AAAA,cAChB,YAAY;AAAA,cACZ,UAAU;AAAA,cACV,cAAc;AAAA,cACd,UAAU;AAAA,YACZ;AAAA,YACA,OAAO;AAAA,YAEN;AAAA;AAAA,QACH;AAAA,QAEA,gBAAAA;AAAA,UAAC;AAAA;AAAA,YACC,OAAO;AAAA,cACL,OAAO;AAAA,cACP,QAAQ;AAAA,cACR,iBAAiB;AAAA,cACjB,YAAY;AAAA,YACd;AAAA;AAAA,QACF;AAAA,QAEA,gBAAAA;AAAA,UAAC;AAAA;AAAA,YACC,MAAK;AAAA,YACL,eAAY;AAAA,YACZ,aAAa,CAAC,MAAM;AAClB,gBAAE,eAAe;AACjB,qBAAO,KAAK,KAAK,UAAU,qBAAqB;AAAA,YAClD;AAAA,YACA,OAAM;AAAA,YACN,OAAO;AAAA,cACL,SAAS;AAAA,cACT,YAAY;AAAA,cACZ,gBAAgB;AAAA,cAChB,OAAO;AAAA,cACP,QAAQ;AAAA,cACR,cAAc;AAAA,cACd,QAAQ;AAAA,cACR,QAAQ;AAAA,cACR,iBAAiB;AAAA,cACjB,OAAO;AAAA,YACT;AAAA,YAEA,0BAAAA,MAAC,sBAAmB,MAAM,IAAI;AAAA;AAAA,QAChC;AAAA,QAEA,gBAAAA;AAAA,UAAC;AAAA;AAAA,YACC,MAAK;AAAA,YACL,eAAY;AAAA,YACZ,aAAa,CAAC,MAAM;AAClB,gBAAE,eAAe;AACjB,qBAAO;AAAA,YACT;AAAA,YACA,OAAM;AAAA,YACN,OAAO;AAAA,cACL,SAAS;AAAA,cACT,YAAY;AAAA,cACZ,gBAAgB;AAAA,cAChB,OAAO;AAAA,cACP,QAAQ;AAAA,cACR,cAAc;AAAA,cACd,QAAQ;AAAA,cACR,QAAQ;AAAA,cACR,iBAAiB;AAAA,cACjB,OAAO;AAAA,YACT;AAAA,YAEA,0BAAAA,MAAC,oBAAiB,MAAM,IAAI;AAAA;AAAA,QAC9B;AAAA,QAEA,gBAAAA;AAAA,UAAC;AAAA;AAAA,YACC,MAAK;AAAA,YACL,eAAY;AAAA,YACZ,aAAa,CAAC,MAAM;AAClB,gBAAE,eAAe;AACjB,uBAAS;AAAA,YACX;AAAA,YACA,OAAM;AAAA,YACN,OAAO;AAAA,cACL,SAAS;AAAA,cACT,YAAY;AAAA,cACZ,gBAAgB;AAAA,cAChB,OAAO;AAAA,cACP,QAAQ;AAAA,cACR,cAAc;AAAA,cACd,QAAQ;AAAA,cACR,QAAQ;AAAA,cACR,iBAAiB;AAAA,cACjB,OAAO;AAAA,YACT;AAAA,YAEA,0BAAAA,MAAC,aAAU,MAAM,IAAI;AAAA;AAAA,QACvB;AAAA,QAEA,gBAAAA;AAAA,UAAC;AAAA;AAAA,YACC,yBAAyB;AAAA,cACvB,QAAQ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,YAYV;AAAA;AAAA,QACF;AAAA;AAAA;AAAA,EACF;AAEJ;;;AC7sBA,SAAS,aAAAe,aAAW,UAAAC,UAAQ,YAAAC,kBAAgB;AAG5C,SAAS,6BAAAC,mCAAiC;AAYnC,SAAS,eAAe;AAAA,EAC7B,aAAa;AAAA,EACb;AACF,IAA2B,CAAC,GAAG;AAC7B,QAAM,CAAC,MAAM,IAAIA,4BAA0B;AAC3C,QAAM,CAAC,iBAAiB,kBAAkB,IAAID,WAAiB,EAAE;AACjE,QAAM,cAAcD,SAAO,QAAQ;AACnC,cAAY,UAAU;AAEtB,EAAAD,YAAU,MAAM;AACd,QAAI,UAAgD;AAGpD,QAAI,oBAA0D;AAE9D,UAAM,aAAa,OAAO,uBAAuB,CAAC,EAAE,YAAY,MAAM;AACpE,0BAAoB;AACpB,UAAI,QAAS,cAAa,OAAO;AAEjC,gBAAU,WAAW,MAAM;AACzB,YAAI,CAAC,kBAAmB;AACxB,cAAM,OAAO,KAAK,UAAU,kBAAkB,OAAO,CAAC;AACtD,4BAAoB;AAEpB,YAAI,CAAC,YAAY,SAAS;AACxB,6BAAmB,IAAI;AAAA,QACzB;AACA,oBAAY,UAAU,IAAI;AAAA,MAC5B,GAAG,UAAU;AAAA,IACf,CAAC;AAED,WAAO,MAAM;AACX,iBAAW;AACX,UAAI,QAAS,cAAa,OAAO;AAAA,IACnC;AAAA,EACF,GAAG,CAAC,QAAQ,UAAU,CAAC;AAEvB,SAAO,EAAE,gBAAgB;AAC3B;;;ACtDA,SAAS,aAAAI,aAAW,UAAAC,UAAQ,YAAAC,kBAAgB;AAC5C,SAAS,6BAAAC,mCAAiC;AAC1C,SAAS,YAAAC,iBAAgB;AAOlB,SAAS,aAAa,aAAa,KAAsB;AAC9D,QAAM,CAAC,MAAM,IAAID,4BAA0B;AAC3C,QAAM,CAAC,QAAQ,SAAS,IAAID,WAA0B,EAAE,OAAO,GAAG,YAAY,EAAE,CAAC;AACjF,QAAM,aAAaD,SAA6C,IAAI;AAEpE,EAAAD,YAAU,MAAM;AACd,UAAM,aAAa,OAAO,uBAAuB,CAAC,EAAE,YAAY,MAAM;AACpE,UAAI,WAAW,QAAS,cAAa,WAAW,OAAO;AAEvD,iBAAW,UAAU,WAAW,MAAM;AACpC,oBAAY,KAAK,MAAM;AACrB,gBAAM,OAAOI,UAAS,EAAE,eAAe;AACvC,gBAAM,aAAa,KAAK;AACxB,gBAAM,QAAQ,KAAK,KAAK,MAAM,KAAK,IAAI,KAAK,KAAK,EAAE,MAAM,KAAK,EAAE;AAChE,oBAAU,EAAE,OAAO,WAAW,CAAC;AAAA,QACjC,CAAC;AAAA,MACH,GAAG,UAAU;AAAA,IACf,CAAC;AAED,WAAO,MAAM;AACX,iBAAW;AACX,UAAI,WAAW,QAAS,cAAa,WAAW,OAAO;AAAA,IACzD;AAAA,EACF,GAAG,CAAC,QAAQ,UAAU,CAAC;AAEvB,SAAO;AACT;;;AClCA,SAAS,eAAAC,eAAa,aAAAC,aAAW,UAAAC,UAAQ,YAAAC,kBAAgB;AAGzD,SAAS,6BAAAC,mCAAiC;AAC1C,SAAS,uBAAAC,4BAA2B;AAGpC,SAAS,gBAAAC,qBAAoB;AAG7B;AAAA,EACE,aAAAC;AAAA,EACA,kBAAAC;AAAA,EACA,qBAAAC;AAAA,EACA,yBAAAC;AAAA,EACA,YAAAC;AAAA,OACK;AAmJG,gBAAAC,aAAA;AAxIV,IAAMC,mBAAmC;AAAA,EACvC,EAAE,MAAMN,YAAW,QAAQ,QAAQ,OAAO,OAAO;AAAA,EACjD,EAAE,MAAMC,iBAAgB,QAAQ,UAAU,OAAO,SAAS;AAAA,EAC1D,EAAE,MAAMC,oBAAmB,QAAQ,aAAa,OAAO,YAAY;AAAA,EACnE,EAAE,MAAMC,wBAAuB,QAAQ,iBAAiB,OAAO,gBAAgB;AAAA,EAC/E,EAAE,MAAMC,WAAU,QAAQ,QAAQ,OAAO,cAAc;AACzD;AAUO,SAAS,gBAAgB;AAC9B,QAAM,CAAC,MAAM,IAAIP,4BAA0B;AAC3C,QAAM,CAAC,eAAe,gBAAgB,IAAID,WAAyB,IAAI;AACvE,QAAM,CAAC,WAAW,YAAY,IAAIA,WAAS,KAAK;AAChD,QAAM,CAAC,iBAAiB,kBAAkB,IAAIA,WAA6B,IAAI;AAC/E,QAAM,iBAAiBD,SAA2B,IAAI;AAItD,EAAAD,YAAU,MAAM;AACd,QAAI,OAAO,WAAW,YAAa;AACnC,UAAM,UACJ,OAAO,WAAW,mBAAmB,EAAE,WACvC,UAAU,iBAAiB,KAC3B,kBAAkB;AACpB,qBAAiB,OAAO;AACxB,uBAAmB,SAAS,IAAI;AAAA,EAClC,GAAG,CAAC,CAAC;AAGL,EAAAA,YAAU,MAAM;AACd,mBAAe,UAAU,OAAO,eAAe;AAAA,EACjD,GAAG,CAAC,MAAM,CAAC;AAGX,EAAAA,YAAU,MAAM;AACd,QAAI,kBAAkB,KAAM;AAE5B,UAAM,oBAAoB,MAAM;AAC9B,YAAM,eAAe,OAAO,aAAa;AACzC,UAAI,CAAC,gBAAgB,aAAa,eAAe,aAAa,eAAe,GAAG;AAC9E,qBAAa,KAAK;AAClB;AAAA,MACF;AAGA,YAAM,SAAS,eAAe;AAC9B,UAAI,CAAC,QAAQ;AACX,qBAAa,KAAK;AAClB;AAAA,MACF;AAEA,YAAM,aAAa,aAAa;AAChC,UAAI,CAAC,cAAc,CAAC,OAAO,SAAS,UAAU,GAAG;AAC/C,qBAAa,KAAK;AAClB;AAAA,MACF;AAEA,mBAAa,IAAI;AAAA,IACnB;AAEA,aAAS,iBAAiB,mBAAmB,iBAAiB;AAC9D,WAAO,MAAM,SAAS,oBAAoB,mBAAmB,iBAAiB;AAAA,EAChF,GAAG,CAAC,aAAa,CAAC;AAElB,QAAM,eAAeD;AAAA,IACnB,CAAC,WAAuB;AACtB,aAAO,gBAAgBK,sBAAqB,MAAM;AAAA,IACpD;AAAA,IACA,CAAC,MAAM;AAAA,EACT;AAGA,MAAI,kBAAkB,QAAQ,CAAC,gBAAiB,QAAO;AAEvD,MAAI,CAAC,UAAW,QAAO;AAEvB,SAAOC;AAAA,IACL,gBAAAM;AAAA,MAAC;AAAA;AAAA,QACC,MAAK;AAAA,QACL,cAAW;AAAA,QACX,eAAY;AAAA,QACZ,OAAO;AAAA,UACL,UAAU;AAAA,UACV,QAAQ;AAAA,UACR,MAAM;AAAA,UACN,OAAO;AAAA,UACP,SAAS;AAAA,UACT,YAAY;AAAA,UACZ,gBAAgB;AAAA,UAChB,KAAK;AAAA,UACL,SAAS;AAAA,UACT,eAAe;AAAA,UACf,iBAAiB;AAAA,UACjB,gBAAgB;AAAA,UAChB,sBAAsB;AAAA,UACtB,WAAW;AAAA,UACX,QAAQ;AAAA,UACR,YACE;AAAA,QACJ;AAAA,QAEC,UAAAC,iBAAgB,IAAI,CAAC,EAAE,MAAM,MAAM,QAAQ,MAAM,MAChD,gBAAAD;AAAA,UAAC;AAAA;AAAA,YAEC,MAAK;AAAA,YACL,OAAO;AAAA,YACP,cAAY;AAAA,YACZ,eAAa,kBAAkB,MAAM;AAAA,YACrC,aAAa,CAAC,MAAM;AAClB,gBAAE,eAAe;AACjB,2BAAa,MAAM;AAAA,YACrB;AAAA,YACA,cAAc,CAAC,MAAM;AACnB,gBAAE,eAAe;AACjB,2BAAa,MAAM;AAAA,YACrB;AAAA,YACA,OAAO;AAAA,cACL,SAAS;AAAA,cACT,YAAY;AAAA,cACZ,gBAAgB;AAAA,cAChB,OAAO;AAAA,cACP,QAAQ;AAAA,cACR,cAAc;AAAA,cACd,QAAQ;AAAA,cACR,QAAQ;AAAA,cACR,iBAAiB;AAAA,cACjB,OAAO;AAAA,YACT;AAAA,YAEA,0BAAAA,MAAC,QAAK,MAAM,IAAI,QAAO,WAAU;AAAA;AAAA,UA1B5B;AAAA,QA2BP,CACD;AAAA;AAAA,IACH;AAAA,IACA;AAAA,EACF;AACF;;;AC1KA,SAAS,aAAAE,mBAAiB;AAC1B,SAAS,6BAAAC,mCAAiC;AAC1C;AAAA,EACE,iBAAAC;AAAA,EACA,qBAAAC;AAAA,EACA,eAAAC;AAAA,EACA,wBAAAC;AAAA,OACK;AAIA,SAAS,cAAc;AAC5B,QAAM,CAAC,MAAM,IAAIC,4BAA0B;AAE3C,EAAAC,YAAU,MAAM;AACd,WAAO,OAAO;AAAA,MACZ;AAAA,MACA,CAAC,UAAkB;AACjB,eAAO,OAAO,MAAM;AAClB,gBAAM,YAAYC,gBAAc;AAChC,cAAI,CAACC,mBAAkB,SAAS,EAAG;AAGnC,gBAAM,QAAQ,UAAU,SAAS;AACjC,qBAAW,QAAQ,OAAO;AACxB,gBAAIC,aAAY,IAAI,GAAG;AACrB,oBAAM,WAAW,KAAK,SAAS;AAC/B,oBAAM,SAAS,iBAAiB,UAAU,SAAS,SAAS,IAAI;AAChE,mBAAK,SAAS,MAAM;AAAA,YACtB;AAAA,UACF;AAAA,QACF,CAAC;AACD,eAAO;AAAA,MACT;AAAA,MACAC;AAAA,IACF;AAAA,EACF,GAAG,CAAC,MAAM,CAAC;AAEX,EAAAJ,YAAU,MAAM;AACd,WAAO,OAAO;AAAA,MACZ;AAAA,MACA,CAAC,UAAkB;AACjB,eAAO,OAAO,MAAM;AAClB,gBAAM,YAAYC,gBAAc;AAChC,cAAI,CAACC,mBAAkB,SAAS,EAAG;AAEnC,gBAAM,QAAQ,UAAU,SAAS;AACjC,qBAAW,QAAQ,OAAO;AACxB,gBAAIC,aAAY,IAAI,GAAG;AACrB,oBAAM,WAAW,KAAK,SAAS;AAC/B,oBAAM,SAAS;AAAA,gBACb;AAAA,gBACA;AAAA,gBACA,SAAS;AAAA,cACX;AACA,mBAAK,SAAS,MAAM;AAAA,YACtB;AAAA,UACF;AAAA,QACF,CAAC;AACD,eAAO;AAAA,MACT;AAAA,MACAC;AAAA,IACF;AAAA,EACF,GAAG,CAAC,MAAM,CAAC;AAEX,EAAAJ,YAAU,MAAM;AACd,WAAO,OAAO;AAAA,MACZ;AAAA,MACA,CAAC,eAAuB;AACtB,eAAO,OAAO,MAAM;AAClB,gBAAM,YAAYC,gBAAc;AAChC,cAAI,CAACC,mBAAkB,SAAS,EAAG;AAEnC,gBAAM,QAAQ,UAAU,SAAS;AACjC,qBAAW,QAAQ,OAAO;AACxB,gBAAIC,aAAY,IAAI,GAAG;AACrB,oBAAM,WAAW,KAAK,SAAS;AAC/B,oBAAM,SAAS;AAAA,gBACb;AAAA,gBACA;AAAA,gBACA,cAAc;AAAA,cAChB;AACA,mBAAK,SAAS,MAAM;AAAA,YACtB;AAAA,UACF;AAAA,QACF,CAAC;AACD,eAAO;AAAA,MACT;AAAA,MACAC;AAAA,IACF;AAAA,EACF,GAAG,CAAC,MAAM,CAAC;AAEX,SAAO;AACT;;;AC7FA,SAAS,aAAAC,mBAAiB;AAE1B,SAAS,6BAAAC,mCAAiC;AAC1C,SAAS,cAAc,yBAAyB;AAOzC,SAAS,aAAa;AAC3B,QAAM,CAAC,MAAM,IAAIA,4BAA0B;AAE3C,EAAAD,YAAU,MAAM;AACd,UAAM,iBAAiB,aAAa,MAAM;AAC1C,UAAM,sBAAsB,kBAAkB,MAAM;AACpD,WAAO,MAAM;AACX,qBAAe;AACf,0BAAoB;AAAA,IACtB;AAAA,EACF,GAAG,CAAC,MAAM,CAAC;AAEX,SAAO;AACT;;;ACvBA,SAAS,aAAAE,mBAAiB;AAC1B,SAAS,6BAAAC,mCAAiC;AAC1C;AAAA,EACE,wBAAAC;AAAA,EACA,iBAAAC;AAAA,EACA,oBAAAC;AAAA,EACA,qBAAAC;AAAA,EACA,wBAAAC;AAAA,EACA,yBAAAC;AAAA,EACA,sBAAAC;AAAA,OACK;AACP;AAAA,EACE;AAAA,EACA,gBAAAC;AAAA,EACA,mBAAAC;AAAA,EACA,oBAAAC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AAUA,SAAS,YAAY;AAAA,EAC1B,eAAe;AAAA,EACf,gBAAgB;AAClB,GAAqB;AACnB,QAAM,CAAC,MAAM,IAAIC,4BAA0B;AAE3C,EAAAC,YAAU,MAAM;AACd,WAAO,oBAAoB,MAAM;AAAA,EACnC,GAAG,CAAC,MAAM,CAAC;AAEX,EAAAA,YAAU,MAAM;AACd,WAAO,+BAA+B,QAAQ,aAAa;AAAA,EAC7D,GAAG,CAAC,QAAQ,aAAa,CAAC;AAE1B,EAAAA,YAAU,MAAM;AACd,QAAI,CAAC,cAAc;AACjB,aAAO,kCAAkC,MAAM;AAAA,IACjD;AAAA,EACF,GAAG,CAAC,QAAQ,YAAY,CAAC;AAEzB,EAAAA,YAAU,MAAM;AACd,WAAO,OAAO;AAAA,MACZ;AAAA,MACA,CAAC,YAA+C;AAC9C,eAAO,OAAO,MAAM;AAClB,gBAAM,YAAYC,gBAAc;AAChC,cAAI,CAACC,oBAAkB,SAAS,EAAG;AAEnC,gBAAM,YAAY;AAAA,YAChB,QAAQ;AAAA,YACR,QAAQ;AAAA,YACR;AAAA,UACF;AAEA,gBAAM,YAAY,UAAU,MAAM,QAAQ;AAC1C,gBAAM,eAAe,UAAU,mBAAmB;AAClD,cAAI,cAAc;AAChB,yBAAa,YAAY,SAAS;AAClC,gBACE,aAAa,eAAe,EAAE,KAAK,MAAM,MACzC,aAAa,QAAQ,MAAM,aAC3B;AACA,2BAAa,OAAO;AAAA,YACtB;AAEA,kBAAM,WAAW,UAAU,YAAY,EAAE,KAAKC,gBAAe;AAC7D,gBAAI,UAAU;AACZ,oBAAM,YAAY,SAAS,YAAY,EAAE,KAAKC,iBAAgB;AAC9D,kBAAI,WAAW;AACb,0BAAU,YAAY;AAAA,cACxB;AAAA,YACF;AAAA,UACF;AAAA,QACF,CAAC;AACD,eAAO;AAAA,MACT;AAAA,MACAC;AAAA,IACF;AAAA,EACF,GAAG,CAAC,MAAM,CAAC;AAEX,EAAAL,YAAU,MAAM;AACd,UAAM,eAAe,CAAC,UAAyB;AAC7C,YAAM,YAAYC,gBAAc;AAChC,UAAI,CAACK,kBAAiB,SAAS,EAAG,QAAO;AAEzC,YAAM,QAAQ,UAAU,SAAS;AACjC,YAAM,YAAY,MAAM,KAAKC,aAAY;AACzC,UAAI,CAAC,UAAW,QAAO;AAEvB,YAAM,eAAe;AACrB,YAAM,YAAYC,sBAAqB;AACvC,gBAAU,aAAa,SAAS;AAChC,gBAAU,OAAO;AACjB,gBAAU,YAAY;AACtB,aAAO;AAAA,IACT;AAEA,UAAM,sBAAsB,OAAO;AAAA,MACjCC;AAAA,MACA;AAAA,MACAJ;AAAA,IACF;AACA,UAAM,mBAAmB,OAAO;AAAA,MAC9BK;AAAA,MACA;AAAA,MACAL;AAAA,IACF;AAEA,WAAO,MAAM;AACX,0BAAoB;AACpB,uBAAiB;AAAA,IACnB;AAAA,EACF,GAAG,CAAC,MAAM,CAAC;AAEX,SAAO;AACT;;;AC5HA,SAAS,eAAAM,eAAa,aAAAC,aAAW,UAAAC,UAAQ,YAAAC,kBAAgB;AACzD,SAAS,6BAAAC,mCAAiC;AAC1C,SAAS,gBAAAC,sBAAoB;AAC7B;AAAA,EACE,iBAAAC;AAAA,EACA,qBAAAC;AAAA,OAGK;AACP;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,oBAAAC;AAAA,EACA,qBAAAC;AAAA,OAEK;AAyQO,SAoBE,OAAAC,OApBF,QAAAC,cAAA;AAnQd,IAAM,iBAAiB;AAAA,EACrB,EAAE,OAAO,WAAW,OAAO,IAAI,QAAQ,cAAc;AAAA,EACrD,EAAE,OAAO,QAAQ,OAAO,gCAAgC,QAAQ,UAAU;AAAA,EAC1E,EAAE,OAAO,SAAS,OAAO,iCAAiC,QAAQ,UAAU;AAAA,EAC5E,EAAE,OAAO,UAAU,OAAO,kCAAkC,QAAQ,UAAU;AAAA,EAC9E,EAAE,OAAO,UAAU,OAAO,kCAAkC,QAAQ,UAAU;AAAA,EAC9E,EAAE,OAAO,SAAS,OAAO,iCAAiC,QAAQ,UAAU;AAAA,EAC5E,EAAE,OAAO,QAAQ,OAAO,gCAAgC,QAAQ,UAAU;AAAA,EAC1E,EAAE,OAAO,UAAU,OAAO,kCAAkC,QAAQ,UAAU;AAAA,EAC9E,EAAE,OAAO,QAAQ,OAAO,gCAAgC,QAAQ,UAAU;AAAA,EAC1E,EAAE,OAAO,OAAO,OAAO,+BAA+B,QAAQ,UAAU;AAC1E;AAmBA,IAAM,aAAyB;AAAA,EAC7B,EAAE,IAAI,oBAAoB,OAAO,mBAAmB;AAAA,EACpD,EAAE,IAAI,oBAAoB,OAAO,mBAAmB;AAAA,EACpD,EAAE,IAAI,mBAAmB,OAAO,qBAAqB;AAAA,EACrD,EAAE,IAAI,oBAAoB,OAAO,sBAAsB;AAAA,EACvD,EAAE,IAAI,cAAc,OAAO,aAAa;AAAA,EACxC,EAAE,IAAI,cAAc,OAAO,gBAAgB;AAAA,EAC3C,EAAE,IAAI,eAAe,OAAO,cAAc;AAAA,EAC1C,EAAE,IAAI,gBAAgB,OAAO,eAAe;AAAA,EAC5C,EAAE,IAAI,cAAc,OAAO,kBAAkB;AAAA,EAC7C,EAAE,IAAI,gBAAgB,OAAO,gBAAgB,QAAQ,KAAK;AAC5D;AAEO,SAAS,kBAAkB;AAChC,QAAM,CAAC,MAAM,IAAIP,4BAA0B;AAC3C,QAAM,CAAC,QAAQ,SAAS,IAAID,WAAS,KAAK;AAC1C,QAAM,CAAC,UAAU,WAAW,IAAIA,WAAS,EAAE,KAAK,GAAG,MAAM,EAAE,CAAC;AAC5D,QAAM,CAAC,kBAAkB,mBAAmB,IAAIA,WAAS,KAAK;AAC9D,QAAM,CAAC,eAAe,gBAAgB,IAAIA,WAAwB,IAAI;AACtE,QAAM,CAAC,mBAAmB,oBAAoB,IAAIA,WAAS,KAAK;AAChE,QAAM,CAAC,YAAY,aAAa,IAAIA,WAAS,KAAK;AAClD,QAAM,UAAUD,SAAuB,IAAI;AAC3C,QAAM,CAAC,iBAAiB,kBAAkB,IAAIC,WAA6B,IAAI;AAE/E,EAAAF,YAAU,MAAM;AACd,QAAI,OAAO,WAAW,YAAa;AACnC,uBAAmB,SAAS,IAAI;AAAA,EAClC,GAAG,CAAC,CAAC;AAGL,EAAAA,YAAU,MAAM;AACd,UAAM,cAAc,OAAO,eAAe;AAC1C,QAAI,CAAC,YAAa;AAElB,UAAM,oBAAoB,CAAC,MAAkB;AAC3C,aAAO,KAAK,MAAM;AAChB,cAAM,YAAYK,gBAAc;AAChC,YAAI,CAAC,UAAW;AAGhB,YAAI,WAAiC;AAErC,YAAIC,oBAAkB,SAAS,GAAG;AAChC,qBAAW,iCAAiC,UAAU,OAAO,QAAQ,CAAC;AAAA,QACxE,WAAWE,mBAAkB,SAAS,GAAG;AACvC,gBAAM,QAAQ,UAAU,SAAS;AACjC,gBAAM,YAAY,MAAM,KAAK,CAAC,MAAMD,kBAAiB,CAAC,CAAC;AACvD,qBAAW,YAAa,YAA8B;AACtD,+BAAqB,IAAI;AAAA,QAC3B;AAEA,YAAI,CAAC,SAAU;AAEf,UAAE,eAAe;AACjB,UAAE,gBAAgB;AAElB,yBAAiB,SAAS,mBAAmB,CAAC;AAC9C,sBAAc,SAAS,WAAW,IAAI,KAAK,SAAS,WAAW,IAAI,CAAC;AAEpE,YAAIC,mBAAkB,SAAS,GAAG;AAChC,+BAAqB,IAAI;AAAA,QAC3B,OAAO;AACL,+BAAqB,KAAK;AAAA,QAC5B;AAEA,oBAAY,EAAE,KAAK,EAAE,SAAS,MAAM,EAAE,QAAQ,CAAC;AAC/C,kBAAU,IAAI;AACd,4BAAoB,KAAK;AAAA,MAC3B,CAAC;AAAA,IACH;AAEA,gBAAY,iBAAiB,eAAe,iBAAiB;AAC7D,WAAO,MAAM,YAAY,oBAAoB,eAAe,iBAAiB;AAAA,EAC/E,GAAG,CAAC,MAAM,CAAC;AAGX,EAAAR,YAAU,MAAM;AACd,QAAI,CAAC,OAAQ;AAEb,UAAM,cAAc,CAAC,MAAkB;AACrC,UAAI,QAAQ,WAAW,CAAC,QAAQ,QAAQ,SAAS,EAAE,MAAc,GAAG;AAClE,kBAAU,KAAK;AAAA,MACjB;AAAA,IACF;AAEA,UAAM,gBAAgB,CAAC,MAAqB;AAC1C,UAAI,EAAE,QAAQ,UAAU;AACtB,kBAAU,KAAK;AAAA,MACjB;AAAA,IACF;AAEA,aAAS,iBAAiB,aAAa,WAAW;AAClD,aAAS,iBAAiB,WAAW,aAAa;AAClD,WAAO,MAAM;AACX,eAAS,oBAAoB,aAAa,WAAW;AACrD,eAAS,oBAAoB,WAAW,aAAa;AAAA,IACvD;AAAA,EACF,GAAG,CAAC,MAAM,CAAC;AAEX,QAAM,eAAeD;AAAA,IACnB,CAAC,WAAuB;AACtB,gBAAU,KAAK;AAEf,aAAO,OAAO,MAAM;AAClB,gBAAQ,QAAQ;AAAA,UACd,KAAK;AACH,uCAA2B,KAAK;AAChC;AAAA,UACF,KAAK;AACH,uCAA2B,IAAI;AAC/B;AAAA,UACF,KAAK;AACH,0CAA8B,KAAK;AACnC;AAAA,UACF,KAAK;AACH,0CAA8B,IAAI;AAClC;AAAA,UACF,KAAK;AACH,uCAA2B;AAC3B;AAAA,UACF,KAAK;AACH,0CAA8B;AAC9B;AAAA,UACF,KAAK,eAAe;AAClB,kBAAM,YAAYM,gBAAc;AAChC,gBAAIG,mBAAkB,SAAS,GAAG;AAChC,oBAAM,QAAQ,UAAU,SAAS;AACjC,oBAAM,QAAQ,MAAM;AAAA,gBAAO,CAAC,MAC1BD,kBAAiB,CAAC;AAAA,cACpB;AACA,kBAAI,MAAM,SAAS,GAAG;AACpB,4BAAY,KAAK;AAAA,cACnB;AAAA,YACF;AACA;AAAA,UACF;AAAA,UACA,KAAK;AACH,yBAAa;AACb;AAAA,UACF,KAAK,gBAAgB;AACnB,kBAAM,YAAYF,gBAAc;AAChC,gBAAI,CAAC,UAAW;AAChB,gBAAI,WAAiC;AACrC,gBAAIC,oBAAkB,SAAS,GAAG;AAChC,yBAAW;AAAA,gBACT,UAAU,OAAO,QAAQ;AAAA,cAC3B;AAAA,YACF,WAAWE,mBAAkB,SAAS,GAAG;AACvC,oBAAM,QAAQ,UAAU,SAAS;AACjC,oBAAM,YAAY,MAAM,KAAK,CAAC,MAAMD,kBAAiB,CAAC,CAAC;AACvD,yBAAW,YAAa,YAA8B;AAAA,YACxD;AACA,gBAAI,UAAU;AACZ,oBAAM,YAAY,oCAAoC,QAAQ;AAC9D,wBAAU,OAAO;AAAA,YACnB;AACA;AAAA,UACF;AAAA,QACF;AAAA,MACF,CAAC;AAAA,IACH;AAAA,IACA,CAAC,MAAM;AAAA,EACT;AAEA,QAAM,kBAAkBR;AAAA,IACtB,CAAC,UAAkB;AACjB,gBAAU,KAAK;AAEf,aAAO,OAAO,MAAM;AAClB,cAAM,YAAYM,gBAAc;AAChC,YAAI,CAAC,UAAW;AAEhB,cAAM,YAAY,CAAC,SAAwB;AACzC,eAAK,mBAAmB,SAAS,IAAI;AAAA,QACvC;AAEA,YAAIG,mBAAkB,SAAS,GAAG;AAChC,gBAAM,QAAQ,UAAU,SAAS;AACjC,qBAAW,QAAQ,OAAO;AACxB,gBAAID,kBAAiB,IAAI,GAAG;AAC1B,wBAAU,IAAI;AAAA,YAChB;AAAA,UACF;AAAA,QACF,WAAWD,oBAAkB,SAAS,GAAG;AACvC,gBAAM,WAAW;AAAA,YACf,UAAU,OAAO,QAAQ;AAAA,UAC3B;AACA,cAAI,UAAU;AACZ,sBAAU,QAAQ;AAAA,UACpB;AAAA,QACF;AAAA,MACF,CAAC;AAAA,IACH;AAAA,IACA,CAAC,MAAM;AAAA,EACT;AAEA,MAAI,CAAC,UAAU,CAAC,gBAAiB,QAAO;AAExC,SAAOF;AAAA,IACL,gBAAAK;AAAA,MAAC;AAAA;AAAA,QACC,KAAK;AAAA,QACL,eAAY;AAAA,QACZ,aAAa,CAAC,MAAM,EAAE,eAAe;AAAA,QACrC,OAAO;AAAA,UACL,UAAU;AAAA,UACV,QAAQ;AAAA,UACR,KAAK,GAAG,SAAS,GAAG;AAAA,UACpB,MAAM,GAAG,SAAS,IAAI;AAAA,UACtB,UAAU;AAAA,UACV,cAAc;AAAA,UACd,QAAQ;AAAA,UACR,iBAAiB;AAAA,UACjB,gBAAgB;AAAA,UAChB,sBAAsB;AAAA,UACtB,WAAW;AAAA,UACX,SAAS;AAAA,UACT,YACE;AAAA,QACJ;AAAA,QAEC,qBAAW,IAAI,CAAC,SAAS;AAExB,cAAI,KAAK,OAAO,iBAAiB,CAAC,kBAAmB,QAAO;AAE5D,cAAI,KAAK,OAAO,kBAAkB,CAAC,WAAY,QAAO;AAEtD,cAAI,KAAK,OAAO,cAAc;AAC5B,mBACE,gBAAAC,OAAC,SAAkB,OAAO,EAAE,UAAU,WAAW,GAC/C;AAAA,8BAAAA;AAAA,gBAAC;AAAA;AAAA,kBACC,MAAK;AAAA,kBACL,eAAY;AAAA,kBACZ,cAAc,MAAM,oBAAoB,IAAI;AAAA,kBAC5C,SAAS,MAAM,oBAAoB,CAAC,SAAS,CAAC,IAAI;AAAA,kBAClD,OAAO;AAAA,oBACL,SAAS;AAAA,oBACT,OAAO;AAAA,oBACP,YAAY;AAAA,oBACZ,gBAAgB;AAAA,oBAChB,KAAK;AAAA,oBACL,SAAS;AAAA,oBACT,cAAc;AAAA,oBACd,QAAQ;AAAA,oBACR,QAAQ;AAAA,oBACR,iBAAiB;AAAA,oBACjB,UAAU;AAAA,oBACV,OAAO;AAAA,kBACT;AAAA,kBAEA;AAAA,oCAAAD,MAAC,UAAM,eAAK,OAAM;AAAA,oBAClB,gBAAAA,MAAC,UAAK,OAAO,EAAE,UAAU,QAAQ,OAAO,gCAAgC,GACrE,oBACH;AAAA;AAAA;AAAA,cACF;AAAA,cAEC,oBACC,gBAAAA;AAAA,gBAAC;AAAA;AAAA,kBACC,OAAO;AAAA,oBACL,UAAU;AAAA,oBACV,KAAK;AAAA,oBACL,MAAM;AAAA,oBACN,YAAY;AAAA,oBACZ,cAAc;AAAA,oBACd,QAAQ;AAAA,oBACR,iBAAiB;AAAA,oBACjB,gBAAgB;AAAA,oBAChB,sBAAsB;AAAA,oBACtB,WAAW;AAAA,oBACX,SAAS;AAAA,oBACT,SAAS;AAAA,oBACT,UAAU;AAAA,oBACV,KAAK;AAAA,oBACL,OAAO;AAAA,kBACT;AAAA,kBAEC,yBAAe,IAAI,CAAC,UACnB,gBAAAA;AAAA,oBAAC;AAAA;AAAA,sBAEC,MAAK;AAAA,sBACL,OAAO,MAAM;AAAA,sBACb,eAAa,oBAAoB,MAAM,MAAM,YAAY,CAAC;AAAA,sBAC1D,aAAa,CAAC,MAAM;AAClB,0BAAE,eAAe;AACjB,wCAAgB,MAAM,KAAK;AAAA,sBAC7B;AAAA,sBACA,OAAO;AAAA,wBACL,OAAO;AAAA,wBACP,QAAQ;AAAA,wBACR,cAAc;AAAA,wBACd,QACE,kBAAkB,MAAM,SACvB,CAAC,iBAAiB,MAAM,UAAU,KAC/B,8CACA;AAAA,wBACN,QAAQ;AAAA,wBACR,iBACE,MAAM,WAAW,gBACb,gBACA,MAAM;AAAA,wBACZ,SAAS;AAAA,wBACT,YAAY;AAAA,wBACZ,gBAAgB;AAAA,sBAClB;AAAA,sBAEC,gBAAM,WAAW,iBAChB,gBAAAA;AAAA,wBAAC;AAAA;AAAA,0BACC,OAAO;AAAA,4BACL,UAAU;AAAA,4BACV,OAAO;AAAA,0BACT;AAAA,0BAEC;AAAA;AAAA,sBACH;AAAA;AAAA,oBAnCG,MAAM;AAAA,kBAqCb,CACD;AAAA;AAAA,cACH;AAAA,iBAxFM,KAAK,EA0Ff;AAAA,UAEJ;AAGA,gBAAM,UAAU,KAAK,OAAO;AAE5B,iBACE,gBAAAC,OAAC,SACE;AAAA,uBACC,gBAAAD;AAAA,cAAC;AAAA;AAAA,gBACC,OAAO;AAAA,kBACL,QAAQ;AAAA,kBACR,iBAAiB;AAAA,kBACjB,QAAQ;AAAA,gBACV;AAAA;AAAA,YACF;AAAA,YAEF,gBAAAA;AAAA,cAAC;AAAA;AAAA,gBACC,MAAK;AAAA,gBACL,eAAa,gBAAgB,KAAK,EAAE;AAAA,gBACpC,aAAa,CAAC,MAAM;AAClB,oBAAE,eAAe;AACjB,+BAAa,KAAK,EAAgB;AAAA,gBACpC;AAAA,gBACA,cAAc,MAAM,oBAAoB,KAAK;AAAA,gBAC7C,OAAO;AAAA,kBACL,SAAS;AAAA,kBACT,OAAO;AAAA,kBACP,YAAY;AAAA,kBACZ,KAAK;AAAA,kBACL,SAAS;AAAA,kBACT,cAAc;AAAA,kBACd,QAAQ;AAAA,kBACR,QAAQ;AAAA,kBACR,iBAAiB;AAAA,kBACjB,UAAU;AAAA,kBACV,OAAO,KAAK,SACR,yCACA;AAAA,gBACN;AAAA,gBAEC,eAAK;AAAA;AAAA,YACR;AAAA,eAnCQ,KAAK,EAoCf;AAAA,QAEJ,CAAC;AAAA;AAAA,IACH;AAAA,IACA;AAAA,EACF;AACF;;;ACzaA,SAAS,aAAAE,aAAW,UAAAC,UAAQ,YAAAC,YAAU,eAAAC,qBAAmB;AACzD,SAAS,6BAAAC,mCAAiC;AAC1C,SAAS,gBAAAC,sBAAoB;AAC7B;AAAA,EACE;AAAA,EACA;AAAA,EACA,iBAAAC;AAAA,EAGA;AAAA,OACK;AACP;AAAA,EACE,gBAAAC;AAAA,EACA,mBAAAC;AAAA,EACA,oBAAAC;AAAA,EACA,8BAAAC;AAAA,EACA,iCAAAC;AAAA,EACA,8BAAAC;AAAA,EACA,iCAAAC;AAAA,OACK;AA+rBH,SA0MQ,YAAAC,WA1MR,OAAAC,OA8KI,QAAAC,cA9KJ;AAnrBG,SAAS,oBAAoB;AAClC,QAAM,CAAC,MAAM,IAAIZ,4BAA0B;AAC3C,QAAM,CAAC,iBAAiB,kBAAkB,IAAIF,WAA6B,IAAI;AAC/E,QAAM,CAAC,MAAM,OAAO,IAAIA,WAA2B,IAAI;AAGvD,QAAM,iBAAiBD,SAAgC,IAAI;AAC3D,QAAM,oBAAoBA,SAAsB,IAAI;AAGpD,QAAM,gBAAgBA,SAAuB,IAAI;AACjD,QAAM,gBAAgBA,SAAuB,IAAI;AACjD,QAAM,eAAeA,SAAuB,IAAI;AAChD,QAAM,eAAeA,SAAuB,IAAI;AAChD,QAAM,eAAeA,SAAuB,IAAI;AAChD,QAAM,kBAAkBA,SAAuB,IAAI;AACnD,QAAM,iBAAiBA,SAAuB,IAAI;AAGlD,QAAM,cAAcA,SAOV,IAAI;AAGd,QAAM,aAAaA,SAAO,KAAK;AAE/B,EAAAD,YAAU,MAAM;AACd,QAAI,OAAO,WAAW,YAAa;AACnC,eAAW,UAAU,OAAO,WAAW,mBAAmB,EAAE;AAC5D,uBAAmB,SAAS,IAAI;AAAA,EAClC,GAAG,CAAC,CAAC;AAEL,QAAM,UAAUG,cAAY,MAAM;AAChC,UAAM,MAAM;AAAA,MACV,cAAc;AAAA,MACd,cAAc;AAAA,MACd,aAAa;AAAA,MACb,aAAa;AAAA,MACb,aAAa;AAAA,MACb,gBAAgB;AAAA,IAClB;AACA,eAAW,MAAM,KAAK;AACpB,UAAI,GAAI,IAAG,MAAM,aAAa;AAAA,IAChC;AAAA,EACF,GAAG,CAAC,CAAC;AAEL,QAAM,kBAAkBA,cAAY,CAAC,UAAsC;AACzE,UAAM,WAAW,MAAM,KAAK,CAAC;AAC7B,QAAI,CAAC,SAAU,QAAO,CAAC;AACvB,UAAM,SAAmB,CAAC;AAC1B,aAAS,IAAI,GAAG,IAAI,SAAS,MAAM,QAAQ,KAAK;AAC9C,aAAO,KAAK,SAAS,MAAM,CAAC,EAAG,WAAW;AAAA,IAC5C;AACA,WAAO;AAAA,EACT,GAAG,CAAC,CAAC;AAEL,QAAM,aAAaA;AAAA,IACjB,CAAC,UAAkB,aAAqB;AACtC,YAAM,MAAM,kBAAkB;AAC9B,UAAI,CAAC,IAAK;AAEV,aAAO,OAAO,MAAM;AAClB,cAAM,YAAYG,gBAAc,GAAG;AACnC,YAAI,CAAC,aAAa,CAACC,cAAa,SAAS,EAAG;AAC5C,cAAM,OAAO,UAAU,YAAY,EAAE,OAAOC,gBAAe;AAC3D,cAAM,MAAM,KAAK,QAAQ;AACzB,YAAI,CAAC,IAAK;AACV,cAAM,QAAQ,IAAI,YAAY,EAAE,OAAOC,iBAAgB;AACvD,cAAM,OAAO,MAAM,QAAQ;AAC3B,YAAI,CAAC,KAAM;AACX,aAAK,UAAU;AAAA,MACjB,CAAC;AAAA,IACH;AAAA,IACA,CAAC,MAAM;AAAA,EACT;AAEA,QAAM,cAAcN;AAAA,IAClB,CAAC,UAAkB,UAAmB;AACpC,YAAM,MAAM,kBAAkB;AAC9B,UAAI,CAAC,IAAK;AAEV,aAAO,OAAO,MAAM;AAClB,cAAM,YAAYG,gBAAc,GAAG;AACnC,YAAI,CAAC,aAAa,CAACC,cAAa,SAAS,EAAG;AAE5C,cAAM,OAAO,UAAU,YAAY,EAAE,OAAOC,gBAAe;AAC3D,cAAM,YAAY,KAAK,QAAQ;AAC/B,YAAI,CAAC,UAAW;AAChB,cAAM,QAAQ,UAAU,YAAY,EAAE,OAAOC,iBAAgB;AAC7D,cAAM,OAAO,MAAM,CAAC;AACpB,YAAI,CAAC,KAAM;AAEX,aAAK,UAAU;AACf,QAAAC,4BAA2B,KAAK;AAAA,MAClC,CAAC;AACD,aAAO,MAAM;AAAA,IACf;AAAA,IACA,CAAC,MAAM;AAAA,EACT;AAEA,QAAM,cAAcP;AAAA,IAClB,CAAC,UAAkB,UAAmB;AACpC,YAAM,MAAM,kBAAkB;AAC9B,UAAI,CAAC,IAAK;AAEV,aAAO,OAAO,MAAM;AAClB,cAAM,YAAYG,gBAAc,GAAG;AACnC,YAAI,CAAC,aAAa,CAACC,cAAa,SAAS,EAAG;AAE5C,cAAM,OAAO,UAAU,YAAY,EAAE,OAAOC,gBAAe;AAC3D,cAAM,WAAW,KAAK,CAAC;AACvB,YAAI,CAAC,SAAU;AACf,cAAM,QAAQ,SAAS,YAAY,EAAE,OAAOC,iBAAgB;AAC5D,cAAM,OAAO,MAAM,QAAQ;AAC3B,YAAI,CAAC,KAAM;AAEX,aAAK,UAAU;AACf,QAAAE,+BAA8B,KAAK;AAAA,MACrC,CAAC;AACD,aAAO,MAAM;AAAA,IACf;AAAA,IACA,CAAC,MAAM;AAAA,EACT;AAEA,QAAM,cAAcR;AAAA,IAClB,CAAC,aAAqB;AACpB,YAAM,MAAM,kBAAkB;AAC9B,UAAI,CAAC,IAAK;AAEV,aAAO,OAAO,MAAM;AAClB,cAAM,YAAYG,gBAAc,GAAG;AACnC,YAAI,CAAC,aAAa,CAACC,cAAa,SAAS,EAAG;AAE5C,cAAM,OAAO,UAAU,YAAY,EAAE,OAAOC,gBAAe;AAE3D,YAAI,KAAK,UAAU,EAAG;AAEtB,cAAM,YAAY,KAAK,QAAQ;AAC/B,YAAI,CAAC,UAAW;AAChB,cAAM,QAAQ,UAAU,YAAY,EAAE,OAAOC,iBAAgB;AAC7D,cAAM,OAAO,MAAM,CAAC;AACpB,YAAI,CAAC,KAAM;AAEX,aAAK,UAAU;AACf,QAAAG,4BAA2B;AAAA,MAC7B,CAAC;AACD,aAAO,MAAM;AAAA,IACf;AAAA,IACA,CAAC,MAAM;AAAA,EACT;AAEA,QAAM,cAAcT;AAAA,IAClB,CAAC,aAAqB;AACpB,YAAM,MAAM,kBAAkB;AAC9B,UAAI,CAAC,IAAK;AAEV,aAAO,OAAO,MAAM;AAClB,cAAM,YAAYG,gBAAc,GAAG;AACnC,YAAI,CAAC,aAAa,CAACC,cAAa,SAAS,EAAG;AAE5C,cAAM,OAAO,UAAU,YAAY,EAAE,OAAOC,gBAAe;AAC3D,cAAM,WAAW,KAAK,CAAC;AACvB,YAAI,CAAC,SAAU;AACf,cAAM,QAAQ,SAAS,YAAY,EAAE,OAAOC,iBAAgB;AAE5D,YAAI,MAAM,UAAU,EAAG;AAEvB,cAAM,OAAO,MAAM,QAAQ;AAC3B,YAAI,CAAC,KAAM;AAEX,aAAK,UAAU;AACf,QAAAI,+BAA8B;AAAA,MAChC,CAAC;AACD,aAAO,MAAM;AAAA,IACf;AAAA,IACA,CAAC,MAAM;AAAA,EACT;AAEA,QAAM,cAAcV,cAAY,MAAM;AACpC,UAAM,MAAM,kBAAkB;AAC9B,QAAI,CAAC,IAAK;AAEV,WAAO,OAAO,MAAM;AAClB,YAAM,gBAAgB,qBAAqB;AAC3C,oBAAc,IAAI,GAAG;AACrB,oBAAc,aAAa;AAAA,IAC7B,CAAC;AACD,WAAO,MAAM;AAAA,EACf,GAAG,CAAC,MAAM,CAAC;AAEX,QAAM,kBAAkBA;AAAA,IACtB,CAAC,SAA2B,cAAuB;AACjD,YAAM,YAAY,cAAc;AAChC,UAAI,CAAC,UAAW;AAEhB,gBAAU,MAAM,aAAa;AAG7B,YAAM,UAAoB,CAAC;AAC3B,eAAS,IAAI,GAAG,IAAI,QAAQ,KAAK,QAAQ,KAAK;AAC5C,cAAM,MAAM,QAAQ,KAAK,CAAC;AAC1B,cAAM,UAAU,IAAI,sBAAsB;AAC1C,gBAAQ;AAAA,UACN,yBAAyB,CAAC;AAAA;AAAA,kBAElB,QAAQ,GAAG;AAAA,mBACV,UAAU,OAAO,EAAE;AAAA;AAAA,qBAEjB,QAAQ,MAAM;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,QAc3B;AAAA,MACF;AACA,gBAAU,YAAY,QAAQ,KAAK,EAAE;AAGrC,YAAM,YAAY,UAAU,iBAAiB,mBAAmB;AAChE,gBAAU,QAAQ,CAAC,OAAO;AACxB,cAAM,SAAS;AACf,eAAO,iBAAiB,cAAc,MAAM;AAC1C,iBAAO,MAAM,kBAAkB;AAC/B,iBAAO,MAAM,QAAQ;AAAA,QACvB,CAAC;AACD,eAAO,iBAAiB,cAAc,MAAM;AAC1C,iBAAO,MAAM,kBAAkB;AAC/B,iBAAO,MAAM,QAAQ;AAAA,QACvB,CAAC;AACD,eAAO,iBAAiB,aAAa,CAAC,MAAM;AAC1C,YAAE,eAAe;AACjB,YAAE,gBAAgB;AAClB,gBAAM,MAAM,SAAS,OAAO,QAAQ,aAAa,KAAK,EAAE;AACxD,gBAAM,OAAO,OAAO,sBAAsB;AAC1C,kBAAQ;AAAA,YACN,MAAM;AAAA,YACN,KAAK,KAAK;AAAA,YACV,MAAM,KAAK,OAAO;AAAA,YAClB,OAAO;AAAA,UACT,CAAC;AAAA,QACH,CAAC;AAAA,MACH,CAAC;AAAA,IACH;AAAA,IACA,CAAC;AAAA,EACH;AAEA,QAAM,kBAAkBA;AAAA,IACtB,CAAC,SAA2B,cAAuB;AACjD,YAAM,YAAY,cAAc;AAChC,UAAI,CAAC,UAAW;AAEhB,gBAAU,MAAM,aAAa;AAE7B,YAAM,WAAW,QAAQ,KAAK,CAAC;AAC/B,UAAI,CAAC,SAAU;AAEf,YAAM,UAAoB,CAAC;AAC3B,eAAS,IAAI,GAAG,IAAI,SAAS,MAAM,QAAQ,KAAK;AAC9C,cAAM,OAAO,SAAS,MAAM,CAAC;AAC7B,cAAM,WAAW,KAAK,sBAAsB;AAC5C,gBAAQ;AAAA,UACN,yBAAyB,CAAC;AAAA;AAAA,kBAElB,UAAU,MAAM,EAAE;AAAA,mBACjB,SAAS,IAAI;AAAA,oBACZ,SAAS,KAAK;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,QAe1B;AAAA,MACF;AACA,gBAAU,YAAY,QAAQ,KAAK,EAAE;AAGrC,YAAM,YAAY,UAAU,iBAAiB,mBAAmB;AAChE,gBAAU,QAAQ,CAAC,OAAO;AACxB,cAAM,SAAS;AACf,eAAO,iBAAiB,cAAc,MAAM;AAC1C,iBAAO,MAAM,kBAAkB;AAC/B,iBAAO,MAAM,QAAQ;AAAA,QACvB,CAAC;AACD,eAAO,iBAAiB,cAAc,MAAM;AAC1C,iBAAO,MAAM,kBAAkB;AAC/B,iBAAO,MAAM,QAAQ;AAAA,QACvB,CAAC;AACD,eAAO,iBAAiB,aAAa,CAAC,MAAM;AAC1C,YAAE,eAAe;AACjB,YAAE,gBAAgB;AAClB,gBAAM,MAAM,SAAS,OAAO,QAAQ,aAAa,KAAK,EAAE;AACxD,gBAAM,OAAO,OAAO,sBAAsB;AAC1C,kBAAQ;AAAA,YACN,MAAM;AAAA,YACN,KAAK,KAAK,MAAM;AAAA,YAChB,MAAM,KAAK;AAAA,YACX,OAAO;AAAA,UACT,CAAC;AAAA,QACH,CAAC;AAAA,MACH,CAAC;AAAA,IACH;AAAA,IACA,CAAC;AAAA,EACH;AAEA,EAAAH,YAAU,MAAM;AACd,QAAI,WAAW,QAAS;AAExB,UAAM,kBAAkB,CAAC,MAAkB;AAEzC,UAAI,YAAY,QAAS;AAEzB,YAAM,SAAS,EAAE;AAGjB,UAAI,OAAO,QAAQ,4BAA4B,EAAG;AAElD,YAAM,UAAU,OAAO,QAAQ,OAAO;AAEtC,UAAI,CAAC,SAAS;AAEZ,cAAM,SAAS,eAAe;AAC9B,YAAI,QAAQ;AACV,gBAAMiB,KAAI,OAAO,sBAAsB;AACvC,gBAAM,SAAS;AACf,cACE,EAAE,WAAWA,GAAE,OAAO,UACtB,EAAE,WAAWA,GAAE,QAAQ,UACvB,EAAE,WAAWA,GAAE,MAAM,UACrB,EAAE,WAAWA,GAAE,SAAS,QACxB;AACA;AAAA,UACF;AAAA,QACF;AACA,uBAAe,UAAU;AACzB,0BAAkB,UAAU;AAC5B,gBAAQ,IAAI;AACZ,gBAAQ;AACR;AAAA,MACF;AAGA,UAAI,WAA0B;AAC9B,aAAO,KAAK,MAAM;AAChB,cAAM,UAAU,2BAA2B,OAAO;AAClD,YAAI,WAAWV,cAAa,OAAO,GAAG;AACpC,qBAAW,QAAQ,OAAO;AAAA,QAC5B,OAAO;AACL,gBAAM,SAAS,QAAQ;AACvB,cAAI,QAAQ;AACV,kBAAM,aAAa,2BAA2B,MAAM;AACpD,gBAAI,cAAcA,cAAa,UAAU,GAAG;AAC1C,yBAAW,WAAW,OAAO;AAAA,YAC/B;AAAA,UACF;AAAA,QACF;AAAA,MACF,CAAC;AAED,UAAI,CAAC,UAAU;AACb,gBAAQ;AACR;AAAA,MACF;AAGA,UAAI,eAAe,YAAY,SAAS;AACtC,cAAMU,KAAI,QAAQ,sBAAsB;AACxC,6BAAqB,GAAG,SAASA,EAAC;AAClC;AAAA,MACF;AAEA,qBAAe,UAAU;AACzB,wBAAkB,UAAU;AAE5B,YAAM,IAAI,QAAQ,sBAAsB;AAGxC,sBAAgB,SAAS,CAAC;AAG1B,sBAAgB,SAAS,CAAC;AAG1B,UAAI,aAAa,SAAS;AACxB,cAAM,MAAM,aAAa;AACzB,YAAI,MAAM,aAAa;AACvB,YAAI,MAAM,MAAM,GAAG,EAAE,SAAS,CAAC;AAC/B,YAAI,MAAM,OAAO,GAAG,EAAE,IAAI;AAC1B,YAAI,MAAM,QAAQ,GAAG,EAAE,KAAK;AAAA,MAC9B;AAGA,UAAI,aAAa,SAAS;AACxB,cAAM,MAAM,aAAa;AACzB,YAAI,MAAM,aAAa;AACvB,YAAI,MAAM,MAAM,GAAG,EAAE,GAAG;AACxB,YAAI,MAAM,OAAO,GAAG,EAAE,QAAQ,CAAC;AAC/B,YAAI,MAAM,SAAS,GAAG,EAAE,MAAM;AAAA,MAChC;AAGA,UAAI,aAAa,SAAS;AACxB,cAAM,OAAO,aAAa;AAC1B,aAAK,MAAM,aAAa;AACxB,aAAK,MAAM,MAAM,GAAG,EAAE,MAAM,EAAE;AAC9B,aAAK,MAAM,OAAO,GAAG,EAAE,OAAO,EAAE;AAAA,MAClC;AAGA,2BAAqB,GAAG,SAAS,CAAC;AAAA,IACpC;AAEA,UAAM,uBAAuB,CAC3B,GACA,SACA,MACG;AACH,YAAM,SAAS,gBAAgB;AAC/B,UAAI,CAAC,OAAQ;AAEb,YAAM,WAAW,QAAQ,KAAK,CAAC;AAC/B,UAAI,CAAC,SAAU;AAEf,eAAS,IAAI,GAAG,IAAI,SAAS,MAAM,SAAS,GAAG,KAAK;AAClD,cAAM,OAAO,SAAS,MAAM,CAAC;AAC7B,cAAM,WAAW,KAAK,sBAAsB;AAC5C,cAAM,UAAU,SAAS;AAEzB,YAAI,KAAK,IAAI,EAAE,UAAU,OAAO,IAAI,IAAI;AACtC,iBAAO,MAAM,aAAa;AAC1B,iBAAO,MAAM,MAAM,GAAG,EAAE,GAAG;AAC3B,iBAAO,MAAM,OAAO,GAAG,UAAU,CAAC;AAClC,iBAAO,MAAM,SAAS,GAAG,EAAE,MAAM;AACjC,iBAAO,QAAQ,cAAc,OAAO,CAAC;AACrC;AAAA,QACF;AAAA,MACF;AAEA,aAAO,MAAM,aAAa;AAAA,IAC5B;AAEA,QAAI,aAAa;AACjB,QAAI,eAAkC;AAEtC,UAAM,qBAAqB,CAAC,MAAkB;AAC5C,qBAAe;AACf,UAAI,eAAe,GAAG;AACpB,qBAAa,sBAAsB,MAAM;AACvC,uBAAa;AACb,cAAI,cAAc;AAChB,4BAAgB,YAAY;AAAA,UAC9B;AAAA,QACF,CAAC;AAAA,MACH;AAAA,IACF;AAEA,aAAS,iBAAiB,aAAa,kBAAkB;AACzD,WAAO,MAAM;AACX,eAAS,oBAAoB,aAAa,kBAAkB;AAC5D,UAAI,WAAY,sBAAqB,UAAU;AAAA,IACjD;AAAA,EACF,GAAG,CAAC,QAAQ,SAAS,iBAAiB,eAAe,CAAC;AAEtD,EAAAjB,YAAU,MAAM;AACd,QAAI,WAAW,QAAS;AAExB,UAAM,SAAS,gBAAgB;AAC/B,QAAI,CAAC,OAAQ;AAEb,UAAM,cAAc,CAAC,MAAkB;AACrC,QAAE,eAAe;AACjB,QAAE,gBAAgB;AAElB,YAAM,UAAU,eAAe;AAC/B,YAAM,WAAW,kBAAkB;AACnC,UAAI,CAAC,WAAW,CAAC,SAAU;AAE3B,YAAM,WAAW,SAAS,OAAO,QAAQ,eAAe,KAAK,EAAE;AAC/D,YAAM,YAAY,gBAAgB,OAAO;AACzC,YAAM,aAAa,UAAU,QAAQ,KAAK;AAE1C,kBAAY,UAAU;AAAA,QACpB,aAAa;AAAA,QACb,QAAQ,EAAE;AAAA,QACV;AAAA,QACA,WAAW,CAAC,GAAG,SAAS;AAAA,QACxB,cAAc;AAAA,QACd,cAAc;AAAA,MAChB;AAEA,eAAS,KAAK,MAAM,SAAS;AAC7B,eAAS,KAAK,MAAM,aAAa;AAEjC,UAAI,eAAe,SAAS;AAC1B,cAAM,IAAI,QAAQ,sBAAsB;AACxC,cAAM,QAAQ,eAAe;AAC7B,cAAM,MAAM,aAAa;AACzB,cAAM,MAAM,MAAM,GAAG,EAAE,GAAG;AAC1B,cAAM,MAAM,SAAS,GAAG,EAAE,MAAM;AAChC,cAAM,MAAM,OAAO,GAAG,EAAE,OAAO;AAAA,MACjC;AAAA,IACF;AAEA,UAAM,cAAc,CAAC,MAAkB;AACrC,UAAI,CAAC,YAAY,QAAS;AAE1B,YAAM,EAAE,aAAa,QAAQ,YAAY,WAAW,aAAa,IAC/D,YAAY;AACd,YAAM,QAAQ,EAAE,UAAU;AAC1B,YAAM,WAAW,KAAK,IAAI,IAAI,aAAa,KAAK;AAChD,gBAAU,WAAW,IAAI;AAEzB,YAAM,OAAO,aAAa,iBAAiB,cAAc;AACzD,YAAM,MAAM,KAAK,WAAW;AAC5B,UAAI,KAAK;AACP,YAAI,MAAM,QAAQ,GAAG,QAAQ;AAAA,MAC/B;AAEA,UAAI,eAAe,SAAS;AAC1B,uBAAe,QAAQ,MAAM,OAAO,GAAG,EAAE,OAAO;AAAA,MAClD;AAAA,IACF;AAEA,UAAM,YAAY,MAAM;AACtB,UAAI,CAAC,YAAY,QAAS;AAE1B,YAAM,EAAE,WAAW,aAAa,IAAI,YAAY;AAEhD,aAAO,OAAO,MAAM;AAClB,cAAM,YAAYM,gBAAc,YAAY;AAC5C,YAAI,aAAaC,cAAa,SAAS,GAAG;AACxC,oBAAU,UAAU,EAAE,aAAa,SAAS;AAAA,QAC9C;AAAA,MACF,CAAC;AAED,kBAAY,UAAU;AACtB,eAAS,KAAK,MAAM,SAAS;AAC7B,eAAS,KAAK,MAAM,aAAa;AAEjC,UAAI,eAAe,SAAS;AAC1B,uBAAe,QAAQ,MAAM,aAAa;AAAA,MAC5C;AAGA,YAAM,UAAU,eAAe;AAC/B,UAAI,SAAS;AACX,cAAM,IAAI,QAAQ,sBAAsB;AACxC,wBAAgB,SAAS,CAAC;AAAA,MAC5B;AAAA,IACF;AAEA,WAAO,iBAAiB,aAAa,WAAW;AAChD,aAAS,iBAAiB,aAAa,WAAW;AAClD,aAAS,iBAAiB,WAAW,SAAS;AAE9C,WAAO,MAAM;AACX,aAAO,oBAAoB,aAAa,WAAW;AACnD,eAAS,oBAAoB,aAAa,WAAW;AACrD,eAAS,oBAAoB,WAAW,SAAS;AACjD,eAAS,KAAK,MAAM,SAAS;AAC7B,eAAS,KAAK,MAAM,aAAa;AAAA,IACnC;AAAA,EACF,GAAG,CAAC,QAAQ,iBAAiB,iBAAiB,eAAe,CAAC;AAE9D,EAAAP,YAAU,MAAM;AACd,QAAI,CAAC,KAAM;AAEX,UAAM,cAAc,CAAC,MAAkB;AACrC,YAAM,SAAS,SAAS,cAAc,2BAA2B;AACjE,UAAI,UAAU,CAAC,OAAO,SAAS,EAAE,MAAc,GAAG;AAChD,gBAAQ,IAAI;AAAA,MACd;AAAA,IACF;AAEA,UAAM,YAAY,CAAC,MAAqB;AACtC,UAAI,EAAE,QAAQ,SAAU,SAAQ,IAAI;AAAA,IACtC;AAEA,aAAS,iBAAiB,aAAa,WAAW;AAClD,aAAS,iBAAiB,WAAW,SAAS;AAC9C,WAAO,MAAM;AACX,eAAS,oBAAoB,aAAa,WAAW;AACrD,eAAS,oBAAoB,WAAW,SAAS;AAAA,IACnD;AAAA,EACF,GAAG,CAAC,IAAI,CAAC;AAET,MAAI,CAAC,mBAAmB,WAAW,QAAS,QAAO;AAEnD,QAAM,mBAAmB,CAAC,WAAmB;AAC3C,QAAI,CAAC,KAAM;AACX,UAAM,EAAE,MAAM,MAAM,IAAI;AACxB,YAAQ,IAAI;AAEZ,YAAQ,QAAQ;AAAA,MACd,KAAK;AACH,oBAAY,OAAO,KAAK;AACxB;AAAA,MACF,KAAK;AACH,oBAAY,OAAO,IAAI;AACvB;AAAA,MACF,KAAK;AACH,oBAAY,KAAK;AACjB;AAAA,MACF,KAAK;AACH,oBAAY,OAAO,KAAK;AACxB;AAAA,MACF,KAAK;AACH,oBAAY,OAAO,IAAI;AACvB;AAAA,MACF,KAAK;AACH,oBAAY,KAAK;AACjB;AAAA,IACJ;AAAA,EACF;AAEA,QAAM,iBAAsC;AAAA,IAC1C,UAAU;AAAA,IACV,SAAS;AAAA,IACT,YAAY;AAAA,IACZ,gBAAgB;AAAA,IAChB,QAAQ;AAAA,IACR,QAAQ;AAAA,IACR,YAAY;AAAA,IACZ,cAAc;AAAA,IACd,QAAQ;AAAA,IACR,iBAAiB;AAAA,IACjB,OAAO;AAAA,IACP,UAAU;AAAA,IACV,YAAY;AAAA,IACZ,YAAY;AAAA,EACd;AAEA,QAAM,gBAAqC;AAAA,IACzC,SAAS;AAAA,IACT,OAAO;AAAA,IACP,YAAY;AAAA,IACZ,KAAK;AAAA,IACL,SAAS;AAAA,IACT,cAAc;AAAA,IACd,QAAQ;AAAA,IACR,QAAQ;AAAA,IACR,iBAAiB;AAAA,IACjB,UAAU;AAAA,IACV,OAAO;AAAA,EACT;AAEA,QAAM,mBAAwC;AAAA,IAC5C,UAAU;AAAA,IACV,UAAU;AAAA,IACV,cAAc;AAAA,IACd,QAAQ;AAAA,IACR,iBAAiB;AAAA,IACjB,gBAAgB;AAAA,IAChB,sBAAsB;AAAA,IACtB,WAAW;AAAA,IACX,SAAS;AAAA,IACT,QAAQ;AAAA,IACR,YACE;AAAA,EACJ;AAEA,QAAM,aAAa,CAAC;AAAA,IAClB;AAAA,IACA;AAAA,IACA;AAAA,EACF,MAKE,gBAAAe;AAAA,IAAC;AAAA;AAAA,MACC,MAAK;AAAA,MACL,aAAa,CAAC,MAAM;AAClB,UAAE,eAAe;AACjB,yBAAiB,MAAM;AAAA,MACzB;AAAA,MACA,OAAO;AAAA,QACL,GAAG;AAAA,QACH,GAAI,cAAc,EAAE,OAAO,uCAAuC,IAAI,CAAC;AAAA,MACzE;AAAA,MACA,cAAc,CAAC,MAAM;AACnB,UAAE,cAAc,MAAM,kBAAkB;AAAA,MAC1C;AAAA,MACA,cAAc,CAAC,MAAM;AACnB,UAAE,cAAc,MAAM,kBAAkB;AAAA,MAC1C;AAAA,MAEC;AAAA;AAAA,EACH;AAGF,QAAM,YAAY,MAChB,gBAAAA;AAAA,IAAC;AAAA;AAAA,MACC,OAAO;AAAA,QACL,QAAQ;AAAA,QACR,iBAAiB;AAAA,QACjB,QAAQ;AAAA,MACV;AAAA;AAAA,EACF;AAGF,SAAOV;AAAA,IACL,gBAAAW,OAAC,SAAI,4BAAwB,MAE3B;AAAA,sBAAAD,MAAC,SAAI,KAAK,eAAe,OAAO,EAAE,YAAY,SAAS,GAAG;AAAA,MAG1D,gBAAAA,MAAC,SAAI,KAAK,eAAe,OAAO,EAAE,YAAY,SAAS,GAAG;AAAA,MAG1D,gBAAAA;AAAA,QAAC;AAAA;AAAA,UACC,KAAK;AAAA,UACL,OAAO;AAAA,YACL,UAAU;AAAA,YACV,OAAO;AAAA,YACP,QAAQ;AAAA,YACR,QAAQ;AAAA,YACR,YAAY;AAAA,YACZ,iBAAiB;AAAA,YACjB,YAAY;AAAA,UACd;AAAA,UACA,cAAc,CAAC,MAAM;AACnB,YAAC,EAAE,cAAiC,MAAM,kBACxC;AAAA,UACJ;AAAA,UACA,cAAc,CAAC,MAAM;AACnB,gBAAI,CAAC,YAAY,SAAS;AACxB,cAAC,EAAE,cAAiC,MAAM,kBACxC;AAAA,YACJ;AAAA,UACF;AAAA;AAAA,MACF;AAAA,MAGA,gBAAAA;AAAA,QAAC;AAAA;AAAA,UACC,KAAK;AAAA,UACL,OAAO;AAAA,YACL,UAAU;AAAA,YACV,OAAO;AAAA,YACP,iBAAiB;AAAA,YACjB,SAAS;AAAA,YACT,QAAQ;AAAA,YACR,YAAY;AAAA,YACZ,eAAe;AAAA,UACjB;AAAA;AAAA,MACF;AAAA,MAGA,gBAAAA;AAAA,QAAC;AAAA;AAAA,UACC,KAAK;AAAA,UACL,aAAa,CAAC,MAAM,EAAE,eAAe;AAAA,UACrC,SAAS,MAAM;AACb,kBAAM,QAAQ,eAAe;AAC7B,gBAAI,CAAC,MAAO;AACZ,kBAAM,aAAa,MAAM,KAAK,SAAS;AACvC,gBAAI,cAAc,EAAG,aAAY,YAAY,IAAI;AAAA,UACnD;AAAA,UACA,cAAc,CAAC,MAAM;AACnB,kBAAM,KAAK,EAAE;AACb,eAAG,MAAM,kBAAkB;AAC3B,eAAG,MAAM,QAAQ;AACjB,eAAG,MAAM,cAAc;AAAA,UACzB;AAAA,UACA,cAAc,CAAC,MAAM;AACnB,kBAAM,KAAK,EAAE;AACb,eAAG,MAAM,kBAAkB;AAC3B,eAAG,MAAM,QAAQ;AACjB,eAAG,MAAM,cAAc;AAAA,UACzB;AAAA,UACA,OAAO;AAAA,YACL,GAAG;AAAA,YACH,QAAQ;AAAA,UACV;AAAA,UACD;AAAA;AAAA,MAED;AAAA,MAGA,gBAAAA;AAAA,QAAC;AAAA;AAAA,UACC,KAAK;AAAA,UACL,aAAa,CAAC,MAAM,EAAE,eAAe;AAAA,UACrC,SAAS,MAAM;AACb,kBAAM,QAAQ,eAAe;AAC7B,gBAAI,CAAC,MAAO;AACZ,kBAAM,WAAW,MAAM,KAAK,CAAC;AAC7B,gBAAI,CAAC,SAAU;AACf,kBAAM,aAAa,SAAS,MAAM,SAAS;AAC3C,gBAAI,cAAc,EAAG,aAAY,YAAY,IAAI;AAAA,UACnD;AAAA,UACA,cAAc,CAAC,MAAM;AACnB,kBAAM,KAAK,EAAE;AACb,eAAG,MAAM,kBAAkB;AAC3B,eAAG,MAAM,QAAQ;AACjB,eAAG,MAAM,cAAc;AAAA,UACzB;AAAA,UACA,cAAc,CAAC,MAAM;AACnB,kBAAM,KAAK,EAAE;AACb,eAAG,MAAM,kBAAkB;AAC3B,eAAG,MAAM,QAAQ;AACjB,eAAG,MAAM,cAAc;AAAA,UACzB;AAAA,UACA,OAAO;AAAA,YACL,GAAG;AAAA,YACH,OAAO;AAAA,UACT;AAAA,UACD;AAAA;AAAA,MAED;AAAA,MAGA,gBAAAA;AAAA,QAAC;AAAA;AAAA,UACC,KAAK;AAAA,UACL,OAAM;AAAA,UACN,aAAa,CAAC,MAAM;AAClB,cAAE,eAAe;AACjB,wBAAY;AAAA,UACd;AAAA,UACA,OAAO;AAAA,YACL,UAAU;AAAA,YACV,OAAO;AAAA,YACP,QAAQ;AAAA,YACR,SAAS;AAAA,YACT,YAAY;AAAA,YACZ,gBAAgB;AAAA,YAChB,cAAc;AAAA,YACd,QAAQ;AAAA,YACR,OAAO;AAAA,YACP,iBAAiB;AAAA,YACjB,QAAQ;AAAA,YACR,YAAY;AAAA,YACZ,YAAY;AAAA,YACZ,UAAU;AAAA,UACZ;AAAA,UACA,cAAc,CAAC,MAAM;AACnB,kBAAM,KAAK,EAAE;AACb,eAAG,MAAM,kBAAkB;AAC3B,eAAG,MAAM,QAAQ;AAAA,UACnB;AAAA,UACA,cAAc,CAAC,MAAM;AACnB,kBAAM,KAAK,EAAE;AACb,eAAG,MAAM,kBAAkB;AAC3B,eAAG,MAAM,QAAQ;AAAA,UACnB;AAAA,UAEA,0BAAAC,OAAC,SAAI,OAAM,MAAK,QAAO,MAAK,SAAQ,aAAY,MAAK,gBACnD;AAAA,4BAAAD,MAAC,YAAO,IAAG,KAAI,IAAG,KAAI,GAAE,OAAM;AAAA,YAC9B,gBAAAA,MAAC,YAAO,IAAG,MAAK,IAAG,KAAI,GAAE,OAAM;AAAA,YAC/B,gBAAAA,MAAC,YAAO,IAAG,KAAI,IAAG,KAAI,GAAE,OAAM;AAAA,YAC9B,gBAAAA,MAAC,YAAO,IAAG,MAAK,IAAG,KAAI,GAAE,OAAM;AAAA,YAC/B,gBAAAA,MAAC,YAAO,IAAG,KAAI,IAAG,MAAK,GAAE,OAAM;AAAA,YAC/B,gBAAAA,MAAC,YAAO,IAAG,MAAK,IAAG,MAAK,GAAE,OAAM;AAAA,aAClC;AAAA;AAAA,MACF;AAAA,MAGC,QACC,gBAAAC;AAAA,QAAC;AAAA;AAAA,UACC,4BAAwB;AAAA,UACxB,2BAAuB;AAAA,UACvB,aAAa,CAAC,MAAM,EAAE,eAAe;AAAA,UACrC,OAAO;AAAA,YACL,GAAG;AAAA,YACH,KAAK,GAAG,KAAK,GAAG;AAAA,YAChB,MACE,KAAK,SAAS,WACV,GAAG,KAAK,IAAI,OACZ,KAAK,SAAS,QACZ,GAAG,KAAK,OAAO,GAAG,OAClB,GAAG,KAAK,IAAI;AAAA,UACtB;AAAA,UAEC;AAAA,iBAAK,SAAS,SACb,gBAAAA,OAAAF,WAAA,EACE;AAAA,8BAAAC,MAAC,cAAW,OAAM,oBAAmB,QAAO,gBAAe;AAAA,cAC3D,gBAAAA,MAAC,cAAW,OAAM,oBAAmB,QAAO,gBAAe;AAAA,cAC3D,gBAAAA,MAAC,aAAU;AAAA,cACX,gBAAAA,MAAC,cAAW,OAAM,cAAa,QAAO,cAAa,aAAW,MAAC;AAAA,eACjE;AAAA,YAED,KAAK,SAAS,YACb,gBAAAC,OAAAF,WAAA,EACE;AAAA,8BAAAC,MAAC,cAAW,OAAM,sBAAqB,QAAO,eAAc;AAAA,cAC5D,gBAAAA,MAAC,cAAW,OAAM,uBAAsB,QAAO,gBAAe;AAAA,cAC9D,gBAAAA,MAAC,aAAU;AAAA,cACX,gBAAAA,MAAC,cAAW,OAAM,iBAAgB,QAAO,cAAa,aAAW,MAAC;AAAA,eACpE;AAAA;AAAA;AAAA,MAEJ;AAAA,OAEJ;AAAA,IACA;AAAA,EACF;AACF;;;ACh7BA,SAAS,aAAAG,mBAAiB;AAE1B,SAAS,6BAAAC,mCAAiC;AAC1C;AAAA,EACE,iBAAAC;AAAA,EACA,qBAAAC;AAAA,EACA,kBAAAC;AAAA,EACA,eAAAC;AAAA,EACA;AAAA,EACA,wBAAAC;AAAA,OAEK;AAKP,IAAM,MAAM;AACZ,IAAM,MACJ;AAIF,IAAM,YAAY,IAAI,OAAO,QAAQ,MAAM,QAAQ,MAAM,GAAG;AAErD,IAAM,kBAAkB,MAAM;AACnC,QAAM,CAAC,MAAM,IAAIC,4BAA0B;AAE3C,EAAAC,YAAU,MAAM;AACd,WAAO,OAAO;AAAA,MACZ;AAAA,MACA,CAAC,cAAc;AACb,eAAO,OAAO,MAAM;AAClB,gBAAM,YAAYC,gBAAc;AAChC,cAAI,CAACC,oBAAkB,SAAS,EAAG;AAEnC,gBAAM,QAAuB,UAAU,SAAS;AAChD,gBAAM,aAAa,oBAAI,IAAmC;AAE1D,qBAAW,QAAQ,OAAO;AACxB,gBAAI,UAAUC,gBAAe,IAAI,IAAI,OAAO,KAAK,UAAU;AAC3D,mBACE,WACA,QAAQ,UAAU,KAClB,CAACC,aAAY,QAAQ,UAAU,CAAC,GAChC;AACA,wBAAU,QAAQ,UAAU;AAAA,YAC9B;AACA,gBAAI,WAAWD,gBAAe,OAAO,KAAK,CAACC,aAAY,OAAO,GAAG;AAC/D,yBAAW,IAAI,OAAO;AAAA,YACxB;AAAA,UACF;AAEA,qBAAW,SAAS,YAAY;AAC9B,kBAAM,aAAa,SAAS;AAAA,UAC9B;AAAA,QACF,CAAC;AACD,eAAO;AAAA,MACT;AAAA,MACAC;AAAA,IACF;AAAA,EACF,GAAG,CAAC,MAAM,CAAC;AAMX,EAAAL,YAAU,MAAM;AACd,WAAO,OAAO,sBAAsB,eAAe,CAAC,SAAS;AAE3D,UAAI,KAAK,aAAa,MAAM,KAAM;AAGlC,UAAI,KAAK,mBAAmB,IAAI,EAAG;AAEnC,YAAM,OAAO,KAAK,mBAAmB;AACrC,UAAI,CAAC,QAAQ,CAACG,gBAAe,IAAI,EAAG;AAGpC,YAAM,UAAU,KAAK,aAAa;AAClC,UAAI,YAAY,MAAM;AACpB,aAAK,aAAa,OAAO;AACzB;AAAA,MACF;AAGA,YAAM,WAAW,KAAK,eAAe;AACrC,UAAI,YAAY,UAAU,KAAK,QAAQ,GAAG;AACxC,aAAK,aAAa,KAAK;AAAA,MACzB;AAAA,IACF,CAAC;AAAA,EACH,GAAG,CAAC,MAAM,CAAC;AAEX,SAAO;AACT;;;AC7FA,SAAS,eAAAG,eAAa,aAAAC,aAAW,UAAAC,UAAQ,YAAAC,kBAAgB;AACzD,SAAS,gBAAAC,sBAAoB;AAC7B,SAAS,6BAAAC,mCAAiC;AAC1C;AAAA,EACE,wBAAAC;AAAA,EACA,iBAAAC;AAAA,EACA,YAAAC;AAAA,EACA,iBAAAC;AAAA,EACA,oBAAAC;AAAA,EACA;AAAA,EACA,qBAAAC;AAAA,EACA,eAAAC;AAAA,EACA,wBAAAC;AAAA,EACA,0BAAAC;AAAA,EACA,yBAAAC;AAAA,EACA,sBAAAC;AAAA,EACA,qBAAAC;AAAA,EACA,4BAAAC;AAAA,EACA,YAAAC;AAAA,OACK;;;ACEA,IAAM,0BAA2C;AAAA,EACtD,EAAE,IAAI,WAAW,OAAO,WAAW,OAAO,aAAa,UAAU,WAAW,cAAc,UAAU;AAAA,EACpG,EAAE,IAAI,QAAW,OAAO,QAAW,OAAO,gBAAqB,UAAU,WAAW,cAAc,UAAU;AAAA,EAC5G,EAAE,IAAI,WAAW,OAAO,WAAW,OAAO,gBAAqB,UAAU,WAAW,cAAc,UAAU;AAAA,EAC5G,EAAE,IAAI,SAAW,OAAO,SAAW,OAAO,aAAa,UAAU,WAAW,cAAc,UAAU;AAAA,EACpG,EAAE,IAAI,WAAW,OAAO,WAAW,OAAO,UAAY,UAAU,WAAW,cAAc,UAAU;AAAA,EACnG,EAAE,IAAI,UAAW,OAAO,QAAW,OAAO,aAAa,UAAU,WAAW,cAAc,UAAU;AACtG;;;AD8aM,SAqBE,OAAAC,OArBF,QAAAC,cAAA;AAtaC,SAAS,cAAc;AAAA,EAC5B;AAAA,EACA,eAAe;AAAA,EACf,gBAAgB;AAClB,IAAwB,CAAC,GAAG;AAC1B,QAAM,CAAC,MAAM,IAAIC,4BAA0B;AAC3C,QAAM,kBAAkB,WAAW;AAEnC,QAAM,CAAC,iBAAiB,kBAAkB,IAAIC,WAA6B,IAAI;AAC/E,QAAM,CAAC,eAAe,gBAAgB,IAAIA,WAKhC,IAAI;AAEd,QAAM,CAAC,iBAAiB,kBAAkB,IAAIA,WAAS,KAAK;AAC5D,QAAM,CAAC,aAAa,cAAc,IAAIA,WAAS,EAAE;AACjD,QAAM,gBAAgBC,SAAyB,IAAI;AAEnD,EAAAC,YAAU,MAAM;AACd,QAAI,OAAO,WAAW,YAAa;AACnC,uBAAmB,SAAS,IAAI;AAAA,EAClC,GAAG,CAAC,CAAC;AAEL,EAAAA,YAAU,MAAM;AACd,WAAO,OAAO;AAAA,MACZ;AAAA,MACA,CAAC,YAAsD;AACrD,eAAO,OAAO,MAAM;AAClB,gBAAM,YAAYC,gBAAc;AAChC,cAAI,CAACC,oBAAkB,SAAS,EAAG;AAEnC,gBAAM,cAAc,mBAAmB;AAAA,YACrC,OAAO,QAAQ,SAAS;AAAA,YACxB,aAAa,QAAQ,eAAe;AAAA,UACtC,CAAC;AAED,gBAAM,YAAYC,sBAAqB;AACvC,sBAAY,OAAO,SAAS;AAE5B,gBAAM,SAAS,UAAU,OAAO,QAAQ;AACxC,cAAI,QAAQ;AACZ,iBAAO,MAAM,UAAU,KAAK,CAACC,aAAY,MAAM,UAAU,CAAC,GAAG;AAC3D,oBAAQ,MAAM,UAAU;AAAA,UAC1B;AAEA,cAAI,kBAAkBC,WAAU;AAC9B,kBAAM,OAAO,OAAO,eAAe;AACnC,gBAAI,KAAK,KAAK,MAAM,KAAK;AACvB,qBAAO,OAAO;AAAA,YAChB;AAAA,UACF;AAEA,cAAID,aAAY,KAAK,GAAG;AACtB,YAAAE,UAAS,EAAE,OAAO,WAAW;AAAA,UAC/B,WACE,qBAAqB,SACrB,OAAO,MAAM,oBAAoB,cAChC,MAAM,gBAAiC,MAAM,GAC9C;AACA,kBAAM,QAAQ,WAAW;AAAA,UAC3B,OAAO;AACL,kBAAM,YAAY,WAAW;AAAA,UAC/B;AAEA,oBAAU,YAAY;AAAA,QACxB,CAAC;AACD,eAAO;AAAA,MACT;AAAA,MACAC;AAAA,IACF;AAAA,EACF,GAAG,CAAC,QAAQ,cAAc,aAAa,CAAC;AAExC,QAAM,qBAAqBC,cAAY,MAAM;AAC3C,WAAO,KAAK,MAAM;AAChB,YAAM,YAAYP,gBAAc;AAChC,UAAI,CAACC,oBAAkB,SAAS,GAAG;AACjC,yBAAiB,IAAI;AACrB;AAAA,MACF;AAEA,UAAI,OAAO,UAAU,OAAO,QAAQ;AACpC,aAAO,MAAM;AACX,YAAI,eAAe,IAAI,GAAG;AACxB,gBAAM,MAAM,KAAK,OAAO;AACxB,gBAAM,aAAa,OAAO,gBAAgB,GAAG;AAC7C,cAAI,YAAY;AACd,kBAAMO,QAAO,WAAW,sBAAsB;AAC9C,6BAAiB;AAAA,cACf,SAAS;AAAA,cACT,OAAO,KAAK,SAAS;AAAA,cACrB,aAAa,KAAK,eAAe;AAAA,cACjC,MAAAA;AAAA,YACF,CAAC;AAAA,UACH;AACA;AAAA,QACF;AACA,eAAO,KAAK,UAAU;AAAA,MACxB;AACA,uBAAiB,IAAI;AAAA,IACvB,CAAC;AAAA,EACH,GAAG,CAAC,MAAM,CAAC;AAEX,QAAM,mBAAmBV,SAAO,CAAC;AACjC,EAAAC,YAAU,MAAM;AACd,WAAO,OAAO;AAAA,MACZU;AAAA,MACA,MAAM;AACJ,YAAI,iBAAiB,YAAY,GAAG;AAClC,2BAAiB,UAAU,sBAAsB,MAAM;AACrD,6BAAiB,UAAU;AAC3B,+BAAmB;AAAA,UACrB,CAAC;AAAA,QACH;AACA,eAAO;AAAA,MACT;AAAA,MACAH;AAAA,IACF;AAAA,EACF,GAAG,CAAC,QAAQ,kBAAkB,CAAC;AAG/B,EAAAP,YAAU,MAAM;AACd,UAAM,cAAc,OAAO,eAAe;AAC1C,QAAI,CAAC,YAAa;AAElB,UAAM,aAAa,CAAC,MAAkB;AAEpC,YAAM,UAAU,EAAE;AAClB,UAAI,SAAS,QAAQ,wBAAwB,EAAG;AAEhD,iBAAW,MAAM;AACf,yBAAiB,IAAI;AACrB,2BAAmB,KAAK;AACxB,uBAAe,EAAE;AAAA,MACnB,GAAG,GAAG;AAAA,IACR;AAEA,gBAAY,iBAAiB,QAAQ,YAAY,IAAI;AACrD,WAAO,MAAM,YAAY,oBAAoB,QAAQ,YAAY,IAAI;AAAA,EACvE,GAAG,CAAC,MAAM,CAAC;AAIX,EAAAA,YAAU,MAAM;AACd,WAAO,OAAO;AAAA,MACZW;AAAA,MACA,CAAC,UAAU;AACT,cAAM,YAAYV,gBAAc;AAChC,YAAI,CAACC,oBAAkB,SAAS,KAAK,CAAC,UAAU,YAAY,EAAG,QAAO;AAEtE,cAAM,aAAa,UAAU,OAAO,QAAQ;AAG5C,YAAI,cAAoD;AACxD,YAAI,UAAU;AACd,eAAO,SAAS;AACd,cAAI,eAAe,OAAO,GAAG;AAC3B,0BAAc;AACd;AAAA,UACF;AACA,oBAAU,QAAQ,UAAU;AAAA,QAC9B;AACA,YAAI,CAAC,eAAe,CAAC,eAAe,WAAW,EAAG,QAAO;AAGzD,cAAM,YAAY,YAAY,aAAa;AAC3C,cAAM,kBAAkB,iBAAiB,UAAU,IAC/C,aACA,WAAW,UAAU;AAEzB,YACE,mBACA,iBAAiB,eAAe,KAChC,oBAAoB,aACpB,gBAAgB,eAAe,MAAM,IACrC;AAEA,iBAAO,eAAe;AACtB,gBAAM,eAAeC,sBAAqB;AAC1C,sBAAY,YAAY,YAAY;AACpC,0BAAgB,OAAO;AACvB,uBAAa,YAAY;AACzB,iBAAO;AAAA,QACT;AAEA,eAAO;AAAA,MACT;AAAA,MACAI;AAAA,IACF;AAAA,EACF,GAAG,CAAC,MAAM,CAAC;AAIX,EAAAP,YAAU,MAAM;AACd,WAAO,OAAO;AAAA,MACZY;AAAA,MACA,CAAC,UAAU;AACT,cAAM,YAAYX,gBAAc;AAChC,YAAI,CAACC,oBAAkB,SAAS,KAAK,CAAC,UAAU,YAAY,EAAG,QAAO;AAEtE,cAAM,aAAa,UAAU,OAAO,QAAQ;AAG5C,YAAI,cAAoD;AACxD,YAAI,UAAU;AACd,eAAO,SAAS;AACd,cAAI,eAAe,OAAO,GAAG;AAC3B,0BAAc;AACd;AAAA,UACF;AACA,oBAAU,QAAQ,UAAU;AAAA,QAC9B;AACA,YAAI,CAAC,eAAe,CAAC,eAAe,WAAW,EAAG,QAAO;AAGzD,cAAM,YAAY,YAAY,aAAa;AAC3C,cAAM,kBAAkB,iBAAiB,UAAU,IAC/C,aACA,WAAW,UAAU;AAEzB,YAAI,oBAAoB,WAAW;AACjC,gBAAM,aAAa,iBAAiB,mBAAmB,KAAK;AAC5D,cAAI,UAAU,OAAO,UAAU,YAAY;AAEzC,kBAAM,eAAe;AACrB,kBAAM,cAAc,YAAY,eAAe;AAC/C,gBAAI,aAAa;AACf,kBAAI,iBAAiB,eAAe,OAAO,YAAY,gBAAgB,YAAY;AACjF,gBAAC,YAA8C,YAAY;AAAA,cAC7D;AAAA,YACF,OAAO;AACL,oBAAM,eAAeC,sBAAqB;AAC1C,0BAAY,YAAY,YAAY;AACpC,2BAAa,YAAY;AAAA,YAC3B;AACA,mBAAO;AAAA,UACT;AAAA,QACF;AAEA,eAAO;AAAA,MACT;AAAA,MACAI;AAAA,IACF;AAAA,EACF,GAAG,CAAC,MAAM,CAAC;AAEX,EAAAP,YAAU,MAAM;AACd,UAAM,kBAAkB,CAAC,UAAyB;AAChD,YAAM,YAAYC,gBAAc;AAGhC,UAAIY,kBAAiB,SAAS,GAAG;AAC/B,cAAM,QAAQ,UAAU,SAAS;AACjC,cAAM,UAAU,MAAM,KAAK,cAAc;AACzC,YAAI,CAAC,QAAS,QAAO;AAErB,cAAM,eAAe;AACrB,cAAM,YAAYV,sBAAqB;AACvC,gBAAQ,aAAa,SAAS;AAC9B,gBAAQ,OAAO;AACf,kBAAU,YAAY;AACtB,eAAO;AAAA,MACT;AAGA,UAAI,CAACD,oBAAkB,SAAS,KAAK,CAAC,UAAU,YAAY,EAAG,QAAO;AACtE,UAAI,UAAU,OAAO,WAAW,EAAG,QAAO;AAE1C,YAAM,aAAa,UAAU,OAAO,QAAQ;AAG5C,UAAI,cAAoD;AACxD,UAAI,UAAU;AACd,aAAO,SAAS;AACd,YAAI,eAAe,OAAO,GAAG;AAC3B,wBAAc;AACd;AAAA,QACF;AACA,kBAAU,QAAQ,UAAU;AAAA,MAC9B;AACA,UAAI,CAAC,eAAe,CAAC,eAAe,WAAW,EAAG,QAAO;AAGzD,YAAM,aAAa,YAAY,cAAc;AAC7C,YAAM,cAAc,iBAAiB,UAAU,IAAI,aAAa,WAAW,UAAU;AACrF,UAAI,gBAAgB,WAAY,QAAO;AAEvC,YAAM,eAAe;AACrB,YAAM,WAAW,YAAY,YAAY;AACzC,iBAAW,SAAS,UAAU;AAC5B,oBAAY,aAAa,KAAK;AAAA,MAChC;AACA,kBAAY,OAAO;AAEnB,UAAI,SAAS,CAAC,KAAK,iBAAiB,SAAS,CAAC,KAAK,OAAO,SAAS,CAAC,EAAE,gBAAgB,YAAY;AAChG,QAAC,SAAS,CAAC,EAAoC,YAAY;AAAA,MAC7D;AACA,aAAO;AAAA,IACT;AAEA,UAAM,eAAe,CAAC,UAAyB;AAC7C,YAAM,YAAYD,gBAAc;AAChC,UAAI,CAACY,kBAAiB,SAAS,EAAG,QAAO;AAEzC,YAAM,QAAQ,UAAU,SAAS;AACjC,YAAM,UAAU,MAAM,KAAK,cAAc;AACzC,UAAI,CAAC,QAAS,QAAO;AAErB,YAAM,eAAe;AACrB,YAAM,YAAYV,sBAAqB;AACvC,cAAQ,aAAa,SAAS;AAC9B,cAAQ,OAAO;AACf,gBAAU,YAAY;AACtB,aAAO;AAAA,IACT;AAEA,UAAM,KAAK,OAAO,gBAAgBW,wBAAuB,iBAAiBP,sBAAoB;AAC9F,UAAM,KAAK,OAAO,gBAAgBQ,qBAAoB,cAAcR,sBAAoB;AACxF,WAAO,MAAM;AAAE,SAAG;AAAG,SAAG;AAAA,IAAG;AAAA,EAC7B,GAAG,CAAC,MAAM,CAAC;AAEX,EAAAP,YAAU,MAAM;AACd,UAAM,cAAc,OAAO,eAAe;AAC1C,QAAI,CAAC,YAAa;AAElB,UAAM,cAAc,CAAC,MAAkB;AACrC,YAAM,SAAS,EAAE;AACjB,UAAI,OAAO,aAAa,4BAA4B,GAAG;AACrD,UAAE,eAAe;AACjB,UAAE,gBAAgB;AAClB,2BAAmB,CAAC,SAAS,CAAC,IAAI;AAAA,MACpC;AAAA,IACF;AAEA,gBAAY,iBAAiB,SAAS,WAAW;AACjD,WAAO,MAAM,YAAY,oBAAoB,SAAS,WAAW;AAAA,EACnE,GAAG,CAAC,MAAM,CAAC;AAEX,EAAAA,YAAU,MAAM;AACd,QAAI,CAAC,eAAe;AAClB,yBAAmB,KAAK;AACxB,qBAAe,EAAE;AAAA,IACnB;AAAA,EACF,GAAG,CAAC,aAAa,CAAC;AAElB,EAAAA,YAAU,MAAM;AACd,QAAI,mBAAmB,cAAc,SAAS;AAC5C,oBAAc,QAAQ,MAAM;AAAA,IAC9B;AAAA,EACF,GAAG,CAAC,eAAe,CAAC;AAEpB,QAAM,cAAcQ;AAAA,IAClB,CAAC,aAAqB;AACpB,UAAI,CAAC,cAAe;AACpB,aAAO,OAAO,MAAM;AAClB,cAAM,OAAOQ,gBAAc,cAAc,OAAO;AAChD,YAAI,eAAe,IAAI,GAAG;AACxB,eAAK,SAAS,QAAQ;AAAA,QACxB;AAAA,MACF,CAAC;AACD,uBAAiB,CAAC,SAAU,OAAO,EAAE,GAAG,MAAM,OAAO,SAAS,IAAI,IAAK;AACvE,yBAAmB,KAAK;AACxB,qBAAe,EAAE;AACjB,aAAO,MAAM;AAAA,IACf;AAAA,IACA,CAAC,QAAQ,aAAa;AAAA,EACxB;AAEA,QAAM,eAAeR;AAAA,IACnB,CAAC,aAAqB;AACpB,UAAI,CAAC,cAAe;AACpB,aAAO,OAAO,MAAM;AAClB,cAAM,OAAOQ,gBAAc,cAAc,OAAO;AAChD,YAAI,eAAe,IAAI,GAAG;AACxB,eAAK,eAAe,QAAQ;AAAA,QAC9B;AAAA,MACF,CAAC;AACD,uBAAiB,CAAC,SAAU,OAAO,EAAE,GAAG,MAAM,aAAa,SAAS,IAAI,IAAK;AAC7E,aAAO,MAAM;AAAA,IACf;AAAA,IACA,CAAC,QAAQ,aAAa;AAAA,EACxB;AAEA,QAAM,gBAAgBR,cAAY,MAAM;AACtC,QAAI,CAAC,cAAe;AACpB,WAAO,OAAO,MAAM;AAClB,YAAM,OAAOQ,gBAAc,cAAc,OAAO;AAChD,UAAI,eAAe,IAAI,GAAG;AACxB,cAAM,WAAW,KAAK,YAAY;AAClC,cAAM,SAAS,KAAK,UAAU;AAC9B,YAAI,QAAQ;AACV,qBAAW,SAAS,UAAU;AAC5B,iBAAK,aAAa,KAAK;AAAA,UACzB;AAAA,QACF;AACA,aAAK,OAAO;AAAA,MACd;AAAA,IACF,CAAC;AACD,qBAAiB,IAAI;AACrB,WAAO,MAAM;AAAA,EACf,GAAG,CAAC,QAAQ,aAAa,CAAC;AAE1B,QAAM,iBAAiB,YAAY,KAAK,IACpC,eAAe;AAAA,IACb,CAAC,MACC,EAAE,KAAK,SAAS,YAAY,YAAY,CAAC,KACzC,EAAE,SAAS,KAAK,CAAC,MAAM,EAAE,SAAS,YAAY,YAAY,CAAC,CAAC;AAAA,EAChE,EAAE,MAAM,GAAG,EAAE,IACb,eAAe,MAAM,GAAG,EAAE;AAE9B,MAAI,CAAC,mBAAmB,CAAC,cAAe,QAAO;AAE/C,QAAM,EAAE,KAAK,IAAI;AAGjB,QAAM,eAAe;AACrB,QAAM,cAAc,KAAK,IAAI,KAAK,QAAQ,cAAc,OAAO,aAAa,eAAe,EAAE;AAC7F,QAAM,mBAAmB;AACzB,QAAM,kBAAkB,KAAK,IAAI,aAAa,OAAO,aAAa,mBAAmB,EAAE;AAEvF,SAAOC;AAAA,IACL,gBAAArB,OAAC,SAAI,wBAAoB,MACvB;AAAA,sBAAAA;AAAA,QAAC;AAAA;AAAA,UACC,OAAO;AAAA,YACL,UAAU;AAAA,YACV,KAAK,GAAG,KAAK,MAAM,CAAC;AAAA,YACpB,MAAM,GAAG,WAAW;AAAA,YACpB,SAAS;AAAA,YACT,YAAY;AAAA,YACZ,KAAK;AAAA,YACL,SAAS;AAAA,YACT,cAAc;AAAA,YACd,QAAQ;AAAA,YACR,iBAAiB;AAAA,YACjB,gBAAgB;AAAA,YAChB,sBAAsB;AAAA,YACtB,WAAW;AAAA,YACX,QAAQ;AAAA,YACR,YACE;AAAA,UACJ;AAAA,UACA,aAAa,CAAC,MAAM,EAAE,eAAe;AAAA,UAErC;AAAA,4BAAAD;AAAA,cAAC;AAAA;AAAA,gBACC,MAAK;AAAA,gBACL,OAAM;AAAA,gBACN,aAAa,CAAC,MAAM;AAClB,oBAAE,eAAe;AACjB,qCAAmB,CAAC,SAAS,CAAC,IAAI;AAAA,gBACpC;AAAA,gBACA,OAAO;AAAA,kBACL,SAAS;AAAA,kBACT,YAAY;AAAA,kBACZ,gBAAgB;AAAA,kBAChB,OAAO;AAAA,kBACP,QAAQ;AAAA,kBACR,cAAc;AAAA,kBACd,QAAQ;AAAA,kBACR,QAAQ;AAAA,kBACR,iBAAiB,kBAAkB,6BAA6B;AAAA,kBAChE,UAAU;AAAA,kBACV,YAAY;AAAA,gBACd;AAAA,gBAEC,wBAAc;AAAA;AAAA,YACjB;AAAA,YAEA,gBAAAA;AAAA,cAAC;AAAA;AAAA,gBACC,OAAO;AAAA,kBACL,OAAO;AAAA,kBACP,QAAQ;AAAA,kBACR,iBAAiB;AAAA,kBACjB,QAAQ;AAAA,gBACV;AAAA;AAAA,YACF;AAAA,YAEC,gBAAgB,IAAI,CAAC,WACpB,gBAAAA;AAAA,cAAC;AAAA;AAAA,gBAEC,MAAK;AAAA,gBACL,OAAO,OAAO;AAAA,gBACd,aAAa,CAAC,MAAM;AAClB,oBAAE,eAAe;AACjB,+BAAa,OAAO,EAAE;AAAA,gBACxB;AAAA,gBACA,OAAO;AAAA,kBACL,SAAS;AAAA,kBACT,YAAY;AAAA,kBACZ,gBAAgB;AAAA,kBAChB,OAAO;AAAA,kBACP,QAAQ;AAAA,kBACR,cAAc;AAAA,kBACd,QACE,cAAc,gBAAgB,OAAO,KACjC,8CACA;AAAA,kBACN,QAAQ;AAAA,kBACR,SAAS;AAAA,kBACT,iBAAiB;AAAA,kBACjB,YAAY;AAAA,gBACd;AAAA,gBAEA,0BAAAA;AAAA,kBAAC;AAAA;AAAA,oBACC,OAAO;AAAA,sBACL,SAAS;AAAA,sBACT,OAAO;AAAA,sBACP,QAAQ;AAAA,sBACR,cAAc;AAAA,sBACd,iBAAiB,OAAO;AAAA,sBACxB,QAAQ,eAAe,OAAO,YAAY;AAAA,oBAC5C;AAAA;AAAA,gBACF;AAAA;AAAA,cAjCK,OAAO;AAAA,YAkCd,CACD;AAAA,YAED,gBAAAA;AAAA,cAAC;AAAA;AAAA,gBACC,OAAO;AAAA,kBACL,OAAO;AAAA,kBACP,QAAQ;AAAA,kBACR,iBAAiB;AAAA,kBACjB,QAAQ;AAAA,gBACV;AAAA;AAAA,YACF;AAAA,YAEA,gBAAAA;AAAA,cAAC;AAAA;AAAA,gBACC,MAAK;AAAA,gBACL,OAAM;AAAA,gBACN,aAAa,CAAC,MAAM;AAClB,oBAAE,eAAe;AACjB,gCAAc;AAAA,gBAChB;AAAA,gBACA,OAAO;AAAA,kBACL,SAAS;AAAA,kBACT,YAAY;AAAA,kBACZ,gBAAgB;AAAA,kBAChB,OAAO;AAAA,kBACP,QAAQ;AAAA,kBACR,cAAc;AAAA,kBACd,QAAQ;AAAA,kBACR,QAAQ;AAAA,kBACR,iBAAiB;AAAA,kBACjB,OAAO;AAAA,kBACP,UAAU;AAAA,kBACV,YAAY;AAAA,gBACd;AAAA,gBACA,cAAc,CAAC,MAAM;AACnB,oBAAE,cAAc,MAAM,kBAAkB;AACxC,oBAAE,cAAc,MAAM,QAAQ;AAAA,gBAChC;AAAA,gBACA,cAAc,CAAC,MAAM;AACnB,oBAAE,cAAc,MAAM,kBAAkB;AACxC,oBAAE,cAAc,MAAM,QAAQ;AAAA,gBAChC;AAAA,gBAEA,0BAAAA,MAAC,SAAI,OAAM,MAAK,QAAO,MAAK,SAAQ,aAAY,MAAK,QAAO,QAAO,gBAAe,aAAY,OAC5F,0BAAAA,MAAC,UAAK,GAAE,sBAAqB,GAC/B;AAAA;AAAA,YACF;AAAA;AAAA;AAAA,MACF;AAAA,MAEC,mBACC,gBAAAC;AAAA,QAAC;AAAA;AAAA,UACC,wBAAoB;AAAA,UACpB,aAAa,CAAC,MAAM,EAAE,eAAe;AAAA,UACrC,OAAO;AAAA,YACL,UAAU;AAAA,YACV,KAAK,GAAG,KAAK,MAAM,EAAE;AAAA,YACrB,MAAM,GAAG,eAAe;AAAA,YACxB,OAAO,GAAG,gBAAgB;AAAA,YAC1B,cAAc;AAAA,YACd,QAAQ;AAAA,YACR,iBAAiB;AAAA,YACjB,gBAAgB;AAAA,YAChB,sBAAsB;AAAA,YACtB,WAAW;AAAA,YACX,QAAQ;AAAA,YACR,YACE;AAAA,UACJ;AAAA,UAEA;AAAA,4BAAAD,MAAC,SAAI,OAAO,EAAE,SAAS,cAAc,GACnC,0BAAAA;AAAA,cAAC;AAAA;AAAA,gBACC,KAAK;AAAA,gBACL,MAAK;AAAA,gBACL,aAAY;AAAA,gBACZ,OAAO;AAAA,gBACP,UAAU,CAAC,MAAM,eAAe,EAAE,OAAO,KAAK;AAAA,gBAC9C,WAAW,CAAC,MAAM;AAChB,sBAAI,EAAE,QAAQ,UAAU;AACtB,uCAAmB,KAAK;AACxB,mCAAe,EAAE;AACjB,2BAAO,MAAM;AAAA,kBACf;AACA,sBAAI,EAAE,QAAQ,WAAW,eAAe,SAAS,GAAG;AAClD,gCAAY,eAAe,CAAC,EAAG,KAAK;AAAA,kBACtC;AAAA,gBACF;AAAA,gBACA,OAAO;AAAA,kBACL,OAAO;AAAA,kBACP,SAAS;AAAA,kBACT,cAAc;AAAA,kBACd,QAAQ;AAAA,kBACR,UAAU;AAAA,kBACV,SAAS;AAAA,kBACT,iBAAiB;AAAA,gBACnB;AAAA;AAAA,YACF,GACF;AAAA,YAEA,gBAAAA;AAAA,cAAC;AAAA;AAAA,gBACC,OAAO;AAAA,kBACL,SAAS;AAAA,kBACT,qBAAqB;AAAA,kBACrB,KAAK;AAAA,kBACL,SAAS;AAAA,kBACT,WAAW;AAAA,kBACX,WAAW;AAAA,gBACb;AAAA,gBAEC,yBAAe,IAAI,CAAC,SACnB,gBAAAA;AAAA,kBAAC;AAAA;AAAA,oBAEC,MAAK;AAAA,oBACL,OAAO,KAAK,KAAK,QAAQ,MAAM,GAAG;AAAA,oBAClC,aAAa,CAAC,MAAM;AAClB,wBAAE,eAAe;AACjB,kCAAY,KAAK,KAAK;AAAA,oBACxB;AAAA,oBACA,OAAO;AAAA,sBACL,SAAS;AAAA,sBACT,YAAY;AAAA,sBACZ,gBAAgB;AAAA,sBAChB,OAAO;AAAA,sBACP,QAAQ;AAAA,sBACR,cAAc;AAAA,sBACd,QAAQ;AAAA,sBACR,QAAQ;AAAA,sBACR,iBAAiB;AAAA,sBACjB,UAAU;AAAA,sBACV,YAAY;AAAA,oBACd;AAAA,oBACA,cAAc,CAAC,MAAM;AACnB,wBAAE,cAAc,MAAM,kBAAkB;AAAA,oBAC1C;AAAA,oBACA,cAAc,CAAC,MAAM;AACnB,wBAAE,cAAc,MAAM,kBAAkB;AAAA,oBAC1C;AAAA,oBAEC,eAAK;AAAA;AAAA,kBA3BD,KAAK;AAAA,gBA4BZ,CACD;AAAA;AAAA,YACH;AAAA;AAAA;AAAA,MACF;AAAA,OAEJ;AAAA,IACA;AAAA,EACF;AACF;;;AErrBA,SAAS,cAAAuB,aAAY,eAAAC,eAAa,aAAAC,aAAW,UAAAC,UAAQ,YAAAC,kBAAgB;AAErE,SAAS,gBAAAC,sBAAoB;AAE7B,SAAS,6BAAAC,mCAAiC;AAC1C;AAAA,EACE,iBAAAC;AAAA,EACA,YAAAC;AAAA,EACA,iBAAAC;AAAA,EACA,qBAAAC;AAAA,EACA,eAAAC;AAAA,EACA,wBAAAC;AAAA,OACK;;;ACIA,SAAS,gBAAgB,KAAoC;AAClE,QAAM,UAAU,IAAI,KAAK;AACzB,MAAI,CAAC,QAAS,QAAO;AAGrB,MAAI;AACJ,MAAI;AACF,aAAS,IAAI,IAAI,OAAO;AAAA,EAC1B,QAAQ;AACN,WAAO;AAAA,EACT;AAEA,MAAI,OAAO,aAAa,WAAW,OAAO,aAAa,UAAU;AAC/D,WAAO;AAAA,EACT;AAEA,QAAM,WAAW,OAAO,SAAS,QAAQ,UAAU,EAAE;AAErD,MAAI,aAAa,iBAAiB,aAAa,iBAAiB;AAC9D,QAAI,UAAyB;AAE7B,QAAI,OAAO,aAAa,UAAU;AAChC,gBAAU,OAAO,aAAa,IAAI,GAAG;AAAA,IACvC;AAEA,QAAI,CAAC,SAAS;AACZ,YAAM,YAAY,OAAO,SAAS;AAAA,QAChC;AAAA,MACF;AACA,UAAI,WAAW;AACb,kBAAU,UAAU,CAAC,KAAK;AAAA,MAC5B;AAAA,IACF;AAEA,QAAI,SAAS;AACX,aAAO;AAAA,QACL,UAAU;AAAA,QACV,UAAU,iCAAiC,OAAO;AAAA,QAClD,cAAc,8BAA8B,OAAO;AAAA,MACrD;AAAA,IACF;AAAA,EACF;AAEA,MAAI,aAAa,YAAY;AAC3B,UAAM,UAAU,OAAO,SAAS,MAAM,CAAC,EAAE,MAAM,GAAG,EAAE,CAAC;AACrD,QAAI,SAAS;AACX,aAAO;AAAA,QACL,UAAU;AAAA,QACV,UAAU,iCAAiC,OAAO;AAAA,QAClD,cAAc,8BAA8B,OAAO;AAAA,MACrD;AAAA,IACF;AAAA,EACF;AAEA,MAAI,aAAa,eAAe,aAAa,oBAAoB;AAC/D,UAAM,aAAa,OAAO,SAAS,MAAM,uCAAuC;AAChF,QAAI,YAAY;AACd,YAAM,UAAU,WAAW,CAAC;AAC5B,aAAO;AAAA,QACL,UAAU;AAAA,QACV,UAAU,kCAAkC,OAAO;AAAA,MACrD;AAAA,IACF;AAAA,EACF;AAEA,MAAI,aAAa,YAAY;AAC3B,UAAM,YAAY,OAAO,SAAS,MAAM,mCAAmC;AAC3E,QAAI,WAAW;AACb,YAAM,UAAU,UAAU,CAAC;AAC3B,aAAO;AAAA,QACL,UAAU;AAAA,QACV,UAAU,8BAA8B,OAAO;AAAA,MACjD;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AAAA,IACL,UAAU;AAAA,IACV,UAAU;AAAA,EACZ;AACF;;;ADzEA;AAAA,EACE,uBAAAC;AAAA,EACA;AAAA,OACK;AAsSH,qBAAAC,WAGM,OAAAC,OA+FJ,QAAAC,cAlGF;AAzRJ,IAAMC,yBAAwB,KAAK,OAAO;AAC1C,IAAMC,2BAA0B;AAAA,EAC9B;AAAA,EACA;AAAA,EACA;AACF;AAaO,SAAS,YAAY;AAAA,EAC1B;AAAA,EACA,cAAcD;AAAA,EACd,iBAAiBC;AAAA,EACjB;AACF,IAAsB,CAAC,GAAG;AACxB,QAAM,CAAC,MAAM,IAAIC,4BAA0B;AAC3C,QAAM,CAAC,aAAa,cAAc,IAAIC,WAAS,KAAK;AACpD,QAAM,CAAC,eAAe,gBAAgB,IAAIA,WAAS,EAAE,KAAK,GAAG,MAAM,EAAE,CAAC;AACtE,QAAM,CAAC,iBAAiB,kBAAkB,IAAIA;AAAA,IAC5C;AAAA,EACF;AACA,QAAM,mBAAmBC,SAAO,aAAa;AAC7C,mBAAiB,UAAU;AAE3B,EAAAC,YAAU,MAAM;AACd,QAAI,OAAO,WAAW,YAAa;AACnC,uBAAmB,SAAS,IAAI;AAAA,EAClC,GAAG,CAAC,CAAC;AAEL,QAAM,eAAeC;AAAA,IACnB,CAAC,SAAwB;AACvB,UAAI,CAAC,eAAe,KAAK,CAAC,QAAQ,KAAK,SAAS,GAAG,GAAG;AACpD,yBAAiB,MAAM,QAAQ;AAC/B,eAAO;AAAA,MACT;AACA,UAAI,KAAK,OAAO,aAAa;AAC3B,yBAAiB,MAAM,MAAM;AAC7B,eAAO;AAAA,MACT;AACA,aAAO;AAAA,IACT;AAAA,IACA,CAAC,gBAAgB,aAAa,cAAc;AAAA,EAC9C;AAEA,QAAM,oBAAoBA;AAAA,IACxB,CAAC,SAAe;AACd,YAAM,UAAU,iBAAiB;AACjC,UAAI,CAAC,QAAS;AACd,UAAI,CAAC,aAAa,IAAI,EAAG;AAEzB,YAAM,YAAY,IAAI,gBAAgB,IAAI;AAC1C,UAAI,iBAAgC;AAEpC,aAAO,OAAO,MAAM;AAClB,cAAM,cAAc,wBAAwB,WAAW,KAAK,IAAI;AAChE,yBAAiB,YAAY,OAAO;AAEpC,cAAM,OAAOC,UAAS;AACtB,cAAM,YAAYC,gBAAc;AAChC,YAAI,cAAoD;AAExD,YAAIC,oBAAkB,SAAS,GAAG;AAChC,cAAI,OAAsC,UAAU,OAAO,QAAQ;AACnE,iBAAO,CAACC,aAAY,IAAI,GAAG;AACzB,kBAAM,SAAS,KAAK,UAAU;AAC9B,gBAAI,CAAC,UAAUA,aAAY,MAAM,GAAG;AAClC,kBAAI,OAAQ,eAAc;AAC1B;AAAA,YACF;AACA,mBAAO;AAAA,UACT;AAAA,QACF;AAEA,YAAI,eAAe,CAACA,aAAY,WAAW,GAAG;AAC5C,sBAAY,YAAY,WAAW;AAAA,QACrC,OAAO;AACL,eAAK,OAAO,WAAW;AAAA,QACzB;AAAA,MACF,CAAC;AAED,cAAQ,IAAI,EACT,KAAK,CAAC,cAAc;AACnB,YAAI;AACF,iBAAO,OAAO,MAAM;AAClB,gBAAI,CAAC,eAAgB;AACrB,kBAAM,cAAcC,gBAAc,cAAc;AAChD,gBAAI,CAAC,eAAe,CAAC,oBAAoB,WAAW,EAAG;AAEvD,kBAAM,YAAY,iBAAiB;AAAA,cACjC,KAAK;AAAA,cACL,WAAW;AAAA,cACX,UAAU;AAAA,cACV,OAAO,KAAK;AAAA,YACd,CAAC;AACD,wBAAY,QAAQ,SAAS;AAAA,UAC/B,CAAC;AAAA,QACH,QAAQ;AAAA,QAER;AACA,YAAI,gBAAgB,SAAS;AAAA,MAC/B,CAAC,EACA,MAAM,MAAM;AACX,YAAI;AACF,iBAAO,OAAO,MAAM;AAClB,gBAAI,CAAC,eAAgB;AACrB,kBAAM,cAAcA,gBAAc,cAAc;AAChD,gBAAI,CAAC,YAAa;AAClB,wBAAY,OAAO;AAAA,UACrB,CAAC;AAAA,QACH,QAAQ;AAAA,QAER;AACA,YAAI,gBAAgB,SAAS;AAAA,MAC/B,CAAC;AAAA,IACL;AAAA,IACA,CAAC,QAAQ,YAAY;AAAA,EACvB;AAEA,QAAM,mBAAmBL;AAAA,IACvB,CAAC,QAAgB;AACf,YAAM,YAAY,gBAAgB,GAAG;AACrC,UAAI,CAAC,UAAW;AAEhB,aAAO,OAAO,MAAM;AAClB,cAAM,OAAOC,UAAS;AACtB,cAAM,YAAYC,gBAAc;AAChC,YAAI,cAAoD;AAExD,YAAIC,oBAAkB,SAAS,GAAG;AAChC,cAAI,OAAsC,UAAU,OAAO,QAAQ;AACnE,iBAAO,CAACC,aAAY,IAAI,GAAG;AACzB,kBAAM,SAAS,KAAK,UAAU;AAC9B,gBAAI,CAAC,UAAUA,aAAY,MAAM,GAAG;AAClC,kBAAI,OAAQ,eAAc;AAC1B;AAAA,YACF;AACA,mBAAO;AAAA,UACT;AAAA,QACF;AAEA,cAAM,YAAY,iBAAiB;AAAA,UACjC,KAAK,UAAU;AAAA,UACf,WAAW;AAAA,UACX,UAAU,UAAU;AAAA,UACpB,OAAO;AAAA,QACT,CAAC;AAED,YAAI,eAAe,CAACA,aAAY,WAAW,GAAG;AAE5C,gBAAM,cAAc,YAAY,eAAe;AAC/C,cAAI,YAAY,KAAK,MAAM,IAAI;AAC7B,wBAAY,QAAQ,SAAS;AAAA,UAC/B,OAAO;AACL,wBAAY,YAAY,SAAS;AAAA,UACnC;AAAA,QACF,OAAO;AACL,eAAK,OAAO,SAAS;AAAA,QACvB;AAAA,MACF,CAAC;AAAA,IACH;AAAA,IACA,CAAC,MAAM;AAAA,EACT;AAEA,EAAAL,YAAU,MAAM;AACd,WAAO,OAAO;AAAA,MACZ;AAAA,MACA,CAAC,YAAY;AACX,YAAI,UAAU,SAAS;AACrB,4BAAkB,QAAQ,IAAI;AAAA,QAChC,OAAO;AACL,2BAAiB,QAAQ,GAAG;AAAA,QAC9B;AACA,eAAO;AAAA,MACT;AAAA,MACAO;AAAA,IACF;AAAA,EACF,GAAG,CAAC,QAAQ,mBAAmB,gBAAgB,CAAC;AAEhD,EAAAP,YAAU,MAAM;AACd,WAAO,OAAO;AAAA,MACZ;AAAA,MACA,MAAM;AACJ,cAAM,eAAe,OAAO,aAAa;AACzC,YAAI,gBAAgB,aAAa,aAAa,GAAG;AAC/C,gBAAM,QAAQ,aAAa,WAAW,CAAC;AACvC,gBAAM,OAAO,MAAM,sBAAsB;AACzC,2BAAiB,EAAE,KAAK,KAAK,KAAK,MAAM,KAAK,KAAK,CAAC;AAAA,QACrD;AACA,uBAAe,IAAI;AACnB,eAAO;AAAA,MACT;AAAA,MACAO;AAAA,IACF;AAAA,EACF,GAAG,CAAC,MAAM,CAAC;AAEX,EAAAP,YAAU,MAAM;AACd,QAAI,CAAC,cAAe;AAEpB,UAAM,cAAc,OAAO,eAAe;AAC1C,QAAI,CAAC,YAAa;AAElB,UAAM,SAAS,CAAC,MAAiB;AAC/B,YAAM,QAAQ,EAAE,cAAc;AAC9B,UAAI,CAAC,SAAS,MAAM,WAAW,EAAG;AAElC,YAAM,aAAa,MAAM,KAAK,KAAK,EAAE;AAAA,QAAO,CAAC,MAC3C,EAAE,KAAK,WAAW,QAAQ;AAAA,MAC5B;AACA,UAAI,WAAW,WAAW,EAAG;AAE7B,QAAE,eAAe;AACjB,QAAE,gBAAgB;AAElB,iBAAW,QAAQ,YAAY;AAC7B,0BAAkB,IAAI;AAAA,MACxB;AAAA,IACF;AAEA,gBAAY,iBAAiB,QAAQ,MAAM;AAC3C,WAAO,MAAM,YAAY,oBAAoB,QAAQ,MAAM;AAAA,EAC7D,GAAG,CAAC,QAAQ,eAAe,iBAAiB,CAAC;AAE7C,EAAAA,YAAU,MAAM;AACd,QAAI,CAAC,cAAe;AAEpB,UAAM,cAAc,OAAO,eAAe;AAC1C,QAAI,CAAC,YAAa;AAElB,UAAM,UAAU,CAAC,MAAsB;AACrC,YAAM,QAAQ,EAAE,eAAe;AAC/B,UAAI,CAAC,SAAS,MAAM,WAAW,EAAG;AAElC,YAAM,aAAa,MAAM,KAAK,KAAK,EAAE;AAAA,QAAO,CAAC,MAC3C,EAAE,KAAK,WAAW,QAAQ;AAAA,MAC5B;AACA,UAAI,WAAW,WAAW,EAAG;AAE7B,QAAE,eAAe;AAEjB,iBAAW,QAAQ,YAAY;AAC7B,0BAAkB,IAAI;AAAA,MACxB;AAAA,IACF;AAEA,gBAAY,iBAAiB,SAAS,OAAO;AAC7C,WAAO,MAAM,YAAY,oBAAoB,SAAS,OAAO;AAAA,EAC/D,GAAG,CAAC,QAAQ,eAAe,iBAAiB,CAAC;AAE7C,QAAM,kBAAkBC;AAAA,IACtB,CAAC,QAAgB;AACf,qBAAe,KAAK;AACpB,aAAO,gBAAgB,sBAAsB,EAAE,IAAI,CAAC;AAAA,IACtD;AAAA,IACA,CAAC,MAAM;AAAA,EACT;AAEA,QAAM,mBAAmBA;AAAA,IACvB,CAAC,SAAe;AACd,qBAAe,KAAK;AACpB,aAAO,gBAAgB,sBAAsB,EAAE,KAAK,CAAC;AAAA,IACvD;AAAA,IACA,CAAC,MAAM;AAAA,EACT;AAEA,QAAM,cAAcA,cAAY,MAAM;AACpC,mBAAe,KAAK;AACpB,WAAO,MAAM;AAAA,EACf,GAAG,CAAC,MAAM,CAAC;AAEX,MAAI,CAAC,gBAAiB,QAAO;AAE7B,SACE,gBAAAR,MAAAD,WAAA,EACG,yBACCgB;AAAA,IACE,gBAAAf;AAAA,MAAC;AAAA;AAAA,QACC,UAAU;AAAA,QACV,aAAa;AAAA,QACb,cAAc,gBAAgB,mBAAmB;AAAA,QACjD,SAAS;AAAA,QACT,eAAe;AAAA;AAAA,IACjB;AAAA,IACA;AAAA,EACF,GACJ;AAEJ;AAUA,IAAM,gBAAgBgB;AAAA,EACpB,SAASC,eACP,EAAE,UAAU,aAAa,cAAc,SAAS,cAAc,GAC9D,KACA;AACA,UAAM,CAAC,OAAO,QAAQ,IAAIZ,WAAS,EAAE;AACrC,UAAM,eAAeC,SAAuB,IAAI;AAChD,UAAM,oBAAoBA,SAAO,KAAK;AAGtC,IAAAC,YAAU,MAAM;AACd,YAAM,qBAAqB,CAAC,MAAkB;AAC5C,YAAI,kBAAkB,QAAS;AAC/B,YACE,aAAa,WACb,CAAC,aAAa,QAAQ,SAAS,EAAE,MAAc,GAC/C;AACA,kBAAQ;AAAA,QACV;AAAA,MACF;AAEA,YAAM,MAAM,sBAAsB,MAAM;AACtC,iBAAS,iBAAiB,aAAa,kBAAkB;AAAA,MAC3D,CAAC;AACD,aAAO,MAAM;AACX,6BAAqB,GAAG;AACxB,iBAAS,oBAAoB,aAAa,kBAAkB;AAAA,MAC9D;AAAA,IACF,GAAG,CAAC,OAAO,CAAC;AAEZ,UAAM,gBAAgB,CAAC,MAA6C;AAClE,QAAE,gBAAgB;AAElB,UAAI,EAAE,QAAQ,WAAW,CAAC,EAAE,UAAU;AACpC,UAAE,eAAe;AACjB,YAAI,MAAM,KAAK,GAAG;AAChB,sBAAY,MAAM,KAAK,CAAC;AAAA,QAC1B;AAAA,MACF;AACA,UAAI,EAAE,QAAQ,UAAU;AACtB,UAAE,eAAe;AACjB,gBAAQ;AAAA,MACV;AAAA,IACF;AAEA,UAAM,iBAAiB,MAAM;AAC3B,UAAI,CAAC,aAAc;AACnB,wBAAkB,UAAU;AAE5B,YAAM,QAAQ,SAAS,cAAc,OAAO;AAC5C,YAAM,OAAO;AACb,YAAM,SAAS,cAAc,KAAK,GAAG;AACrC,YAAM,WAAW,MAAM;AACrB,0BAAkB,UAAU;AAC5B,cAAM,OAAO,MAAM,QAAQ,CAAC;AAC5B,YAAI,QAAQ,cAAc;AACxB,uBAAa,IAAI;AAAA,QACnB;AAAA,MACF;AAEA,aAAO;AAAA,QACL;AAAA,QACA,MAAM;AAEJ,qBAAW,MAAM;AACf,8BAAkB,UAAU;AAAA,UAC9B,GAAG,GAAG;AAAA,QACR;AAAA,QACA,EAAE,MAAM,KAAK;AAAA,MACf;AACA,YAAM,MAAM;AAAA,IACd;AAEA,WACE,gBAAAN;AAAA,MAAC;AAAA;AAAA,QACC,KAAK;AAAA,QACL,eAAY;AAAA,QACZ,OAAO;AAAA,UACL,UAAU;AAAA,UACV,KAAK,GAAG,SAAS,GAAG;AAAA,UACpB,MAAM,GAAG,SAAS,IAAI;AAAA,UACtB,QAAQ;AAAA,UACR,SAAS;AAAA,UACT,YAAY;AAAA,UACZ,KAAK;AAAA,UACL,SAAS;AAAA,UACT,cAAc;AAAA,UACd,QAAQ;AAAA,UACR,iBAAiB;AAAA,UACjB,gBAAgB;AAAA,UAChB,sBAAsB;AAAA,UACtB,WAAW;AAAA,UACX,YAAY;AAAA,UACZ,WAAW;AAAA,UACX,UAAU;AAAA,QACZ;AAAA,QAEA;AAAA,0BAAAD;AAAA,YAAC;AAAA;AAAA,cACC,KAAK,CAAC,OAAO;AACX,oBAAI,GAAI,IAAG,MAAM;AACjB,oBAAI,OAAO,QAAQ,WAAY,KAAI,EAAE;AAAA,yBAC5B,IAAK,KAAI,UAAU;AAAA,cAC9B;AAAA,cACA,MAAK;AAAA,cACL;AAAA,cACA,UAAU,CAAC,MAAM,SAAS,EAAE,OAAO,KAAK;AAAA,cACxC,WAAW;AAAA,cACX,aAAY;AAAA,cACZ,OAAO;AAAA,gBACL,MAAM;AAAA,gBACN,QAAQ;AAAA,gBACR,SAAS;AAAA,gBACT,YAAY;AAAA,gBACZ,UAAU;AAAA,gBACV,OAAO;AAAA,gBACP,YAAY;AAAA,cACd;AAAA;AAAA,UACF;AAAA,UAEA,gBAAAA;AAAA,YAAC;AAAA;AAAA,cACC,MAAK;AAAA,cACL,eAAY;AAAA,cACZ,SAAS,MAAM;AACb,oBAAI,MAAM,KAAK,EAAG,aAAY,MAAM,KAAK,CAAC;AAAA,cAC5C;AAAA,cACA,UAAU,CAAC,MAAM,KAAK;AAAA,cACtB,OAAO;AAAA,gBACL,SAAS;AAAA,gBACT,YAAY;AAAA,gBACZ,gBAAgB;AAAA,gBAChB,OAAO;AAAA,gBACP,QAAQ;AAAA,gBACR,cAAc;AAAA,gBACd,QAAQ;AAAA,gBACR,QAAQ,MAAM,KAAK,IAAI,YAAY;AAAA,gBACnC,iBAAiB,MAAM,KAAK,IACxB,oCACA;AAAA,gBACJ,OAAO,MAAM,KAAK,IACd,4CACA;AAAA,gBACJ,YAAY;AAAA,gBACZ,YAAY;AAAA,cACd;AAAA,cAEA,0BAAAA,MAACF,sBAAA,EAAoB,MAAM,IAAI,QAAO,QAAO;AAAA;AAAA,UAC/C;AAAA,UAEC,gBACC,gBAAAE;AAAA,YAAC;AAAA;AAAA,cACC,MAAK;AAAA,cACL,eAAY;AAAA,cACZ,SAAS;AAAA,cACT,OAAO;AAAA,gBACL,SAAS;AAAA,gBACT,YAAY;AAAA,gBACZ,gBAAgB;AAAA,gBAChB,OAAO;AAAA,gBACP,QAAQ;AAAA,gBACR,cAAc;AAAA,gBACd,QAAQ;AAAA,gBACR,QAAQ;AAAA,gBACR,iBAAiB;AAAA,gBACjB,OAAO;AAAA,gBACP,YAAY;AAAA,gBACZ,YAAY;AAAA,cACd;AAAA,cAEA,0BAAAA,MAAC,oBAAiB,MAAM,IAAI,QAAO,QAAO;AAAA;AAAA,UAC5C;AAAA,UAGF,gBAAAA;AAAA,YAAC;AAAA;AAAA,cACC,yBAAyB;AAAA,gBACvB,QAAQ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,cAYV;AAAA;AAAA,UACF;AAAA;AAAA;AAAA,IACF;AAAA,EAEJ;AACF;;;AEvhBA,SAAS,aAAAkB,mBAAiB;AAE1B,SAAS,6BAAAC,mCAAiC;AAC1C;AAAA,EACE;AAAA,EACA;AAAA,OACK;AACP;AAAA,EACE,wBAAAC;AAAA,EACA,iBAAAC;AAAA,EACA,kBAAAC;AAAA,EACA,qBAAAC;AAAA,EACA,eAAAC;AAAA,EACA,wBAAAC;AAAA,EACA;AAAA,EACA,0BAAAC;AAAA,EACA;AAAA,EACA;AAAA,EACA,wBAAAC;AAAA,OACK;AAmBA,SAAS,eAAe;AAC7B,QAAM,CAAC,MAAM,IAAIC,4BAA0B;AAE3C,EAAAC,YAAU,MAAM;AACd,UAAM,cAAc,MAAM;AACxB,YAAM,YAAYC,gBAAc;AAChC,UACEC,oBAAkB,SAAS,KAC3B,UAAU,YAAY,KACtB,UAAU,OAAO,WAAW,GAC5B;AACA,cAAM,YAAY;AAAA,UAChB,UAAU,OAAO,QAAQ;AAAA,UACzB;AAAA,QACF;AACA,YAAI,uBAAuB,SAAS,GAAG;AACrC,gBAAM,SAAS,UAAU,UAAU;AACnC,cACE,WAAW,QACX,OAAO,cAAc,MAAM,aAC3B,UAAU,OAAO,QACf,UAAU,mBAAmB,GAAG,OAAO,GACzC;AACA,sBAAU,aAAaC,sBAAqB,CAAC;AAAA,UAC/C;AAAA,QACF;AAAA,MACF;AACA,aAAO;AAAA,IACT;AAEA,UAAM,gBAAgB,MAAM;AAC1B,YAAM,YAAYF,gBAAc;AAChC,UAAIC,oBAAkB,SAAS,KAAK,UAAU,YAAY,GAAG;AAC3D,cAAM,YAAY;AAAA,UAChB,UAAU,OAAO,QAAQ;AAAA,UACzB;AAAA,QACF;AACA,YAAI,uBAAuB,SAAS,GAAG;AACrC,gBAAM,SAAS,UAAU,UAAU;AACnC,cAAI,WAAW,QAAQ,OAAO,aAAa,MAAM,WAAW;AAC1D,kBAAM,iBAAiB,UAAU,kBAAkB;AACnD,gBACE,mBAAmB,QACnB,UAAU,OAAO,QAAQ,eAAe,OAAO,KAC/C,UAAU,OAAO,WACf,eAAe,mBAAmB,GACpC;AACA,wBAAU,YAAYC,sBAAqB,CAAC;AAAA,YAC9C;AAAA,UACF;AAAA,QACF;AAAA,MACF;AACA,aAAO;AAAA,IACT;AAEA,WAAO;AAAA;AAAA,MAEL,OAAO,sBAAsB,mBAAmB,CAAC,SAAS;AACxD,cAAM,SAAS,KAAK,UAAU;AAC9B,YAAI,CAAC,uBAAuB,MAAM,GAAG;AACnC,gBAAM,WAAW,KAAK,YAAY;AAClC,qBAAW,SAAS,UAAU;AAC5B,iBAAK,aAAa,KAAK;AAAA,UACzB;AACA,eAAK,OAAO;AAAA,QACd;AAAA,MACF,CAAC;AAAA;AAAA,MAGD,OAAO,sBAAsB,iBAAiB,CAAC,SAAS;AACtD,cAAM,SAAS,KAAK,UAAU;AAC9B,YAAI,CAAC,uBAAuB,MAAM,GAAG;AACnC,eAAK;AAAA,YACHA,sBAAqB,EAAE,OAAO,GAAG,KAAK,YAAY,CAAC;AAAA,UACrD;AAAA,QACF;AAAA,MACF,CAAC;AAAA;AAAA,MAGD,OAAO,sBAAsB,qBAAqB,CAAC,SAAS;AAC1D,cAAM,WAAW,KAAK,YAAY;AAClC,YACE,SAAS,WAAW,KACpB,CAAC,mBAAmB,SAAS,CAAC,CAAC,KAC/B,CAAC,qBAAqB,SAAS,CAAC,CAAC,GACjC;AAEA,qBAAW,SAAS,UAAU;AAC5B,iBAAK,aAAa,KAAK;AAAA,UACzB;AACA,eAAK,OAAO;AAAA,QACd;AAAA,MACF,CAAC;AAAA,MAED,OAAO;AAAA,QACLC;AAAA,QACA;AAAA,QACAC;AAAA,MACF;AAAA,MACA,OAAO;AAAA,QACL;AAAA,QACA;AAAA,QACAA;AAAA,MACF;AAAA,MACA,OAAO;AAAA,QACLC;AAAA,QACA;AAAA,QACAD;AAAA,MACF;AAAA,MACA,OAAO;AAAA,QACL;AAAA,QACA;AAAA,QACAA;AAAA,MACF;AAAA,MAEA,OAAO;AAAA,QACL;AAAA,QACA,MAAM;AACJ,gBAAM,YAAYJ,gBAAc;AAChC,cAAI,CAACC,oBAAkB,SAAS,EAAG,QAAO;AAE1C,gBAAM,YAAY;AAAA,YAChB,UAAU,OAAO,QAAQ;AAAA,YACzB;AAAA,UACF;AACA,cAAI,CAAC,mBAAmB,SAAS,EAAG,QAAO;AAE3C,gBAAM,YAAY,UAAU,UAAU;AACtC,cAAI,CAAC,uBAAuB,SAAS,EAAG,QAAO;AAG/C,cAAI,CAAC,UAAU,QAAQ,GAAG;AACxB,sBAAU,WAAW;AAAA,UACvB;AAGA,gBAAM,UAAU,UAAU,eAAe;AACzC,cAAI,qBAAqB,OAAO,GAAG;AACjC,kBAAM,aAAa,QAAQ,cAAc;AACzC,gBAAI,cAAc,eAAe,YAAY;AAC3C,cACE,WACA,UAAU;AAAA,YACd,OAAO;AACL,sBAAQ,UAAU;AAAA,YACpB;AAAA,UACF;AAEA,iBAAO;AAAA,QACT;AAAA,QACAG;AAAA,MACF;AAAA,MAEA,OAAO;AAAA,QACL;AAAA,QACA,CAAC,YAAY;AACX,iBAAO,OAAO,MAAM;AAClB,kBAAM,YAAYJ,gBAAc;AAChC,gBAAI,CAACC,oBAAkB,SAAS,EAAG;AAEnC,kBAAM,QAAQ,uBAAuB;AACrC,kBAAM,UAAU,yBAAyB;AACzC,kBAAM,iBAAiBC,sBAAqB;AAC5C,oBAAQ,OAAO,cAAc;AAE7B,kBAAM,YAAY,2BAA2B;AAAA,cAC3C,MAAM,SAAS,UAAU;AAAA,YAC3B,CAAC;AACD,sBAAU,OAAO,OAAO,OAAO;AAG/B,kBAAM,SAAS,UAAU,OAAO,QAAQ;AACxC,gBAAI,WAAW;AACf,mBACE,SAAS,UAAU,KACnB,CAACI,aAAY,SAAS,UAAU,CAAC,GACjC;AACA,yBAAW,SAAS,UAAU;AAAA,YAChC;AAGA,gBACEC,gBAAe,QAAQ,KACvB,SAAS,eAAe,EAAE,KAAK,MAAM,IACrC;AACA,uBAAS,QAAQ,SAAS;AAAA,YAC5B,OAAO;AACL,uBAAS,YAAY,SAAS;AAAA,YAChC;AAEA,kBAAM,UAAU;AAAA,UAClB,CAAC;AACD,iBAAO;AAAA,QACT;AAAA,QACAH;AAAA,MACF;AAAA,IACF;AAAA,EACF,GAAG,CAAC,MAAM,CAAC;AAEX,SAAO;AACT;;;AC9OA,SAAS,gBAAAI,sBAAoB;;;ACA7B,SAAS,eAAAC,eAAa,aAAAC,aAAW,UAAAC,gBAAc;AAC/C,SAAS,6BAAAC,mCAAiC;AAC1C;AAAA,EACE,iBAAAC;AAAA,EACA,qBAAAC;AAAA,EACA,eAAAC;AAAA,EACA,wBAAAC;AAAA,EACA,4BAAAC;AAAA,OACK;;;ACTP,SAAS,eAAAC,oBAAqC;AASvC,IAAM,oBAAoB;AAE1B,IAAM,uBACX;AAKK,SAAS,eACd,GACA,GACS;AACT,SAAO,EAAE,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,EAAE,UAAU,EAAE,SAAS,EAAE;AAClF;AAOO,SAAS,aAAa,MAAuC;AAClE,MAAI,UAA8B;AAClC,SAAO,YAAY,MAAM;AACvB,UAAM,SAA6B,QAAQ,UAAU;AACrD,QAAI,WAAW,KAAM,QAAO;AAC5B,QAAIA,aAAY,MAAM,EAAG,QAAO;AAChC,cAAU;AAAA,EACZ;AACA,SAAO;AACT;;;ADtBO,SAAS,oBAAoB;AAClC,QAAM,CAAC,MAAM,IAAIC,4BAA0B;AAC3C,QAAM,SAASC,SAAO,CAAC;AACvB,QAAM,uBAAuBA,SAAO,KAAK;AACzC,QAAM,gBAAgBA,SAAO,KAAK;AAElC,QAAM,kBAAkBC,cAAY,MAAM;AACxC,UAAM,OAAO,OAAO,eAAe;AACnC,QAAI,CAAC,KAAM;AACX,UAAM,WAAW,KAAK,iBAAiB,uBAAuB;AAC9D,aAAS,IAAI,GAAG,IAAI,SAAS,QAAQ,KAAK;AACxC,eAAS,CAAC,EAAG,gBAAgB,qBAAqB;AAAA,IACpD;AACA,yBAAqB,UAAU;AAAA,EACjC,GAAG,CAAC,MAAM,CAAC;AAEX,EAAAC,YAAU,MAAM;AACd,WAAO,OAAO;AAAA,MACZC;AAAA,MACA,MAAM;AACJ,YAAI,cAAc,QAAS,QAAO;AAElC,YAAI,OAAO,QAAS,sBAAqB,OAAO,OAAO;AACvD,eAAO,UAAU,sBAAsB,MAAM;AAC3C,iBAAO,UAAU;AAEjB,cAAI,qBAAqB,SAAS;AAChC,4BAAgB;AAAA,UAClB;AAEA,iBAAO,KAAK,MAAM;AAChB,kBAAM,OAAO,OAAO,eAAe;AACnC,gBAAI,CAAC,KAAM;AAEX,kBAAM,WAAW,KAAK,iBAAiB,uBAAuB;AAC9D,qBAAS,IAAI,GAAG,IAAI,SAAS,QAAQ,KAAK;AACxC,uBAAS,CAAC,EAAG,gBAAgB,qBAAqB;AAAA,YACpD;AAEA,kBAAM,YAAYC,gBAAc;AAChC,gBAAI,CAACC,oBAAkB,SAAS,KAAK,UAAU,YAAY,EAAG;AAE9D,kBAAM,cAAc,aAAa,UAAU,OAAO,QAAQ,CAAC;AAC3D,kBAAM,aAAa,aAAa,UAAU,MAAM,QAAQ,CAAC;AACzD,gBAAI,CAAC,eAAe,CAAC,WAAY;AACjC,gBAAI,YAAY,OAAO,MAAM,WAAW,OAAO,EAAG;AAElD,kBAAM,WAAW,YAAY,UAAU;AACvC,gBAAI,CAAC,YAAY,CAACC,cAAY,QAAQ,EAAG;AAEzC,kBAAM,WAAW,SAAS,YAAY;AACtC,kBAAM,YAAY,SAAS;AAAA,cACzB,CAAC,MAAM,EAAE,OAAO,MAAM,YAAY,OAAO;AAAA,YAC3C;AACA,kBAAM,WAAW,SAAS;AAAA,cACxB,CAAC,MAAM,EAAE,OAAO,MAAM,WAAW,OAAO;AAAA,YAC1C;AACA,gBAAI,cAAc,MAAM,aAAa,GAAI;AAEzC,kBAAM,QAAQ,KAAK,IAAI,WAAW,QAAQ;AAC1C,kBAAM,MAAM,KAAK,IAAI,WAAW,QAAQ;AAExC,qBAAS,IAAI,OAAO,KAAK,KAAK,KAAK;AACjC,oBAAM,QAAQ,SAAS,CAAC;AACxB,kBAAI,CAAC,MAAO;AACZ,oBAAM,KAAK,OAAO,gBAAgB,MAAM,OAAO,CAAC;AAChD,kBAAI,GAAI,IAAG,aAAa,uBAAuB,MAAM;AAAA,YACvD;AAAA,UACF,CAAC;AAAA,QACH,CAAC;AACD,eAAO;AAAA,MACT;AAAA,MACAC;AAAA,IACF;AAAA,EACF,GAAG,CAAC,QAAQ,eAAe,CAAC;AAE5B,SAAO,EAAE,iBAAiB,sBAAsB,cAAc;AAChE;;;AE5FA,SAAS,aAAAC,aAAW,UAAAC,UAAQ,YAAAC,kBAAgB;AAC5C,SAAS,6BAAAC,mCAAiC;AAC1C,SAAS,YAAAC,iBAAgB;AAYlB,SAAS,iBACd,sBACA,eACA;AACA,QAAM,CAAC,MAAM,IAAIC,4BAA0B;AAC3C,QAAM,CAAC,aAAa,cAAc,IAAIC,WAA6B,IAAI;AACvE,QAAM,gBAAgBC,SAAO,EAAE,GAAG,GAAG,GAAG,EAAE,CAAC;AAC3C,QAAM,cAAcA,SAAO,KAAK;AAChC,QAAM,aAAaA,SAA2B,IAAI;AAClD,QAAM,mBAAmBA,SAAO,KAAK;AAGrC,EAAAC,YAAU,MAAM;AACd,QAAI,OAAO,WAAW,YAAa;AAEnC,qBAAiB,UACf,OAAO,WAAW,mBAAmB,EAAE,WACvC,UAAU,iBAAiB,KAC3B,kBAAkB;AAEpB,UAAM,SAAS,OAAO,eAAe;AACrC,QAAI,QAAQ;AACV,UAAI,KAAyB;AAC7B,aAAO,MAAM,CAAC,GAAG,aAAa,oBAAoB,GAAG;AACnD,aAAK,GAAG;AAAA,MACV;AACA,iBAAW,UAAU;AAAA,IACvB;AAAA,EACF,GAAG,CAAC,MAAM,CAAC;AAGX,EAAAA,YAAU,MAAM;AACd,QAAI,iBAAiB,QAAS;AAC9B,QAAI,OAAO,aAAa,YAAa;AAErC,UAAM,cAAc,OAAO,eAAe;AAC1C,QAAI,CAAC,YAAa;AAElB,QAAI,UAAU;AAEd,UAAM,cAAc,CAAC,MAAkB;AACrC,UAAI,EAAE,WAAW,EAAG;AAEpB,YAAM,UAAU,WAAW;AAC3B,UAAI,CAAC,QAAS;AAEd,YAAM,SAAS,EAAE;AAEjB,UAAI,YAAY,SAAS,MAAM,KAAK,WAAW,YAAa;AAE5D,YAAM,gBAAgB,OAAO,QAAQ,sBAAsB;AAC3D,UAAI,iBAAiB,kBAAkB,QAAS;AAEhD,UAAI,OAAO,QAAQ,oBAAoB,EAAG;AAE1C,YAAM,eACJ,WAAW,WACX,WAAW,eACX,OAAO,SAAS,OAAO;AACzB,UAAI,CAAC,aAAc;AAGnB,YAAM,cAAc,QAAQ,sBAAsB;AAClD,UACE,EAAE,UAAU,YAAY,MAAM,OAC9B,EAAE,UAAU,YAAY,SAAS;AAEjC;AAEF,aAAO,aAAa,GAAG,gBAAgB;AACvC,QAAE,eAAe;AAEjB,oBAAc,UAAU,EAAE,GAAG,EAAE,SAAS,GAAG,EAAE,QAAQ;AACrD,kBAAY,UAAU;AACtB,oBAAc,UAAU;AAExB,eAAS,iBAAiB,aAAa,WAAW;AAClD,eAAS,iBAAiB,WAAW,SAAS;AAAA,IAChD;AAEA,UAAM,cAAc,CAAC,MAAkB;AACrC,UAAI,CAAC,cAAc,QAAS;AAE5B,YAAM,KAAK,EAAE,UAAU,cAAc,QAAQ;AAC7C,YAAM,KAAK,EAAE,UAAU,cAAc,QAAQ;AAE7C,UAAI,CAAC,YAAY,SAAS;AACxB,YACE,KAAK,IAAI,EAAE,IAAI,qBACf,KAAK,IAAI,EAAE,IAAI;AAEf;AACF,oBAAY,UAAU;AAAA,MACxB;AAEA,UAAI,QAAS,sBAAqB,OAAO;AACzC,gBAAU,sBAAsB,MAAM;AACpC,kBAAU;AACV,YAAI,CAAC,cAAc,QAAS;AAE5B,cAAM,KAAK,cAAc,QAAQ;AACjC,cAAM,KAAK,cAAc,QAAQ;AACjC,cAAM,KAAK,EAAE;AACb,cAAM,KAAK,EAAE;AAEb,cAAM,OAAO,KAAK,IAAI,IAAI,EAAE;AAC5B,cAAM,MAAM,KAAK,IAAI,IAAI,EAAE;AAC3B,cAAM,QAAQ,KAAK,IAAI,IAAI,EAAE;AAC7B,cAAM,SAAS,KAAK,IAAI,IAAI,EAAE;AAE9B,uBAAe,EAAE,KAAK,MAAM,OAAO,QAAQ,MAAM,QAAQ,SAAS,IAAI,CAAC;AAEvE,cAAM,kBAAkB,EAAE,KAAK,MAAM,QAAQ,MAAM;AAEnD,eAAO,KAAK,MAAM;AAChB,gBAAM,WAAWC,UAAS;AAC1B,gBAAM,WAAW,SAAS,YAAY;AAEtC,qBAAW,SAAS,UAAU;AAC5B,kBAAM,KAAK,OAAO,gBAAgB,MAAM,OAAO,CAAC;AAChD,gBAAI,CAAC,GAAI;AACT,kBAAM,YAAY,GAAG,sBAAsB;AAE3C,gBAAI,eAAe,iBAAiB,SAAS,GAAG;AAC9C,iBAAG,aAAa,uBAAuB,MAAM;AAAA,YAC/C,OAAO;AACL,iBAAG,gBAAgB,qBAAqB;AAAA,YAC1C;AAAA,UACF;AAAA,QACF,CAAC;AAAA,MACH,CAAC;AAAA,IACH;AAEA,UAAM,YAAY,MAAM;AACtB,oBAAc,UAAU;AAExB,eAAS,oBAAoB,aAAa,WAAW;AACrD,eAAS,oBAAoB,WAAW,SAAS;AAEjD,UAAI,SAAS;AACX,6BAAqB,OAAO;AAC5B,kBAAU;AAAA,MACZ;AAEA,qBAAe,IAAI;AAEnB,YAAM,OAAO,OAAO,eAAe;AACnC,UAAI,QAAQ,KAAK,cAAc,uBAAuB,GAAG;AACvD,6BAAqB,UAAU;AAAA,MACjC;AAAA,IACF;AAEA,aAAS,iBAAiB,aAAa,WAAW;AAElD,WAAO,MAAM;AACX,eAAS,oBAAoB,aAAa,WAAW;AACrD,eAAS,oBAAoB,aAAa,WAAW;AACrD,eAAS,oBAAoB,WAAW,SAAS;AACjD,UAAI,QAAS,sBAAqB,OAAO;AAAA,IAC3C;AAAA,EACF,GAAG,CAAC,QAAQ,eAAe,oBAAoB,CAAC;AAEhD,SAAO,EAAE,YAAY;AACvB;;;ACjLA,SAAS,aAAAC,aAAW,UAAAC,gBAAc;AAClC,SAAS,6BAAAC,mCAAiC;AAC1C,SAAS,YAAAC,kBAAgB;AAMlB,SAAS,yBACd,sBACA,eACA,iBACA;AACA,QAAM,CAAC,MAAM,IAAID,4BAA0B;AAC3C,QAAM,YAAYD,SAAO,MAAM;AAC/B,YAAU,UAAU;AAEpB,EAAAD,YAAU,MAAM;AACd,UAAM,iBAAiB,MAAM;AAC3B,UAAI,qBAAqB,WAAW,CAAC,cAAc,SAAS;AAC1D,wBAAgB;AAAA,MAClB;AAAA,IACF;AAEA,UAAM,YAAY,CAAC,MAAqB;AACtC,UAAI,CAAC,qBAAqB,WAAW,cAAc,QAAS;AAE5D,UAAI,EAAE,QAAQ,eAAe,EAAE,QAAQ,UAAU;AAC/C,UAAE,eAAe;AACjB,UAAE,gBAAgB;AAElB,cAAM,KAAK,UAAU;AAErB,WAAG,OAAO,MAAM;AACd,gBAAM,WAAWG,WAAS;AAC1B,gBAAM,WAAW,SAAS,YAAY;AAEtC,qBAAW,SAAS,UAAU;AAC5B,kBAAM,KAAK,GAAG,gBAAgB,MAAM,OAAO,CAAC;AAC5C,gBAAI,MAAM,GAAG,aAAa,qBAAqB,GAAG;AAChD,oBAAM,OAAO;AAAA,YACf;AAAA,UACF;AAAA,QACF,CAAC;AAED,wBAAgB;AAChB;AAAA,MACF;AAEA,sBAAgB;AAAA,IAClB;AAEA,aAAS,iBAAiB,aAAa,gBAAgB,IAAI;AAC3D,aAAS,iBAAiB,WAAW,WAAW,IAAI;AAEpD,WAAO,MAAM;AACX,eAAS,oBAAoB,aAAa,gBAAgB,IAAI;AAC9D,eAAS,oBAAoB,WAAW,WAAW,IAAI;AAAA,IACzD;AAAA,EACF,GAAG,CAAC,iBAAiB,sBAAsB,aAAa,CAAC;AAC3D;;;AJ9CI,gBAAAC,aAAA;AATG,SAAS,uBAAuB;AACrC,QAAM,EAAE,iBAAiB,sBAAsB,cAAc,IAC3D,kBAAkB;AACpB,QAAM,EAAE,YAAY,IAAI,iBAAiB,sBAAsB,aAAa;AAC5E,2BAAyB,sBAAsB,eAAe,eAAe;AAE7E,MAAI,CAAC,eAAe,OAAO,aAAa,YAAa,QAAO;AAE5D,SAAOC;AAAA,IACL,gBAAAD;AAAA,MAAC;AAAA;AAAA,QACC,eAAY;AAAA,QACZ,OAAO;AAAA,UACL,UAAU;AAAA,UACV,KAAK,GAAG,YAAY,GAAG;AAAA,UACvB,MAAM,GAAG,YAAY,IAAI;AAAA,UACzB,OAAO,GAAG,YAAY,KAAK;AAAA,UAC3B,QAAQ,GAAG,YAAY,MAAM;AAAA,UAC7B,iBACE;AAAA,UACF,QAAQ;AAAA,UACR,cAAc;AAAA,UACd,eAAe;AAAA,UACf,QAAQ;AAAA,QACV;AAAA;AAAA,IACF;AAAA,IACA,SAAS;AAAA,EACX;AACF;","names":["useEffect","useLexicalComposerContext","DecoratorNode","jsx","useCallback","useEffect","useRef","$getNodeByKey","DecoratorNode","useLexicalComposerContext","$createParagraphNode","$isElementNode","useCallback","useEffect","useRef","$getNodeByKey","CLICK_COMMAND","COMMAND_PRIORITY_LOW","DecoratorNode","KEY_BACKSPACE_COMMAND","KEY_DELETE_COMMAND","useLexicalComposerContext","useLexicalNodeSelection","jsx","jsxs","useCallback","useEffect","useRef","$getNodeByKey","CLICK_COMMAND","COMMAND_PRIORITY_LOW","DecoratorNode","KEY_BACKSPACE_COMMAND","KEY_DELETE_COMMAND","useLexicalComposerContext","useLexicalNodeSelection","jsx","ElementNode","$createParagraphNode","$isElementNode","ElementNode","IS_CHROME","ElementNode","ElementNode","IS_CHROME","$isElementNode","paragraph","$createParagraphNode","$isElementNode","$createParagraphNode","jsx","jsxs","DecoratorNode","useLexicalComposerContext","useRef","useEffect","useCallback","$getNodeByKey","$getSelection","$isNodeSelection","DecoratorNode","KEY_BACKSPACE_COMMAND","KEY_DELETE_COMMAND","COMMAND_PRIORITY_LOW","useLexicalComposerContext","useEffect","jsx","jsxs","useCallback","useEffect","useRef","useState","$getNodeByKey","CLICK_COMMAND","COMMAND_PRIORITY_LOW","DecoratorNode","KEY_BACKSPACE_COMMAND","KEY_DELETE_COMMAND","useLexicalComposerContext","useLexicalNodeSelection","CheckIcon","jsx","jsxs","DecoratorNode","jsx","jsxs","jsx","jsxs","useLexicalComposerContext","useEffect","useLexicalComposerContext","$getSelection","$isRangeSelection","TextNode","useCallback","useEffect","useRef","useState","useLexicalComposerContext","$getSelection","$isTextNode","$isElementNode","COMMAND_PRIORITY_LOW","ArrowClockwiseIcon","$isLinkNode","useCallback","useLexicalComposerContext","CheckIcon","jsx","jsxs","useLexicalComposerContext","useCallback","CheckIcon","useCallback","useLexicalComposerContext","CheckIcon","jsx","jsxs","useLexicalComposerContext","useCallback","CheckIcon","jsx","jsxs","useLexicalComposerContext","useState","useRef","useEffect","COMMAND_PRIORITY_LOW","useCallback","$getSelection","$isLinkNode","$isTextNode","$isElementNode","showBelow","ArrowClockwiseIcon","useCallback","useEffect","useRef","useState","useLexicalComposerContext","$createParagraphNode","$getRoot","$getSelection","$isElementNode","$isRangeSelection","$isRootNode","COMMAND_PRIORITY_LOW","KEY_ESCAPE_COMMAND","$createHeadingNode","$createQuoteNode","$createListNode","$createListItemNode","createPortal","SparkleIcon","TextAaIcon","TextAlignLeftIcon","TextAlignRightIcon","jsx","jsxs","SparkleIcon","TextAaIcon","TextAlignLeftIcon","TextAlignRightIcon","$getSelection","$isRangeSelection","$isRootNode","$getRoot","$createHeadingNode","$createQuoteNode","$createListNode","$createListItemNode","$createParagraphNode","$isElementNode","useLexicalComposerContext","useState","useRef","useEffect","useCallback","COMMAND_PRIORITY_LOW","KEY_ESCAPE_COMMAND","createPortal","useCallback","useEffect","useRef","useState","useLexicalComposerContext","$getNodeByKey","$getRoot","createPortal","useCallback","useEffect","useRef","createPortal","$createParagraphNode","$createTextNode","$getNodeByKey","$isElementNode","$createHeadingNode","$isHeadingNode","$isQuoteNode","$createQuoteNode","$createListNode","$createListItemNode","$isListNode","TextAlignLeftIcon","TextHOneIcon","TextHTwoIcon","TextHThreeIcon","QuotesIcon","ListBulletsIcon","ListNumbersIcon","CheckSquareIcon","CodeSimpleIcon","InfoIcon","CheckIcon","CaretCircleDownIcon","jsx","jsxs","$getNodeByKey","$isHeadingNode","$isQuoteNode","$isListNode","$isElementNode","$createParagraphNode","$createTextNode","$createListNode","$createListItemNode","$createHeadingNode","$createQuoteNode","useRef","useEffect","useCallback","createPortal","Fragment","jsx","jsxs","$getRoot","useLexicalComposerContext","useState","useRef","useEffect","useCallback","$getNodeByKey","createPortal","useEffect","useLexicalComposerContext","TextNode","$createParagraphNode","$createHeadingNode","$createQuoteNode","$createListNode","$createListItemNode","$createHeadingNode","$createQuoteNode","$createListNode","$createListItemNode","$createParagraphNode","useLexicalComposerContext","useEffect","TextNode","useEffect","useRef","useLexicalComposerContext","$getNodeByKey","$getRoot","$getSelection","$isRangeSelection","$isRootNode","COMMAND_PRIORITY_LOW","useLexicalComposerContext","useRef","useEffect","COMMAND_PRIORITY_LOW","$getRoot","$getSelection","$isRangeSelection","$isRootNode","$getNodeByKey","useCallback","useEffect","useRef","useState","createPortal","useLexicalComposerContext","$getRoot","$getSelection","$isRangeSelection","$isRootNode","COMMAND_PRIORITY_LOW","Fragment","jsx","jsxs","useLexicalComposerContext","useState","useRef","useEffect","COMMAND_PRIORITY_LOW","$getRoot","$getSelection","$isRangeSelection","$isRootNode","useCallback","createPortal","AIPromptInput","useCallback","useEffect","useRef","useState","createPortal","useLexicalComposerContext","$getSelection","$isRangeSelection","$isTextNode","KEY_ARROW_DOWN_COMMAND","KEY_ARROW_UP_COMMAND","KEY_ENTER_COMMAND","KEY_ESCAPE_COMMAND","TextNode","jsx","jsxs","useEffect","useLexicalComposerContext","$getSelection","$isRangeSelection","normalized","useLexicalComposerContext","useEffect","$getSelection","$isRangeSelection","useCallback","useEffect","useRef","useState","createPortal","useLexicalComposerContext","$getSelection","$isRangeSelection","$isTextNode","COMMAND_PRIORITY_HIGH","COMMAND_PRIORITY_LOW","KEY_ARROW_DOWN_COMMAND","KEY_ARROW_UP_COMMAND","KEY_ENTER_COMMAND","KEY_ESCAPE_COMMAND","KEY_TAB_COMMAND","jsx","jsxs","useLexicalComposerContext","useState","useRef","useEffect","useCallback","COMMAND_PRIORITY_LOW","$getSelection","$isRangeSelection","$isTextNode","KEY_ARROW_DOWN_COMMAND","COMMAND_PRIORITY_HIGH","KEY_ARROW_UP_COMMAND","KEY_ENTER_COMMAND","KEY_TAB_COMMAND","KEY_ESCAPE_COMMAND","createPortal","useCallback","useEffect","useRef","useState","createPortal","useLexicalComposerContext","$getSelection","$isRangeSelection","COMMAND_PRIORITY_LOW","SELECTION_CHANGE_COMMAND","$isLinkNode","LinkIcon","forwardRef","Fragment","jsx","jsxs","useLexicalComposerContext","useState","useRef","useEffect","COMMAND_PRIORITY_LOW","useCallback","$getSelection","$isRangeSelection","target","rootElement","SELECTION_CHANGE_COMMAND","createPortal","LinkInputPopover","useEffect","useRef","useState","useLexicalComposerContext","useEffect","useRef","useState","useLexicalComposerContext","$getRoot","useCallback","useEffect","useRef","useState","useLexicalComposerContext","FORMAT_TEXT_COMMAND","createPortal","TextBIcon","TextItalicIcon","TextUnderlineIcon","TextStrikethroughIcon","CodeIcon","jsx","TOOLBAR_BUTTONS","useEffect","useLexicalComposerContext","$getSelection","$isRangeSelection","$isTextNode","COMMAND_PRIORITY_LOW","useLexicalComposerContext","useEffect","$getSelection","$isRangeSelection","$isTextNode","COMMAND_PRIORITY_LOW","useEffect","useLexicalComposerContext","useEffect","useLexicalComposerContext","$createParagraphNode","$getSelection","$isNodeSelection","$isRangeSelection","COMMAND_PRIORITY_LOW","KEY_BACKSPACE_COMMAND","KEY_DELETE_COMMAND","$isTableNode","$isTableRowNode","$isTableCellNode","useLexicalComposerContext","useEffect","$getSelection","$isRangeSelection","$isTableRowNode","$isTableCellNode","COMMAND_PRIORITY_LOW","$isNodeSelection","$isTableNode","$createParagraphNode","KEY_BACKSPACE_COMMAND","KEY_DELETE_COMMAND","useCallback","useEffect","useRef","useState","useLexicalComposerContext","createPortal","$getSelection","$isRangeSelection","$isTableCellNode","$isTableSelection","jsx","jsxs","useEffect","useRef","useState","useCallback","useLexicalComposerContext","createPortal","$getNodeByKey","$isTableNode","$isTableRowNode","$isTableCellNode","$insertTableRowAtSelection","$insertTableColumnAtSelection","$deleteTableRowAtSelection","$deleteTableColumnAtSelection","Fragment","jsx","jsxs","r","useEffect","useLexicalComposerContext","$getSelection","$isRangeSelection","$isElementNode","$isRootNode","COMMAND_PRIORITY_LOW","useLexicalComposerContext","useEffect","$getSelection","$isRangeSelection","$isElementNode","$isRootNode","COMMAND_PRIORITY_LOW","useCallback","useEffect","useRef","useState","createPortal","useLexicalComposerContext","$createParagraphNode","$getNodeByKey","$getRoot","$getSelection","$isNodeSelection","$isRangeSelection","$isRootNode","COMMAND_PRIORITY_LOW","KEY_ARROW_DOWN_COMMAND","KEY_BACKSPACE_COMMAND","KEY_DELETE_COMMAND","KEY_ENTER_COMMAND","SELECTION_CHANGE_COMMAND","TextNode","jsx","jsxs","useLexicalComposerContext","useState","useRef","useEffect","$getSelection","$isRangeSelection","$createParagraphNode","$isRootNode","TextNode","$getRoot","COMMAND_PRIORITY_LOW","useCallback","rect","SELECTION_CHANGE_COMMAND","KEY_ENTER_COMMAND","KEY_ARROW_DOWN_COMMAND","$isNodeSelection","KEY_BACKSPACE_COMMAND","KEY_DELETE_COMMAND","$getNodeByKey","createPortal","forwardRef","useCallback","useEffect","useRef","useState","createPortal","useLexicalComposerContext","$getNodeByKey","$getRoot","$getSelection","$isRangeSelection","$isRootNode","COMMAND_PRIORITY_LOW","PaperPlaneRightIcon","Fragment","jsx","jsxs","DEFAULT_MAX_FILE_SIZE","DEFAULT_ALLOWED_FORMATS","useLexicalComposerContext","useState","useRef","useEffect","useCallback","$getRoot","$getSelection","$isRangeSelection","$isRootNode","$getNodeByKey","COMMAND_PRIORITY_LOW","createPortal","forwardRef","VideoUrlInput","useEffect","useLexicalComposerContext","$createParagraphNode","$getSelection","$isElementNode","$isRangeSelection","$isRootNode","COMMAND_PRIORITY_LOW","KEY_ARROW_DOWN_COMMAND","KEY_ARROW_UP_COMMAND","useLexicalComposerContext","useEffect","$getSelection","$isRangeSelection","$createParagraphNode","KEY_ARROW_DOWN_COMMAND","COMMAND_PRIORITY_LOW","KEY_ARROW_UP_COMMAND","$isRootNode","$isElementNode","createPortal","useCallback","useEffect","useRef","useLexicalComposerContext","$getSelection","$isRangeSelection","$isRootNode","COMMAND_PRIORITY_LOW","SELECTION_CHANGE_COMMAND","$isRootNode","useLexicalComposerContext","useRef","useCallback","useEffect","SELECTION_CHANGE_COMMAND","$getSelection","$isRangeSelection","$isRootNode","COMMAND_PRIORITY_LOW","useEffect","useRef","useState","useLexicalComposerContext","$getRoot","useLexicalComposerContext","useState","useRef","useEffect","$getRoot","useEffect","useRef","useLexicalComposerContext","$getRoot","jsx","createPortal"]}
|