@changerawr/markdown 1.1.3 → 1.1.4

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.
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/react/MarkdownRenderer.tsx","../../src/react/hooks.ts","../../src/parser.ts","../../src/utils.ts","../../src/renderer.ts","../../src/extensions/core/blockquote.ts","../../src/extensions/core/breaks.ts","../../src/extensions/core/code.ts","../../src/extensions/core/emphasis.ts","../../src/extensions/core/heading.ts","../../src/extensions/core/hr.ts","../../src/extensions/core/image.ts","../../src/extensions/core/links.ts","../../src/extensions/core/lists.ts","../../src/extensions/core/paragraph.ts","../../src/extensions/core/text.ts","../../src/extensions/core/index.ts","../../src/extensions/alert.ts","../../src/extensions/button.ts","../../src/extensions/embed.ts","../../src/engine.ts"],"sourcesContent":["import React, { useMemo, useEffect } from 'react';\r\nimport { useMarkdown } from './hooks';\r\nimport type { MarkdownRendererProps, UseMarkdownOptions } from './types';\r\n\r\n/**\r\n * MarkdownRenderer - Main React component for rendering markdown\r\n *\r\n * @example\r\n * ```tsx\r\n * <MarkdownRenderer\r\n * content=\"# Hello **World**!\"\r\n * className=\"prose\"\r\n * />\r\n * ```\r\n */\r\nexport function MarkdownRenderer({\r\n content,\r\n className,\r\n config,\r\n format = 'tailwind',\r\n as: Component = 'div',\r\n wrapperProps = {},\r\n debug = false,\r\n errorFallback,\r\n loading,\r\n onRender,\r\n onError,\r\n extensions,\r\n sanitize = true,\r\n allowUnsafeHtml = false,\r\n ...restProps\r\n }: MarkdownRendererProps) {\r\n // Prepare markdown options with proper type safety\r\n const markdownOptions = useMemo(() => {\r\n const options: UseMarkdownOptions = {\r\n format,\r\n debug,\r\n debounceMs: 0, // No debounce for tests\r\n memoize: true\r\n };\r\n\r\n // Add config if provided\r\n if (config) {\r\n options.config = {\r\n ...config,\r\n renderer: {\r\n format, // Required field\r\n sanitize,\r\n allowUnsafeHtml,\r\n debugMode: debug,\r\n ...config.renderer\r\n }\r\n };\r\n } else {\r\n // Create minimal config with required format field\r\n options.config = {\r\n renderer: {\r\n format,\r\n sanitize,\r\n allowUnsafeHtml,\r\n debugMode: debug\r\n }\r\n };\r\n }\r\n\r\n // Add extensions if provided\r\n if (extensions) {\r\n options.extensions = extensions;\r\n }\r\n\r\n return options;\r\n }, [config, format, debug, extensions, sanitize, allowUnsafeHtml]);\r\n\r\n // Use the markdown hook\r\n const { html, tokens, isLoading, error } = useMarkdown(content, markdownOptions);\r\n\r\n // Call onRender callback when rendering completes\r\n useEffect(() => {\r\n if (html && onRender) {\r\n onRender(html, tokens);\r\n }\r\n }, [html, tokens, onRender]);\r\n\r\n // Call onError callback when error occurs\r\n useEffect(() => {\r\n if (error && onError) {\r\n onError(error);\r\n }\r\n }, [error, onError]);\r\n\r\n // Show loading state\r\n if (isLoading && loading) {\r\n return <>{loading}</>;\r\n }\r\n\r\n // Show error state\r\n if (error) {\r\n if (errorFallback) {\r\n return <>{errorFallback(error)}</>;\r\n }\r\n\r\n // Default error display\r\n return (\r\n <div className=\"changerawr-error bg-red-50 border border-red-200 text-red-700 px-4 py-3 rounded\">\r\n <div className=\"font-medium\">Markdown Render Error</div>\r\n <div className=\"text-sm mt-1\">{error.message}</div>\r\n </div>\r\n );\r\n }\r\n\r\n // Prepare wrapper props\r\n const finalWrapperProps = {\r\n ...wrapperProps,\r\n ...restProps,\r\n className: className ?\r\n `${className} changerawr-markdown` : 'changerawr-markdown',\r\n dangerouslySetInnerHTML: { __html: html }\r\n };\r\n\r\n // Render the component\r\n return React.createElement(Component, finalWrapperProps);\r\n}\r\n\r\n// Display name for debugging\r\nMarkdownRenderer.displayName = 'MarkdownRenderer';\r\n\r\n/**\r\n * MarkdownRenderer with error boundary\r\n */\r\nexport function SafeMarkdownRenderer(props: MarkdownRendererProps) {\r\n return (\r\n <MarkdownErrorBoundary {...(props.errorFallback && { fallback: props.errorFallback })}>\r\n <MarkdownRenderer {...props} />\r\n </MarkdownErrorBoundary>\r\n );\r\n}\r\n\r\n/**\r\n * Error boundary component for markdown rendering\r\n */\r\ninterface MarkdownErrorBoundaryProps {\r\n children: React.ReactNode;\r\n fallback?: (error: Error) => React.ReactNode;\r\n}\r\n\r\ninterface MarkdownErrorBoundaryState {\r\n hasError: boolean;\r\n error: Error | null;\r\n}\r\n\r\nclass MarkdownErrorBoundary extends React.Component<\r\n MarkdownErrorBoundaryProps,\r\n MarkdownErrorBoundaryState\r\n> {\r\n constructor(props: MarkdownErrorBoundaryProps) {\r\n super(props);\r\n this.state = { hasError: false, error: null };\r\n }\r\n\r\n static getDerivedStateFromError(error: Error): MarkdownErrorBoundaryState {\r\n return { hasError: true, error };\r\n }\r\n\r\n override componentDidCatch(error: Error, errorInfo: React.ErrorInfo) {\r\n console.error('MarkdownRenderer Error:', error, errorInfo);\r\n }\r\n\r\n override render() {\r\n if (this.state.hasError && this.state.error) {\r\n if (this.props.fallback) {\r\n return this.props.fallback(this.state.error);\r\n }\r\n\r\n return (\r\n <div className=\"changerawr-error-boundary bg-red-50 border border-red-200 text-red-700 px-4 py-3 rounded\">\r\n <div className=\"font-medium\">Markdown Component Error</div>\r\n <div className=\"text-sm mt-1\">{this.state.error.message}</div>\r\n <button\r\n onClick={() => this.setState({ hasError: false, error: null })}\r\n className=\"text-xs mt-2 px-2 py-1 bg-red-200 hover:bg-red-300 rounded\"\r\n >\r\n Try Again\r\n </button>\r\n </div>\r\n );\r\n }\r\n\r\n return this.props.children;\r\n }\r\n}\r\n\r\n/**\r\n * Lightweight markdown renderer for simple use cases\r\n */\r\nexport function SimpleMarkdownRenderer({\r\n content,\r\n className\r\n }: {\r\n content: string;\r\n className?: string;\r\n}) {\r\n return (\r\n <MarkdownRenderer\r\n content={content}\r\n {...(className && { className })}\r\n format=\"tailwind\"\r\n config={{\r\n renderer: {\r\n format: 'tailwind',\r\n sanitize: true\r\n }\r\n }}\r\n />\r\n );\r\n}\r\n\r\n/**\r\n * HTML-only markdown renderer (no Tailwind classes)\r\n */\r\nexport function HTMLMarkdownRenderer({\r\n content,\r\n className,\r\n sanitize = true\r\n }: {\r\n content: string;\r\n className?: string;\r\n sanitize?: boolean;\r\n}) {\r\n return (\r\n <MarkdownRenderer\r\n content={content}\r\n {...(className && { className })}\r\n format=\"html\"\r\n sanitize={sanitize}\r\n config={{\r\n renderer: { format: 'html' }\r\n }}\r\n />\r\n );\r\n}\r\n\r\n/**\r\n * Debug markdown renderer with performance info\r\n */\r\nexport function DebugMarkdownRenderer({\r\n content,\r\n className\r\n }: {\r\n content: string;\r\n className?: string;\r\n}) {\r\n return (\r\n <MarkdownRenderer\r\n content={content}\r\n {...(className && { className })}\r\n debug={true}\r\n format=\"tailwind\"\r\n config={{\r\n renderer: {\r\n format: 'tailwind',\r\n debugMode: true\r\n }\r\n }}\r\n />\r\n );\r\n}","import { useState, useCallback, useMemo, useRef, useEffect } from 'react';\r\nimport { ChangerawrMarkdown } from '../engine';\r\nimport type {\r\n UseMarkdownOptions,\r\n UseMarkdownResult,\r\n MarkdownEngineHookOptions,\r\n MarkdownDebugInfo,\r\n EngineConfig,\r\n RendererConfig,\r\n OutputFormat\r\n} from './types';\r\nimport type { MarkdownToken } from '../types';\r\n\r\n/**\r\n * Main hook for rendering markdown content\r\n */\r\nexport function useMarkdown(\r\n initialContent = '',\r\n options: UseMarkdownOptions = {}\r\n): UseMarkdownResult {\r\n const [content, setContent] = useState(initialContent);\r\n const [html, setHtml] = useState('');\r\n const [tokens, setTokens] = useState<MarkdownToken[]>([]);\r\n const [isLoading, setIsLoading] = useState(false);\r\n const [error, setError] = useState<Error | null>(null);\r\n const [debug, setDebug] = useState<MarkdownDebugInfo | null>(null);\r\n\r\n const engineRef = useRef<ChangerawrMarkdown | null>(null);\r\n\r\n // Create engine instance with proper type safety - recreate when format changes\r\n const engine = useMemo(() => {\r\n // Always recreate engine when dependencies change\r\n const format: OutputFormat = options.format ?? 'tailwind';\r\n const rendererConfig: RendererConfig = {\r\n format,\r\n ...(options.config?.renderer && {\r\n sanitize: options.config.renderer.sanitize,\r\n allowUnsafeHtml: options.config.renderer.allowUnsafeHtml,\r\n customClasses: options.config.renderer.customClasses,\r\n debugMode: options.debug ?? options.config.renderer.debugMode ?? false\r\n })\r\n };\r\n\r\n // Build full engine config\r\n const engineConfig: EngineConfig = {\r\n ...(options.config && {\r\n parser: options.config.parser,\r\n extensions: options.config.extensions\r\n }),\r\n renderer: rendererConfig\r\n };\r\n\r\n const newEngine = new ChangerawrMarkdown(engineConfig);\r\n\r\n // Register custom extensions if provided\r\n if (options.extensions) {\r\n options.extensions.forEach(extension => {\r\n newEngine.registerExtension(extension);\r\n });\r\n }\r\n\r\n engineRef.current = newEngine;\r\n return newEngine;\r\n }, [options.config, options.format, options.debug, options.extensions]);\r\n\r\n // Process markdown content\r\n const processMarkdown = useCallback((markdownContent: string) => {\r\n if (!markdownContent.trim()) {\r\n setHtml('');\r\n setTokens([]);\r\n setError(null);\r\n setDebug(null);\r\n setIsLoading(false);\r\n return;\r\n }\r\n\r\n setIsLoading(true);\r\n setError(null);\r\n\r\n try {\r\n // Parse and render using the actual engine methods\r\n const parsedTokens = engine.parse(markdownContent);\r\n const renderedHtml = engine.render(parsedTokens);\r\n\r\n setHtml(renderedHtml);\r\n setTokens(parsedTokens);\r\n\r\n // Set debug info if enabled\r\n if (options.debug) {\r\n const coreDebug = engine.getDebugInfo();\r\n const performanceMetrics = engine.getPerformanceMetrics();\r\n\r\n setDebug({\r\n core: coreDebug,\r\n performance: performanceMetrics,\r\n renderedAt: new Date(),\r\n contentLength: markdownContent.length,\r\n htmlLength: renderedHtml.length,\r\n extensionsUsed: engine.getExtensions()\r\n });\r\n }\r\n\r\n } catch (err) {\r\n const errorObj = err instanceof Error ? err : new Error(String(err));\r\n setError(errorObj);\r\n } finally {\r\n setIsLoading(false);\r\n }\r\n }, [engine, options.debug]);\r\n\r\n // Process content when it changes\r\n useEffect(() => {\r\n processMarkdown(content);\r\n }, [content, processMarkdown]);\r\n\r\n // Update content when initialContent changes\r\n useEffect(() => {\r\n setContent(initialContent);\r\n }, [initialContent]);\r\n\r\n const render = useCallback((newContent: string) => {\r\n setContent(newContent);\r\n }, []);\r\n\r\n const clear = useCallback(() => {\r\n setContent('');\r\n setHtml('');\r\n setTokens([]);\r\n setError(null);\r\n setDebug(null);\r\n }, []);\r\n\r\n return {\r\n html,\r\n tokens,\r\n isLoading,\r\n error,\r\n debug,\r\n render,\r\n clear\r\n };\r\n}\r\n\r\n/**\r\n * Hook for managing a markdown engine instance\r\n */\r\nexport function useMarkdownEngine(options: MarkdownEngineHookOptions = {}) {\r\n const engineRef = useRef<ChangerawrMarkdown | null>(null);\r\n\r\n const engine = useMemo(() => {\r\n // Always recreate engine when dependencies change\r\n const engineConfig: EngineConfig = {\r\n ...options.config,\r\n renderer: {\r\n format: 'tailwind', // Required field\r\n ...options.config?.renderer\r\n }\r\n };\r\n\r\n // Handle auto-register extensions option\r\n if (options.autoRegisterExtensions === false) {\r\n engineConfig.extensions = [];\r\n }\r\n\r\n const newEngine = new ChangerawrMarkdown(engineConfig);\r\n engineRef.current = newEngine;\r\n return newEngine;\r\n }, [options.config, options.autoRegisterExtensions]);\r\n\r\n const toHtml = useCallback((content: string) => {\r\n return engine.toHtml(content);\r\n }, [engine]);\r\n\r\n const parse = useCallback((content: string) => {\r\n return engine.parse(content);\r\n }, [engine]);\r\n\r\n const render = useCallback((tokens: MarkdownToken[]) => {\r\n return engine.render(tokens);\r\n }, [engine]);\r\n\r\n const getExtensions = useCallback(() => {\r\n return engine.getExtensions();\r\n }, [engine]);\r\n\r\n const hasExtension = useCallback((name: string) => {\r\n return engine.hasExtension(name);\r\n }, [engine]);\r\n\r\n const registerExtension = useCallback((extension: Parameters<ChangerawrMarkdown['registerExtension']>[0]) => {\r\n return engine.registerExtension(extension);\r\n }, [engine]);\r\n\r\n const unregisterExtension = useCallback((name: string) => {\r\n return engine.unregisterExtension(name);\r\n }, [engine]);\r\n\r\n const getWarnings = useCallback(() => {\r\n return engine.getWarnings();\r\n }, [engine]);\r\n\r\n const getDebugInfo = useCallback(() => {\r\n return engine.getDebugInfo();\r\n }, [engine]);\r\n\r\n const getPerformanceMetrics = useCallback(() => {\r\n return engine.getPerformanceMetrics();\r\n }, [engine]);\r\n\r\n return {\r\n engine,\r\n toHtml,\r\n parse,\r\n render,\r\n getExtensions,\r\n hasExtension,\r\n registerExtension,\r\n unregisterExtension,\r\n getWarnings,\r\n getDebugInfo,\r\n getPerformanceMetrics\r\n };\r\n}\r\n\r\n/**\r\n * Debug hook for markdown processing\r\n */\r\nexport function useMarkdownDebug(content: string) {\r\n const { html, tokens, debug } = useMarkdown(content, { debug: true });\r\n\r\n return {\r\n html,\r\n tokens,\r\n debug,\r\n stats: {\r\n tokenCount: tokens.length,\r\n htmlLength: html.length,\r\n contentLength: content.length\r\n }\r\n };\r\n}","import type { MarkdownToken, ParseRule, ParserConfig } from './types';\r\n\r\nexport class MarkdownParser {\r\n private rules: ParseRule[] = [];\r\n private warnings: string[] = [];\r\n private config: ParserConfig;\r\n\r\n constructor(config?: ParserConfig) {\r\n this.config = {\r\n debugMode: false,\r\n maxIterations: 10000,\r\n validateMarkdown: false,\r\n ...config\r\n };\r\n }\r\n\r\n addRule(rule: ParseRule): void {\r\n this.rules.push(rule);\r\n // Sort by priority - extensions should define their own priority\r\n this.rules.sort((a, b) => {\r\n // Feature extensions first (alert, button, embed) - they have more specific patterns\r\n const aFeatureExtension = ['alert', 'button', 'embed'].includes(a.name);\r\n const bFeatureExtension = ['alert', 'button', 'embed'].includes(b.name);\r\n\r\n if (aFeatureExtension && !bFeatureExtension) return -1;\r\n if (!aFeatureExtension && bFeatureExtension) return 1;\r\n\r\n // Core extensions next\r\n const aCoreExtension = ['text', 'heading', 'bold', 'italic', 'code', 'codeblock', 'link', 'image', 'list', 'task-list', 'blockquote', 'hr', 'paragraph', 'line-break'].includes(a.name);\r\n const bCoreExtension = ['text', 'heading', 'bold', 'italic', 'code', 'codeblock', 'link', 'image', 'list', 'task-list', 'blockquote', 'hr', 'paragraph', 'line-break'].includes(b.name);\r\n\r\n if (aCoreExtension && !bCoreExtension) return -1;\r\n if (!aCoreExtension && bCoreExtension) return 1;\r\n\r\n // Within same category, specific ordering\r\n // Images before links (more specific pattern)\r\n if (a.name === 'image' && b.name === 'link') return -1;\r\n if (a.name === 'link' && b.name === 'image') return 1;\r\n\r\n // Task lists before regular lists\r\n if (a.name === 'task-item' && b.name === 'list-item') return -1;\r\n if (a.name === 'list-item' && b.name === 'task-item') return 1;\r\n\r\n // Code blocks before inline code\r\n if (a.name === 'codeblock' && b.name === 'code') return -1;\r\n if (a.name === 'code' && b.name === 'codeblock') return 1;\r\n\r\n // Bold before italic\r\n if (a.name === 'bold' && b.name === 'italic') return -1;\r\n if (a.name === 'italic' && b.name === 'bold') return 1;\r\n\r\n // Then alphabetical\r\n return a.name.localeCompare(b.name);\r\n });\r\n }\r\n\r\n hasRule(name: string): boolean {\r\n return this.rules.some(rule => rule.name === name);\r\n }\r\n\r\n parse(markdown: string): MarkdownToken[] {\r\n // Clear previous warnings\r\n this.warnings = [];\r\n\r\n if (!markdown.trim()) {\r\n return [];\r\n }\r\n\r\n // Check if we have any rules at all\r\n if (this.rules.length === 0) {\r\n this.warnings.push('No parse rules registered - consider using CoreExtensions');\r\n return [{\r\n type: 'text',\r\n content: markdown,\r\n raw: markdown\r\n }];\r\n }\r\n\r\n // Pre-process markdown to handle common issues\r\n const processedMarkdown = this.preprocessMarkdown(markdown);\r\n\r\n const tokens: MarkdownToken[] = [];\r\n let remaining = processedMarkdown;\r\n let iterationCount = 0;\r\n const maxIterations = this.config.maxIterations || 10000;\r\n\r\n while (remaining.length > 0 && iterationCount < maxIterations) {\r\n iterationCount++;\r\n let matched = false;\r\n let bestMatch: { rule: ParseRule; match: RegExpMatchArray; priority: number } | null = null;\r\n\r\n // Try each rule and find the best match (earliest position)\r\n for (const rule of this.rules) {\r\n try {\r\n // Create a fresh regex without global flag for position-based matching\r\n const pattern = new RegExp(rule.pattern.source, rule.pattern.flags.replace('g', ''));\r\n const match = remaining.match(pattern);\r\n\r\n if (match && match.index !== undefined) {\r\n // Prioritize matches at position 0, but also consider nearby matches\r\n const priority = match.index === 0 ? 1000 : (1000 - match.index);\r\n\r\n if (!bestMatch || priority > bestMatch.priority ||\r\n (priority === bestMatch.priority && match.index < (bestMatch.match.index || 0))) {\r\n bestMatch = { rule, match, priority };\r\n }\r\n }\r\n } catch (error) {\r\n if (this.config.debugMode) {\r\n console.warn(`Error in rule \"${rule.name}\":`, error);\r\n }\r\n }\r\n }\r\n\r\n if (bestMatch && bestMatch.match.index !== undefined) {\r\n const { rule, match } = bestMatch;\r\n const matchIndex = match.index as number;\r\n\r\n // If match is not at the beginning, take text before it\r\n if (matchIndex > 0) {\r\n const textBefore = remaining.slice(0, matchIndex);\r\n tokens.push({\r\n type: 'text',\r\n content: textBefore,\r\n raw: textBefore\r\n });\r\n remaining = remaining.slice(matchIndex);\r\n continue;\r\n }\r\n\r\n // Process the match\r\n try {\r\n const token = rule.render(match);\r\n tokens.push({\r\n ...token,\r\n raw: match[0] || ''\r\n });\r\n\r\n remaining = remaining.slice(match[0]?.length || 0);\r\n matched = true;\r\n } catch (error) {\r\n const errorMessage = error instanceof Error ? error.message : String(error);\r\n this.warnings.push(`Failed to render ${rule.name}: ${errorMessage}`);\r\n\r\n // Fall back to treating as text\r\n const char = remaining[0];\r\n if (char) {\r\n tokens.push({\r\n type: 'text',\r\n content: char,\r\n raw: char\r\n });\r\n remaining = remaining.slice(1);\r\n }\r\n }\r\n }\r\n\r\n if (!matched) {\r\n // Take one character and continue\r\n const char = remaining[0];\r\n if (char) {\r\n tokens.push({\r\n type: 'text',\r\n content: char,\r\n raw: char\r\n });\r\n remaining = remaining.slice(1);\r\n }\r\n }\r\n }\r\n\r\n if (iterationCount >= maxIterations) {\r\n this.warnings.push('Parser hit maximum iterations - possible infinite loop detected');\r\n }\r\n\r\n // Post-process tokens to merge consecutive text and validate structure\r\n const processedTokens = this.postProcessTokens(tokens);\r\n\r\n return processedTokens;\r\n }\r\n\r\n getWarnings(): string[] {\r\n return [...this.warnings];\r\n }\r\n\r\n getConfig(): ParserConfig {\r\n return { ...this.config };\r\n }\r\n\r\n updateConfig(config: Partial<ParserConfig>): void {\r\n this.config = { ...this.config, ...config };\r\n }\r\n\r\n setDebugMode(enabled: boolean): void {\r\n this.config.debugMode = enabled;\r\n }\r\n\r\n clearWarnings(): void {\r\n this.warnings = [];\r\n }\r\n\r\n private preprocessMarkdown(markdown: string): string {\r\n // Check for common markdown issues and warn about them\r\n if (this.config.validateMarkdown) {\r\n this.validateMarkdown(markdown);\r\n }\r\n\r\n // Normalize line endings\r\n return markdown.replace(/\\r\\n/g, '\\n').replace(/\\r/g, '\\n');\r\n }\r\n\r\n private validateMarkdown(markdown: string): void {\r\n // Check for unclosed bold markers\r\n const boldMatches = markdown.match(/\\*\\*/g);\r\n if (boldMatches && boldMatches.length % 2 !== 0) {\r\n this.warnings.push('Unclosed bold markers (**) detected - some bold formatting may not work');\r\n }\r\n\r\n // Check for unclosed italic markers\r\n const italicMatches = markdown.match(/(?<!\\*)\\*(?!\\*)/g);\r\n if (italicMatches && italicMatches.length % 2 !== 0) {\r\n this.warnings.push('Unclosed italic markers (*) detected - some italic formatting may not work');\r\n }\r\n\r\n // Check for unclosed code blocks\r\n const codeBlockMatches = markdown.match(/```/g);\r\n if (codeBlockMatches && codeBlockMatches.length % 2 !== 0) {\r\n this.warnings.push('Unclosed code blocks (```) detected - some code formatting may not work');\r\n }\r\n\r\n // Check for unclosed inline code\r\n const inlineCodeMatches = markdown.match(/`/g);\r\n if (inlineCodeMatches && inlineCodeMatches.length % 2 !== 0) {\r\n this.warnings.push('Unclosed inline code markers (`) detected - some code formatting may not work');\r\n }\r\n }\r\n\r\n private postProcessTokens(tokens: MarkdownToken[]): MarkdownToken[] {\r\n const processed: MarkdownToken[] = [];\r\n let i = 0;\r\n\r\n while (i < tokens.length) {\r\n const token = tokens[i];\r\n\r\n if (token && token.type === 'text') {\r\n // Collect consecutive text tokens\r\n let textContent = token.content || token.raw || '';\r\n let j = i + 1;\r\n\r\n while (j < tokens.length && tokens[j] && tokens[j]!.type === 'text') {\r\n const nextToken = tokens[j]!;\r\n textContent += nextToken.content || nextToken.raw || '';\r\n j++;\r\n }\r\n\r\n // Only create a text token if there's actual content\r\n if (textContent.trim().length > 0 || textContent.includes('\\n')) {\r\n processed.push({\r\n type: 'text',\r\n content: textContent,\r\n raw: textContent\r\n });\r\n }\r\n\r\n i = j;\r\n } else if (token) {\r\n processed.push(token);\r\n i++;\r\n } else {\r\n i++;\r\n }\r\n }\r\n\r\n return processed;\r\n }\r\n}","/**\r\n * Utility functions for Changerawr Markdown\r\n */\r\n\r\n// Import DOMPurify with SSR safety\r\nlet DOMPurify: { sanitize: (html: string, options?: Record<string, unknown>) => string } = {\r\n sanitize: (html: string) => html\r\n};\r\n\r\nif (typeof window !== 'undefined') {\r\n import('dompurify').then(module => {\r\n DOMPurify = module.default;\r\n }).catch(err => {\r\n console.error('Failed to load DOMPurify', err);\r\n });\r\n}\r\n\r\n// Allowed HTML tags and attributes for sanitization\r\nconst ALLOWED_TAGS = [\r\n // Standard HTML\r\n 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'p', 'br', 'strong', 'em', 'del', 'ins',\r\n 'a', 'img', 'ul', 'ol', 'li', 'blockquote', 'pre', 'code', 'table', 'thead',\r\n 'tbody', 'tr', 'th', 'td', 'div', 'span', 'sup', 'sub', 'hr', 'input',\r\n // Embeds\r\n 'iframe', 'embed', 'object', 'param', 'video', 'audio', 'source',\r\n // SVG\r\n 'svg', 'path', 'polyline', 'line', 'circle', 'rect', 'g', 'defs', 'use',\r\n // Form elements\r\n 'form', 'fieldset', 'legend', 'label', 'select', 'option', 'textarea', 'button'\r\n];\r\n\r\nconst ALLOWED_ATTR = [\r\n // Standard attributes\r\n 'href', 'title', 'alt', 'src', 'class', 'id', 'target', 'rel', 'type',\r\n 'checked', 'disabled', 'loading', 'width', 'height', 'style', 'role',\r\n // Iframe attributes\r\n 'frameborder', 'allowfullscreen', 'allow', 'sandbox', 'scrolling',\r\n 'allowtransparency', 'name', 'seamless', 'srcdoc',\r\n // Data attributes (for embeds)\r\n 'data-*',\r\n // SVG attributes\r\n 'viewBox', 'fill', 'stroke', 'stroke-width', 'stroke-linecap', 'stroke-linejoin',\r\n 'd', 'points', 'x1', 'y1', 'x2', 'y2', 'cx', 'cy', 'r', 'rx', 'ry',\r\n // Media attributes\r\n 'autoplay', 'controls', 'loop', 'muted', 'preload', 'poster',\r\n // Form attributes\r\n 'value', 'placeholder', 'required', 'readonly', 'maxlength', 'minlength',\r\n 'max', 'min', 'step', 'pattern', 'autocomplete', 'autofocus'\r\n];\r\n\r\n/**\r\n * Escape HTML special characters\r\n */\r\nexport function escapeHtml(text: string): string {\r\n const map: Record<string, string> = {\r\n '&': '&amp;',\r\n '<': '&lt;',\r\n '>': '&gt;',\r\n '\"': '&quot;',\r\n \"'\": '&#39;'\r\n };\r\n return text.replace(/[&<>\"']/g, char => map[char] || char);\r\n}\r\n\r\n/**\r\n * Generate URL-friendly ID from text\r\n */\r\nexport function generateId(text: string): string {\r\n return text\r\n .toLowerCase()\r\n .replace(/[^\\w\\s-]/g, '')\r\n .replace(/\\s+/g, '-')\r\n .replace(/-+/g, '-')\r\n .replace(/^-|-$/g, '')\r\n .trim();\r\n}\r\n\r\n/**\r\n * Sanitize HTML content using DOMPurify\r\n */\r\nexport function sanitizeHtml(html: string): string {\r\n try {\r\n // Skip sanitization for embed content that might be sensitive\r\n if (html.includes('codepen.io/') || html.includes('youtube.com/embed/')) {\r\n return html;\r\n }\r\n\r\n // Use DOMPurify if available\r\n if (typeof DOMPurify?.sanitize === 'function') {\r\n const sanitized = DOMPurify.sanitize(html, {\r\n ALLOWED_TAGS,\r\n ALLOWED_ATTR,\r\n ALLOW_DATA_ATTR: true,\r\n ALLOW_UNKNOWN_PROTOCOLS: false,\r\n SAFE_FOR_TEMPLATES: false,\r\n WHOLE_DOCUMENT: false,\r\n RETURN_DOM: false,\r\n RETURN_DOM_FRAGMENT: false,\r\n FORCE_BODY: false,\r\n SANITIZE_DOM: false,\r\n SANITIZE_NAMED_PROPS: false,\r\n FORBID_ATTR: ['onload', 'onerror', 'onclick', 'onmouseover', 'onmouseout', 'onfocus', 'onblur'],\r\n ADD_TAGS: ['iframe', 'embed', 'object', 'param'],\r\n ADD_ATTR: [\r\n 'allow', 'allowfullscreen', 'frameborder', 'scrolling',\r\n 'allowtransparency', 'sandbox', 'loading', 'style',\r\n 'title', 'name', 'seamless', 'srcdoc'\r\n ],\r\n ALLOWED_URI_REGEXP: /^(?:(?:(?:f|ht)tps?|mailto|tel|callto|cid|xmpp|xxx):|[^a-z]|[a-z+.\\-]+(?:[^a-z+.\\-:]|$))/i\r\n });\r\n\r\n // If too much content is lost, fall back to basic sanitization\r\n if (sanitized.length < html.length * 0.7) {\r\n return basicSanitize(html);\r\n }\r\n\r\n return sanitized;\r\n }\r\n\r\n // Fallback to basic sanitization\r\n return basicSanitize(html);\r\n } catch (error) {\r\n console.error('Sanitization failed:', error);\r\n return basicSanitize(html);\r\n }\r\n}\r\n\r\n/**\r\n * Basic HTML sanitization - removes dangerous content\r\n */\r\nexport function basicSanitize(html: string): string {\r\n return html\r\n .replace(/<script\\b[^<]*(?:(?!<\\/script>)<[^<]*)*<\\/script>/gi, '')\r\n .replace(/on\\w+\\s*=\\s*\"[^\"]*\"/gi, '')\r\n .replace(/on\\w+\\s*=\\s*'[^']*'/gi, '')\r\n .replace(/javascript:/gi, '');\r\n}\r\n\r\n/**\r\n * Check if code is running in browser environment\r\n */\r\nexport function isBrowser(): boolean {\r\n return typeof window !== 'undefined' && typeof document !== 'undefined';\r\n}\r\n\r\n/**\r\n * Check if code is running in Node.js environment\r\n */\r\nexport function isNode(): boolean {\r\n return typeof process !== 'undefined' &&\r\n process.versions != null &&\r\n process.versions.node != null;\r\n}\r\n\r\n/**\r\n * Debounce function for performance optimization\r\n */\r\nexport function debounce<T extends (...args: any[]) => any>(\r\n func: T,\r\n wait: number\r\n): (...args: Parameters<T>) => void {\r\n let timeout: NodeJS.Timeout | number;\r\n\r\n return function executedFunction(...args: Parameters<T>) {\r\n const later = () => {\r\n clearTimeout(timeout as NodeJS.Timeout);\r\n func(...args);\r\n };\r\n\r\n clearTimeout(timeout as NodeJS.Timeout);\r\n timeout = setTimeout(later, wait);\r\n };\r\n}\r\n\r\n/**\r\n * Deep merge two objects\r\n */\r\nexport function deepMerge<T extends Record<string, any>>(target: T, source: Partial<T>): T {\r\n const output = { ...target };\r\n\r\n for (const key in source) {\r\n if (source[key] && typeof source[key] === 'object' && !Array.isArray(source[key])) {\r\n if (key in target && typeof target[key] === 'object' && !Array.isArray(target[key])) {\r\n output[key] = deepMerge(target[key], source[key] as any);\r\n } else {\r\n output[key] = source[key] as any;\r\n }\r\n } else {\r\n output[key] = source[key] as any;\r\n }\r\n }\r\n\r\n return output;\r\n}\r\n\r\n/**\r\n * Extract domain from URL\r\n */\r\nexport function extractDomain(url: string): string {\r\n try {\r\n return new URL(url).hostname;\r\n } catch {\r\n return url;\r\n }\r\n}\r\n\r\n/**\r\n * Check if URL is valid\r\n */\r\nexport function isValidUrl(url: string): boolean {\r\n try {\r\n new URL(url);\r\n return true;\r\n } catch {\r\n return false;\r\n }\r\n}\r\n\r\n/**\r\n * Parse options string into key-value object\r\n */\r\nexport function parseOptions(options: string): Record<string, string> {\r\n const parsed: Record<string, string> = {};\r\n if (!options) return parsed;\r\n\r\n // Parse options like \"height:400,theme:dark,autoplay:1\"\r\n options.split(',').forEach(option => {\r\n const [key, value] = option.split(':').map(s => s.trim());\r\n if (key && value) {\r\n parsed[key] = value;\r\n }\r\n });\r\n\r\n return parsed;\r\n}\r\n\r\n/**\r\n * Performance measurement utility\r\n */\r\nexport class PerformanceTimer {\r\n private startTime: number;\r\n private marks: Record<string, number> = {};\r\n\r\n constructor() {\r\n this.startTime = performance.now();\r\n }\r\n\r\n mark(name: string): void {\r\n this.marks[name] = performance.now() - this.startTime;\r\n }\r\n\r\n getTime(name?: string): number {\r\n if (name && this.marks[name] !== undefined) {\r\n return this.marks[name];\r\n }\r\n return performance.now() - this.startTime;\r\n }\r\n\r\n getAllMarks(): Record<string, number> {\r\n return { ...this.marks };\r\n }\r\n}\r\n\r\n/**\r\n * Simple logger with different levels\r\n */\r\nexport class Logger {\r\n private debugMode: boolean;\r\n\r\n constructor(debugMode = false) {\r\n this.debugMode = debugMode;\r\n }\r\n\r\n debug(...args: any[]): void {\r\n if (this.debugMode) {\r\n console.log('[DEBUG]', ...args);\r\n }\r\n }\r\n\r\n info(...args: any[]): void {\r\n console.info('[INFO]', ...args);\r\n }\r\n\r\n warn(...args: any[]): void {\r\n console.warn('[WARN]', ...args);\r\n }\r\n\r\n error(...args: any[]): void {\r\n console.error('[ERROR]', ...args);\r\n }\r\n\r\n setDebugMode(enabled: boolean): void {\r\n this.debugMode = enabled;\r\n }\r\n}","import type { MarkdownToken, RenderRule, RendererConfig } from './types';\r\nimport { sanitizeHtml, escapeHtml } from './utils';\r\n\r\nexport class MarkdownRenderer {\r\n private rules = new Map<string, RenderRule>();\r\n private warnings: string[] = [];\r\n private config: RendererConfig;\r\n\r\n constructor(config?: RendererConfig) {\r\n this.config = {\r\n format: 'tailwind',\r\n sanitize: true,\r\n allowUnsafeHtml: false,\r\n debugMode: false,\r\n ...config\r\n };\r\n }\r\n\r\n addRule(rule: RenderRule): void {\r\n this.rules.set(rule.type, rule);\r\n }\r\n\r\n hasRule(type: string): boolean {\r\n return this.rules.has(type);\r\n }\r\n\r\n render(tokens: MarkdownToken[]): string {\r\n this.warnings = [];\r\n\r\n // Inject format into each token for extensions to use\r\n const tokensWithFormat = tokens.map(token => ({\r\n ...token,\r\n attributes: {\r\n ...token.attributes,\r\n format: this.config.format\r\n }\r\n }));\r\n\r\n // Render each token using registered extensions\r\n const htmlParts = tokensWithFormat.map(token => this.renderToken(token));\r\n const combinedHtml = htmlParts.join('');\r\n\r\n // Apply sanitization if enabled\r\n if (this.config.sanitize && !this.config.allowUnsafeHtml) {\r\n return sanitizeHtml(combinedHtml);\r\n }\r\n\r\n return combinedHtml;\r\n }\r\n\r\n private renderToken(token: MarkdownToken): string {\r\n const rule = this.rules.get(token.type);\r\n\r\n if (rule) {\r\n try {\r\n return rule.render(token);\r\n } catch (error) {\r\n const errorMessage = error instanceof Error ? error.message : String(error);\r\n this.warnings.push(`Render error for ${token.type}: ${errorMessage}`);\r\n return this.createErrorBlock(`Render error for ${token.type}: ${errorMessage}`);\r\n }\r\n }\r\n\r\n // For unknown types in development, show debug info\r\n if (this.config.debugMode) {\r\n return this.createDebugBlock(token);\r\n }\r\n\r\n // Fallback: treat as text if no rule found\r\n return escapeHtml(token.content || token.raw || '');\r\n }\r\n\r\n private createErrorBlock(message: string): string {\r\n if (this.config.format === 'html') {\r\n return `<div style=\"background-color: #fee; border: 1px solid #fcc; color: #c66; padding: 8px; border-radius: 4px; margin: 8px 0; font-size: 14px;\">\r\n <strong>Render Error:</strong> ${escapeHtml(message)}\r\n </div>`;\r\n }\r\n\r\n return `<div class=\"bg-red-100 border border-red-300 text-red-800 p-2 rounded text-sm mb-2\">\r\n <strong>Render Error:</strong> ${escapeHtml(message)}\r\n </div>`;\r\n }\r\n\r\n private createDebugBlock(token: MarkdownToken): string {\r\n if (this.config.format === 'html') {\r\n return `<div style=\"background-color: #fffbf0; border: 1px solid #fed; color: #b8860b; padding: 8px; border-radius: 4px; margin: 8px 0; font-size: 14px;\">\r\n <strong>Unknown token type:</strong> ${escapeHtml(token.type)}<br>\r\n <strong>Content:</strong> ${escapeHtml(token.content || token.raw || '')}\r\n </div>`;\r\n }\r\n\r\n return `<div class=\"bg-yellow-100 border border-yellow-300 text-yellow-800 p-2 rounded text-sm mb-2\">\r\n <strong>Unknown token type:</strong> ${escapeHtml(token.type)}<br>\r\n <strong>Content:</strong> ${escapeHtml(token.content || token.raw || '')}\r\n </div>`;\r\n }\r\n\r\n getWarnings(): string[] {\r\n return [...this.warnings];\r\n }\r\n\r\n getConfig(): RendererConfig {\r\n return { ...this.config };\r\n }\r\n\r\n updateConfig(config: Partial<RendererConfig>): void {\r\n this.config = { ...this.config, ...config };\r\n }\r\n\r\n setDebugMode(enabled: boolean): void {\r\n this.config.debugMode = enabled;\r\n }\r\n\r\n clearWarnings(): void {\r\n this.warnings = [];\r\n }\r\n}","import {escapeHtml} from \"@/utils.ts\";\r\nimport {Extension} from \"@/types.ts\";\r\n\r\nexport const BlockquoteExtension: Extension = {\r\n name: 'blockquote',\r\n parseRules: [\r\n {\r\n name: 'blockquote',\r\n pattern: /^>\\s+(.+)$/m,\r\n render: (match) => ({\r\n type: 'blockquote',\r\n content: match[1] || '',\r\n raw: match[0] || ''\r\n })\r\n }\r\n ],\r\n renderRules: [\r\n {\r\n type: 'blockquote',\r\n render: (token) => {\r\n const content = escapeHtml(token.content);\r\n const format = token.attributes?.format || 'html';\r\n\r\n if (format === 'html') {\r\n return `<blockquote style=\"border-left: 2px solid #d1d5db; padding: 8px 0 8px 16px; margin: 16px 0; font-style: italic; color: #6b7280;\">${content}</blockquote>`;\r\n }\r\n return `<blockquote class=\"pl-4 py-2 border-l-2 border-border italic text-muted-foreground my-4\">${content}</blockquote>`;\r\n }\r\n }\r\n ]\r\n};","import {Extension} from \"@/types.ts\";\r\n\r\nexport const LineBreakExtension: Extension = {\r\n name: 'line-break',\r\n parseRules: [\r\n {\r\n name: 'hard-break-backslash',\r\n pattern: /\\\\\\s*\\n/,\r\n render: (match) => ({\r\n type: 'line-break',\r\n content: '',\r\n raw: match[0] || ''\r\n })\r\n },\r\n {\r\n name: 'hard-break-spaces',\r\n pattern: / +\\n/,\r\n render: (match) => ({\r\n type: 'line-break',\r\n content: '',\r\n raw: match[0] || ''\r\n })\r\n }\r\n ],\r\n renderRules: [\r\n {\r\n type: 'line-break',\r\n render: () => '<br>'\r\n },\r\n {\r\n type: 'paragraph-break',\r\n render: () => '</p><p>'\r\n },\r\n {\r\n type: 'soft-break',\r\n render: (token) => token.content || ' '\r\n }\r\n ]\r\n};","import type { Extension } from '../../types';\r\nimport { escapeHtml } from '../../utils';\r\n\r\nexport const InlineCodeExtension: Extension = {\r\n name: 'inline-code',\r\n parseRules: [\r\n {\r\n name: 'code',\r\n pattern: /`([^`]+)`/,\r\n render: (match) => ({\r\n type: 'code',\r\n content: match[1] || '',\r\n raw: match[0] || ''\r\n })\r\n }\r\n ],\r\n renderRules: [\r\n {\r\n type: 'code',\r\n render: (token) => {\r\n const content = escapeHtml(token.content);\r\n const format = token.attributes?.format;\r\n\r\n if (format === 'html') {\r\n return `<code style=\"background-color: #f3f4f6; padding: 2px 6px; border-radius: 4px; font-family: monospace; font-size: 0.875rem;\">${content}</code>`;\r\n }\r\n // Default to Tailwind\r\n return `<code class=\"bg-muted px-1.5 py-0.5 rounded text-sm font-mono\">${content}</code>`;\r\n }\r\n }\r\n ]\r\n};\r\n\r\nexport const CodeBlockExtension: Extension = {\r\n name: 'codeblock',\r\n parseRules: [\r\n {\r\n name: 'codeblock',\r\n pattern: /```(\\w+)?\\s*\\n([\\s\\S]*?)\\n```/,\r\n render: (match) => ({\r\n type: 'codeblock',\r\n content: match[2] || '',\r\n raw: match[0] || '',\r\n attributes: {\r\n language: match[1] || 'text'\r\n }\r\n })\r\n }\r\n ],\r\n renderRules: [\r\n {\r\n type: 'codeblock',\r\n render: (token) => {\r\n const language = token.attributes?.language || 'text';\r\n const escapedCode = escapeHtml(token.content);\r\n const format = token.attributes?.format || 'html';\r\n\r\n if (format === 'html') {\r\n return `<pre style=\"background-color: #f3f4f6; padding: 16px; border-radius: 6px; overflow-x: auto; margin: 16px 0;\"><code class=\"language-${escapeHtml(language)}\">${escapedCode}</code></pre>`;\r\n }\r\n\r\n return `<pre class=\"bg-muted p-4 rounded-md overflow-x-auto my-4\"><code class=\"language-${escapeHtml(language)}\">${escapedCode}</code></pre>`;\r\n }\r\n }\r\n ]\r\n};","import type { Extension } from '../../types';\r\nimport { escapeHtml } from '../../utils';\r\n\r\nexport const BoldExtension: Extension = {\r\n name: 'bold',\r\n parseRules: [\r\n {\r\n name: 'bold',\r\n pattern: /\\*\\*((?:(?!\\*\\*).)+)\\*\\*/,\r\n render: (match) => ({\r\n type: 'bold',\r\n content: match[1] || '',\r\n raw: match[0] || ''\r\n })\r\n }\r\n ],\r\n renderRules: [\r\n {\r\n type: 'bold',\r\n render: (token) => {\r\n const content = escapeHtml(token.content);\r\n const format = token.attributes?.format;\r\n\r\n if (format === 'html') {\r\n return `<strong>${content}</strong>`;\r\n }\r\n // Default to Tailwind\r\n return `<strong class=\"font-bold\">${content}</strong>`;\r\n }\r\n }\r\n ]\r\n};\r\n\r\nexport const ItalicExtension: Extension = {\r\n name: 'italic',\r\n parseRules: [\r\n {\r\n name: 'italic',\r\n pattern: /\\*((?:(?!\\*).)+)\\*/,\r\n render: (match) => ({\r\n type: 'italic',\r\n content: match[1] || '',\r\n raw: match[0] || ''\r\n })\r\n }\r\n ],\r\n renderRules: [\r\n {\r\n type: 'italic',\r\n render: (token) => {\r\n const content = escapeHtml(token.content);\r\n const format = token.attributes?.format;\r\n\r\n if (format === 'html') {\r\n return `<em>${content}</em>`;\r\n }\r\n // Default to Tailwind\r\n return `<em class=\"italic\">${content}</em>`;\r\n }\r\n }\r\n ]\r\n};","import type { Extension } from '../../types';\r\nimport { escapeHtml, generateId } from '../../utils';\r\n\r\nexport const HeadingExtension: Extension = {\r\n name: 'heading',\r\n parseRules: [\r\n {\r\n name: 'heading',\r\n pattern: /^(#{1,6})\\s+(.+)$/m,\r\n render: (match) => ({\r\n type: 'heading',\r\n content: match[2]?.trim() || '',\r\n raw: match[0] || '',\r\n attributes: {\r\n level: String(match[1]?.length || 1)\r\n }\r\n })\r\n }\r\n ],\r\n renderRules: [\r\n {\r\n type: 'heading',\r\n render: (token) => {\r\n const level = parseInt(token.attributes?.level || '1');\r\n const text = token.content;\r\n const id = generateId(text);\r\n const escapedContent = escapeHtml(text);\r\n\r\n // Default to HTML format, extensions can override\r\n const format = token.attributes?.format || 'html';\r\n\r\n if (format === 'html') {\r\n return `<h${level} id=\"${id}\">${escapedContent}</h${level}>`;\r\n }\r\n\r\n // Tailwind format\r\n let headingClasses = 'group relative flex items-center gap-2';\r\n\r\n switch (level) {\r\n case 1: headingClasses += ' text-3xl font-bold mt-8 mb-4'; break;\r\n case 2: headingClasses += ' text-2xl font-semibold mt-6 mb-3'; break;\r\n case 3: headingClasses += ' text-xl font-medium mt-5 mb-3'; break;\r\n case 4: headingClasses += ' text-lg font-medium mt-4 mb-2'; break;\r\n case 5: headingClasses += ' text-base font-medium mt-3 mb-2'; break;\r\n case 6: headingClasses += ' text-sm font-medium mt-3 mb-2'; break;\r\n }\r\n\r\n return `<h${level} id=\"${id}\" class=\"${headingClasses}\">\r\n ${escapedContent}\r\n <a href=\"#${id}\" class=\"opacity-0 group-hover:opacity-100 text-muted-foreground transition-opacity\">\r\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\r\n <path d=\"M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71\"/>\r\n <path d=\"M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71\"/>\r\n</svg>\r\n </a>\r\n </h${level}>`;\r\n }\r\n }\r\n ]\r\n};","import {Extension} from \"@/types.ts\";\r\n\r\nexport const HorizontalRuleExtension: Extension = {\r\n name: 'hr',\r\n parseRules: [\r\n {\r\n name: 'hr',\r\n pattern: /^---$/m,\r\n render: (match) => ({\r\n type: 'hr',\r\n content: '',\r\n raw: match[0] || ''\r\n })\r\n }\r\n ],\r\n renderRules: [\r\n {\r\n type: 'hr',\r\n render: (token) => {\r\n const format = token.attributes?.format;\r\n\r\n if (format === 'html') {\r\n return '<hr style=\"margin: 24px 0; border: none; border-top: 1px solid #d1d5db;\">';\r\n }\r\n // Default to Tailwind\r\n return '<hr class=\"my-6 border-t border-border\">';\r\n }\r\n }\r\n ]\r\n};","import {escapeHtml} from \"@/utils.ts\";\r\nimport {Extension} from \"@/types.ts\";\r\n\r\nexport const ImageExtension: Extension = {\r\n name: 'image',\r\n parseRules: [\r\n {\r\n name: 'image',\r\n pattern: /!\\[([^\\]]*)\\]\\(([^)]+?)(?:\\s+\"([^\"]+)\")?\\)/,\r\n render: (match) => ({\r\n type: 'image',\r\n content: match[1] || '',\r\n raw: match[0] || '',\r\n attributes: {\r\n alt: match[1] || '',\r\n src: match[2] || '',\r\n title: match[3] || ''\r\n }\r\n })\r\n }\r\n ],\r\n renderRules: [\r\n {\r\n type: 'image',\r\n render: (token) => {\r\n const src = token.attributes?.src || '';\r\n const alt = token.attributes?.alt || '';\r\n const title = token.attributes?.title || '';\r\n const titleAttr = title ? ` title=\"${escapeHtml(title)}\"` : '';\r\n const format = token.attributes?.format || 'html';\r\n\r\n if (format === 'html') {\r\n return `<img src=\"${escapeHtml(src)}\" alt=\"${escapeHtml(alt)}\"${titleAttr} style=\"max-width: 100%; height: auto; border-radius: 8px; margin: 16px 0;\" loading=\"lazy\" />`;\r\n }\r\n\r\n return `<img src=\"${escapeHtml(src)}\" alt=\"${escapeHtml(alt)}\"${titleAttr} class=\"max-w-full h-auto rounded-lg my-4\" loading=\"lazy\" />`;\r\n }\r\n }\r\n ]\r\n};","import type { Extension } from '../../types';\r\nimport { escapeHtml } from '../../utils';\r\n\r\nexport const LinkExtension: Extension = {\r\n name: 'link',\r\n parseRules: [\r\n {\r\n name: 'link',\r\n pattern: /\\[(?!(?:button|embed):)([^\\]]+)\\]\\(([^)]+)\\)/,\r\n render: (match) => ({\r\n type: 'link',\r\n content: match[1] || '',\r\n raw: match[0] || '',\r\n attributes: {\r\n href: match[2] || ''\r\n }\r\n })\r\n }\r\n ],\r\n renderRules: [\r\n {\r\n type: 'link',\r\n render: (token) => {\r\n const href = token.attributes?.href || '#';\r\n const escapedHref = escapeHtml(href);\r\n const escapedText = escapeHtml(token.content);\r\n const format = token.attributes?.format || 'html';\r\n\r\n if (format === 'html') {\r\n return `<a href=\"${escapedHref}\" target=\"_blank\" rel=\"noopener noreferrer\">${escapedText}</a>`;\r\n }\r\n\r\n return `<a href=\"${escapedHref}\" class=\"text-primary hover:underline inline-flex items-center gap-1\" target=\"_blank\" rel=\"noopener noreferrer\">\r\n ${escapedText}\r\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"12\" height=\"12\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" class=\"lucide lucide-external-link\">\r\n <path d=\"M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6\"></path>\r\n <polyline points=\"15 3 21 3 21 9\"></polyline>\r\n <line x1=\"10\" y1=\"14\" x2=\"21\" y2=\"3\"></line>\r\n </svg>\r\n </a>`;\r\n }\r\n }\r\n ]\r\n};","import {escapeHtml} from \"@/utils.ts\";\r\nimport {Extension} from \"@/types.ts\";\r\n\r\nexport const ListExtension: Extension = {\r\n name: 'list',\r\n parseRules: [\r\n {\r\n name: 'list-item',\r\n pattern: /^(\\s*)[-*+]\\s+(.+)$/m,\r\n render: (match) => ({\r\n type: 'list-item',\r\n content: match[2] || '',\r\n raw: match[0] || ''\r\n })\r\n }\r\n ],\r\n renderRules: [\r\n {\r\n type: 'list-item',\r\n render: (token) => `<li>${escapeHtml(token.content)}</li>`\r\n }\r\n ]\r\n};\r\n\r\nexport const TaskListExtension: Extension = {\r\n name: 'task-list',\r\n parseRules: [\r\n {\r\n name: 'task-item',\r\n pattern: /^(\\s*)-\\s*\\[([ xX])\\]\\s*(.+)$/m,\r\n render: (match) => ({\r\n type: 'task-item',\r\n content: match[3] || '',\r\n raw: match[0] || '',\r\n attributes: {\r\n checked: String((match[2] || '').toLowerCase() === 'x')\r\n }\r\n })\r\n }\r\n ],\r\n renderRules: [\r\n {\r\n type: 'task-item',\r\n render: (token) => {\r\n const isChecked = token.attributes?.checked === 'true';\r\n const escapedContent = escapeHtml(token.content);\r\n const format = token.attributes?.format || 'html';\r\n\r\n if (format === 'html') {\r\n return `<div style=\"display: flex; align-items: center; gap: 8px; margin: 8px 0;\">\r\n <input type=\"checkbox\" ${isChecked ? 'checked' : ''} disabled style=\"margin: 0;\" />\r\n <span${isChecked ? ' style=\"text-decoration: line-through; color: #6b7280;\"' : ''}>${escapedContent}</span>\r\n </div>`;\r\n }\r\n\r\n return `<div class=\"flex items-center gap-2 my-2 task-list-item\">\r\n <input type=\"checkbox\" ${isChecked ? 'checked' : ''} disabled \r\n class=\"form-checkbox h-4 w-4 rounded border-gray-300 text-primary focus:ring-primary\" />\r\n <span${isChecked ? ' class=\"line-through text-muted-foreground\"' : ''}>${escapedContent}</span>\r\n </div>`;\r\n }\r\n }\r\n ]\r\n};","import {Extension} from \"@/types.ts\";\r\nimport {escapeHtml} from \"@/utils.ts\";\r\n\r\nexport const ParagraphExtension: Extension = {\r\n name: 'paragraph',\r\n parseRules: [],\r\n renderRules: [\r\n {\r\n type: 'paragraph',\r\n render: (token) => {\r\n if (!token.content) return '';\r\n const content = token.content.trim();\r\n if (!content) return '';\r\n\r\n const processedContent = content.includes('<br>') ? content : escapeHtml(content);\r\n const format = token.attributes?.format || 'html';\r\n\r\n if (format === 'html') {\r\n return `<p style=\"line-height: 1.75; margin-bottom: 16px;\">${processedContent}</p>`;\r\n }\r\n\r\n return `<p class=\"leading-7 mb-4\">${processedContent}</p>`;\r\n }\r\n }\r\n ]\r\n};","import type { Extension } from '../../types';\r\nimport { escapeHtml } from '../../utils';\r\n\r\nexport const TextExtension: Extension = {\r\n name: 'text',\r\n parseRules: [],\r\n renderRules: [\r\n {\r\n type: 'text',\r\n render: (token) => {\r\n if (!token.content) return '';\r\n return escapeHtml(token.content);\r\n }\r\n }\r\n ]\r\n};","import { BlockquoteExtension } from \"./blockquote\";\r\nimport { LineBreakExtension } from \"./breaks\";\r\nimport {CodeBlockExtension, InlineCodeExtension } from \"./code\";\r\nimport { BoldExtension, ItalicExtension } from \"./emphasis\";\r\nimport { HeadingExtension } from \"./heading\";\r\nimport { HorizontalRuleExtension } from \"./hr\";\r\nimport { ImageExtension } from \"./image\";\r\nimport { LinkExtension } from \"./links\";\r\nimport { ListExtension, TaskListExtension } from \"./lists\";\r\nimport { ParagraphExtension } from \"./paragraph\";\r\nimport { TextExtension } from \"./text\";\r\n\r\nexport const CoreExtensions = [\r\n TextExtension,\r\n HeadingExtension,\r\n BoldExtension,\r\n ItalicExtension,\r\n InlineCodeExtension,\r\n CodeBlockExtension,\r\n LinkExtension,\r\n ImageExtension,\r\n ListExtension,\r\n TaskListExtension,\r\n BlockquoteExtension,\r\n HorizontalRuleExtension,\r\n ParagraphExtension,\r\n LineBreakExtension\r\n] as const;\r\n\r\nexport {\r\n TextExtension,\r\n HeadingExtension,\r\n BoldExtension,\r\n ItalicExtension,\r\n InlineCodeExtension,\r\n CodeBlockExtension,\r\n LinkExtension,\r\n ImageExtension,\r\n ListExtension,\r\n TaskListExtension,\r\n BlockquoteExtension,\r\n HorizontalRuleExtension,\r\n ParagraphExtension,\r\n LineBreakExtension\r\n};","import type { Extension } from '../types';\r\n\r\ninterface AlertTypeConfig {\r\n icon: string;\r\n classes: string;\r\n}\r\n\r\nexport const AlertExtension: Extension = {\r\n name: 'alert',\r\n parseRules: [\r\n {\r\n name: 'alert',\r\n pattern: /:::(\\w+)(?:\\s+(.*?))?\\s*\\n([\\s\\S]*?)\\n:::/,\r\n render: (match: RegExpMatchArray) => {\r\n return {\r\n type: 'alert',\r\n content: match[3]?.trim() || '',\r\n raw: match[0] || '',\r\n attributes: {\r\n type: match[1] || 'info',\r\n title: match[2] || ''\r\n }\r\n };\r\n }\r\n }\r\n ],\r\n renderRules: [\r\n {\r\n type: 'alert',\r\n render: (token) => {\r\n const type = token.attributes?.type || 'info';\r\n const title = token.attributes?.title || '';\r\n\r\n const typeConfig: Record<string, AlertTypeConfig> = {\r\n info: {\r\n icon: 'ℹ️',\r\n classes: 'bg-blue-500/10 border-blue-500/30 text-blue-600 border-l-blue-500'\r\n },\r\n warning: {\r\n icon: '⚠️',\r\n classes: 'bg-amber-500/10 border-amber-500/30 text-amber-600 border-l-amber-500'\r\n },\r\n error: {\r\n icon: '❌',\r\n classes: 'bg-red-500/10 border-red-500/30 text-red-600 border-l-red-500'\r\n },\r\n success: {\r\n icon: '✅',\r\n classes: 'bg-green-500/10 border-green-500/30 text-green-600 border-l-green-500'\r\n },\r\n tip: {\r\n icon: '💡',\r\n classes: 'bg-purple-500/10 border-purple-500/30 text-purple-600 border-l-purple-500'\r\n },\r\n note: {\r\n icon: '📝',\r\n classes: 'bg-gray-500/10 border-gray-500/30 text-gray-600 border-l-gray-500'\r\n }\r\n };\r\n\r\n const config = typeConfig[type] || typeConfig.info;\r\n const baseClasses = 'border-l-4 p-4 mb-4 rounded-md transition-colors duration-200';\r\n const classes = `${baseClasses} ${config?.classes}`;\r\n\r\n const titleHtml = title\r\n ? `<div class=\"font-medium mb-2 flex items-center gap-2\">\r\n <span class=\"text-lg\" role=\"img\" aria-label=\"${type}\">${config?.icon}</span>\r\n <span>${title}</span>\r\n </div>`\r\n : `<div class=\"font-medium mb-2 flex items-center gap-2\">\r\n <span class=\"text-lg\" role=\"img\" aria-label=\"${type}\">${config?.icon}</span>\r\n <span>${type.charAt(0).toUpperCase() + type.slice(1)}</span>\r\n </div>`;\r\n\r\n return `<div class=\"${classes}\" role=\"alert\" aria-live=\"polite\">\r\n ${titleHtml}\r\n <div class=\"leading-relaxed\">${token.content}</div>\r\n </div>`;\r\n }\r\n }\r\n ]\r\n};","import type { Extension } from '../types';\r\n\r\nexport const ButtonExtension: Extension = {\r\n name: 'button',\r\n parseRules: [\r\n {\r\n name: 'button',\r\n pattern: /\\[button:([^\\]]+)\\]\\(([^)]+)\\)(?:\\{([^}]+)\\})?/,\r\n render: (match) => {\r\n const options = match[3] ? match[3].split(',').map(opt => opt.trim()) : [];\r\n\r\n return {\r\n type: 'button',\r\n content: match[1] || '',\r\n raw: match[0] || '',\r\n attributes: {\r\n href: match[2] || '',\r\n style: options.find(opt =>\r\n ['default', 'primary', 'secondary', 'success', 'danger', 'outline', 'ghost'].includes(opt)\r\n ) || 'primary',\r\n size: options.find(opt => ['sm', 'md', 'lg'].includes(opt)) || 'md',\r\n disabled: String(options.includes('disabled')),\r\n target: options.includes('self') ? '_self' : '_blank'\r\n }\r\n };\r\n }\r\n }\r\n ],\r\n renderRules: [\r\n {\r\n type: 'button',\r\n render: (token) => {\r\n const href = token.attributes?.href || '#';\r\n const style = token.attributes?.style || 'primary';\r\n const size = token.attributes?.size || 'md';\r\n const disabled = token.attributes?.disabled === 'true';\r\n const target = token.attributes?.target || '_blank';\r\n\r\n // Base classes with optical border effect\r\n const baseClasses = `\r\n inline-flex items-center justify-center font-medium rounded-lg \r\n transition-all duration-200 ease-out\r\n focus:outline-none focus:ring-2 focus:ring-offset-2\r\n disabled:opacity-50 disabled:cursor-not-allowed disabled:pointer-events-none\r\n transform hover:scale-[1.02] active:scale-[0.98]\r\n shadow-sm hover:shadow-md active:shadow-sm\r\n border border-transparent\r\n relative overflow-hidden\r\n before:absolute before:inset-0 before:rounded-lg\r\n before:bg-gradient-to-br before:from-white/20 before:to-transparent\r\n before:opacity-0 hover:before:opacity-100 before:transition-opacity before:duration-200\r\n `.replace(/\\s+/g, ' ').trim();\r\n\r\n // Size classes\r\n const sizeClasses: Record<string, string> = {\r\n sm: 'px-3 py-1.5 text-sm gap-1.5',\r\n md: 'px-4 py-2 text-base gap-2',\r\n lg: 'px-6 py-3 text-lg gap-2.5'\r\n };\r\n\r\n // Style classes with optical borders using box-shadow\r\n const styleClasses: Record<string, string> = {\r\n default: `\r\n bg-slate-600 text-white border-slate-500\r\n hover:bg-slate-700 hover:border-slate-400\r\n focus:ring-slate-500\r\n shadow-[0_1px_0_0_rgba(255,255,255,0.1)_inset,0_1px_2px_0_rgba(0,0,0,0.1)]\r\n hover:shadow-[0_1px_0_0_rgba(255,255,255,0.15)_inset,0_2px_4px_0_rgba(0,0,0,0.15)]\r\n `,\r\n primary: `\r\n bg-blue-600 text-white border-blue-500\r\n hover:bg-blue-700 hover:border-blue-400\r\n focus:ring-blue-500\r\n shadow-[0_1px_0_0_rgba(255,255,255,0.1)_inset,0_1px_2px_0_rgba(0,0,0,0.1)]\r\n hover:shadow-[0_1px_0_0_rgba(255,255,255,0.15)_inset,0_2px_4px_0_rgba(0,0,0,0.15)]\r\n `,\r\n secondary: `\r\n bg-gray-600 text-white border-gray-500\r\n hover:bg-gray-700 hover:border-gray-400\r\n focus:ring-gray-500\r\n shadow-[0_1px_0_0_rgba(255,255,255,0.1)_inset,0_1px_2px_0_rgba(0,0,0,0.1)]\r\n hover:shadow-[0_1px_0_0_rgba(255,255,255,0.15)_inset,0_2px_4px_0_rgba(0,0,0,0.15)]\r\n `,\r\n success: `\r\n bg-green-600 text-white border-green-500\r\n hover:bg-green-700 hover:border-green-400\r\n focus:ring-green-500\r\n shadow-[0_1px_0_0_rgba(255,255,255,0.1)_inset,0_1px_2px_0_rgba(0,0,0,0.1)]\r\n hover:shadow-[0_1px_0_0_rgba(255,255,255,0.15)_inset,0_2px_4px_0_rgba(0,0,0,0.15)]\r\n `,\r\n danger: `\r\n bg-red-600 text-white border-red-500\r\n hover:bg-red-700 hover:border-red-400\r\n focus:ring-red-500\r\n shadow-[0_1px_0_0_rgba(255,255,255,0.1)_inset,0_1px_2px_0_rgba(0,0,0,0.1)]\r\n hover:shadow-[0_1px_0_0_rgba(255,255,255,0.15)_inset,0_2px_4px_0_rgba(0,0,0,0.15)]\r\n `,\r\n outline: `\r\n bg-transparent text-blue-600 border-blue-600\r\n hover:bg-blue-50 hover:border-blue-700 hover:text-blue-700\r\n focus:ring-blue-500\r\n shadow-[0_0_0_1px_rgba(59,130,246,0.5)_inset]\r\n hover:shadow-[0_0_0_1px_rgba(29,78,216,0.6)_inset,0_1px_2px_0_rgba(0,0,0,0.05)]\r\n `,\r\n ghost: `\r\n bg-transparent text-gray-700 border-transparent\r\n hover:bg-gray-100 hover:text-gray-900\r\n focus:ring-gray-500\r\n shadow-none\r\n hover:shadow-[0_1px_2px_0_rgba(0,0,0,0.05)]\r\n `\r\n };\r\n\r\n const classes = `\r\n ${baseClasses}\r\n ${sizeClasses[size] || sizeClasses.md}\r\n ${styleClasses[style] || styleClasses.primary}\r\n `.replace(/\\s+/g, ' ').trim();\r\n\r\n const targetAttr = target === '_blank' ? ' target=\"_blank\" rel=\"noopener noreferrer\"' :\r\n target === '_self' ? ' target=\"_self\"' : '';\r\n const disabledAttr = disabled ? ' aria-disabled=\"true\" tabindex=\"-1\"' : '';\r\n const externalIcon = target === '_blank' && !disabled ?\r\n `<svg class=\"w-4 h-4 ml-1 opacity-75\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\r\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M10 6H6a2 2 0 00-2 2v10a2 2 0 002 2h10a2 2 0 002-2v-4M14 4h6m0 0v6m0-6L10 14\"/>\r\n </svg>` : '';\r\n\r\n return `<a href=\"${href}\" class=\"${classes}\"${targetAttr}${disabledAttr}>\r\n <span class=\"relative z-10\">${token.content}</span>${externalIcon}\r\n </a>`;\r\n }\r\n }\r\n ]\r\n};","import type { Extension } from '../types';\r\nimport { parseOptions, extractDomain } from '../utils';\r\n\r\nexport const EmbedExtension: Extension = {\r\n name: 'embed',\r\n parseRules: [\r\n {\r\n name: 'embed',\r\n pattern: /\\[embed:(\\w+)\\]\\(([^)]+)\\)(?:\\{([^}]+)\\})?/,\r\n render: (match) => {\r\n return {\r\n type: 'embed',\r\n content: match[2] || '', // URL\r\n raw: match[0] || '',\r\n attributes: {\r\n provider: match[1] || 'generic',\r\n url: match[2] || '',\r\n options: match[3] || ''\r\n }\r\n };\r\n }\r\n }\r\n ],\r\n renderRules: [\r\n {\r\n type: 'embed',\r\n render: (token) => {\r\n const provider = token.attributes?.provider || 'generic';\r\n const url = token.attributes?.url || '';\r\n const options = token.attributes?.options || '';\r\n\r\n return renderEmbed(provider, url, options);\r\n }\r\n }\r\n ]\r\n};\r\n\r\nfunction renderEmbed(provider: string, url: string, options: string): string {\r\n const baseClasses = 'rounded-lg border bg-card text-card-foreground shadow-sm mb-6 overflow-hidden';\r\n const parsedOptions = parseOptions(options);\r\n\r\n switch (provider.toLowerCase()) {\r\n case 'youtube':\r\n return renderYouTubeEmbed(url, parsedOptions, baseClasses);\r\n case 'codepen':\r\n return renderCodePenEmbed(url, parsedOptions, baseClasses);\r\n case 'figma':\r\n return renderFigmaEmbed(url, parsedOptions, baseClasses);\r\n case 'twitter':\r\n case 'tweet':\r\n return renderTwitterEmbed(url, parsedOptions, baseClasses);\r\n case 'github':\r\n return renderGitHubEmbed(url, parsedOptions, baseClasses);\r\n case 'vimeo':\r\n return renderVimeoEmbed(url, parsedOptions, baseClasses);\r\n case 'spotify':\r\n return renderSpotifyEmbed(url, parsedOptions, baseClasses);\r\n case 'codesandbox':\r\n return renderCodeSandboxEmbed(url, parsedOptions, baseClasses);\r\n default:\r\n return renderGenericEmbed(url, parsedOptions, baseClasses);\r\n }\r\n}\r\n\r\nfunction renderYouTubeEmbed(url: string, options: Record<string, string>, classes: string): string {\r\n const videoId = extractYouTubeId(url);\r\n if (!videoId) {\r\n return createErrorEmbed('Invalid YouTube URL', url, classes);\r\n }\r\n\r\n const params = new URLSearchParams();\r\n if (options.autoplay === '1') params.set('autoplay', '1');\r\n if (options.mute === '1') params.set('mute', '1');\r\n if (options.loop === '1') {\r\n params.set('loop', '1');\r\n params.set('playlist', videoId);\r\n }\r\n if (options.controls === '0') params.set('controls', '0');\r\n if (options.start) params.set('start', options.start);\r\n\r\n params.set('rel', '0');\r\n params.set('modestbranding', '1');\r\n\r\n const embedUrl = `https://www.youtube.com/embed/${videoId}?${params.toString()}`;\r\n\r\n return `<div class=\"${classes}\">\r\n <div style=\"position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;\">\r\n <iframe \r\n style=\"position: absolute; top: 0; left: 0; width: 100%; height: 100%; border: 0;\"\r\n src=\"${embedUrl}\" \r\n title=\"YouTube video player\"\r\n frameborder=\"0\" \r\n allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share\"\r\n allowfullscreen>\r\n </iframe>\r\n </div>\r\n </div>`;\r\n}\r\n\r\nfunction renderCodePenEmbed(url: string, options: Record<string, string>, classes: string): string {\r\n const match = url.match(/codepen\\.io\\/([^\\/]+)\\/(?:pen|embed)\\/([^\\/\\?#]+)/);\r\n\r\n if (!match) {\r\n return createErrorEmbed('Invalid CodePen URL', url, classes);\r\n }\r\n\r\n const [, user, penId] = match;\r\n const height = options.height || '400';\r\n const theme = options.theme === 'light' ? 'light' : 'dark';\r\n const defaultTab = options.tab || 'result';\r\n\r\n const embedParams = new URLSearchParams({\r\n 'default-tab': defaultTab,\r\n 'theme-id': theme,\r\n 'editable': 'true'\r\n });\r\n\r\n const embedUrl = `https://codepen.io/${user}/embed/${penId}?${embedParams.toString()}`;\r\n\r\n return `<div class=\"${classes}\">\r\n <iframe \r\n height=\"${height}\" \r\n style=\"width: 100%; border: 0;\" \r\n scrolling=\"no\" \r\n title=\"CodePen Embed - ${penId}\" \r\n src=\"${embedUrl}\" \r\n frameborder=\"0\" \r\n loading=\"lazy\" \r\n allowtransparency=\"true\" \r\n allowfullscreen=\"true\">\r\n </iframe>\r\n </div>`;\r\n}\r\n\r\nfunction renderVimeoEmbed(url: string, options: Record<string, string>, classes: string): string {\r\n const videoId = extractVimeoId(url);\r\n if (!videoId) {\r\n return createErrorEmbed('Invalid Vimeo URL', url, classes);\r\n }\r\n\r\n const params = new URLSearchParams();\r\n if (options.autoplay === '1') params.set('autoplay', '1');\r\n if (options.mute === '1') params.set('muted', '1');\r\n if (options.loop === '1') params.set('loop', '1');\r\n\r\n const embedUrl = `https://player.vimeo.com/video/${videoId}?${params.toString()}`;\r\n\r\n return `<div class=\"${classes}\">\r\n <div style=\"position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;\">\r\n <iframe \r\n style=\"position: absolute; top: 0; left: 0; width: 100%; height: 100%; border: 0;\"\r\n src=\"${embedUrl}\" \r\n title=\"Vimeo video player\"\r\n frameborder=\"0\" \r\n allow=\"autoplay; fullscreen; picture-in-picture\"\r\n allowfullscreen>\r\n </iframe>\r\n </div>\r\n </div>`;\r\n}\r\n\r\nfunction renderSpotifyEmbed(url: string, options: Record<string, string>, classes: string): string {\r\n const embedUrl = url.replace('open.spotify.com', 'open.spotify.com/embed');\r\n const height = options.height || '380';\r\n\r\n return `<div class=\"${classes}\">\r\n <iframe \r\n style=\"border-radius: 12px;\" \r\n src=\"${embedUrl}\" \r\n width=\"100%\" \r\n height=\"${height}\" \r\n frameborder=\"0\" \r\n allowfullscreen=\"\" \r\n allow=\"autoplay; clipboard-write; encrypted-media; fullscreen; picture-in-picture\" \r\n loading=\"lazy\">\r\n </iframe>\r\n </div>`;\r\n}\r\n\r\nfunction renderCodeSandboxEmbed(url: string, options: Record<string, string>, classes: string): string {\r\n let embedUrl = url;\r\n if (url.includes('/s/')) {\r\n embedUrl = url.replace('/s/', '/embed/');\r\n }\r\n\r\n const height = options.height || '500';\r\n const view = options.view || 'preview';\r\n\r\n if (!embedUrl.includes('?')) {\r\n embedUrl += `?view=${view}`;\r\n }\r\n\r\n return `<div class=\"${classes}\">\r\n <iframe \r\n src=\"${embedUrl}\"\r\n style=\"width: 100%; height: ${height}px; border: 0; border-radius: 4px; overflow: hidden;\"\r\n title=\"CodeSandbox Embed\"\r\n allow=\"accelerometer; ambient-light-sensor; camera; encrypted-media; geolocation; gyroscope; hid; microphone; midi; payment; usb; vr; xr-spatial-tracking\"\r\n sandbox=\"allow-forms allow-modals allow-popups allow-presentation allow-same-origin allow-scripts\">\r\n </iframe>\r\n </div>`;\r\n}\r\n\r\nfunction renderFigmaEmbed(url: string, options: Record<string, string>, classes: string): string {\r\n const embedUrl = `https://www.figma.com/embed?embed_host=share&url=${encodeURIComponent(url)}`;\r\n const height = options.height || '450';\r\n\r\n return `<div class=\"${classes}\">\r\n <iframe \r\n style=\"border: none;\" \r\n width=\"100%\" \r\n height=\"${height}\" \r\n src=\"${embedUrl}\" \r\n allowfullscreen>\r\n </iframe>\r\n </div>`;\r\n}\r\n\r\nfunction renderTwitterEmbed(url: string, _options: Record<string, string>, classes: string): string {\r\n return `<div class=\"${classes}\">\r\n <div class=\"p-4\">\r\n <div class=\"flex items-center gap-3 mb-3\">\r\n <svg class=\"w-6 h-6 fill-current text-blue-500\" viewBox=\"0 0 24 24\">\r\n <path d=\"M23.953 4.57a10 10 0 01-2.825.775 4.958 4.958 0 002.163-2.723c-.951.555-2.005.959-3.127 1.184a4.92 4.92 0 00-8.384 4.482C7.69 8.095 4.067 6.13 1.64 3.162a4.822 4.822 0 00-.666 2.475c0 1.71.87 3.213 2.188 4.096a4.904 4.904 0 01-2.228-.616v.06a4.923 4.923 0 003.946 4.827 4.996 4.996 0 01-2.212.085 4.936 4.936 0 004.604 3.417 9.867 9.867 0 01-6.102 2.105c-.39 0-.779-.023-1.17-.067a13.995 13.995 0 007.557 2.209c9.053 0 13.998-7.496 13.998-13.985 0-.21 0-.42-.015-.63A9.935 9.935 0 0024 4.59z\"/>\r\n </svg>\r\n <div>\r\n <div class=\"font-semibold text-foreground\">Twitter Post</div>\r\n <div class=\"text-sm text-muted-foreground\">External Link</div>\r\n </div>\r\n </div>\r\n <a href=\"${url}\" target=\"_blank\" \r\n class=\"inline-flex items-center gap-2 text-primary hover:text-primary/80 font-medium transition-colors\">\r\n View on Twitter\r\n <svg class=\"w-4 h-4\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\r\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M10 6H6a2 2 0 00-2 2v10a2 2 0 002 2h10a2 2 0 002-2v-4M14 4h6m0 0v6m0-6L10 14\"/>\r\n </svg>\r\n </a>\r\n </div>\r\n </div>`;\r\n}\r\n\r\nfunction renderGitHubEmbed(url: string, _options: Record<string, string>, classes: string): string {\r\n const parts = url.replace('https://github.com/', '').split('/');\r\n const owner = parts[0];\r\n const repo = parts[1];\r\n\r\n if (!owner || !repo) {\r\n return createErrorEmbed('Invalid GitHub URL', url, classes);\r\n }\r\n\r\n return `<div class=\"${classes}\">\r\n <div class=\"p-4\">\r\n <div class=\"flex items-center gap-3 mb-3\">\r\n <svg class=\"w-6 h-6 fill-current\" viewBox=\"0 0 24 24\">\r\n <path d=\"M12 0c-6.626 0-12 5.373-12 12 0 5.302 3.438 9.8 8.207 11.387.599.111.793-.261.793-.577v-2.234c-3.338.726-4.033-1.416-4.033-1.416-.546-1.387-1.333-1.756-1.333-1.756-1.089-.745.083-.729.083-.729 1.205.084 1.839 1.237 1.839 1.237 1.07 1.834 2.807 1.304 3.492.997.107-.775.418-1.305.762-1.604-2.665-.305-5.467-1.334-5.467-5.931 0-1.311.469-2.381 1.236-3.221-.124-.303-.535-1.524.117-3.176 0 0 1.008-.322 3.301 1.23.957-.266 1.983-.399 3.003-.404 1.02.005 2.047.138 3.006.404 2.291-1.552 3.297-1.23 3.297-1.23.653 1.653.242 2.874.118 3.176.77.84 1.235 1.911 1.235 3.221 0 4.609-2.807 5.624-5.479 5.921.43.372.823 1.102.823 2.222v3.293c0 .319.192.694.801.576 4.765-1.589 8.199-6.086 8.199-11.386 0-6.627-5.373-12-12-12z\"/>\r\n </svg>\r\n <div>\r\n <div class=\"font-semibold text-foreground text-lg\">${owner}/${repo}</div>\r\n <div class=\"text-sm text-muted-foreground\">GitHub Repository</div>\r\n </div>\r\n </div>\r\n <a href=\"${url}\" target=\"_blank\" \r\n class=\"inline-flex items-center gap-2 text-primary hover:text-primary/80 font-medium transition-colors\">\r\n View on GitHub\r\n <svg class=\"w-4 h-4\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\r\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M10 6H6a2 2 0 00-2 2v10a2 2 0 002 2h10a2 2 0 002-2v-4M14 4h6m0 0v6m0-6L10 14\"/>\r\n </svg>\r\n </a>\r\n </div>\r\n </div>`;\r\n}\r\n\r\nfunction renderGenericEmbed(url: string, _options: Record<string, string>, classes: string): string {\r\n const domain = extractDomain(url);\r\n\r\n return `<div class=\"${classes}\">\r\n <div class=\"p-4\">\r\n <div class=\"flex items-center gap-3 mb-3\">\r\n <div class=\"w-10 h-10 rounded-lg bg-muted flex items-center justify-center\">\r\n <svg class=\"w-5 h-5 text-muted-foreground\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\r\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1\"/>\r\n </svg>\r\n </div>\r\n <div>\r\n <div class=\"font-semibold text-foreground\">External Link</div>\r\n <div class=\"text-sm text-muted-foreground\">${domain}</div>\r\n </div>\r\n </div>\r\n <a href=\"${url}\" target=\"_blank\" \r\n class=\"inline-flex items-center gap-2 text-primary hover:text-primary/80 font-medium transition-colors break-all\">\r\n ${url}\r\n <svg class=\"w-4 h-4 flex-shrink-0\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\r\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M10 6H6a2 2 0 00-2 2v10a2 2 0 002 2h10a2 2 0 002-2v-4M14 4h6m0 0v6m0-6L10 14\"/>\r\n </svg>\r\n </a>\r\n </div>\r\n </div>`;\r\n}\r\n\r\nfunction createErrorEmbed(error: string, url: string, classes: string): string {\r\n return `<div class=\"${classes}\">\r\n <div class=\"p-4 text-destructive\">\r\n <div class=\"font-medium flex items-center gap-2\">\r\n <svg class=\"w-5 h-5\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\r\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M12 8v4m0 4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z\"/>\r\n </svg>\r\n ${error}\r\n </div>\r\n <div class=\"text-sm text-muted-foreground mt-1 break-all\">${url}</div>\r\n </div>\r\n </div>`;\r\n}\r\n\r\n// Utility functions for extracting IDs\r\nfunction extractYouTubeId(url: string): string | null {\r\n const patterns = [\r\n /(?:youtube\\.com\\/watch\\?v=|youtu\\.be\\/|youtube\\.com\\/embed\\/|youtube\\.com\\/shorts\\/)([^&\\n?#]+)/,\r\n /youtube\\.com\\/watch\\?.*v=([^&\\n?#]+)/\r\n ];\r\n\r\n for (const pattern of patterns) {\r\n const match = url.match(pattern);\r\n if (match) return match[1] || null;\r\n }\r\n\r\n return null;\r\n}\r\n\r\nfunction extractVimeoId(url: string): string | null {\r\n const match = url.match(/vimeo\\.com\\/(?:.*\\/)?(\\d+)/);\r\n return match?.[1] ?? null;\r\n}","import { MarkdownParser } from './parser';\r\nimport { MarkdownRenderer } from './renderer';\r\nimport type {\r\n MarkdownToken,\r\n Extension,\r\n EngineConfig,\r\n ExtensionRegistration,\r\n DebugInfo,\r\n PerformanceMetrics\r\n} from './types';\r\n\r\n// Import core extensions\r\nimport { CoreExtensions } from './extensions/core';\r\n// Import feature extensions\r\nimport { AlertExtension } from './extensions/alert';\r\nimport { ButtonExtension } from './extensions/button';\r\nimport { EmbedExtension } from './extensions/embed';\r\n\r\nexport class ChangerawrMarkdown {\r\n private parser: MarkdownParser;\r\n private renderer: MarkdownRenderer;\r\n private extensions = new Map<string, Extension>();\r\n\r\n constructor(config?: EngineConfig) {\r\n this.parser = new MarkdownParser(config?.parser);\r\n this.renderer = new MarkdownRenderer(config?.renderer);\r\n\r\n // Register core extensions first (for backwards compatibility)\r\n this.registerCoreExtensions();\r\n\r\n // Register feature extensions (for backwards compatibility)\r\n this.registerFeatureExtensions();\r\n\r\n // Register custom extensions if provided\r\n if (config?.extensions) {\r\n config.extensions.forEach(extension => {\r\n this.registerExtension(extension);\r\n });\r\n }\r\n\r\n // No need for default rules - everything is extension-based now!\r\n }\r\n\r\n private registerFeatureExtensions(): void {\r\n this.registerExtension(AlertExtension);\r\n this.registerExtension(ButtonExtension);\r\n this.registerExtension(EmbedExtension);\r\n }\r\n\r\n private registerCoreExtensions(): void {\r\n CoreExtensions.forEach(extension => {\r\n this.registerExtension(extension);\r\n });\r\n }\r\n\r\n registerExtension(extension: Extension): ExtensionRegistration {\r\n try {\r\n // Validate extension before registration\r\n if (!extension.name || typeof extension.name !== 'string') {\r\n throw new Error('Extension must have a valid name');\r\n }\r\n\r\n if (!Array.isArray(extension.parseRules)) {\r\n throw new Error('Extension must have parseRules array');\r\n }\r\n\r\n if (!Array.isArray(extension.renderRules)) {\r\n throw new Error('Extension must have renderRules array');\r\n }\r\n\r\n // Validate parse rules\r\n extension.parseRules.forEach((rule, index) => {\r\n if (!rule.name || typeof rule.name !== 'string') {\r\n throw new Error(`Parse rule ${index} must have a valid name`);\r\n }\r\n if (!rule.pattern || !(rule.pattern instanceof RegExp)) {\r\n throw new Error(`Parse rule ${index} must have a valid RegExp pattern`);\r\n }\r\n if (!rule.render || typeof rule.render !== 'function') {\r\n throw new Error(`Parse rule ${index} must have a valid render function`);\r\n }\r\n });\r\n\r\n // Validate render rules\r\n extension.renderRules.forEach((rule, index) => {\r\n if (!rule.type || typeof rule.type !== 'string') {\r\n throw new Error(`Render rule ${index} must have a valid type`);\r\n }\r\n if (!rule.render || typeof rule.render !== 'function') {\r\n throw new Error(`Render rule ${index} must have a valid render function`);\r\n }\r\n });\r\n\r\n // Store extension\r\n this.extensions.set(extension.name, extension);\r\n\r\n // Add rules to parser and renderer\r\n extension.parseRules.forEach(rule => {\r\n this.parser.addRule(rule);\r\n });\r\n\r\n extension.renderRules.forEach(rule => {\r\n this.renderer.addRule(rule);\r\n });\r\n\r\n return {\r\n success: true,\r\n extensionName: extension.name\r\n };\r\n\r\n } catch (error) {\r\n const errorMessage = error instanceof Error ? error.message : String(error);\r\n\r\n return {\r\n success: false,\r\n extensionName: extension.name,\r\n error: errorMessage\r\n };\r\n }\r\n }\r\n\r\n unregisterExtension(name: string): boolean {\r\n const extension = this.extensions.get(name);\r\n if (!extension) {\r\n return false;\r\n }\r\n\r\n try {\r\n // Remove extension from map\r\n this.extensions.delete(name);\r\n\r\n // Rebuild parser and renderer to remove extension rules\r\n this.rebuildParserAndRenderer();\r\n\r\n return true;\r\n } catch {\r\n return false;\r\n }\r\n }\r\n\r\n parse(markdown: string): MarkdownToken[] {\r\n return this.parser.parse(markdown);\r\n }\r\n\r\n render(tokens: MarkdownToken[]): string {\r\n return this.renderer.render(tokens);\r\n }\r\n\r\n toHtml(markdown: string): string {\r\n const tokens = this.parse(markdown);\r\n return this.render(tokens);\r\n }\r\n\r\n getExtensions(): string[] {\r\n return Array.from(this.extensions.keys());\r\n }\r\n\r\n hasExtension(name: string): boolean {\r\n return this.extensions.has(name);\r\n }\r\n\r\n getWarnings(): string[] {\r\n return [...this.parser.getWarnings(), ...this.renderer.getWarnings()];\r\n }\r\n\r\n getDebugInfo(): DebugInfo | null {\r\n return {\r\n warnings: this.getWarnings(),\r\n parseTime: 0,\r\n renderTime: 0,\r\n tokenCount: 0,\r\n iterationCount: 0\r\n };\r\n }\r\n\r\n getPerformanceMetrics(): PerformanceMetrics | null {\r\n return {\r\n parseTime: 0,\r\n renderTime: 0,\r\n totalTime: 0,\r\n tokenCount: 0\r\n };\r\n }\r\n\r\n private rebuildParserAndRenderer(): void {\r\n // Get current configs\r\n const parserConfig = this.parser.getConfig();\r\n const rendererConfig = this.renderer.getConfig();\r\n\r\n // Recreate parser and renderer completely\r\n this.parser = new MarkdownParser(parserConfig);\r\n this.renderer = new MarkdownRenderer(rendererConfig);\r\n\r\n // Get the extensions that are still in the map (after removal)\r\n const extensionsToRegister = Array.from(this.extensions.values());\r\n\r\n // Re-register remaining extensions in the correct order\r\n // Feature extensions first\r\n const featureExtensions = extensionsToRegister.filter(ext =>\r\n ['alert', 'button', 'embed'].includes(ext.name)\r\n );\r\n\r\n // Core extensions second\r\n const coreExtensions = extensionsToRegister.filter(ext =>\r\n ['text', 'heading', 'bold', 'italic', 'code', 'codeblock', 'link', 'image', 'list', 'task-list', 'blockquote', 'hr', 'paragraph', 'line-break'].includes(ext.name)\r\n );\r\n\r\n // Custom extensions last\r\n const customExtensions = extensionsToRegister.filter(ext =>\r\n !['alert', 'button', 'embed', 'text', 'heading', 'bold', 'italic', 'code', 'codeblock', 'link', 'image', 'list', 'task-list', 'blockquote', 'hr', 'paragraph', 'line-break'].includes(ext.name)\r\n );\r\n\r\n // Register in correct order without going through the extension map\r\n [...featureExtensions, ...coreExtensions, ...customExtensions].forEach(extension => {\r\n // Add rules directly to parser and renderer\r\n extension.parseRules.forEach(rule => {\r\n this.parser.addRule(rule);\r\n });\r\n\r\n extension.renderRules.forEach(rule => {\r\n this.renderer.addRule(rule);\r\n });\r\n });\r\n }\r\n}\r\n\r\n// Factory functions for specific use cases\r\nexport function createMinimalEngine(config?: EngineConfig): ChangerawrMarkdown {\r\n // Create engine with NO default extensions\r\n const minimalConfig = {\r\n ...config,\r\n extensions: config?.extensions || []\r\n };\r\n\r\n const engine = new ChangerawrMarkdown();\r\n\r\n // Clear all default extensions\r\n const defaultExtensions = engine.getExtensions();\r\n defaultExtensions.forEach(ext => engine.unregisterExtension(ext));\r\n\r\n // Only add the ones specified in config\r\n if (minimalConfig.extensions) {\r\n minimalConfig.extensions.forEach(ext => engine.registerExtension(ext));\r\n }\r\n\r\n return engine;\r\n}\r\n\r\nexport function createCoreOnlyEngine(config?: EngineConfig): ChangerawrMarkdown {\r\n // Create engine with only core extensions (no alerts, buttons, embeds)\r\n const engine = new ChangerawrMarkdown();\r\n\r\n // Remove feature extensions, keep core\r\n engine.unregisterExtension('alert');\r\n engine.unregisterExtension('button');\r\n engine.unregisterExtension('embed');\r\n\r\n // Add any custom extensions\r\n if (config?.extensions) {\r\n config.extensions.forEach(ext => engine.registerExtension(ext));\r\n }\r\n\r\n return engine;\r\n}\r\n\r\n// Default instance for convenience functions\r\nexport const markdown = new ChangerawrMarkdown();\r\n\r\n// Convenience functions\r\nexport function parseMarkdown(content: string): MarkdownToken[] {\r\n return markdown.parse(content);\r\n}\r\n\r\nexport function renderMarkdown(content: string): string {\r\n return markdown.toHtml(content);\r\n}"],"mappings":";AAAA,OAAO,SAAS,WAAAA,UAAS,aAAAC,kBAAiB;;;ACA1C,SAAS,UAAU,aAAa,SAAS,QAAQ,iBAAiB;;;ACE3D,IAAM,iBAAN,MAAqB;AAAA,EAKxB,YAAY,QAAuB;AAJnC,SAAQ,QAAqB,CAAC;AAC9B,SAAQ,WAAqB,CAAC;AAI1B,SAAK,SAAS;AAAA,MACV,WAAW;AAAA,MACX,eAAe;AAAA,MACf,kBAAkB;AAAA,MAClB,GAAG;AAAA,IACP;AAAA,EACJ;AAAA,EAEA,QAAQ,MAAuB;AAC3B,SAAK,MAAM,KAAK,IAAI;AAEpB,SAAK,MAAM,KAAK,CAAC,GAAG,MAAM;AAEtB,YAAM,oBAAoB,CAAC,SAAS,UAAU,OAAO,EAAE,SAAS,EAAE,IAAI;AACtE,YAAM,oBAAoB,CAAC,SAAS,UAAU,OAAO,EAAE,SAAS,EAAE,IAAI;AAEtE,UAAI,qBAAqB,CAAC,kBAAmB,QAAO;AACpD,UAAI,CAAC,qBAAqB,kBAAmB,QAAO;AAGpD,YAAM,iBAAiB,CAAC,QAAQ,WAAW,QAAQ,UAAU,QAAQ,aAAa,QAAQ,SAAS,QAAQ,aAAa,cAAc,MAAM,aAAa,YAAY,EAAE,SAAS,EAAE,IAAI;AACtL,YAAM,iBAAiB,CAAC,QAAQ,WAAW,QAAQ,UAAU,QAAQ,aAAa,QAAQ,SAAS,QAAQ,aAAa,cAAc,MAAM,aAAa,YAAY,EAAE,SAAS,EAAE,IAAI;AAEtL,UAAI,kBAAkB,CAAC,eAAgB,QAAO;AAC9C,UAAI,CAAC,kBAAkB,eAAgB,QAAO;AAI9C,UAAI,EAAE,SAAS,WAAW,EAAE,SAAS,OAAQ,QAAO;AACpD,UAAI,EAAE,SAAS,UAAU,EAAE,SAAS,QAAS,QAAO;AAGpD,UAAI,EAAE,SAAS,eAAe,EAAE,SAAS,YAAa,QAAO;AAC7D,UAAI,EAAE,SAAS,eAAe,EAAE,SAAS,YAAa,QAAO;AAG7D,UAAI,EAAE,SAAS,eAAe,EAAE,SAAS,OAAQ,QAAO;AACxD,UAAI,EAAE,SAAS,UAAU,EAAE,SAAS,YAAa,QAAO;AAGxD,UAAI,EAAE,SAAS,UAAU,EAAE,SAAS,SAAU,QAAO;AACrD,UAAI,EAAE,SAAS,YAAY,EAAE,SAAS,OAAQ,QAAO;AAGrD,aAAO,EAAE,KAAK,cAAc,EAAE,IAAI;AAAA,IACtC,CAAC;AAAA,EACL;AAAA,EAEA,QAAQ,MAAuB;AAC3B,WAAO,KAAK,MAAM,KAAK,UAAQ,KAAK,SAAS,IAAI;AAAA,EACrD;AAAA,EAEA,MAAMC,WAAmC;AAErC,SAAK,WAAW,CAAC;AAEjB,QAAI,CAACA,UAAS,KAAK,GAAG;AAClB,aAAO,CAAC;AAAA,IACZ;AAGA,QAAI,KAAK,MAAM,WAAW,GAAG;AACzB,WAAK,SAAS,KAAK,2DAA2D;AAC9E,aAAO,CAAC;AAAA,QACJ,MAAM;AAAA,QACN,SAASA;AAAA,QACT,KAAKA;AAAA,MACT,CAAC;AAAA,IACL;AAGA,UAAM,oBAAoB,KAAK,mBAAmBA,SAAQ;AAE1D,UAAM,SAA0B,CAAC;AACjC,QAAI,YAAY;AAChB,QAAI,iBAAiB;AACrB,UAAM,gBAAgB,KAAK,OAAO,iBAAiB;AAEnD,WAAO,UAAU,SAAS,KAAK,iBAAiB,eAAe;AAC3D;AACA,UAAI,UAAU;AACd,UAAI,YAAmF;AAGvF,iBAAW,QAAQ,KAAK,OAAO;AAC3B,YAAI;AAEA,gBAAM,UAAU,IAAI,OAAO,KAAK,QAAQ,QAAQ,KAAK,QAAQ,MAAM,QAAQ,KAAK,EAAE,CAAC;AACnF,gBAAM,QAAQ,UAAU,MAAM,OAAO;AAErC,cAAI,SAAS,MAAM,UAAU,QAAW;AAEpC,kBAAM,WAAW,MAAM,UAAU,IAAI,MAAQ,MAAO,MAAM;AAE1D,gBAAI,CAAC,aAAa,WAAW,UAAU,YAClC,aAAa,UAAU,YAAY,MAAM,SAAS,UAAU,MAAM,SAAS,IAAK;AACjF,0BAAY,EAAE,MAAM,OAAO,SAAS;AAAA,YACxC;AAAA,UACJ;AAAA,QACJ,SAAS,OAAO;AACZ,cAAI,KAAK,OAAO,WAAW;AACvB,oBAAQ,KAAK,kBAAkB,KAAK,IAAI,MAAM,KAAK;AAAA,UACvD;AAAA,QACJ;AAAA,MACJ;AAEA,UAAI,aAAa,UAAU,MAAM,UAAU,QAAW;AAClD,cAAM,EAAE,MAAM,MAAM,IAAI;AACxB,cAAM,aAAa,MAAM;AAGzB,YAAI,aAAa,GAAG;AAChB,gBAAM,aAAa,UAAU,MAAM,GAAG,UAAU;AAChD,iBAAO,KAAK;AAAA,YACR,MAAM;AAAA,YACN,SAAS;AAAA,YACT,KAAK;AAAA,UACT,CAAC;AACD,sBAAY,UAAU,MAAM,UAAU;AACtC;AAAA,QACJ;AAGA,YAAI;AACA,gBAAM,QAAQ,KAAK,OAAO,KAAK;AAC/B,iBAAO,KAAK;AAAA,YACR,GAAG;AAAA,YACH,KAAK,MAAM,CAAC,KAAK;AAAA,UACrB,CAAC;AAED,sBAAY,UAAU,MAAM,MAAM,CAAC,GAAG,UAAU,CAAC;AACjD,oBAAU;AAAA,QACd,SAAS,OAAO;AACZ,gBAAM,eAAe,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AAC1E,eAAK,SAAS,KAAK,oBAAoB,KAAK,IAAI,KAAK,YAAY,EAAE;AAGnE,gBAAM,OAAO,UAAU,CAAC;AACxB,cAAI,MAAM;AACN,mBAAO,KAAK;AAAA,cACR,MAAM;AAAA,cACN,SAAS;AAAA,cACT,KAAK;AAAA,YACT,CAAC;AACD,wBAAY,UAAU,MAAM,CAAC;AAAA,UACjC;AAAA,QACJ;AAAA,MACJ;AAEA,UAAI,CAAC,SAAS;AAEV,cAAM,OAAO,UAAU,CAAC;AACxB,YAAI,MAAM;AACN,iBAAO,KAAK;AAAA,YACR,MAAM;AAAA,YACN,SAAS;AAAA,YACT,KAAK;AAAA,UACT,CAAC;AACD,sBAAY,UAAU,MAAM,CAAC;AAAA,QACjC;AAAA,MACJ;AAAA,IACJ;AAEA,QAAI,kBAAkB,eAAe;AACjC,WAAK,SAAS,KAAK,iEAAiE;AAAA,IACxF;AAGA,UAAM,kBAAkB,KAAK,kBAAkB,MAAM;AAErD,WAAO;AAAA,EACX;AAAA,EAEA,cAAwB;AACpB,WAAO,CAAC,GAAG,KAAK,QAAQ;AAAA,EAC5B;AAAA,EAEA,YAA0B;AACtB,WAAO,EAAE,GAAG,KAAK,OAAO;AAAA,EAC5B;AAAA,EAEA,aAAa,QAAqC;AAC9C,SAAK,SAAS,EAAE,GAAG,KAAK,QAAQ,GAAG,OAAO;AAAA,EAC9C;AAAA,EAEA,aAAa,SAAwB;AACjC,SAAK,OAAO,YAAY;AAAA,EAC5B;AAAA,EAEA,gBAAsB;AAClB,SAAK,WAAW,CAAC;AAAA,EACrB;AAAA,EAEQ,mBAAmBA,WAA0B;AAEjD,QAAI,KAAK,OAAO,kBAAkB;AAC9B,WAAK,iBAAiBA,SAAQ;AAAA,IAClC;AAGA,WAAOA,UAAS,QAAQ,SAAS,IAAI,EAAE,QAAQ,OAAO,IAAI;AAAA,EAC9D;AAAA,EAEQ,iBAAiBA,WAAwB;AAE7C,UAAM,cAAcA,UAAS,MAAM,OAAO;AAC1C,QAAI,eAAe,YAAY,SAAS,MAAM,GAAG;AAC7C,WAAK,SAAS,KAAK,yEAAyE;AAAA,IAChG;AAGA,UAAM,gBAAgBA,UAAS,MAAM,kBAAkB;AACvD,QAAI,iBAAiB,cAAc,SAAS,MAAM,GAAG;AACjD,WAAK,SAAS,KAAK,4EAA4E;AAAA,IACnG;AAGA,UAAM,mBAAmBA,UAAS,MAAM,MAAM;AAC9C,QAAI,oBAAoB,iBAAiB,SAAS,MAAM,GAAG;AACvD,WAAK,SAAS,KAAK,yEAAyE;AAAA,IAChG;AAGA,UAAM,oBAAoBA,UAAS,MAAM,IAAI;AAC7C,QAAI,qBAAqB,kBAAkB,SAAS,MAAM,GAAG;AACzD,WAAK,SAAS,KAAK,+EAA+E;AAAA,IACtG;AAAA,EACJ;AAAA,EAEQ,kBAAkB,QAA0C;AAChE,UAAM,YAA6B,CAAC;AACpC,QAAI,IAAI;AAER,WAAO,IAAI,OAAO,QAAQ;AACtB,YAAM,QAAQ,OAAO,CAAC;AAEtB,UAAI,SAAS,MAAM,SAAS,QAAQ;AAEhC,YAAI,cAAc,MAAM,WAAW,MAAM,OAAO;AAChD,YAAI,IAAI,IAAI;AAEZ,eAAO,IAAI,OAAO,UAAU,OAAO,CAAC,KAAK,OAAO,CAAC,EAAG,SAAS,QAAQ;AACjE,gBAAM,YAAY,OAAO,CAAC;AAC1B,yBAAe,UAAU,WAAW,UAAU,OAAO;AACrD;AAAA,QACJ;AAGA,YAAI,YAAY,KAAK,EAAE,SAAS,KAAK,YAAY,SAAS,IAAI,GAAG;AAC7D,oBAAU,KAAK;AAAA,YACX,MAAM;AAAA,YACN,SAAS;AAAA,YACT,KAAK;AAAA,UACT,CAAC;AAAA,QACL;AAEA,YAAI;AAAA,MACR,WAAW,OAAO;AACd,kBAAU,KAAK,KAAK;AACpB;AAAA,MACJ,OAAO;AACH;AAAA,MACJ;AAAA,IACJ;AAEA,WAAO;AAAA,EACX;AACJ;;;AC9QA,IAAI,YAAuF;AAAA,EACvF,UAAU,CAAC,SAAiB;AAChC;AAEA,IAAI,OAAO,WAAW,aAAa;AAC/B,SAAO,WAAW,EAAE,KAAK,YAAU;AAC/B,gBAAY,OAAO;AAAA,EACvB,CAAC,EAAE,MAAM,SAAO;AACZ,YAAQ,MAAM,4BAA4B,GAAG;AAAA,EACjD,CAAC;AACL;AAGA,IAAM,eAAe;AAAA;AAAA,EAEjB;AAAA,EAAM;AAAA,EAAM;AAAA,EAAM;AAAA,EAAM;AAAA,EAAM;AAAA,EAAM;AAAA,EAAK;AAAA,EAAM;AAAA,EAAU;AAAA,EAAM;AAAA,EAAO;AAAA,EACtE;AAAA,EAAK;AAAA,EAAO;AAAA,EAAM;AAAA,EAAM;AAAA,EAAM;AAAA,EAAc;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAS;AAAA,EACpE;AAAA,EAAS;AAAA,EAAM;AAAA,EAAM;AAAA,EAAM;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAO;AAAA,EAAM;AAAA;AAAA,EAE9D;AAAA,EAAU;AAAA,EAAS;AAAA,EAAU;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA;AAAA,EAExD;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAY;AAAA,EAAQ;AAAA,EAAU;AAAA,EAAQ;AAAA,EAAK;AAAA,EAAQ;AAAA;AAAA,EAElE;AAAA,EAAQ;AAAA,EAAY;AAAA,EAAU;AAAA,EAAS;AAAA,EAAU;AAAA,EAAU;AAAA,EAAY;AAC3E;AAEA,IAAM,eAAe;AAAA;AAAA,EAEjB;AAAA,EAAQ;AAAA,EAAS;AAAA,EAAO;AAAA,EAAO;AAAA,EAAS;AAAA,EAAM;AAAA,EAAU;AAAA,EAAO;AAAA,EAC/D;AAAA,EAAW;AAAA,EAAY;AAAA,EAAW;AAAA,EAAS;AAAA,EAAU;AAAA,EAAS;AAAA;AAAA,EAE9D;AAAA,EAAe;AAAA,EAAmB;AAAA,EAAS;AAAA,EAAW;AAAA,EACtD;AAAA,EAAqB;AAAA,EAAQ;AAAA,EAAY;AAAA;AAAA,EAEzC;AAAA;AAAA,EAEA;AAAA,EAAW;AAAA,EAAQ;AAAA,EAAU;AAAA,EAAgB;AAAA,EAAkB;AAAA,EAC/D;AAAA,EAAK;AAAA,EAAU;AAAA,EAAM;AAAA,EAAM;AAAA,EAAM;AAAA,EAAM;AAAA,EAAM;AAAA,EAAM;AAAA,EAAK;AAAA,EAAM;AAAA;AAAA,EAE9D;AAAA,EAAY;AAAA,EAAY;AAAA,EAAQ;AAAA,EAAS;AAAA,EAAW;AAAA;AAAA,EAEpD;AAAA,EAAS;AAAA,EAAe;AAAA,EAAY;AAAA,EAAY;AAAA,EAAa;AAAA,EAC7D;AAAA,EAAO;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAW;AAAA,EAAgB;AACrD;AAKO,SAAS,WAAW,MAAsB;AAC7C,QAAM,MAA8B;AAAA,IAChC,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,EACT;AACA,SAAO,KAAK,QAAQ,YAAY,UAAQ,IAAI,IAAI,KAAK,IAAI;AAC7D;AAKO,SAAS,WAAW,MAAsB;AAC7C,SAAO,KACF,YAAY,EACZ,QAAQ,aAAa,EAAE,EACvB,QAAQ,QAAQ,GAAG,EACnB,QAAQ,OAAO,GAAG,EAClB,QAAQ,UAAU,EAAE,EACpB,KAAK;AACd;AAKO,SAAS,aAAa,MAAsB;AAC/C,MAAI;AAEA,QAAI,KAAK,SAAS,aAAa,KAAK,KAAK,SAAS,oBAAoB,GAAG;AACrE,aAAO;AAAA,IACX;AAGA,QAAI,OAAO,WAAW,aAAa,YAAY;AAC3C,YAAM,YAAY,UAAU,SAAS,MAAM;AAAA,QACvC;AAAA,QACA;AAAA,QACA,iBAAiB;AAAA,QACjB,yBAAyB;AAAA,QACzB,oBAAoB;AAAA,QACpB,gBAAgB;AAAA,QAChB,YAAY;AAAA,QACZ,qBAAqB;AAAA,QACrB,YAAY;AAAA,QACZ,cAAc;AAAA,QACd,sBAAsB;AAAA,QACtB,aAAa,CAAC,UAAU,WAAW,WAAW,eAAe,cAAc,WAAW,QAAQ;AAAA,QAC9F,UAAU,CAAC,UAAU,SAAS,UAAU,OAAO;AAAA,QAC/C,UAAU;AAAA,UACN;AAAA,UAAS;AAAA,UAAmB;AAAA,UAAe;AAAA,UAC3C;AAAA,UAAqB;AAAA,UAAW;AAAA,UAAW;AAAA,UAC3C;AAAA,UAAS;AAAA,UAAQ;AAAA,UAAY;AAAA,QACjC;AAAA,QACA,oBAAoB;AAAA,MACxB,CAAC;AAGD,UAAI,UAAU,SAAS,KAAK,SAAS,KAAK;AACtC,eAAO,cAAc,IAAI;AAAA,MAC7B;AAEA,aAAO;AAAA,IACX;AAGA,WAAO,cAAc,IAAI;AAAA,EAC7B,SAAS,OAAO;AACZ,YAAQ,MAAM,wBAAwB,KAAK;AAC3C,WAAO,cAAc,IAAI;AAAA,EAC7B;AACJ;AAKO,SAAS,cAAc,MAAsB;AAChD,SAAO,KACF,QAAQ,uDAAuD,EAAE,EACjE,QAAQ,yBAAyB,EAAE,EACnC,QAAQ,yBAAyB,EAAE,EACnC,QAAQ,iBAAiB,EAAE;AACpC;AA8DO,SAAS,cAAc,KAAqB;AAC/C,MAAI;AACA,WAAO,IAAI,IAAI,GAAG,EAAE;AAAA,EACxB,QAAQ;AACJ,WAAO;AAAA,EACX;AACJ;AAiBO,SAAS,aAAa,SAAyC;AAClE,QAAM,SAAiC,CAAC;AACxC,MAAI,CAAC,QAAS,QAAO;AAGrB,UAAQ,MAAM,GAAG,EAAE,QAAQ,YAAU;AACjC,UAAM,CAAC,KAAK,KAAK,IAAI,OAAO,MAAM,GAAG,EAAE,IAAI,OAAK,EAAE,KAAK,CAAC;AACxD,QAAI,OAAO,OAAO;AACd,aAAO,GAAG,IAAI;AAAA,IAClB;AAAA,EACJ,CAAC;AAED,SAAO;AACX;;;ACvOO,IAAM,mBAAN,MAAuB;AAAA,EAK1B,YAAY,QAAyB;AAJrC,SAAQ,QAAQ,oBAAI,IAAwB;AAC5C,SAAQ,WAAqB,CAAC;AAI1B,SAAK,SAAS;AAAA,MACV,QAAQ;AAAA,MACR,UAAU;AAAA,MACV,iBAAiB;AAAA,MACjB,WAAW;AAAA,MACX,GAAG;AAAA,IACP;AAAA,EACJ;AAAA,EAEA,QAAQ,MAAwB;AAC5B,SAAK,MAAM,IAAI,KAAK,MAAM,IAAI;AAAA,EAClC;AAAA,EAEA,QAAQ,MAAuB;AAC3B,WAAO,KAAK,MAAM,IAAI,IAAI;AAAA,EAC9B;AAAA,EAEA,OAAO,QAAiC;AACpC,SAAK,WAAW,CAAC;AAGjB,UAAM,mBAAmB,OAAO,IAAI,YAAU;AAAA,MAC1C,GAAG;AAAA,MACH,YAAY;AAAA,QACR,GAAG,MAAM;AAAA,QACT,QAAQ,KAAK,OAAO;AAAA,MACxB;AAAA,IACJ,EAAE;AAGF,UAAM,YAAY,iBAAiB,IAAI,WAAS,KAAK,YAAY,KAAK,CAAC;AACvE,UAAM,eAAe,UAAU,KAAK,EAAE;AAGtC,QAAI,KAAK,OAAO,YAAY,CAAC,KAAK,OAAO,iBAAiB;AACtD,aAAO,aAAa,YAAY;AAAA,IACpC;AAEA,WAAO;AAAA,EACX;AAAA,EAEQ,YAAY,OAA8B;AAC9C,UAAM,OAAO,KAAK,MAAM,IAAI,MAAM,IAAI;AAEtC,QAAI,MAAM;AACN,UAAI;AACA,eAAO,KAAK,OAAO,KAAK;AAAA,MAC5B,SAAS,OAAO;AACZ,cAAM,eAAe,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AAC1E,aAAK,SAAS,KAAK,oBAAoB,MAAM,IAAI,KAAK,YAAY,EAAE;AACpE,eAAO,KAAK,iBAAiB,oBAAoB,MAAM,IAAI,KAAK,YAAY,EAAE;AAAA,MAClF;AAAA,IACJ;AAGA,QAAI,KAAK,OAAO,WAAW;AACvB,aAAO,KAAK,iBAAiB,KAAK;AAAA,IACtC;AAGA,WAAO,WAAW,MAAM,WAAW,MAAM,OAAO,EAAE;AAAA,EACtD;AAAA,EAEQ,iBAAiB,SAAyB;AAC9C,QAAI,KAAK,OAAO,WAAW,QAAQ;AAC/B,aAAO;AAAA,yCACsB,WAAW,OAAO,CAAC;AAAA;AAAA,IAEpD;AAEA,WAAO;AAAA,uCACwB,WAAW,OAAO,CAAC;AAAA;AAAA,EAEtD;AAAA,EAEQ,iBAAiB,OAA8B;AACnD,QAAI,KAAK,OAAO,WAAW,QAAQ;AAC/B,aAAO;AAAA,+CAC4B,WAAW,MAAM,IAAI,CAAC;AAAA,oCACjC,WAAW,MAAM,WAAW,MAAM,OAAO,EAAE,CAAC;AAAA;AAAA,IAExE;AAEA,WAAO;AAAA,6CAC8B,WAAW,MAAM,IAAI,CAAC;AAAA,kCACjC,WAAW,MAAM,WAAW,MAAM,OAAO,EAAE,CAAC;AAAA;AAAA,EAE1E;AAAA,EAEA,cAAwB;AACpB,WAAO,CAAC,GAAG,KAAK,QAAQ;AAAA,EAC5B;AAAA,EAEA,YAA4B;AACxB,WAAO,EAAE,GAAG,KAAK,OAAO;AAAA,EAC5B;AAAA,EAEA,aAAa,QAAuC;AAChD,SAAK,SAAS,EAAE,GAAG,KAAK,QAAQ,GAAG,OAAO;AAAA,EAC9C;AAAA,EAEA,aAAa,SAAwB;AACjC,SAAK,OAAO,YAAY;AAAA,EAC5B;AAAA,EAEA,gBAAsB;AAClB,SAAK,WAAW,CAAC;AAAA,EACrB;AACJ;;;AClHO,IAAM,sBAAiC;AAAA,EAC1C,MAAM;AAAA,EACN,YAAY;AAAA,IACR;AAAA,MACI,MAAM;AAAA,MACN,SAAS;AAAA,MACT,QAAQ,CAAC,WAAW;AAAA,QAChB,MAAM;AAAA,QACN,SAAS,MAAM,CAAC,KAAK;AAAA,QACrB,KAAK,MAAM,CAAC,KAAK;AAAA,MACrB;AAAA,IACJ;AAAA,EACJ;AAAA,EACA,aAAa;AAAA,IACT;AAAA,MACI,MAAM;AAAA,MACN,QAAQ,CAAC,UAAU;AACf,cAAM,UAAU,WAAW,MAAM,OAAO;AACxC,cAAM,SAAS,MAAM,YAAY,UAAU;AAE3C,YAAI,WAAW,QAAQ;AACnB,iBAAO,oIAAoI,OAAO;AAAA,QACtJ;AACA,eAAO,4FAA4F,OAAO;AAAA,MAC9G;AAAA,IACJ;AAAA,EACJ;AACJ;;;AC5BO,IAAM,qBAAgC;AAAA,EACzC,MAAM;AAAA,EACN,YAAY;AAAA,IACR;AAAA,MACI,MAAM;AAAA,MACN,SAAS;AAAA,MACT,QAAQ,CAAC,WAAW;AAAA,QAChB,MAAM;AAAA,QACN,SAAS;AAAA,QACT,KAAK,MAAM,CAAC,KAAK;AAAA,MACrB;AAAA,IACJ;AAAA,IACA;AAAA,MACI,MAAM;AAAA,MACN,SAAS;AAAA,MACT,QAAQ,CAAC,WAAW;AAAA,QAChB,MAAM;AAAA,QACN,SAAS;AAAA,QACT,KAAK,MAAM,CAAC,KAAK;AAAA,MACrB;AAAA,IACJ;AAAA,EACJ;AAAA,EACA,aAAa;AAAA,IACT;AAAA,MACI,MAAM;AAAA,MACN,QAAQ,MAAM;AAAA,IAClB;AAAA,IACA;AAAA,MACI,MAAM;AAAA,MACN,QAAQ,MAAM;AAAA,IAClB;AAAA,IACA;AAAA,MACI,MAAM;AAAA,MACN,QAAQ,CAAC,UAAU,MAAM,WAAW;AAAA,IACxC;AAAA,EACJ;AACJ;;;ACnCO,IAAM,sBAAiC;AAAA,EAC1C,MAAM;AAAA,EACN,YAAY;AAAA,IACR;AAAA,MACI,MAAM;AAAA,MACN,SAAS;AAAA,MACT,QAAQ,CAAC,WAAW;AAAA,QAChB,MAAM;AAAA,QACN,SAAS,MAAM,CAAC,KAAK;AAAA,QACrB,KAAK,MAAM,CAAC,KAAK;AAAA,MACrB;AAAA,IACJ;AAAA,EACJ;AAAA,EACA,aAAa;AAAA,IACT;AAAA,MACI,MAAM;AAAA,MACN,QAAQ,CAAC,UAAU;AACf,cAAM,UAAU,WAAW,MAAM,OAAO;AACxC,cAAM,SAAS,MAAM,YAAY;AAEjC,YAAI,WAAW,QAAQ;AACnB,iBAAO,+HAA+H,OAAO;AAAA,QACjJ;AAEA,eAAO,kEAAkE,OAAO;AAAA,MACpF;AAAA,IACJ;AAAA,EACJ;AACJ;AAEO,IAAM,qBAAgC;AAAA,EACzC,MAAM;AAAA,EACN,YAAY;AAAA,IACR;AAAA,MACI,MAAM;AAAA,MACN,SAAS;AAAA,MACT,QAAQ,CAAC,WAAW;AAAA,QAChB,MAAM;AAAA,QACN,SAAS,MAAM,CAAC,KAAK;AAAA,QACrB,KAAK,MAAM,CAAC,KAAK;AAAA,QACjB,YAAY;AAAA,UACR,UAAU,MAAM,CAAC,KAAK;AAAA,QAC1B;AAAA,MACJ;AAAA,IACJ;AAAA,EACJ;AAAA,EACA,aAAa;AAAA,IACT;AAAA,MACI,MAAM;AAAA,MACN,QAAQ,CAAC,UAAU;AACf,cAAM,WAAW,MAAM,YAAY,YAAY;AAC/C,cAAM,cAAc,WAAW,MAAM,OAAO;AAC5C,cAAM,SAAS,MAAM,YAAY,UAAU;AAE3C,YAAI,WAAW,QAAQ;AACnB,iBAAO,sIAAsI,WAAW,QAAQ,CAAC,KAAK,WAAW;AAAA,QACrL;AAEA,eAAO,mFAAmF,WAAW,QAAQ,CAAC,KAAK,WAAW;AAAA,MAClI;AAAA,IACJ;AAAA,EACJ;AACJ;;;AC9DO,IAAM,gBAA2B;AAAA,EACpC,MAAM;AAAA,EACN,YAAY;AAAA,IACR;AAAA,MACI,MAAM;AAAA,MACN,SAAS;AAAA,MACT,QAAQ,CAAC,WAAW;AAAA,QAChB,MAAM;AAAA,QACN,SAAS,MAAM,CAAC,KAAK;AAAA,QACrB,KAAK,MAAM,CAAC,KAAK;AAAA,MACrB;AAAA,IACJ;AAAA,EACJ;AAAA,EACA,aAAa;AAAA,IACT;AAAA,MACI,MAAM;AAAA,MACN,QAAQ,CAAC,UAAU;AACf,cAAM,UAAU,WAAW,MAAM,OAAO;AACxC,cAAM,SAAS,MAAM,YAAY;AAEjC,YAAI,WAAW,QAAQ;AACnB,iBAAO,WAAW,OAAO;AAAA,QAC7B;AAEA,eAAO,6BAA6B,OAAO;AAAA,MAC/C;AAAA,IACJ;AAAA,EACJ;AACJ;AAEO,IAAM,kBAA6B;AAAA,EACtC,MAAM;AAAA,EACN,YAAY;AAAA,IACR;AAAA,MACI,MAAM;AAAA,MACN,SAAS;AAAA,MACT,QAAQ,CAAC,WAAW;AAAA,QAChB,MAAM;AAAA,QACN,SAAS,MAAM,CAAC,KAAK;AAAA,QACrB,KAAK,MAAM,CAAC,KAAK;AAAA,MACrB;AAAA,IACJ;AAAA,EACJ;AAAA,EACA,aAAa;AAAA,IACT;AAAA,MACI,MAAM;AAAA,MACN,QAAQ,CAAC,UAAU;AACf,cAAM,UAAU,WAAW,MAAM,OAAO;AACxC,cAAM,SAAS,MAAM,YAAY;AAEjC,YAAI,WAAW,QAAQ;AACnB,iBAAO,OAAO,OAAO;AAAA,QACzB;AAEA,eAAO,sBAAsB,OAAO;AAAA,MACxC;AAAA,IACJ;AAAA,EACJ;AACJ;;;AC1DO,IAAM,mBAA8B;AAAA,EACvC,MAAM;AAAA,EACN,YAAY;AAAA,IACR;AAAA,MACI,MAAM;AAAA,MACN,SAAS;AAAA,MACT,QAAQ,CAAC,WAAW;AAAA,QAChB,MAAM;AAAA,QACN,SAAS,MAAM,CAAC,GAAG,KAAK,KAAK;AAAA,QAC7B,KAAK,MAAM,CAAC,KAAK;AAAA,QACjB,YAAY;AAAA,UACR,OAAO,OAAO,MAAM,CAAC,GAAG,UAAU,CAAC;AAAA,QACvC;AAAA,MACJ;AAAA,IACJ;AAAA,EACJ;AAAA,EACA,aAAa;AAAA,IACT;AAAA,MACI,MAAM;AAAA,MACN,QAAQ,CAAC,UAAU;AACf,cAAM,QAAQ,SAAS,MAAM,YAAY,SAAS,GAAG;AACrD,cAAM,OAAO,MAAM;AACnB,cAAM,KAAK,WAAW,IAAI;AAC1B,cAAM,iBAAiB,WAAW,IAAI;AAGtC,cAAM,SAAS,MAAM,YAAY,UAAU;AAE3C,YAAI,WAAW,QAAQ;AACnB,iBAAO,KAAK,KAAK,QAAQ,EAAE,KAAK,cAAc,MAAM,KAAK;AAAA,QAC7D;AAGA,YAAI,iBAAiB;AAErB,gBAAQ,OAAO;AAAA,UACX,KAAK;AAAG,8BAAkB;AAAiC;AAAA,UAC3D,KAAK;AAAG,8BAAkB;AAAqC;AAAA,UAC/D,KAAK;AAAG,8BAAkB;AAAkC;AAAA,UAC5D,KAAK;AAAG,8BAAkB;AAAkC;AAAA,UAC5D,KAAK;AAAG,8BAAkB;AAAoC;AAAA,UAC9D,KAAK;AAAG,8BAAkB;AAAkC;AAAA,QAChE;AAEA,eAAO,KAAK,KAAK,QAAQ,EAAE,YAAY,cAAc;AAAA,YACzD,cAAc;AAAA,sBACJ,EAAE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,aAMX,KAAK;AAAA,MACN;AAAA,IACJ;AAAA,EACJ;AACJ;;;ACzDO,IAAM,0BAAqC;AAAA,EAC9C,MAAM;AAAA,EACN,YAAY;AAAA,IACR;AAAA,MACI,MAAM;AAAA,MACN,SAAS;AAAA,MACT,QAAQ,CAAC,WAAW;AAAA,QAChB,MAAM;AAAA,QACN,SAAS;AAAA,QACT,KAAK,MAAM,CAAC,KAAK;AAAA,MACrB;AAAA,IACJ;AAAA,EACJ;AAAA,EACA,aAAa;AAAA,IACT;AAAA,MACI,MAAM;AAAA,MACN,QAAQ,CAAC,UAAU;AACf,cAAM,SAAS,MAAM,YAAY;AAEjC,YAAI,WAAW,QAAQ;AACnB,iBAAO;AAAA,QACX;AAEA,eAAO;AAAA,MACX;AAAA,IACJ;AAAA,EACJ;AACJ;;;AC1BO,IAAM,iBAA4B;AAAA,EACrC,MAAM;AAAA,EACN,YAAY;AAAA,IACR;AAAA,MACI,MAAM;AAAA,MACN,SAAS;AAAA,MACT,QAAQ,CAAC,WAAW;AAAA,QAChB,MAAM;AAAA,QACN,SAAS,MAAM,CAAC,KAAK;AAAA,QACrB,KAAK,MAAM,CAAC,KAAK;AAAA,QACjB,YAAY;AAAA,UACR,KAAK,MAAM,CAAC,KAAK;AAAA,UACjB,KAAK,MAAM,CAAC,KAAK;AAAA,UACjB,OAAO,MAAM,CAAC,KAAK;AAAA,QACvB;AAAA,MACJ;AAAA,IACJ;AAAA,EACJ;AAAA,EACA,aAAa;AAAA,IACT;AAAA,MACI,MAAM;AAAA,MACN,QAAQ,CAAC,UAAU;AACf,cAAM,MAAM,MAAM,YAAY,OAAO;AACrC,cAAM,MAAM,MAAM,YAAY,OAAO;AACrC,cAAM,QAAQ,MAAM,YAAY,SAAS;AACzC,cAAM,YAAY,QAAQ,WAAW,WAAW,KAAK,CAAC,MAAM;AAC5D,cAAM,SAAS,MAAM,YAAY,UAAU;AAE3C,YAAI,WAAW,QAAQ;AACnB,iBAAO,aAAa,WAAW,GAAG,CAAC,UAAU,WAAW,GAAG,CAAC,IAAI,SAAS;AAAA,QAC7E;AAEA,eAAO,aAAa,WAAW,GAAG,CAAC,UAAU,WAAW,GAAG,CAAC,IAAI,SAAS;AAAA,MAC7E;AAAA,IACJ;AAAA,EACJ;AACJ;;;ACpCO,IAAM,gBAA2B;AAAA,EACpC,MAAM;AAAA,EACN,YAAY;AAAA,IACR;AAAA,MACI,MAAM;AAAA,MACN,SAAS;AAAA,MACT,QAAQ,CAAC,WAAW;AAAA,QAChB,MAAM;AAAA,QACN,SAAS,MAAM,CAAC,KAAK;AAAA,QACrB,KAAK,MAAM,CAAC,KAAK;AAAA,QACjB,YAAY;AAAA,UACR,MAAM,MAAM,CAAC,KAAK;AAAA,QACtB;AAAA,MACJ;AAAA,IACJ;AAAA,EACJ;AAAA,EACA,aAAa;AAAA,IACT;AAAA,MACI,MAAM;AAAA,MACN,QAAQ,CAAC,UAAU;AACf,cAAM,OAAO,MAAM,YAAY,QAAQ;AACvC,cAAM,cAAc,WAAW,IAAI;AACnC,cAAM,cAAc,WAAW,MAAM,OAAO;AAC5C,cAAM,SAAS,MAAM,YAAY,UAAU;AAE3C,YAAI,WAAW,QAAQ;AACnB,iBAAO,YAAY,WAAW,+CAA+C,WAAW;AAAA,QAC5F;AAEA,eAAO,YAAY,WAAW;AAAA,YAClC,WAAW;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MAOX;AAAA,IACJ;AAAA,EACJ;AACJ;;;ACxCO,IAAM,gBAA2B;AAAA,EACpC,MAAM;AAAA,EACN,YAAY;AAAA,IACR;AAAA,MACI,MAAM;AAAA,MACN,SAAS;AAAA,MACT,QAAQ,CAAC,WAAW;AAAA,QAChB,MAAM;AAAA,QACN,SAAS,MAAM,CAAC,KAAK;AAAA,QACrB,KAAK,MAAM,CAAC,KAAK;AAAA,MACrB;AAAA,IACJ;AAAA,EACJ;AAAA,EACA,aAAa;AAAA,IACT;AAAA,MACI,MAAM;AAAA,MACN,QAAQ,CAAC,UAAU,OAAO,WAAW,MAAM,OAAO,CAAC;AAAA,IACvD;AAAA,EACJ;AACJ;AAEO,IAAM,oBAA+B;AAAA,EACxC,MAAM;AAAA,EACN,YAAY;AAAA,IACR;AAAA,MACI,MAAM;AAAA,MACN,SAAS;AAAA,MACT,QAAQ,CAAC,WAAW;AAAA,QAChB,MAAM;AAAA,QACN,SAAS,MAAM,CAAC,KAAK;AAAA,QACrB,KAAK,MAAM,CAAC,KAAK;AAAA,QACjB,YAAY;AAAA,UACR,SAAS,QAAQ,MAAM,CAAC,KAAK,IAAI,YAAY,MAAM,GAAG;AAAA,QAC1D;AAAA,MACJ;AAAA,IACJ;AAAA,EACJ;AAAA,EACA,aAAa;AAAA,IACT;AAAA,MACI,MAAM;AAAA,MACN,QAAQ,CAAC,UAAU;AACf,cAAM,YAAY,MAAM,YAAY,YAAY;AAChD,cAAM,iBAAiB,WAAW,MAAM,OAAO;AAC/C,cAAM,SAAS,MAAM,YAAY,UAAU;AAE3C,YAAI,WAAW,QAAQ;AACnB,iBAAO;AAAA,qCACU,YAAY,YAAY,EAAE;AAAA,mBAC5C,YAAY,4DAA4D,EAAE,IAAI,cAAc;AAAA;AAAA,QAE/F;AAEA,eAAO;AAAA,mCACY,YAAY,YAAY,EAAE;AAAA;AAAA,iBAE5C,YAAY,gDAAgD,EAAE,IAAI,cAAc;AAAA;AAAA,MAErF;AAAA,IACJ;AAAA,EACJ;AACJ;;;AC5DO,IAAM,qBAAgC;AAAA,EACzC,MAAM;AAAA,EACN,YAAY,CAAC;AAAA,EACb,aAAa;AAAA,IACT;AAAA,MACI,MAAM;AAAA,MACN,QAAQ,CAAC,UAAU;AACf,YAAI,CAAC,MAAM,QAAS,QAAO;AAC3B,cAAM,UAAU,MAAM,QAAQ,KAAK;AACnC,YAAI,CAAC,QAAS,QAAO;AAErB,cAAM,mBAAmB,QAAQ,SAAS,MAAM,IAAI,UAAU,WAAW,OAAO;AAChF,cAAM,SAAS,MAAM,YAAY,UAAU;AAE3C,YAAI,WAAW,QAAQ;AACnB,iBAAO,sDAAsD,gBAAgB;AAAA,QACjF;AAEA,eAAO,6BAA6B,gBAAgB;AAAA,MACxD;AAAA,IACJ;AAAA,EACJ;AACJ;;;ACtBO,IAAM,gBAA2B;AAAA,EACpC,MAAM;AAAA,EACN,YAAY,CAAC;AAAA,EACb,aAAa;AAAA,IACT;AAAA,MACI,MAAM;AAAA,MACN,QAAQ,CAAC,UAAU;AACf,YAAI,CAAC,MAAM,QAAS,QAAO;AAC3B,eAAO,WAAW,MAAM,OAAO;AAAA,MACnC;AAAA,IACJ;AAAA,EACJ;AACJ;;;ACHO,IAAM,iBAAiB;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;AACJ;;;ACpBO,IAAM,iBAA4B;AAAA,EACrC,MAAM;AAAA,EACN,YAAY;AAAA,IACR;AAAA,MACI,MAAM;AAAA,MACN,SAAS;AAAA,MACT,QAAQ,CAAC,UAA4B;AACjC,eAAO;AAAA,UACH,MAAM;AAAA,UACN,SAAS,MAAM,CAAC,GAAG,KAAK,KAAK;AAAA,UAC7B,KAAK,MAAM,CAAC,KAAK;AAAA,UACjB,YAAY;AAAA,YACR,MAAM,MAAM,CAAC,KAAK;AAAA,YAClB,OAAO,MAAM,CAAC,KAAK;AAAA,UACvB;AAAA,QACJ;AAAA,MACJ;AAAA,IACJ;AAAA,EACJ;AAAA,EACA,aAAa;AAAA,IACT;AAAA,MACI,MAAM;AAAA,MACN,QAAQ,CAAC,UAAU;AACf,cAAM,OAAO,MAAM,YAAY,QAAQ;AACvC,cAAM,QAAQ,MAAM,YAAY,SAAS;AAEzC,cAAM,aAA8C;AAAA,UAChD,MAAM;AAAA,YACF,MAAM;AAAA,YACN,SAAS;AAAA,UACb;AAAA,UACA,SAAS;AAAA,YACL,MAAM;AAAA,YACN,SAAS;AAAA,UACb;AAAA,UACA,OAAO;AAAA,YACH,MAAM;AAAA,YACN,SAAS;AAAA,UACb;AAAA,UACA,SAAS;AAAA,YACL,MAAM;AAAA,YACN,SAAS;AAAA,UACb;AAAA,UACA,KAAK;AAAA,YACD,MAAM;AAAA,YACN,SAAS;AAAA,UACb;AAAA,UACA,MAAM;AAAA,YACF,MAAM;AAAA,YACN,SAAS;AAAA,UACb;AAAA,QACJ;AAEA,cAAM,SAAS,WAAW,IAAI,KAAK,WAAW;AAC9C,cAAM,cAAc;AACpB,cAAM,UAAU,GAAG,WAAW,IAAI,QAAQ,OAAO;AAEjD,cAAM,YAAY,QACZ;AAAA,8DACwC,IAAI,KAAK,QAAQ,IAAI;AAAA,uBAC5D,KAAK;AAAA,uBAEN;AAAA,8DACwC,IAAI,KAAK,QAAQ,IAAI;AAAA,uBAC5D,KAAK,OAAO,CAAC,EAAE,YAAY,IAAI,KAAK,MAAM,CAAC,CAAC;AAAA;AAGnD,eAAO,eAAe,OAAO;AAAA,oBACzB,SAAS;AAAA,iDACoB,MAAM,OAAO;AAAA;AAAA,MAElD;AAAA,IACJ;AAAA,EACJ;AACJ;;;AC/EO,IAAM,kBAA6B;AAAA,EACtC,MAAM;AAAA,EACN,YAAY;AAAA,IACR;AAAA,MACI,MAAM;AAAA,MACN,SAAS;AAAA,MACT,QAAQ,CAAC,UAAU;AACf,cAAM,UAAU,MAAM,CAAC,IAAI,MAAM,CAAC,EAAE,MAAM,GAAG,EAAE,IAAI,SAAO,IAAI,KAAK,CAAC,IAAI,CAAC;AAEzE,eAAO;AAAA,UACH,MAAM;AAAA,UACN,SAAS,MAAM,CAAC,KAAK;AAAA,UACrB,KAAK,MAAM,CAAC,KAAK;AAAA,UACjB,YAAY;AAAA,YACR,MAAM,MAAM,CAAC,KAAK;AAAA,YAClB,OAAO,QAAQ;AAAA,cAAK,SAChB,CAAC,WAAW,WAAW,aAAa,WAAW,UAAU,WAAW,OAAO,EAAE,SAAS,GAAG;AAAA,YAC7F,KAAK;AAAA,YACL,MAAM,QAAQ,KAAK,SAAO,CAAC,MAAM,MAAM,IAAI,EAAE,SAAS,GAAG,CAAC,KAAK;AAAA,YAC/D,UAAU,OAAO,QAAQ,SAAS,UAAU,CAAC;AAAA,YAC7C,QAAQ,QAAQ,SAAS,MAAM,IAAI,UAAU;AAAA,UACjD;AAAA,QACJ;AAAA,MACJ;AAAA,IACJ;AAAA,EACJ;AAAA,EACA,aAAa;AAAA,IACT;AAAA,MACI,MAAM;AAAA,MACN,QAAQ,CAAC,UAAU;AACf,cAAM,OAAO,MAAM,YAAY,QAAQ;AACvC,cAAM,QAAQ,MAAM,YAAY,SAAS;AACzC,cAAM,OAAO,MAAM,YAAY,QAAQ;AACvC,cAAM,WAAW,MAAM,YAAY,aAAa;AAChD,cAAM,SAAS,MAAM,YAAY,UAAU;AAG3C,cAAM,cAAc;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,kBAYlB,QAAQ,QAAQ,GAAG,EAAE,KAAK;AAG5B,cAAM,cAAsC;AAAA,UACxC,IAAI;AAAA,UACJ,IAAI;AAAA,UACJ,IAAI;AAAA,QACR;AAGA,cAAM,eAAuC;AAAA,UACzC,SAAS;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,UAOT,SAAS;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,UAOT,WAAW;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,UAOX,SAAS;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,UAOT,QAAQ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,UAOR,SAAS;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,UAOT,OAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,QAOX;AAEA,cAAM,UAAU;AAAA,sBACV,WAAW;AAAA,sBACX,YAAY,IAAI,KAAK,YAAY,EAAE;AAAA,sBACnC,aAAa,KAAK,KAAK,aAAa,OAAO;AAAA,kBAC/C,QAAQ,QAAQ,GAAG,EAAE,KAAK;AAE5B,cAAM,aAAa,WAAW,WAAW,+CACrC,WAAW,UAAU,oBAAoB;AAC7C,cAAM,eAAe,WAAW,wCAAwC;AACxE,cAAM,eAAe,WAAW,YAAY,CAAC,WACzC;AAAA;AAAA,8BAEU;AAEd,eAAO,YAAY,IAAI,YAAY,OAAO,IAAI,UAAU,GAAG,YAAY;AAAA,kDACrC,MAAM,OAAO,UAAU,YAAY;AAAA;AAAA,MAEzE;AAAA,IACJ;AAAA,EACJ;AACJ;;;AClIO,IAAM,iBAA4B;AAAA,EACrC,MAAM;AAAA,EACN,YAAY;AAAA,IACR;AAAA,MACI,MAAM;AAAA,MACN,SAAS;AAAA,MACT,QAAQ,CAAC,UAAU;AACf,eAAO;AAAA,UACH,MAAM;AAAA,UACN,SAAS,MAAM,CAAC,KAAK;AAAA;AAAA,UACrB,KAAK,MAAM,CAAC,KAAK;AAAA,UACjB,YAAY;AAAA,YACR,UAAU,MAAM,CAAC,KAAK;AAAA,YACtB,KAAK,MAAM,CAAC,KAAK;AAAA,YACjB,SAAS,MAAM,CAAC,KAAK;AAAA,UACzB;AAAA,QACJ;AAAA,MACJ;AAAA,IACJ;AAAA,EACJ;AAAA,EACA,aAAa;AAAA,IACT;AAAA,MACI,MAAM;AAAA,MACN,QAAQ,CAAC,UAAU;AACf,cAAM,WAAW,MAAM,YAAY,YAAY;AAC/C,cAAM,MAAM,MAAM,YAAY,OAAO;AACrC,cAAM,UAAU,MAAM,YAAY,WAAW;AAE7C,eAAO,YAAY,UAAU,KAAK,OAAO;AAAA,MAC7C;AAAA,IACJ;AAAA,EACJ;AACJ;AAEA,SAAS,YAAY,UAAkB,KAAa,SAAyB;AACzE,QAAM,cAAc;AACpB,QAAM,gBAAgB,aAAa,OAAO;AAE1C,UAAQ,SAAS,YAAY,GAAG;AAAA,IAC5B,KAAK;AACD,aAAO,mBAAmB,KAAK,eAAe,WAAW;AAAA,IAC7D,KAAK;AACD,aAAO,mBAAmB,KAAK,eAAe,WAAW;AAAA,IAC7D,KAAK;AACD,aAAO,iBAAiB,KAAK,eAAe,WAAW;AAAA,IAC3D,KAAK;AAAA,IACL,KAAK;AACD,aAAO,mBAAmB,KAAK,eAAe,WAAW;AAAA,IAC7D,KAAK;AACD,aAAO,kBAAkB,KAAK,eAAe,WAAW;AAAA,IAC5D,KAAK;AACD,aAAO,iBAAiB,KAAK,eAAe,WAAW;AAAA,IAC3D,KAAK;AACD,aAAO,mBAAmB,KAAK,eAAe,WAAW;AAAA,IAC7D,KAAK;AACD,aAAO,uBAAuB,KAAK,eAAe,WAAW;AAAA,IACjE;AACI,aAAO,mBAAmB,KAAK,eAAe,WAAW;AAAA,EACjE;AACJ;AAEA,SAAS,mBAAmB,KAAa,SAAiC,SAAyB;AAC/F,QAAM,UAAU,iBAAiB,GAAG;AACpC,MAAI,CAAC,SAAS;AACV,WAAO,iBAAiB,uBAAuB,KAAK,OAAO;AAAA,EAC/D;AAEA,QAAM,SAAS,IAAI,gBAAgB;AACnC,MAAI,QAAQ,aAAa,IAAK,QAAO,IAAI,YAAY,GAAG;AACxD,MAAI,QAAQ,SAAS,IAAK,QAAO,IAAI,QAAQ,GAAG;AAChD,MAAI,QAAQ,SAAS,KAAK;AACtB,WAAO,IAAI,QAAQ,GAAG;AACtB,WAAO,IAAI,YAAY,OAAO;AAAA,EAClC;AACA,MAAI,QAAQ,aAAa,IAAK,QAAO,IAAI,YAAY,GAAG;AACxD,MAAI,QAAQ,MAAO,QAAO,IAAI,SAAS,QAAQ,KAAK;AAEpD,SAAO,IAAI,OAAO,GAAG;AACrB,SAAO,IAAI,kBAAkB,GAAG;AAEhC,QAAM,WAAW,iCAAiC,OAAO,IAAI,OAAO,SAAS,CAAC;AAE9E,SAAO,eAAe,OAAO;AAAA;AAAA;AAAA;AAAA,eAIlB,QAAQ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAQvB;AAEA,SAAS,mBAAmB,KAAa,SAAiC,SAAyB;AAC/F,QAAM,QAAQ,IAAI,MAAM,mDAAmD;AAE3E,MAAI,CAAC,OAAO;AACR,WAAO,iBAAiB,uBAAuB,KAAK,OAAO;AAAA,EAC/D;AAEA,QAAM,CAAC,EAAE,MAAM,KAAK,IAAI;AACxB,QAAM,SAAS,QAAQ,UAAU;AACjC,QAAM,QAAQ,QAAQ,UAAU,UAAU,UAAU;AACpD,QAAM,aAAa,QAAQ,OAAO;AAElC,QAAM,cAAc,IAAI,gBAAgB;AAAA,IACpC,eAAe;AAAA,IACf,YAAY;AAAA,IACZ,YAAY;AAAA,EAChB,CAAC;AAED,QAAM,WAAW,sBAAsB,IAAI,UAAU,KAAK,IAAI,YAAY,SAAS,CAAC;AAEpF,SAAO,eAAe,OAAO;AAAA;AAAA,gBAEjB,MAAM;AAAA;AAAA;AAAA,+BAGS,KAAK;AAAA,aACvB,QAAQ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAOrB;AAEA,SAAS,iBAAiB,KAAa,SAAiC,SAAyB;AAC7F,QAAM,UAAU,eAAe,GAAG;AAClC,MAAI,CAAC,SAAS;AACV,WAAO,iBAAiB,qBAAqB,KAAK,OAAO;AAAA,EAC7D;AAEA,QAAM,SAAS,IAAI,gBAAgB;AACnC,MAAI,QAAQ,aAAa,IAAK,QAAO,IAAI,YAAY,GAAG;AACxD,MAAI,QAAQ,SAAS,IAAK,QAAO,IAAI,SAAS,GAAG;AACjD,MAAI,QAAQ,SAAS,IAAK,QAAO,IAAI,QAAQ,GAAG;AAEhD,QAAM,WAAW,kCAAkC,OAAO,IAAI,OAAO,SAAS,CAAC;AAE/E,SAAO,eAAe,OAAO;AAAA;AAAA;AAAA;AAAA,eAIlB,QAAQ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAQvB;AAEA,SAAS,mBAAmB,KAAa,SAAiC,SAAyB;AAC/F,QAAM,WAAW,IAAI,QAAQ,oBAAoB,wBAAwB;AACzE,QAAM,SAAS,QAAQ,UAAU;AAEjC,SAAO,eAAe,OAAO;AAAA;AAAA;AAAA,aAGpB,QAAQ;AAAA;AAAA,gBAEL,MAAM;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAOtB;AAEA,SAAS,uBAAuB,KAAa,SAAiC,SAAyB;AACnG,MAAI,WAAW;AACf,MAAI,IAAI,SAAS,KAAK,GAAG;AACrB,eAAW,IAAI,QAAQ,OAAO,SAAS;AAAA,EAC3C;AAEA,QAAM,SAAS,QAAQ,UAAU;AACjC,QAAM,OAAO,QAAQ,QAAQ;AAE7B,MAAI,CAAC,SAAS,SAAS,GAAG,GAAG;AACzB,gBAAY,SAAS,IAAI;AAAA,EAC7B;AAEA,SAAO,eAAe,OAAO;AAAA;AAAA,aAEpB,QAAQ;AAAA,oCACe,MAAM;AAAA;AAAA;AAAA;AAAA;AAAA;AAM1C;AAEA,SAAS,iBAAiB,KAAa,SAAiC,SAAyB;AAC7F,QAAM,WAAW,oDAAoD,mBAAmB,GAAG,CAAC;AAC5F,QAAM,SAAS,QAAQ,UAAU;AAEjC,SAAO,eAAe,OAAO;AAAA;AAAA;AAAA;AAAA,gBAIjB,MAAM;AAAA,aACT,QAAQ;AAAA;AAAA;AAAA;AAIrB;AAEA,SAAS,mBAAmB,KAAa,UAAkC,SAAyB;AAChG,SAAO,eAAe,OAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,iBAWhB,GAAG;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AASpB;AAEA,SAAS,kBAAkB,KAAa,UAAkC,SAAyB;AAC/F,QAAM,QAAQ,IAAI,QAAQ,uBAAuB,EAAE,EAAE,MAAM,GAAG;AAC9D,QAAM,QAAQ,MAAM,CAAC;AACrB,QAAM,OAAO,MAAM,CAAC;AAEpB,MAAI,CAAC,SAAS,CAAC,MAAM;AACjB,WAAO,iBAAiB,sBAAsB,KAAK,OAAO;AAAA,EAC9D;AAEA,SAAO,eAAe,OAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,+DAO8B,KAAK,IAAI,IAAI;AAAA;AAAA;AAAA;AAAA,iBAI3D,GAAG;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AASpB;AAEA,SAAS,mBAAmB,KAAa,UAAkC,SAAyB;AAChG,QAAM,SAAS,cAAc,GAAG;AAEhC,SAAO,eAAe,OAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,uDAUsB,MAAM;AAAA;AAAA;AAAA,iBAG5C,GAAG;AAAA;AAAA,UAEV,GAAG;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAOb;AAEA,SAAS,iBAAiB,OAAe,KAAa,SAAyB;AAC3E,SAAO,eAAe,OAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,UAMvB,KAAK;AAAA;AAAA,kEAEmD,GAAG;AAAA;AAAA;AAGrE;AAGA,SAAS,iBAAiB,KAA4B;AAClD,QAAM,WAAW;AAAA,IACb;AAAA,IACA;AAAA,EACJ;AAEA,aAAW,WAAW,UAAU;AAC5B,UAAM,QAAQ,IAAI,MAAM,OAAO;AAC/B,QAAI,MAAO,QAAO,MAAM,CAAC,KAAK;AAAA,EAClC;AAEA,SAAO;AACX;AAEA,SAAS,eAAe,KAA4B;AAChD,QAAM,QAAQ,IAAI,MAAM,4BAA4B;AACpD,SAAO,QAAQ,CAAC,KAAK;AACzB;;;ACzTO,IAAM,qBAAN,MAAyB;AAAA,EAK5B,YAAY,QAAuB;AAFnC,SAAQ,aAAa,oBAAI,IAAuB;AAG5C,SAAK,SAAS,IAAI,eAAe,QAAQ,MAAM;AAC/C,SAAK,WAAW,IAAI,iBAAiB,QAAQ,QAAQ;AAGrD,SAAK,uBAAuB;AAG5B,SAAK,0BAA0B;AAG/B,QAAI,QAAQ,YAAY;AACpB,aAAO,WAAW,QAAQ,eAAa;AACnC,aAAK,kBAAkB,SAAS;AAAA,MACpC,CAAC;AAAA,IACL;AAAA,EAGJ;AAAA,EAEQ,4BAAkC;AACtC,SAAK,kBAAkB,cAAc;AACrC,SAAK,kBAAkB,eAAe;AACtC,SAAK,kBAAkB,cAAc;AAAA,EACzC;AAAA,EAEQ,yBAA+B;AACnC,mBAAe,QAAQ,eAAa;AAChC,WAAK,kBAAkB,SAAS;AAAA,IACpC,CAAC;AAAA,EACL;AAAA,EAEA,kBAAkB,WAA6C;AAC3D,QAAI;AAEA,UAAI,CAAC,UAAU,QAAQ,OAAO,UAAU,SAAS,UAAU;AACvD,cAAM,IAAI,MAAM,kCAAkC;AAAA,MACtD;AAEA,UAAI,CAAC,MAAM,QAAQ,UAAU,UAAU,GAAG;AACtC,cAAM,IAAI,MAAM,sCAAsC;AAAA,MAC1D;AAEA,UAAI,CAAC,MAAM,QAAQ,UAAU,WAAW,GAAG;AACvC,cAAM,IAAI,MAAM,uCAAuC;AAAA,MAC3D;AAGA,gBAAU,WAAW,QAAQ,CAAC,MAAM,UAAU;AAC1C,YAAI,CAAC,KAAK,QAAQ,OAAO,KAAK,SAAS,UAAU;AAC7C,gBAAM,IAAI,MAAM,cAAc,KAAK,yBAAyB;AAAA,QAChE;AACA,YAAI,CAAC,KAAK,WAAW,EAAE,KAAK,mBAAmB,SAAS;AACpD,gBAAM,IAAI,MAAM,cAAc,KAAK,mCAAmC;AAAA,QAC1E;AACA,YAAI,CAAC,KAAK,UAAU,OAAO,KAAK,WAAW,YAAY;AACnD,gBAAM,IAAI,MAAM,cAAc,KAAK,oCAAoC;AAAA,QAC3E;AAAA,MACJ,CAAC;AAGD,gBAAU,YAAY,QAAQ,CAAC,MAAM,UAAU;AAC3C,YAAI,CAAC,KAAK,QAAQ,OAAO,KAAK,SAAS,UAAU;AAC7C,gBAAM,IAAI,MAAM,eAAe,KAAK,yBAAyB;AAAA,QACjE;AACA,YAAI,CAAC,KAAK,UAAU,OAAO,KAAK,WAAW,YAAY;AACnD,gBAAM,IAAI,MAAM,eAAe,KAAK,oCAAoC;AAAA,QAC5E;AAAA,MACJ,CAAC;AAGD,WAAK,WAAW,IAAI,UAAU,MAAM,SAAS;AAG7C,gBAAU,WAAW,QAAQ,UAAQ;AACjC,aAAK,OAAO,QAAQ,IAAI;AAAA,MAC5B,CAAC;AAED,gBAAU,YAAY,QAAQ,UAAQ;AAClC,aAAK,SAAS,QAAQ,IAAI;AAAA,MAC9B,CAAC;AAED,aAAO;AAAA,QACH,SAAS;AAAA,QACT,eAAe,UAAU;AAAA,MAC7B;AAAA,IAEJ,SAAS,OAAO;AACZ,YAAM,eAAe,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AAE1E,aAAO;AAAA,QACH,SAAS;AAAA,QACT,eAAe,UAAU;AAAA,QACzB,OAAO;AAAA,MACX;AAAA,IACJ;AAAA,EACJ;AAAA,EAEA,oBAAoB,MAAuB;AACvC,UAAM,YAAY,KAAK,WAAW,IAAI,IAAI;AAC1C,QAAI,CAAC,WAAW;AACZ,aAAO;AAAA,IACX;AAEA,QAAI;AAEA,WAAK,WAAW,OAAO,IAAI;AAG3B,WAAK,yBAAyB;AAE9B,aAAO;AAAA,IACX,QAAQ;AACJ,aAAO;AAAA,IACX;AAAA,EACJ;AAAA,EAEA,MAAMC,WAAmC;AACrC,WAAO,KAAK,OAAO,MAAMA,SAAQ;AAAA,EACrC;AAAA,EAEA,OAAO,QAAiC;AACpC,WAAO,KAAK,SAAS,OAAO,MAAM;AAAA,EACtC;AAAA,EAEA,OAAOA,WAA0B;AAC7B,UAAM,SAAS,KAAK,MAAMA,SAAQ;AAClC,WAAO,KAAK,OAAO,MAAM;AAAA,EAC7B;AAAA,EAEA,gBAA0B;AACtB,WAAO,MAAM,KAAK,KAAK,WAAW,KAAK,CAAC;AAAA,EAC5C;AAAA,EAEA,aAAa,MAAuB;AAChC,WAAO,KAAK,WAAW,IAAI,IAAI;AAAA,EACnC;AAAA,EAEA,cAAwB;AACpB,WAAO,CAAC,GAAG,KAAK,OAAO,YAAY,GAAG,GAAG,KAAK,SAAS,YAAY,CAAC;AAAA,EACxE;AAAA,EAEA,eAAiC;AAC7B,WAAO;AAAA,MACH,UAAU,KAAK,YAAY;AAAA,MAC3B,WAAW;AAAA,MACX,YAAY;AAAA,MACZ,YAAY;AAAA,MACZ,gBAAgB;AAAA,IACpB;AAAA,EACJ;AAAA,EAEA,wBAAmD;AAC/C,WAAO;AAAA,MACH,WAAW;AAAA,MACX,YAAY;AAAA,MACZ,WAAW;AAAA,MACX,YAAY;AAAA,IAChB;AAAA,EACJ;AAAA,EAEQ,2BAAiC;AAErC,UAAM,eAAe,KAAK,OAAO,UAAU;AAC3C,UAAM,iBAAiB,KAAK,SAAS,UAAU;AAG/C,SAAK,SAAS,IAAI,eAAe,YAAY;AAC7C,SAAK,WAAW,IAAI,iBAAiB,cAAc;AAGnD,UAAM,uBAAuB,MAAM,KAAK,KAAK,WAAW,OAAO,CAAC;AAIhE,UAAM,oBAAoB,qBAAqB;AAAA,MAAO,SAClD,CAAC,SAAS,UAAU,OAAO,EAAE,SAAS,IAAI,IAAI;AAAA,IAClD;AAGA,UAAM,iBAAiB,qBAAqB;AAAA,MAAO,SAC/C,CAAC,QAAQ,WAAW,QAAQ,UAAU,QAAQ,aAAa,QAAQ,SAAS,QAAQ,aAAa,cAAc,MAAM,aAAa,YAAY,EAAE,SAAS,IAAI,IAAI;AAAA,IACrK;AAGA,UAAM,mBAAmB,qBAAqB;AAAA,MAAO,SACjD,CAAC,CAAC,SAAS,UAAU,SAAS,QAAQ,WAAW,QAAQ,UAAU,QAAQ,aAAa,QAAQ,SAAS,QAAQ,aAAa,cAAc,MAAM,aAAa,YAAY,EAAE,SAAS,IAAI,IAAI;AAAA,IAClM;AAGA,KAAC,GAAG,mBAAmB,GAAG,gBAAgB,GAAG,gBAAgB,EAAE,QAAQ,eAAa;AAEhF,gBAAU,WAAW,QAAQ,UAAQ;AACjC,aAAK,OAAO,QAAQ,IAAI;AAAA,MAC5B,CAAC;AAED,gBAAU,YAAY,QAAQ,UAAQ;AAClC,aAAK,SAAS,QAAQ,IAAI;AAAA,MAC9B,CAAC;AAAA,IACL,CAAC;AAAA,EACL;AACJ;AA0CO,IAAM,WAAW,IAAI,mBAAmB;;;AnB1PxC,SAAS,YACZ,iBAAiB,IACjB,UAA8B,CAAC,GACd;AACjB,QAAM,CAAC,SAAS,UAAU,IAAI,SAAS,cAAc;AACrD,QAAM,CAAC,MAAM,OAAO,IAAI,SAAS,EAAE;AACnC,QAAM,CAAC,QAAQ,SAAS,IAAI,SAA0B,CAAC,CAAC;AACxD,QAAM,CAAC,WAAW,YAAY,IAAI,SAAS,KAAK;AAChD,QAAM,CAAC,OAAO,QAAQ,IAAI,SAAuB,IAAI;AACrD,QAAM,CAAC,OAAO,QAAQ,IAAI,SAAmC,IAAI;AAEjE,QAAM,YAAY,OAAkC,IAAI;AAGxD,QAAM,SAAS,QAAQ,MAAM;AAEzB,UAAM,SAAuB,QAAQ,UAAU;AAC/C,UAAM,iBAAiC;AAAA,MACnC;AAAA,MACA,GAAI,QAAQ,QAAQ,YAAY;AAAA,QAC5B,UAAU,QAAQ,OAAO,SAAS;AAAA,QAClC,iBAAiB,QAAQ,OAAO,SAAS;AAAA,QACzC,eAAe,QAAQ,OAAO,SAAS;AAAA,QACvC,WAAW,QAAQ,SAAS,QAAQ,OAAO,SAAS,aAAa;AAAA,MACrE;AAAA,IACJ;AAGA,UAAM,eAA6B;AAAA,MAC/B,GAAI,QAAQ,UAAU;AAAA,QAClB,QAAQ,QAAQ,OAAO;AAAA,QACvB,YAAY,QAAQ,OAAO;AAAA,MAC/B;AAAA,MACA,UAAU;AAAA,IACd;AAEA,UAAM,YAAY,IAAI,mBAAmB,YAAY;AAGrD,QAAI,QAAQ,YAAY;AACpB,cAAQ,WAAW,QAAQ,eAAa;AACpC,kBAAU,kBAAkB,SAAS;AAAA,MACzC,CAAC;AAAA,IACL;AAEA,cAAU,UAAU;AACpB,WAAO;AAAA,EACX,GAAG,CAAC,QAAQ,QAAQ,QAAQ,QAAQ,QAAQ,OAAO,QAAQ,UAAU,CAAC;AAGtE,QAAM,kBAAkB,YAAY,CAAC,oBAA4B;AAC7D,QAAI,CAAC,gBAAgB,KAAK,GAAG;AACzB,cAAQ,EAAE;AACV,gBAAU,CAAC,CAAC;AACZ,eAAS,IAAI;AACb,eAAS,IAAI;AACb,mBAAa,KAAK;AAClB;AAAA,IACJ;AAEA,iBAAa,IAAI;AACjB,aAAS,IAAI;AAEb,QAAI;AAEA,YAAM,eAAe,OAAO,MAAM,eAAe;AACjD,YAAM,eAAe,OAAO,OAAO,YAAY;AAE/C,cAAQ,YAAY;AACpB,gBAAU,YAAY;AAGtB,UAAI,QAAQ,OAAO;AACf,cAAM,YAAY,OAAO,aAAa;AACtC,cAAM,qBAAqB,OAAO,sBAAsB;AAExD,iBAAS;AAAA,UACL,MAAM;AAAA,UACN,aAAa;AAAA,UACb,YAAY,oBAAI,KAAK;AAAA,UACrB,eAAe,gBAAgB;AAAA,UAC/B,YAAY,aAAa;AAAA,UACzB,gBAAgB,OAAO,cAAc;AAAA,QACzC,CAAC;AAAA,MACL;AAAA,IAEJ,SAAS,KAAK;AACV,YAAM,WAAW,eAAe,QAAQ,MAAM,IAAI,MAAM,OAAO,GAAG,CAAC;AACnE,eAAS,QAAQ;AAAA,IACrB,UAAE;AACE,mBAAa,KAAK;AAAA,IACtB;AAAA,EACJ,GAAG,CAAC,QAAQ,QAAQ,KAAK,CAAC;AAG1B,YAAU,MAAM;AACZ,oBAAgB,OAAO;AAAA,EAC3B,GAAG,CAAC,SAAS,eAAe,CAAC;AAG7B,YAAU,MAAM;AACZ,eAAW,cAAc;AAAA,EAC7B,GAAG,CAAC,cAAc,CAAC;AAEnB,QAAM,SAAS,YAAY,CAAC,eAAuB;AAC/C,eAAW,UAAU;AAAA,EACzB,GAAG,CAAC,CAAC;AAEL,QAAM,QAAQ,YAAY,MAAM;AAC5B,eAAW,EAAE;AACb,YAAQ,EAAE;AACV,cAAU,CAAC,CAAC;AACZ,aAAS,IAAI;AACb,aAAS,IAAI;AAAA,EACjB,GAAG,CAAC,CAAC;AAEL,SAAO;AAAA,IACH;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACJ;AACJ;AAKO,SAAS,kBAAkB,UAAqC,CAAC,GAAG;AACvE,QAAM,YAAY,OAAkC,IAAI;AAExD,QAAM,SAAS,QAAQ,MAAM;AAEzB,UAAM,eAA6B;AAAA,MAC/B,GAAG,QAAQ;AAAA,MACX,UAAU;AAAA,QACN,QAAQ;AAAA;AAAA,QACR,GAAG,QAAQ,QAAQ;AAAA,MACvB;AAAA,IACJ;AAGA,QAAI,QAAQ,2BAA2B,OAAO;AAC1C,mBAAa,aAAa,CAAC;AAAA,IAC/B;AAEA,UAAM,YAAY,IAAI,mBAAmB,YAAY;AACrD,cAAU,UAAU;AACpB,WAAO;AAAA,EACX,GAAG,CAAC,QAAQ,QAAQ,QAAQ,sBAAsB,CAAC;AAEnD,QAAM,SAAS,YAAY,CAAC,YAAoB;AAC5C,WAAO,OAAO,OAAO,OAAO;AAAA,EAChC,GAAG,CAAC,MAAM,CAAC;AAEX,QAAM,QAAQ,YAAY,CAAC,YAAoB;AAC3C,WAAO,OAAO,MAAM,OAAO;AAAA,EAC/B,GAAG,CAAC,MAAM,CAAC;AAEX,QAAM,SAAS,YAAY,CAAC,WAA4B;AACpD,WAAO,OAAO,OAAO,MAAM;AAAA,EAC/B,GAAG,CAAC,MAAM,CAAC;AAEX,QAAM,gBAAgB,YAAY,MAAM;AACpC,WAAO,OAAO,cAAc;AAAA,EAChC,GAAG,CAAC,MAAM,CAAC;AAEX,QAAM,eAAe,YAAY,CAAC,SAAiB;AAC/C,WAAO,OAAO,aAAa,IAAI;AAAA,EACnC,GAAG,CAAC,MAAM,CAAC;AAEX,QAAM,oBAAoB,YAAY,CAAC,cAAsE;AACzG,WAAO,OAAO,kBAAkB,SAAS;AAAA,EAC7C,GAAG,CAAC,MAAM,CAAC;AAEX,QAAM,sBAAsB,YAAY,CAAC,SAAiB;AACtD,WAAO,OAAO,oBAAoB,IAAI;AAAA,EAC1C,GAAG,CAAC,MAAM,CAAC;AAEX,QAAM,cAAc,YAAY,MAAM;AAClC,WAAO,OAAO,YAAY;AAAA,EAC9B,GAAG,CAAC,MAAM,CAAC;AAEX,QAAM,eAAe,YAAY,MAAM;AACnC,WAAO,OAAO,aAAa;AAAA,EAC/B,GAAG,CAAC,MAAM,CAAC;AAEX,QAAM,wBAAwB,YAAY,MAAM;AAC5C,WAAO,OAAO,sBAAsB;AAAA,EACxC,GAAG,CAAC,MAAM,CAAC;AAEX,SAAO;AAAA,IACH;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACJ;AACJ;AAKO,SAAS,iBAAiB,SAAiB;AAC9C,QAAM,EAAE,MAAM,QAAQ,MAAM,IAAI,YAAY,SAAS,EAAE,OAAO,KAAK,CAAC;AAEpE,SAAO;AAAA,IACH;AAAA,IACA;AAAA,IACA;AAAA,IACA,OAAO;AAAA,MACH,YAAY,OAAO;AAAA,MACnB,YAAY,KAAK;AAAA,MACjB,eAAe,QAAQ;AAAA,IAC3B;AAAA,EACJ;AACJ;;;ADpJe,wBAWH,YAXG;AA7ER,SAASC,kBAAiB;AAAA,EACI;AAAA,EACA;AAAA,EACA;AAAA,EACA,SAAS;AAAA,EACT,IAAI,YAAY;AAAA,EAChB,eAAe,CAAC;AAAA,EAChB,QAAQ;AAAA,EACR;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,WAAW;AAAA,EACX,kBAAkB;AAAA,EAClB,GAAG;AACP,GAA0B;AAEvD,QAAM,kBAAkBC,SAAQ,MAAM;AAClC,UAAM,UAA8B;AAAA,MAChC;AAAA,MACA;AAAA,MACA,YAAY;AAAA;AAAA,MACZ,SAAS;AAAA,IACb;AAGA,QAAI,QAAQ;AACR,cAAQ,SAAS;AAAA,QACb,GAAG;AAAA,QACH,UAAU;AAAA,UACN;AAAA;AAAA,UACA;AAAA,UACA;AAAA,UACA,WAAW;AAAA,UACX,GAAG,OAAO;AAAA,QACd;AAAA,MACJ;AAAA,IACJ,OAAO;AAEH,cAAQ,SAAS;AAAA,QACb,UAAU;AAAA,UACN;AAAA,UACA;AAAA,UACA;AAAA,UACA,WAAW;AAAA,QACf;AAAA,MACJ;AAAA,IACJ;AAGA,QAAI,YAAY;AACZ,cAAQ,aAAa;AAAA,IACzB;AAEA,WAAO;AAAA,EACX,GAAG,CAAC,QAAQ,QAAQ,OAAO,YAAY,UAAU,eAAe,CAAC;AAGjE,QAAM,EAAE,MAAM,QAAQ,WAAW,MAAM,IAAI,YAAY,SAAS,eAAe;AAG/E,EAAAC,WAAU,MAAM;AACZ,QAAI,QAAQ,UAAU;AAClB,eAAS,MAAM,MAAM;AAAA,IACzB;AAAA,EACJ,GAAG,CAAC,MAAM,QAAQ,QAAQ,CAAC;AAG3B,EAAAA,WAAU,MAAM;AACZ,QAAI,SAAS,SAAS;AAClB,cAAQ,KAAK;AAAA,IACjB;AAAA,EACJ,GAAG,CAAC,OAAO,OAAO,CAAC;AAGnB,MAAI,aAAa,SAAS;AACtB,WAAO,gCAAG,mBAAQ;AAAA,EACtB;AAGA,MAAI,OAAO;AACP,QAAI,eAAe;AACf,aAAO,gCAAG,wBAAc,KAAK,GAAE;AAAA,IACnC;AAGA,WACI,qBAAC,SAAI,WAAU,mFACX;AAAA,0BAAC,SAAI,WAAU,eAAc,mCAAqB;AAAA,MAClD,oBAAC,SAAI,WAAU,gBAAgB,gBAAM,SAAQ;AAAA,OACjD;AAAA,EAER;AAGA,QAAM,oBAAoB;AAAA,IACtB,GAAG;AAAA,IACH,GAAG;AAAA,IACH,WAAW,YACP,GAAG,SAAS,yBAAyB;AAAA,IACzC,yBAAyB,EAAE,QAAQ,KAAK;AAAA,EAC5C;AAGA,SAAO,MAAM,cAAc,WAAW,iBAAiB;AAC3D;AAGAF,kBAAiB,cAAc;AA0B/B,IAAM,wBAAN,cAAoC,MAAM,UAGxC;AAAA,EACE,YAAY,OAAmC;AAC3C,UAAM,KAAK;AACX,SAAK,QAAQ,EAAE,UAAU,OAAO,OAAO,KAAK;AAAA,EAChD;AAAA,EAEA,OAAO,yBAAyB,OAA0C;AACtE,WAAO,EAAE,UAAU,MAAM,MAAM;AAAA,EACnC;AAAA,EAES,kBAAkB,OAAc,WAA4B;AACjE,YAAQ,MAAM,2BAA2B,OAAO,SAAS;AAAA,EAC7D;AAAA,EAES,SAAS;AACd,QAAI,KAAK,MAAM,YAAY,KAAK,MAAM,OAAO;AACzC,UAAI,KAAK,MAAM,UAAU;AACrB,eAAO,KAAK,MAAM,SAAS,KAAK,MAAM,KAAK;AAAA,MAC/C;AAEA,aACI,qBAAC,SAAI,WAAU,4FACX;AAAA,4BAAC,SAAI,WAAU,eAAc,sCAAwB;AAAA,QACrD,oBAAC,SAAI,WAAU,gBAAgB,eAAK,MAAM,MAAM,SAAQ;AAAA,QACxD;AAAA,UAAC;AAAA;AAAA,YACG,SAAS,MAAM,KAAK,SAAS,EAAE,UAAU,OAAO,OAAO,KAAK,CAAC;AAAA,YAC7D,WAAU;AAAA,YACb;AAAA;AAAA,QAED;AAAA,SACJ;AAAA,IAER;AAEA,WAAO,KAAK,MAAM;AAAA,EACtB;AACJ;","names":["useMemo","useEffect","markdown","markdown","MarkdownRenderer","useMemo","useEffect"]}
1
+ {"version":3,"sources":["../../src/react/MarkdownRenderer.tsx","../../src/react/hooks.ts","../../src/parser.ts","../../src/utils.ts","../../src/renderer.ts","../../src/extensions/core/blockquote.ts","../../src/extensions/core/breaks.ts","../../src/extensions/core/code.ts","../../src/extensions/core/emphasis.ts","../../src/extensions/core/heading.ts","../../src/extensions/core/hr.ts","../../src/extensions/core/image.ts","../../src/extensions/core/links.ts","../../src/extensions/core/lists.ts","../../src/extensions/core/paragraph.ts","../../src/extensions/core/text.ts","../../src/extensions/core/index.ts","../../src/extensions/alert.ts","../../src/extensions/button.ts","../../src/extensions/embed.ts","../../src/engine.ts"],"sourcesContent":["import React, { useMemo, useEffect } from 'react';\r\nimport { useMarkdown } from './hooks';\r\nimport type { MarkdownRendererProps, UseMarkdownOptions } from './types';\r\n\r\n/**\r\n * MarkdownRenderer - Main React component for rendering markdown\r\n *\r\n * @example\r\n * ```tsx\r\n * <MarkdownRenderer\r\n * content=\"# Hello **World**!\"\r\n * className=\"prose\"\r\n * />\r\n * ```\r\n */\r\nexport function MarkdownRenderer({\r\n content,\r\n className,\r\n config,\r\n format = 'tailwind',\r\n as: Component = 'div',\r\n wrapperProps = {},\r\n debug = false,\r\n errorFallback,\r\n loading,\r\n onRender,\r\n onError,\r\n extensions,\r\n sanitize = true,\r\n allowUnsafeHtml = false,\r\n ...restProps\r\n }: MarkdownRendererProps) {\r\n // Prepare markdown options with proper type safety\r\n const markdownOptions = useMemo(() => {\r\n const options: UseMarkdownOptions = {\r\n format,\r\n debug,\r\n debounceMs: 0, // No debounce for tests\r\n memoize: true\r\n };\r\n\r\n // Add config if provided\r\n if (config) {\r\n options.config = {\r\n ...config,\r\n renderer: {\r\n format, // Required field\r\n sanitize,\r\n allowUnsafeHtml,\r\n debugMode: debug,\r\n ...config.renderer\r\n }\r\n };\r\n } else {\r\n // Create minimal config with required format field\r\n options.config = {\r\n renderer: {\r\n format,\r\n sanitize,\r\n allowUnsafeHtml,\r\n debugMode: debug\r\n }\r\n };\r\n }\r\n\r\n // Add extensions if provided\r\n if (extensions) {\r\n options.extensions = extensions;\r\n }\r\n\r\n return options;\r\n }, [config, format, debug, extensions, sanitize, allowUnsafeHtml]);\r\n\r\n // Use the markdown hook\r\n const { html, tokens, isLoading, error } = useMarkdown(content, markdownOptions);\r\n\r\n // Call onRender callback when rendering completes\r\n useEffect(() => {\r\n if (html && onRender) {\r\n onRender(html, tokens);\r\n }\r\n }, [html, tokens, onRender]);\r\n\r\n // Call onError callback when error occurs\r\n useEffect(() => {\r\n if (error && onError) {\r\n onError(error);\r\n }\r\n }, [error, onError]);\r\n\r\n // Show loading state\r\n if (isLoading && loading) {\r\n return <>{loading}</>;\r\n }\r\n\r\n // Show error state\r\n if (error) {\r\n if (errorFallback) {\r\n return <>{errorFallback(error)}</>;\r\n }\r\n\r\n // Default error display\r\n return (\r\n <div className=\"changerawr-error bg-red-50 border border-red-200 text-red-700 px-4 py-3 rounded\">\r\n <div className=\"font-medium\">Markdown Render Error</div>\r\n <div className=\"text-sm mt-1\">{error.message}</div>\r\n </div>\r\n );\r\n }\r\n\r\n // Prepare wrapper props\r\n const finalWrapperProps = {\r\n ...wrapperProps,\r\n ...restProps,\r\n className: className ?\r\n `${className} changerawr-markdown` : 'changerawr-markdown',\r\n dangerouslySetInnerHTML: { __html: html }\r\n };\r\n\r\n // Render the component\r\n return React.createElement(Component, finalWrapperProps);\r\n}\r\n\r\n// Display name for debugging\r\nMarkdownRenderer.displayName = 'MarkdownRenderer';\r\n\r\n/**\r\n * MarkdownRenderer with error boundary\r\n */\r\nexport function SafeMarkdownRenderer(props: MarkdownRendererProps) {\r\n return (\r\n <MarkdownErrorBoundary {...(props.errorFallback && { fallback: props.errorFallback })}>\r\n <MarkdownRenderer {...props} />\r\n </MarkdownErrorBoundary>\r\n );\r\n}\r\n\r\n/**\r\n * Error boundary component for markdown rendering\r\n */\r\ninterface MarkdownErrorBoundaryProps {\r\n children: React.ReactNode;\r\n fallback?: (error: Error) => React.ReactNode;\r\n}\r\n\r\ninterface MarkdownErrorBoundaryState {\r\n hasError: boolean;\r\n error: Error | null;\r\n}\r\n\r\nclass MarkdownErrorBoundary extends React.Component<\r\n MarkdownErrorBoundaryProps,\r\n MarkdownErrorBoundaryState\r\n> {\r\n constructor(props: MarkdownErrorBoundaryProps) {\r\n super(props);\r\n this.state = { hasError: false, error: null };\r\n }\r\n\r\n static getDerivedStateFromError(error: Error): MarkdownErrorBoundaryState {\r\n return { hasError: true, error };\r\n }\r\n\r\n override componentDidCatch(error: Error, errorInfo: React.ErrorInfo) {\r\n console.error('MarkdownRenderer Error:', error, errorInfo);\r\n }\r\n\r\n override render() {\r\n if (this.state.hasError && this.state.error) {\r\n if (this.props.fallback) {\r\n return this.props.fallback(this.state.error);\r\n }\r\n\r\n return (\r\n <div className=\"changerawr-error-boundary bg-red-50 border border-red-200 text-red-700 px-4 py-3 rounded\">\r\n <div className=\"font-medium\">Markdown Component Error</div>\r\n <div className=\"text-sm mt-1\">{this.state.error.message}</div>\r\n <button\r\n onClick={() => this.setState({ hasError: false, error: null })}\r\n className=\"text-xs mt-2 px-2 py-1 bg-red-200 hover:bg-red-300 rounded\"\r\n >\r\n Try Again\r\n </button>\r\n </div>\r\n );\r\n }\r\n\r\n return this.props.children;\r\n }\r\n}\r\n\r\n/**\r\n * Lightweight markdown renderer for simple use cases\r\n */\r\nexport function SimpleMarkdownRenderer({\r\n content,\r\n className\r\n }: {\r\n content: string;\r\n className?: string;\r\n}) {\r\n return (\r\n <MarkdownRenderer\r\n content={content}\r\n {...(className && { className })}\r\n format=\"tailwind\"\r\n config={{\r\n renderer: {\r\n format: 'tailwind',\r\n sanitize: true\r\n }\r\n }}\r\n />\r\n );\r\n}\r\n\r\n/**\r\n * HTML-only markdown renderer (no Tailwind classes)\r\n */\r\nexport function HTMLMarkdownRenderer({\r\n content,\r\n className,\r\n sanitize = true\r\n }: {\r\n content: string;\r\n className?: string;\r\n sanitize?: boolean;\r\n}) {\r\n return (\r\n <MarkdownRenderer\r\n content={content}\r\n {...(className && { className })}\r\n format=\"html\"\r\n sanitize={sanitize}\r\n config={{\r\n renderer: { format: 'html' }\r\n }}\r\n />\r\n );\r\n}\r\n\r\n/**\r\n * Debug markdown renderer with performance info\r\n */\r\nexport function DebugMarkdownRenderer({\r\n content,\r\n className\r\n }: {\r\n content: string;\r\n className?: string;\r\n}) {\r\n return (\r\n <MarkdownRenderer\r\n content={content}\r\n {...(className && { className })}\r\n debug={true}\r\n format=\"tailwind\"\r\n config={{\r\n renderer: {\r\n format: 'tailwind',\r\n debugMode: true\r\n }\r\n }}\r\n />\r\n );\r\n}","import { useState, useCallback, useMemo, useRef, useEffect } from 'react';\r\nimport { ChangerawrMarkdown } from '../engine';\r\nimport type {\r\n UseMarkdownOptions,\r\n UseMarkdownResult,\r\n MarkdownEngineHookOptions,\r\n MarkdownDebugInfo,\r\n EngineConfig,\r\n RendererConfig,\r\n OutputFormat\r\n} from './types';\r\nimport type { MarkdownToken } from '../types';\r\n\r\n/**\r\n * Main hook for rendering markdown content\r\n */\r\nexport function useMarkdown(\r\n initialContent = '',\r\n options: UseMarkdownOptions = {}\r\n): UseMarkdownResult {\r\n const [content, setContent] = useState(initialContent);\r\n const [html, setHtml] = useState('');\r\n const [tokens, setTokens] = useState<MarkdownToken[]>([]);\r\n const [isLoading, setIsLoading] = useState(false);\r\n const [error, setError] = useState<Error | null>(null);\r\n const [debug, setDebug] = useState<MarkdownDebugInfo | null>(null);\r\n\r\n const engineRef = useRef<ChangerawrMarkdown | null>(null);\r\n\r\n // Create engine instance with proper type safety - recreate when format changes\r\n const engine = useMemo(() => {\r\n // Always recreate engine when dependencies change\r\n const format: OutputFormat = options.format ?? 'tailwind';\r\n const rendererConfig: RendererConfig = {\r\n format,\r\n ...(options.config?.renderer && {\r\n sanitize: options.config.renderer.sanitize,\r\n allowUnsafeHtml: options.config.renderer.allowUnsafeHtml,\r\n customClasses: options.config.renderer.customClasses,\r\n debugMode: options.debug ?? options.config.renderer.debugMode ?? false\r\n })\r\n };\r\n\r\n // Build full engine config\r\n const engineConfig: EngineConfig = {\r\n ...(options.config && {\r\n parser: options.config.parser,\r\n extensions: options.config.extensions\r\n }),\r\n renderer: rendererConfig\r\n };\r\n\r\n const newEngine = new ChangerawrMarkdown(engineConfig);\r\n\r\n // Register custom extensions if provided\r\n if (options.extensions) {\r\n options.extensions.forEach(extension => {\r\n newEngine.registerExtension(extension);\r\n });\r\n }\r\n\r\n engineRef.current = newEngine;\r\n return newEngine;\r\n }, [options.config, options.format, options.debug, options.extensions]);\r\n\r\n // Process markdown content\r\n const processMarkdown = useCallback((markdownContent: string) => {\r\n if (!markdownContent.trim()) {\r\n setHtml('');\r\n setTokens([]);\r\n setError(null);\r\n setDebug(null);\r\n setIsLoading(false);\r\n return;\r\n }\r\n\r\n setIsLoading(true);\r\n setError(null);\r\n\r\n try {\r\n // Parse and render using the actual engine methods\r\n const parsedTokens = engine.parse(markdownContent);\r\n const renderedHtml = engine.render(parsedTokens);\r\n\r\n setHtml(renderedHtml);\r\n setTokens(parsedTokens);\r\n\r\n // Set debug info if enabled\r\n if (options.debug) {\r\n const coreDebug = engine.getDebugInfo();\r\n const performanceMetrics = engine.getPerformanceMetrics();\r\n\r\n setDebug({\r\n core: coreDebug,\r\n performance: performanceMetrics,\r\n renderedAt: new Date(),\r\n contentLength: markdownContent.length,\r\n htmlLength: renderedHtml.length,\r\n extensionsUsed: engine.getExtensions()\r\n });\r\n }\r\n\r\n } catch (err) {\r\n const errorObj = err instanceof Error ? err : new Error(String(err));\r\n setError(errorObj);\r\n } finally {\r\n setIsLoading(false);\r\n }\r\n }, [engine, options.debug]);\r\n\r\n // Process content when it changes\r\n useEffect(() => {\r\n processMarkdown(content);\r\n }, [content, processMarkdown]);\r\n\r\n // Update content when initialContent changes\r\n useEffect(() => {\r\n setContent(initialContent);\r\n }, [initialContent]);\r\n\r\n const render = useCallback((newContent: string) => {\r\n setContent(newContent);\r\n }, []);\r\n\r\n const clear = useCallback(() => {\r\n setContent('');\r\n setHtml('');\r\n setTokens([]);\r\n setError(null);\r\n setDebug(null);\r\n }, []);\r\n\r\n return {\r\n html,\r\n tokens,\r\n isLoading,\r\n error,\r\n debug,\r\n render,\r\n clear\r\n };\r\n}\r\n\r\n/**\r\n * Hook for managing a markdown engine instance\r\n */\r\nexport function useMarkdownEngine(options: MarkdownEngineHookOptions = {}) {\r\n const engineRef = useRef<ChangerawrMarkdown | null>(null);\r\n\r\n const engine = useMemo(() => {\r\n // Always recreate engine when dependencies change\r\n const engineConfig: EngineConfig = {\r\n ...options.config,\r\n renderer: {\r\n format: 'tailwind', // Required field\r\n ...options.config?.renderer\r\n }\r\n };\r\n\r\n // Handle auto-register extensions option\r\n if (options.autoRegisterExtensions === false) {\r\n engineConfig.extensions = [];\r\n }\r\n\r\n const newEngine = new ChangerawrMarkdown(engineConfig);\r\n engineRef.current = newEngine;\r\n return newEngine;\r\n }, [options.config, options.autoRegisterExtensions]);\r\n\r\n const toHtml = useCallback((content: string) => {\r\n return engine.toHtml(content);\r\n }, [engine]);\r\n\r\n const parse = useCallback((content: string) => {\r\n return engine.parse(content);\r\n }, [engine]);\r\n\r\n const render = useCallback((tokens: MarkdownToken[]) => {\r\n return engine.render(tokens);\r\n }, [engine]);\r\n\r\n const getExtensions = useCallback(() => {\r\n return engine.getExtensions();\r\n }, [engine]);\r\n\r\n const hasExtension = useCallback((name: string) => {\r\n return engine.hasExtension(name);\r\n }, [engine]);\r\n\r\n const registerExtension = useCallback((extension: Parameters<ChangerawrMarkdown['registerExtension']>[0]) => {\r\n return engine.registerExtension(extension);\r\n }, [engine]);\r\n\r\n const unregisterExtension = useCallback((name: string) => {\r\n return engine.unregisterExtension(name);\r\n }, [engine]);\r\n\r\n const getWarnings = useCallback(() => {\r\n return engine.getWarnings();\r\n }, [engine]);\r\n\r\n const getDebugInfo = useCallback(() => {\r\n return engine.getDebugInfo();\r\n }, [engine]);\r\n\r\n const getPerformanceMetrics = useCallback(() => {\r\n return engine.getPerformanceMetrics();\r\n }, [engine]);\r\n\r\n return {\r\n engine,\r\n toHtml,\r\n parse,\r\n render,\r\n getExtensions,\r\n hasExtension,\r\n registerExtension,\r\n unregisterExtension,\r\n getWarnings,\r\n getDebugInfo,\r\n getPerformanceMetrics\r\n };\r\n}\r\n\r\n/**\r\n * Debug hook for markdown processing\r\n */\r\nexport function useMarkdownDebug(content: string) {\r\n const { html, tokens, debug } = useMarkdown(content, { debug: true });\r\n\r\n return {\r\n html,\r\n tokens,\r\n debug,\r\n stats: {\r\n tokenCount: tokens.length,\r\n htmlLength: html.length,\r\n contentLength: content.length\r\n }\r\n };\r\n}","import type { MarkdownToken, ParseRule, ParserConfig } from './types';\r\n\r\nexport class MarkdownParser {\r\n private rules: ParseRule[] = [];\r\n private warnings: string[] = [];\r\n private config: ParserConfig;\r\n\r\n constructor(config?: ParserConfig) {\r\n this.config = {\r\n debugMode: false,\r\n maxIterations: 10000,\r\n validateMarkdown: false,\r\n ...config\r\n };\r\n }\r\n\r\n addRule(rule: ParseRule): void {\r\n this.rules.push(rule);\r\n // Sort by priority - extensions should define their own priority\r\n this.rules.sort((a, b) => {\r\n // Feature extensions first (alert, button, embed) - they have more specific patterns\r\n const aFeatureExtension = ['alert', 'button', 'embed'].includes(a.name);\r\n const bFeatureExtension = ['alert', 'button', 'embed'].includes(b.name);\r\n\r\n if (aFeatureExtension && !bFeatureExtension) return -1;\r\n if (!aFeatureExtension && bFeatureExtension) return 1;\r\n\r\n // Core extensions next\r\n const aCoreExtension = ['text', 'heading', 'bold', 'italic', 'code', 'codeblock', 'link', 'image', 'list', 'task-list', 'blockquote', 'hr', 'paragraph', 'line-break'].includes(a.name);\r\n const bCoreExtension = ['text', 'heading', 'bold', 'italic', 'code', 'codeblock', 'link', 'image', 'list', 'task-list', 'blockquote', 'hr', 'paragraph', 'line-break'].includes(b.name);\r\n\r\n if (aCoreExtension && !bCoreExtension) return -1;\r\n if (!aCoreExtension && bCoreExtension) return 1;\r\n\r\n // Within same category, specific ordering\r\n // Images before links (more specific pattern)\r\n if (a.name === 'image' && b.name === 'link') return -1;\r\n if (a.name === 'link' && b.name === 'image') return 1;\r\n\r\n // Task lists before regular lists\r\n if (a.name === 'task-item' && b.name === 'list-item') return -1;\r\n if (a.name === 'list-item' && b.name === 'task-item') return 1;\r\n\r\n // Code blocks before inline code\r\n if (a.name === 'codeblock' && b.name === 'code') return -1;\r\n if (a.name === 'code' && b.name === 'codeblock') return 1;\r\n\r\n // Bold before italic\r\n if (a.name === 'bold' && b.name === 'italic') return -1;\r\n if (a.name === 'italic' && b.name === 'bold') return 1;\r\n\r\n // Then alphabetical\r\n return a.name.localeCompare(b.name);\r\n });\r\n }\r\n\r\n hasRule(name: string): boolean {\r\n return this.rules.some(rule => rule.name === name);\r\n }\r\n\r\n parse(markdown: string): MarkdownToken[] {\r\n // Clear previous warnings\r\n this.warnings = [];\r\n\r\n if (!markdown.trim()) {\r\n return [];\r\n }\r\n\r\n // Check if we have any rules at all\r\n if (this.rules.length === 0) {\r\n this.warnings.push('No parse rules registered - consider using CoreExtensions');\r\n return [{\r\n type: 'text',\r\n content: markdown,\r\n raw: markdown\r\n }];\r\n }\r\n\r\n // Pre-process markdown to handle common issues\r\n const processedMarkdown = this.preprocessMarkdown(markdown);\r\n\r\n const tokens: MarkdownToken[] = [];\r\n let remaining = processedMarkdown;\r\n let iterationCount = 0;\r\n const maxIterations = this.config.maxIterations || 10000;\r\n\r\n while (remaining.length > 0 && iterationCount < maxIterations) {\r\n iterationCount++;\r\n let matched = false;\r\n let bestMatch: { rule: ParseRule; match: RegExpMatchArray; priority: number } | null = null;\r\n\r\n // Try each rule and find the best match (earliest position)\r\n for (const rule of this.rules) {\r\n try {\r\n // Create a fresh regex without global flag for position-based matching\r\n const pattern = new RegExp(rule.pattern.source, rule.pattern.flags.replace('g', ''));\r\n const match = remaining.match(pattern);\r\n\r\n if (match && match.index !== undefined) {\r\n // Prioritize matches at position 0, but also consider nearby matches\r\n const priority = match.index === 0 ? 1000 : (1000 - match.index);\r\n\r\n if (!bestMatch || priority > bestMatch.priority ||\r\n (priority === bestMatch.priority && match.index < (bestMatch.match.index || 0))) {\r\n bestMatch = { rule, match, priority };\r\n }\r\n }\r\n } catch (error) {\r\n if (this.config.debugMode) {\r\n console.warn(`Error in rule \"${rule.name}\":`, error);\r\n }\r\n }\r\n }\r\n\r\n if (bestMatch && bestMatch.match.index !== undefined) {\r\n const { rule, match } = bestMatch;\r\n const matchIndex = match.index as number;\r\n\r\n // If match is not at the beginning, take text before it\r\n if (matchIndex > 0) {\r\n const textBefore = remaining.slice(0, matchIndex);\r\n tokens.push({\r\n type: 'text',\r\n content: textBefore,\r\n raw: textBefore\r\n });\r\n remaining = remaining.slice(matchIndex);\r\n continue;\r\n }\r\n\r\n // Process the match\r\n try {\r\n const token = rule.render(match);\r\n tokens.push({\r\n ...token,\r\n raw: match[0] || ''\r\n });\r\n\r\n remaining = remaining.slice(match[0]?.length || 0);\r\n matched = true;\r\n } catch (error) {\r\n const errorMessage = error instanceof Error ? error.message : String(error);\r\n this.warnings.push(`Failed to render ${rule.name}: ${errorMessage}`);\r\n\r\n // Fall back to treating as text\r\n const char = remaining[0];\r\n if (char) {\r\n tokens.push({\r\n type: 'text',\r\n content: char,\r\n raw: char\r\n });\r\n remaining = remaining.slice(1);\r\n }\r\n }\r\n }\r\n\r\n if (!matched) {\r\n // Take one character and continue\r\n const char = remaining[0];\r\n if (char) {\r\n tokens.push({\r\n type: 'text',\r\n content: char,\r\n raw: char\r\n });\r\n remaining = remaining.slice(1);\r\n }\r\n }\r\n }\r\n\r\n if (iterationCount >= maxIterations) {\r\n this.warnings.push('Parser hit maximum iterations - possible infinite loop detected');\r\n }\r\n\r\n // Post-process tokens to merge consecutive text and validate structure\r\n const processedTokens = this.postProcessTokens(tokens);\r\n\r\n return processedTokens;\r\n }\r\n\r\n getWarnings(): string[] {\r\n return [...this.warnings];\r\n }\r\n\r\n getConfig(): ParserConfig {\r\n return { ...this.config };\r\n }\r\n\r\n updateConfig(config: Partial<ParserConfig>): void {\r\n this.config = { ...this.config, ...config };\r\n }\r\n\r\n setDebugMode(enabled: boolean): void {\r\n this.config.debugMode = enabled;\r\n }\r\n\r\n clearWarnings(): void {\r\n this.warnings = [];\r\n }\r\n\r\n private preprocessMarkdown(markdown: string): string {\r\n // Check for common markdown issues and warn about them\r\n if (this.config.validateMarkdown) {\r\n this.validateMarkdown(markdown);\r\n }\r\n\r\n // Normalize line endings\r\n return markdown.replace(/\\r\\n/g, '\\n').replace(/\\r/g, '\\n');\r\n }\r\n\r\n private validateMarkdown(markdown: string): void {\r\n // Check for unclosed bold markers\r\n const boldMatches = markdown.match(/\\*\\*/g);\r\n if (boldMatches && boldMatches.length % 2 !== 0) {\r\n this.warnings.push('Unclosed bold markers (**) detected - some bold formatting may not work');\r\n }\r\n\r\n // Check for unclosed italic markers\r\n const italicMatches = markdown.match(/(?<!\\*)\\*(?!\\*)/g);\r\n if (italicMatches && italicMatches.length % 2 !== 0) {\r\n this.warnings.push('Unclosed italic markers (*) detected - some italic formatting may not work');\r\n }\r\n\r\n // Check for unclosed code blocks\r\n const codeBlockMatches = markdown.match(/```/g);\r\n if (codeBlockMatches && codeBlockMatches.length % 2 !== 0) {\r\n this.warnings.push('Unclosed code blocks (```) detected - some code formatting may not work');\r\n }\r\n\r\n // Check for unclosed inline code\r\n const inlineCodeMatches = markdown.match(/`/g);\r\n if (inlineCodeMatches && inlineCodeMatches.length % 2 !== 0) {\r\n this.warnings.push('Unclosed inline code markers (`) detected - some code formatting may not work');\r\n }\r\n }\r\n\r\n private postProcessTokens(tokens: MarkdownToken[]): MarkdownToken[] {\r\n const processed: MarkdownToken[] = [];\r\n let i = 0;\r\n\r\n while (i < tokens.length) {\r\n const token = tokens[i];\r\n\r\n if (token && token.type === 'text') {\r\n // Collect consecutive text tokens\r\n let textContent = token.content || token.raw || '';\r\n let j = i + 1;\r\n\r\n while (j < tokens.length && tokens[j] && tokens[j]!.type === 'text') {\r\n const nextToken = tokens[j]!;\r\n textContent += nextToken.content || nextToken.raw || '';\r\n j++;\r\n }\r\n\r\n // Only create a text token if there's actual content\r\n if (textContent.trim().length > 0 || textContent.includes('\\n')) {\r\n processed.push({\r\n type: 'text',\r\n content: textContent,\r\n raw: textContent\r\n });\r\n }\r\n\r\n i = j;\r\n } else if (token) {\r\n // Recursively parse content for block-level elements\r\n const processedToken = this.recursivelyParseBlockContent(token);\r\n processed.push(processedToken);\r\n i++;\r\n } else {\r\n i++;\r\n }\r\n }\r\n\r\n return processed;\r\n }\r\n\r\n private recursivelyParseBlockContent(token: MarkdownToken): MarkdownToken {\r\n // List of token types that should have their content recursively parsed\r\n const blockTypes = ['alert', 'blockquote'];\r\n\r\n if (blockTypes.includes(token.type) && token.content && token.content.trim()) {\r\n // Recursively parse the content into child tokens\r\n const children = this.parse(token.content);\r\n\r\n return {\r\n ...token,\r\n children\r\n };\r\n }\r\n\r\n return token;\r\n }\r\n}","/**\r\n * Utility functions for Changerawr Markdown\r\n */\r\n\r\n// Import DOMPurify with SSR safety\r\nlet DOMPurify: { sanitize: (html: string, options?: Record<string, unknown>) => string } = {\r\n sanitize: (html: string) => html\r\n};\r\n\r\nif (typeof window !== 'undefined') {\r\n import('dompurify').then(module => {\r\n DOMPurify = module.default;\r\n }).catch(err => {\r\n console.error('Failed to load DOMPurify', err);\r\n });\r\n}\r\n\r\n// Allowed HTML tags and attributes for sanitization\r\nconst ALLOWED_TAGS = [\r\n // Standard HTML\r\n 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'p', 'br', 'strong', 'em', 'del', 'ins',\r\n 'a', 'img', 'ul', 'ol', 'li', 'blockquote', 'pre', 'code', 'table', 'thead',\r\n 'tbody', 'tr', 'th', 'td', 'div', 'span', 'sup', 'sub', 'hr', 'input',\r\n // Embeds\r\n 'iframe', 'embed', 'object', 'param', 'video', 'audio', 'source',\r\n // SVG\r\n 'svg', 'path', 'polyline', 'line', 'circle', 'rect', 'g', 'defs', 'use',\r\n // Form elements\r\n 'form', 'fieldset', 'legend', 'label', 'select', 'option', 'textarea', 'button'\r\n];\r\n\r\nconst ALLOWED_ATTR = [\r\n // Standard attributes\r\n 'href', 'title', 'alt', 'src', 'class', 'id', 'target', 'rel', 'type',\r\n 'checked', 'disabled', 'loading', 'width', 'height', 'style', 'role',\r\n // Iframe attributes\r\n 'frameborder', 'allowfullscreen', 'allow', 'sandbox', 'scrolling',\r\n 'allowtransparency', 'name', 'seamless', 'srcdoc',\r\n // Data attributes (for embeds)\r\n 'data-*',\r\n // SVG attributes\r\n 'viewBox', 'fill', 'stroke', 'stroke-width', 'stroke-linecap', 'stroke-linejoin',\r\n 'd', 'points', 'x1', 'y1', 'x2', 'y2', 'cx', 'cy', 'r', 'rx', 'ry',\r\n // Media attributes\r\n 'autoplay', 'controls', 'loop', 'muted', 'preload', 'poster',\r\n // Form attributes\r\n 'value', 'placeholder', 'required', 'readonly', 'maxlength', 'minlength',\r\n 'max', 'min', 'step', 'pattern', 'autocomplete', 'autofocus'\r\n];\r\n\r\n/**\r\n * Escape HTML special characters\r\n */\r\nexport function escapeHtml(text: string): string {\r\n const map: Record<string, string> = {\r\n '&': '&amp;',\r\n '<': '&lt;',\r\n '>': '&gt;',\r\n '\"': '&quot;',\r\n \"'\": '&#39;'\r\n };\r\n return text.replace(/[&<>\"']/g, char => map[char] || char);\r\n}\r\n\r\n/**\r\n * Generate URL-friendly ID from text\r\n */\r\nexport function generateId(text: string): string {\r\n return text\r\n .toLowerCase()\r\n .replace(/[^\\w\\s-]/g, '')\r\n .replace(/\\s+/g, '-')\r\n .replace(/-+/g, '-')\r\n .replace(/^-|-$/g, '')\r\n .trim();\r\n}\r\n\r\n/**\r\n * Sanitize HTML content using DOMPurify\r\n */\r\nexport function sanitizeHtml(html: string): string {\r\n try {\r\n // Skip sanitization for embed content that might be sensitive\r\n if (html.includes('codepen.io/') || html.includes('youtube.com/embed/')) {\r\n return html;\r\n }\r\n\r\n // Use DOMPurify if available\r\n if (typeof DOMPurify?.sanitize === 'function') {\r\n const sanitized = DOMPurify.sanitize(html, {\r\n ALLOWED_TAGS,\r\n ALLOWED_ATTR,\r\n ALLOW_DATA_ATTR: true,\r\n ALLOW_UNKNOWN_PROTOCOLS: false,\r\n SAFE_FOR_TEMPLATES: false,\r\n WHOLE_DOCUMENT: false,\r\n RETURN_DOM: false,\r\n RETURN_DOM_FRAGMENT: false,\r\n FORCE_BODY: false,\r\n SANITIZE_DOM: false,\r\n SANITIZE_NAMED_PROPS: false,\r\n FORBID_ATTR: ['onload', 'onerror', 'onclick', 'onmouseover', 'onmouseout', 'onfocus', 'onblur'],\r\n ADD_TAGS: ['iframe', 'embed', 'object', 'param'],\r\n ADD_ATTR: [\r\n 'allow', 'allowfullscreen', 'frameborder', 'scrolling',\r\n 'allowtransparency', 'sandbox', 'loading', 'style',\r\n 'title', 'name', 'seamless', 'srcdoc'\r\n ],\r\n ALLOWED_URI_REGEXP: /^(?:(?:(?:f|ht)tps?|mailto|tel|callto|cid|xmpp|xxx):|[^a-z]|[a-z+.\\-]+(?:[^a-z+.\\-:]|$))/i\r\n });\r\n\r\n // If too much content is lost, fall back to basic sanitization\r\n if (sanitized.length < html.length * 0.7) {\r\n return basicSanitize(html);\r\n }\r\n\r\n return sanitized;\r\n }\r\n\r\n // Fallback to basic sanitization\r\n return basicSanitize(html);\r\n } catch (error) {\r\n console.error('Sanitization failed:', error);\r\n return basicSanitize(html);\r\n }\r\n}\r\n\r\n/**\r\n * Basic HTML sanitization - removes dangerous content\r\n */\r\nexport function basicSanitize(html: string): string {\r\n return html\r\n .replace(/<script\\b[^<]*(?:(?!<\\/script>)<[^<]*)*<\\/script>/gi, '')\r\n .replace(/on\\w+\\s*=\\s*\"[^\"]*\"/gi, '')\r\n .replace(/on\\w+\\s*=\\s*'[^']*'/gi, '')\r\n .replace(/javascript:/gi, '');\r\n}\r\n\r\n/**\r\n * Check if code is running in browser environment\r\n */\r\nexport function isBrowser(): boolean {\r\n return typeof window !== 'undefined' && typeof document !== 'undefined';\r\n}\r\n\r\n/**\r\n * Check if code is running in Node.js environment\r\n */\r\nexport function isNode(): boolean {\r\n return typeof process !== 'undefined' &&\r\n process.versions != null &&\r\n process.versions.node != null;\r\n}\r\n\r\n/**\r\n * Debounce function for performance optimization\r\n */\r\nexport function debounce<T extends (...args: any[]) => any>(\r\n func: T,\r\n wait: number\r\n): (...args: Parameters<T>) => void {\r\n let timeout: NodeJS.Timeout | number;\r\n\r\n return function executedFunction(...args: Parameters<T>) {\r\n const later = () => {\r\n clearTimeout(timeout as NodeJS.Timeout);\r\n func(...args);\r\n };\r\n\r\n clearTimeout(timeout as NodeJS.Timeout);\r\n timeout = setTimeout(later, wait);\r\n };\r\n}\r\n\r\n/**\r\n * Deep merge two objects\r\n */\r\nexport function deepMerge<T extends Record<string, any>>(target: T, source: Partial<T>): T {\r\n const output = { ...target };\r\n\r\n for (const key in source) {\r\n if (source[key] && typeof source[key] === 'object' && !Array.isArray(source[key])) {\r\n if (key in target && typeof target[key] === 'object' && !Array.isArray(target[key])) {\r\n output[key] = deepMerge(target[key], source[key] as any);\r\n } else {\r\n output[key] = source[key] as any;\r\n }\r\n } else {\r\n output[key] = source[key] as any;\r\n }\r\n }\r\n\r\n return output;\r\n}\r\n\r\n/**\r\n * Extract domain from URL\r\n */\r\nexport function extractDomain(url: string): string {\r\n try {\r\n return new URL(url).hostname;\r\n } catch {\r\n return url;\r\n }\r\n}\r\n\r\n/**\r\n * Check if URL is valid\r\n */\r\nexport function isValidUrl(url: string): boolean {\r\n try {\r\n new URL(url);\r\n return true;\r\n } catch {\r\n return false;\r\n }\r\n}\r\n\r\n/**\r\n * Parse options string into key-value object\r\n */\r\nexport function parseOptions(options: string): Record<string, string> {\r\n const parsed: Record<string, string> = {};\r\n if (!options) return parsed;\r\n\r\n // Parse options like \"height:400,theme:dark,autoplay:1\"\r\n options.split(',').forEach(option => {\r\n const [key, value] = option.split(':').map(s => s.trim());\r\n if (key && value) {\r\n parsed[key] = value;\r\n }\r\n });\r\n\r\n return parsed;\r\n}\r\n\r\n/**\r\n * Performance measurement utility\r\n */\r\nexport class PerformanceTimer {\r\n private startTime: number;\r\n private marks: Record<string, number> = {};\r\n\r\n constructor() {\r\n this.startTime = performance.now();\r\n }\r\n\r\n mark(name: string): void {\r\n this.marks[name] = performance.now() - this.startTime;\r\n }\r\n\r\n getTime(name?: string): number {\r\n if (name && this.marks[name] !== undefined) {\r\n return this.marks[name];\r\n }\r\n return performance.now() - this.startTime;\r\n }\r\n\r\n getAllMarks(): Record<string, number> {\r\n return { ...this.marks };\r\n }\r\n}\r\n\r\n/**\r\n * Simple logger with different levels\r\n */\r\nexport class Logger {\r\n private debugMode: boolean;\r\n\r\n constructor(debugMode = false) {\r\n this.debugMode = debugMode;\r\n }\r\n\r\n debug(...args: any[]): void {\r\n if (this.debugMode) {\r\n console.log('[DEBUG]', ...args);\r\n }\r\n }\r\n\r\n info(...args: any[]): void {\r\n console.info('[INFO]', ...args);\r\n }\r\n\r\n warn(...args: any[]): void {\r\n console.warn('[WARN]', ...args);\r\n }\r\n\r\n error(...args: any[]): void {\r\n console.error('[ERROR]', ...args);\r\n }\r\n\r\n setDebugMode(enabled: boolean): void {\r\n this.debugMode = enabled;\r\n }\r\n}","import type { MarkdownToken, RenderRule, RendererConfig } from './types';\r\nimport { sanitizeHtml, escapeHtml } from './utils';\r\n\r\nexport class MarkdownRenderer {\r\n private rules = new Map<string, RenderRule>();\r\n private warnings: string[] = [];\r\n private config: RendererConfig;\r\n\r\n constructor(config?: RendererConfig) {\r\n this.config = {\r\n format: 'tailwind',\r\n sanitize: true,\r\n allowUnsafeHtml: false,\r\n debugMode: false,\r\n ...config\r\n };\r\n }\r\n\r\n addRule(rule: RenderRule): void {\r\n this.rules.set(rule.type, rule);\r\n }\r\n\r\n hasRule(type: string): boolean {\r\n return this.rules.has(type);\r\n }\r\n\r\n render(tokens: MarkdownToken[]): string {\r\n this.warnings = [];\r\n\r\n // Inject format into each token for extensions to use\r\n const tokensWithFormat = tokens.map(token => ({\r\n ...token,\r\n attributes: {\r\n ...token.attributes,\r\n format: this.config.format\r\n }\r\n }));\r\n\r\n // Render each token using registered extensions\r\n const htmlParts = tokensWithFormat.map(token => this.renderToken(token));\r\n const combinedHtml = htmlParts.join('');\r\n\r\n // Apply sanitization if enabled\r\n if (this.config.sanitize && !this.config.allowUnsafeHtml) {\r\n return sanitizeHtml(combinedHtml);\r\n }\r\n\r\n return combinedHtml;\r\n }\r\n\r\n private renderToken(token: MarkdownToken): string {\r\n const rule = this.rules.get(token.type);\r\n\r\n if (rule) {\r\n try {\r\n // If token has children, render them and inject into attributes\r\n let tokenToRender = token;\r\n if (token.children && token.children.length > 0) {\r\n const renderedChildren = this.render(token.children);\r\n tokenToRender = {\r\n ...token,\r\n attributes: {\r\n ...token.attributes,\r\n renderedChildren // Extensions can use this instead of re-parsing\r\n }\r\n };\r\n }\r\n\r\n return rule.render(tokenToRender);\r\n } catch (error) {\r\n const errorMessage = error instanceof Error ? error.message : String(error);\r\n this.warnings.push(`Render error for ${token.type}: ${errorMessage}`);\r\n return this.createErrorBlock(`Render error for ${token.type}: ${errorMessage}`);\r\n }\r\n }\r\n\r\n // For unknown types in development, show debug info\r\n if (this.config.debugMode) {\r\n return this.createDebugBlock(token);\r\n }\r\n\r\n // Fallback: treat as text if no rule found\r\n return escapeHtml(token.content || token.raw || '');\r\n }\r\n\r\n private createErrorBlock(message: string): string {\r\n if (this.config.format === 'html') {\r\n return `<div style=\"background-color: #fee; border: 1px solid #fcc; color: #c66; padding: 8px; border-radius: 4px; margin: 8px 0; font-size: 14px;\">\r\n <strong>Render Error:</strong> ${escapeHtml(message)}\r\n </div>`;\r\n }\r\n\r\n return `<div class=\"bg-red-100 border border-red-300 text-red-800 p-2 rounded text-sm mb-2\">\r\n <strong>Render Error:</strong> ${escapeHtml(message)}\r\n </div>`;\r\n }\r\n\r\n private createDebugBlock(token: MarkdownToken): string {\r\n if (this.config.format === 'html') {\r\n return `<div style=\"background-color: #fffbf0; border: 1px solid #fed; color: #b8860b; padding: 8px; border-radius: 4px; margin: 8px 0; font-size: 14px;\">\r\n <strong>Unknown token type:</strong> ${escapeHtml(token.type)}<br>\r\n <strong>Content:</strong> ${escapeHtml(token.content || token.raw || '')}\r\n </div>`;\r\n }\r\n\r\n return `<div class=\"bg-yellow-100 border border-yellow-300 text-yellow-800 p-2 rounded text-sm mb-2\">\r\n <strong>Unknown token type:</strong> ${escapeHtml(token.type)}<br>\r\n <strong>Content:</strong> ${escapeHtml(token.content || token.raw || '')}\r\n </div>`;\r\n }\r\n\r\n getWarnings(): string[] {\r\n return [...this.warnings];\r\n }\r\n\r\n getConfig(): RendererConfig {\r\n return { ...this.config };\r\n }\r\n\r\n updateConfig(config: Partial<RendererConfig>): void {\r\n this.config = { ...this.config, ...config };\r\n }\r\n\r\n setDebugMode(enabled: boolean): void {\r\n this.config.debugMode = enabled;\r\n }\r\n\r\n clearWarnings(): void {\r\n this.warnings = [];\r\n }\r\n}","import {escapeHtml} from \"@/utils.ts\";\r\nimport {Extension} from \"@/types.ts\";\r\n\r\nexport const BlockquoteExtension: Extension = {\r\n name: 'blockquote',\r\n parseRules: [\r\n {\r\n name: 'blockquote',\r\n pattern: /^>\\s+(.+)$/m,\r\n render: (match) => ({\r\n type: 'blockquote',\r\n content: match[1] || '',\r\n raw: match[0] || ''\r\n })\r\n }\r\n ],\r\n renderRules: [\r\n {\r\n type: 'blockquote',\r\n render: (token) => {\r\n const format = token.attributes?.format || 'html';\r\n\r\n // Use pre-rendered children if available (new efficient approach)\r\n // Otherwise fall back to renderMarkdown callback (backwards compat) or escaped content\r\n const renderedChildren = token.attributes?.renderedChildren as string | undefined;\r\n const renderMarkdown = token.attributes?.renderMarkdown as ((md: string) => string) | undefined;\r\n const content = renderedChildren || (renderMarkdown ? renderMarkdown(token.content) : escapeHtml(token.content));\r\n\r\n if (format === 'html') {\r\n return `<blockquote style=\"border-left: 2px solid #d1d5db; padding: 8px 0 8px 16px; margin: 16px 0; font-style: italic; color: #6b7280;\">${content}</blockquote>`;\r\n }\r\n return `<blockquote class=\"pl-4 py-2 border-l-2 border-border italic text-muted-foreground my-4\">${content}</blockquote>`;\r\n }\r\n }\r\n ]\r\n};","import {Extension} from \"@/types.ts\";\r\n\r\nexport const LineBreakExtension: Extension = {\r\n name: 'line-break',\r\n parseRules: [\r\n {\r\n name: 'hard-break-backslash',\r\n pattern: /\\\\\\s*\\n/,\r\n render: (match) => ({\r\n type: 'line-break',\r\n content: '',\r\n raw: match[0] || ''\r\n })\r\n },\r\n {\r\n name: 'hard-break-spaces',\r\n pattern: / +\\n/,\r\n render: (match) => ({\r\n type: 'line-break',\r\n content: '',\r\n raw: match[0] || ''\r\n })\r\n }\r\n ],\r\n renderRules: [\r\n {\r\n type: 'line-break',\r\n render: () => '<br>'\r\n },\r\n {\r\n type: 'paragraph-break',\r\n render: () => '</p><p>'\r\n },\r\n {\r\n type: 'soft-break',\r\n render: (token) => token.content || ' '\r\n }\r\n ]\r\n};","import type { Extension } from '../../types';\r\nimport { escapeHtml } from '../../utils';\r\n\r\nexport const InlineCodeExtension: Extension = {\r\n name: 'inline-code',\r\n parseRules: [\r\n {\r\n name: 'code',\r\n pattern: /`([^`]+)`/,\r\n render: (match) => ({\r\n type: 'code',\r\n content: match[1] || '',\r\n raw: match[0] || ''\r\n })\r\n }\r\n ],\r\n renderRules: [\r\n {\r\n type: 'code',\r\n render: (token) => {\r\n const content = escapeHtml(token.content);\r\n const format = token.attributes?.format;\r\n\r\n if (format === 'html') {\r\n return `<code style=\"background-color: #f3f4f6; padding: 2px 6px; border-radius: 4px; font-family: monospace; font-size: 0.875rem;\">${content}</code>`;\r\n }\r\n // Default to Tailwind\r\n return `<code class=\"bg-muted px-1.5 py-0.5 rounded text-sm font-mono\">${content}</code>`;\r\n }\r\n }\r\n ]\r\n};\r\n\r\nexport const CodeBlockExtension: Extension = {\r\n name: 'codeblock',\r\n parseRules: [\r\n {\r\n name: 'codeblock',\r\n pattern: /```(\\w+)?\\s*\\n([\\s\\S]*?)\\n```/,\r\n render: (match) => ({\r\n type: 'codeblock',\r\n content: match[2] || '',\r\n raw: match[0] || '',\r\n attributes: {\r\n language: match[1] || 'text'\r\n }\r\n })\r\n }\r\n ],\r\n renderRules: [\r\n {\r\n type: 'codeblock',\r\n render: (token) => {\r\n const language = token.attributes?.language || 'text';\r\n const escapedCode = escapeHtml(token.content);\r\n const format = token.attributes?.format || 'html';\r\n\r\n if (format === 'html') {\r\n return `<pre style=\"background-color: #f3f4f6; padding: 16px; border-radius: 6px; overflow-x: auto; margin: 16px 0;\"><code class=\"language-${escapeHtml(language)}\">${escapedCode}</code></pre>`;\r\n }\r\n\r\n return `<pre class=\"bg-muted p-4 rounded-md overflow-x-auto my-4\"><code class=\"language-${escapeHtml(language)}\">${escapedCode}</code></pre>`;\r\n }\r\n }\r\n ]\r\n};","import type { Extension } from '../../types';\r\nimport { escapeHtml } from '../../utils';\r\n\r\nexport const BoldExtension: Extension = {\r\n name: 'bold',\r\n parseRules: [\r\n {\r\n name: 'bold',\r\n pattern: /\\*\\*((?:(?!\\*\\*).)+)\\*\\*/,\r\n render: (match) => ({\r\n type: 'bold',\r\n content: match[1] || '',\r\n raw: match[0] || ''\r\n })\r\n }\r\n ],\r\n renderRules: [\r\n {\r\n type: 'bold',\r\n render: (token) => {\r\n const content = escapeHtml(token.content);\r\n const format = token.attributes?.format;\r\n\r\n if (format === 'html') {\r\n return `<strong>${content}</strong>`;\r\n }\r\n // Default to Tailwind\r\n return `<strong class=\"font-bold\">${content}</strong>`;\r\n }\r\n }\r\n ]\r\n};\r\n\r\nexport const ItalicExtension: Extension = {\r\n name: 'italic',\r\n parseRules: [\r\n {\r\n name: 'italic',\r\n pattern: /\\*((?:(?!\\*).)+)\\*/,\r\n render: (match) => ({\r\n type: 'italic',\r\n content: match[1] || '',\r\n raw: match[0] || ''\r\n })\r\n }\r\n ],\r\n renderRules: [\r\n {\r\n type: 'italic',\r\n render: (token) => {\r\n const content = escapeHtml(token.content);\r\n const format = token.attributes?.format;\r\n\r\n if (format === 'html') {\r\n return `<em>${content}</em>`;\r\n }\r\n // Default to Tailwind\r\n return `<em class=\"italic\">${content}</em>`;\r\n }\r\n }\r\n ]\r\n};","import type { Extension } from '../../types';\r\nimport { escapeHtml, generateId } from '../../utils';\r\n\r\nexport const HeadingExtension: Extension = {\r\n name: 'heading',\r\n parseRules: [\r\n {\r\n name: 'heading',\r\n pattern: /^(#{1,6})\\s+(.+)$/m,\r\n render: (match) => ({\r\n type: 'heading',\r\n content: match[2]?.trim() || '',\r\n raw: match[0] || '',\r\n attributes: {\r\n level: String(match[1]?.length || 1)\r\n }\r\n })\r\n }\r\n ],\r\n renderRules: [\r\n {\r\n type: 'heading',\r\n render: (token) => {\r\n const level = parseInt(token.attributes?.level || '1');\r\n const text = token.content;\r\n const id = generateId(text);\r\n const escapedContent = escapeHtml(text);\r\n\r\n // Default to HTML format, extensions can override\r\n const format = token.attributes?.format || 'html';\r\n\r\n if (format === 'html') {\r\n return `<h${level} id=\"${id}\">${escapedContent}</h${level}>`;\r\n }\r\n\r\n // Tailwind format\r\n let headingClasses = 'group relative flex items-center gap-2';\r\n\r\n switch (level) {\r\n case 1: headingClasses += ' text-3xl font-bold mt-8 mb-4'; break;\r\n case 2: headingClasses += ' text-2xl font-semibold mt-6 mb-3'; break;\r\n case 3: headingClasses += ' text-xl font-medium mt-5 mb-3'; break;\r\n case 4: headingClasses += ' text-lg font-medium mt-4 mb-2'; break;\r\n case 5: headingClasses += ' text-base font-medium mt-3 mb-2'; break;\r\n case 6: headingClasses += ' text-sm font-medium mt-3 mb-2'; break;\r\n }\r\n\r\n return `<h${level} id=\"${id}\" class=\"${headingClasses}\">\r\n ${escapedContent}\r\n <a href=\"#${id}\" class=\"opacity-0 group-hover:opacity-100 text-muted-foreground transition-opacity\">\r\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\r\n <path d=\"M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71\"/>\r\n <path d=\"M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71\"/>\r\n</svg>\r\n </a>\r\n </h${level}>`;\r\n }\r\n }\r\n ]\r\n};","import {Extension} from \"@/types.ts\";\r\n\r\nexport const HorizontalRuleExtension: Extension = {\r\n name: 'hr',\r\n parseRules: [\r\n {\r\n name: 'hr',\r\n pattern: /^---$/m,\r\n render: (match) => ({\r\n type: 'hr',\r\n content: '',\r\n raw: match[0] || ''\r\n })\r\n }\r\n ],\r\n renderRules: [\r\n {\r\n type: 'hr',\r\n render: (token) => {\r\n const format = token.attributes?.format;\r\n\r\n if (format === 'html') {\r\n return '<hr style=\"margin: 24px 0; border: none; border-top: 1px solid #d1d5db;\">';\r\n }\r\n // Default to Tailwind\r\n return '<hr class=\"my-6 border-t border-border\">';\r\n }\r\n }\r\n ]\r\n};","import {escapeHtml} from \"@/utils.ts\";\r\nimport {Extension} from \"@/types.ts\";\r\n\r\nexport const ImageExtension: Extension = {\r\n name: 'image',\r\n parseRules: [\r\n {\r\n name: 'image',\r\n pattern: /!\\[([^\\]]*)\\]\\(([^)]+?)(?:\\s+\"([^\"]+)\")?\\)/,\r\n render: (match) => ({\r\n type: 'image',\r\n content: match[1] || '',\r\n raw: match[0] || '',\r\n attributes: {\r\n alt: match[1] || '',\r\n src: match[2] || '',\r\n title: match[3] || ''\r\n }\r\n })\r\n }\r\n ],\r\n renderRules: [\r\n {\r\n type: 'image',\r\n render: (token) => {\r\n const src = token.attributes?.src || '';\r\n const alt = token.attributes?.alt || '';\r\n const title = token.attributes?.title || '';\r\n const titleAttr = title ? ` title=\"${escapeHtml(title)}\"` : '';\r\n const format = token.attributes?.format || 'html';\r\n\r\n if (format === 'html') {\r\n return `<img src=\"${escapeHtml(src)}\" alt=\"${escapeHtml(alt)}\"${titleAttr} style=\"max-width: 100%; height: auto; border-radius: 8px; margin: 16px 0;\" loading=\"lazy\" />`;\r\n }\r\n\r\n return `<img src=\"${escapeHtml(src)}\" alt=\"${escapeHtml(alt)}\"${titleAttr} class=\"max-w-full h-auto rounded-lg my-4\" loading=\"lazy\" />`;\r\n }\r\n }\r\n ]\r\n};","import type { Extension } from '../../types';\r\nimport { escapeHtml } from '../../utils';\r\n\r\nexport const LinkExtension: Extension = {\r\n name: 'link',\r\n parseRules: [\r\n {\r\n name: 'link',\r\n pattern: /\\[(?!(?:button|embed):)([^\\]]+)\\]\\(([^)]+)\\)/,\r\n render: (match) => ({\r\n type: 'link',\r\n content: match[1] || '',\r\n raw: match[0] || '',\r\n attributes: {\r\n href: match[2] || ''\r\n }\r\n })\r\n }\r\n ],\r\n renderRules: [\r\n {\r\n type: 'link',\r\n render: (token) => {\r\n const href = token.attributes?.href || '#';\r\n const escapedHref = escapeHtml(href);\r\n const escapedText = escapeHtml(token.content);\r\n const format = token.attributes?.format || 'html';\r\n\r\n if (format === 'html') {\r\n return `<a href=\"${escapedHref}\" target=\"_blank\" rel=\"noopener noreferrer\">${escapedText}</a>`;\r\n }\r\n\r\n return `<a href=\"${escapedHref}\" class=\"text-primary hover:underline inline-flex items-center gap-1\" target=\"_blank\" rel=\"noopener noreferrer\">\r\n ${escapedText}\r\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"12\" height=\"12\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" class=\"lucide lucide-external-link\">\r\n <path d=\"M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6\"></path>\r\n <polyline points=\"15 3 21 3 21 9\"></polyline>\r\n <line x1=\"10\" y1=\"14\" x2=\"21\" y2=\"3\"></line>\r\n </svg>\r\n </a>`;\r\n }\r\n }\r\n ]\r\n};","import {escapeHtml} from \"@/utils.ts\";\r\nimport {Extension} from \"@/types.ts\";\r\n\r\nexport const ListExtension: Extension = {\r\n name: 'list',\r\n parseRules: [\r\n {\r\n name: 'list-item',\r\n pattern: /^(\\s*)[-*+]\\s+(.+)$/m,\r\n render: (match) => ({\r\n type: 'list-item',\r\n content: match[2] || '',\r\n raw: match[0] || ''\r\n })\r\n }\r\n ],\r\n renderRules: [\r\n {\r\n type: 'list-item',\r\n render: (token) => `<li>${escapeHtml(token.content)}</li>`\r\n }\r\n ]\r\n};\r\n\r\nexport const TaskListExtension: Extension = {\r\n name: 'task-list',\r\n parseRules: [\r\n {\r\n name: 'task-item',\r\n pattern: /^(\\s*)-\\s*\\[([ xX])\\]\\s*(.+)$/m,\r\n render: (match) => ({\r\n type: 'task-item',\r\n content: match[3] || '',\r\n raw: match[0] || '',\r\n attributes: {\r\n checked: String((match[2] || '').toLowerCase() === 'x')\r\n }\r\n })\r\n }\r\n ],\r\n renderRules: [\r\n {\r\n type: 'task-item',\r\n render: (token) => {\r\n const isChecked = token.attributes?.checked === 'true';\r\n const escapedContent = escapeHtml(token.content);\r\n const format = token.attributes?.format || 'html';\r\n\r\n if (format === 'html') {\r\n return `<div style=\"display: flex; align-items: center; gap: 8px; margin: 8px 0;\">\r\n <input type=\"checkbox\" ${isChecked ? 'checked' : ''} disabled style=\"margin: 0;\" />\r\n <span${isChecked ? ' style=\"text-decoration: line-through; color: #6b7280;\"' : ''}>${escapedContent}</span>\r\n </div>`;\r\n }\r\n\r\n return `<div class=\"flex items-center gap-2 my-2 task-list-item\">\r\n <input type=\"checkbox\" ${isChecked ? 'checked' : ''} disabled \r\n class=\"form-checkbox h-4 w-4 rounded border-gray-300 text-primary focus:ring-primary\" />\r\n <span${isChecked ? ' class=\"line-through text-muted-foreground\"' : ''}>${escapedContent}</span>\r\n </div>`;\r\n }\r\n }\r\n ]\r\n};","import {Extension} from \"@/types.ts\";\r\nimport {escapeHtml} from \"@/utils.ts\";\r\n\r\nexport const ParagraphExtension: Extension = {\r\n name: 'paragraph',\r\n parseRules: [],\r\n renderRules: [\r\n {\r\n type: 'paragraph',\r\n render: (token) => {\r\n if (!token.content) return '';\r\n const content = token.content.trim();\r\n if (!content) return '';\r\n\r\n const processedContent = content.includes('<br>') ? content : escapeHtml(content);\r\n const format = token.attributes?.format || 'html';\r\n\r\n if (format === 'html') {\r\n return `<p style=\"line-height: 1.75; margin-bottom: 16px;\">${processedContent}</p>`;\r\n }\r\n\r\n return `<p class=\"leading-7 mb-4\">${processedContent}</p>`;\r\n }\r\n }\r\n ]\r\n};","import type { Extension } from '../../types';\r\nimport { escapeHtml } from '../../utils';\r\n\r\nexport const TextExtension: Extension = {\r\n name: 'text',\r\n parseRules: [],\r\n renderRules: [\r\n {\r\n type: 'text',\r\n render: (token) => {\r\n if (!token.content) return '';\r\n return escapeHtml(token.content);\r\n }\r\n }\r\n ]\r\n};","import { BlockquoteExtension } from \"./blockquote\";\r\nimport { LineBreakExtension } from \"./breaks\";\r\nimport {CodeBlockExtension, InlineCodeExtension } from \"./code\";\r\nimport { BoldExtension, ItalicExtension } from \"./emphasis\";\r\nimport { HeadingExtension } from \"./heading\";\r\nimport { HorizontalRuleExtension } from \"./hr\";\r\nimport { ImageExtension } from \"./image\";\r\nimport { LinkExtension } from \"./links\";\r\nimport { ListExtension, TaskListExtension } from \"./lists\";\r\nimport { ParagraphExtension } from \"./paragraph\";\r\nimport { TextExtension } from \"./text\";\r\n\r\nexport const CoreExtensions = [\r\n TextExtension,\r\n HeadingExtension,\r\n BoldExtension,\r\n ItalicExtension,\r\n InlineCodeExtension,\r\n CodeBlockExtension,\r\n LinkExtension,\r\n ImageExtension,\r\n ListExtension,\r\n TaskListExtension,\r\n BlockquoteExtension,\r\n HorizontalRuleExtension,\r\n ParagraphExtension,\r\n LineBreakExtension\r\n] as const;\r\n\r\nexport {\r\n TextExtension,\r\n HeadingExtension,\r\n BoldExtension,\r\n ItalicExtension,\r\n InlineCodeExtension,\r\n CodeBlockExtension,\r\n LinkExtension,\r\n ImageExtension,\r\n ListExtension,\r\n TaskListExtension,\r\n BlockquoteExtension,\r\n HorizontalRuleExtension,\r\n ParagraphExtension,\r\n LineBreakExtension\r\n};","import type { Extension } from '../types';\r\n\r\ninterface AlertTypeConfig {\r\n icon: string;\r\n classes: string;\r\n}\r\n\r\nexport const AlertExtension: Extension = {\r\n name: 'alert',\r\n parseRules: [\r\n {\r\n name: 'alert',\r\n pattern: /:::(\\w+)(?:\\s+(.*?))?\\s*\\n([\\s\\S]*?)\\n:::/,\r\n render: (match: RegExpMatchArray) => {\r\n return {\r\n type: 'alert',\r\n content: match[3]?.trim() || '',\r\n raw: match[0] || '',\r\n attributes: {\r\n type: match[1] || 'info',\r\n title: match[2] || ''\r\n }\r\n };\r\n }\r\n }\r\n ],\r\n renderRules: [\r\n {\r\n type: 'alert',\r\n render: (token) => {\r\n const type = token.attributes?.type || 'info';\r\n const title = token.attributes?.title || '';\r\n\r\n const typeConfig: Record<string, AlertTypeConfig> = {\r\n info: {\r\n icon: 'ℹ️',\r\n classes: 'bg-blue-500/10 border-blue-500/30 text-blue-600 border-l-blue-500'\r\n },\r\n warning: {\r\n icon: '⚠️',\r\n classes: 'bg-amber-500/10 border-amber-500/30 text-amber-600 border-l-amber-500'\r\n },\r\n error: {\r\n icon: '❌',\r\n classes: 'bg-red-500/10 border-red-500/30 text-red-600 border-l-red-500'\r\n },\r\n success: {\r\n icon: '✅',\r\n classes: 'bg-green-500/10 border-green-500/30 text-green-600 border-l-green-500'\r\n },\r\n tip: {\r\n icon: '💡',\r\n classes: 'bg-purple-500/10 border-purple-500/30 text-purple-600 border-l-purple-500'\r\n },\r\n note: {\r\n icon: '📝',\r\n classes: 'bg-gray-500/10 border-gray-500/30 text-gray-600 border-l-gray-500'\r\n }\r\n };\r\n\r\n const config = typeConfig[type] || typeConfig.info;\r\n const baseClasses = 'border-l-4 p-4 mb-4 rounded-md transition-colors duration-200';\r\n const classes = `${baseClasses} ${config?.classes}`;\r\n\r\n // Use pre-rendered children if available (new efficient approach)\r\n // Otherwise fall back to renderMarkdown callback (backwards compat) or raw content\r\n const renderedChildren = token.attributes?.renderedChildren as string | undefined;\r\n const renderMarkdown = token.attributes?.renderMarkdown as ((md: string) => string) | undefined;\r\n const renderedContent = renderedChildren || (renderMarkdown ? renderMarkdown(token.content) : token.content);\r\n\r\n const titleHtml = title\r\n ? `<div class=\"font-medium mb-2 flex items-center gap-2\">\r\n <span class=\"text-lg\" role=\"img\" aria-label=\"${type}\">${config?.icon}</span>\r\n <span>${title}</span>\r\n </div>`\r\n : `<div class=\"font-medium mb-2 flex items-center gap-2\">\r\n <span class=\"text-lg\" role=\"img\" aria-label=\"${type}\">${config?.icon}</span>\r\n <span>${type.charAt(0).toUpperCase() + type.slice(1)}</span>\r\n </div>`;\r\n\r\n return `<div class=\"${classes}\" role=\"alert\" aria-live=\"polite\">\r\n ${titleHtml}\r\n <div class=\"leading-relaxed\">${renderedContent}</div>\r\n </div>`;\r\n }\r\n }\r\n ]\r\n};","import type { Extension } from '../types';\r\n\r\nexport const ButtonExtension: Extension = {\r\n name: 'button',\r\n parseRules: [\r\n {\r\n name: 'button',\r\n pattern: /\\[button:([^\\]]+)\\]\\(([^)]+)\\)(?:\\{([^}]+)\\})?/,\r\n render: (match) => {\r\n const options = match[3] ? match[3].split(',').map(opt => opt.trim()) : [];\r\n\r\n return {\r\n type: 'button',\r\n content: match[1] || '',\r\n raw: match[0] || '',\r\n attributes: {\r\n href: match[2] || '',\r\n style: options.find(opt =>\r\n ['default', 'primary', 'secondary', 'success', 'danger', 'outline', 'ghost'].includes(opt)\r\n ) || 'primary',\r\n size: options.find(opt => ['sm', 'md', 'lg'].includes(opt)) || 'md',\r\n disabled: String(options.includes('disabled')),\r\n target: options.includes('self') ? '_self' : '_blank'\r\n }\r\n };\r\n }\r\n }\r\n ],\r\n renderRules: [\r\n {\r\n type: 'button',\r\n render: (token) => {\r\n const href = token.attributes?.href || '#';\r\n const style = token.attributes?.style || 'primary';\r\n const size = token.attributes?.size || 'md';\r\n const disabled = token.attributes?.disabled === 'true';\r\n const target = token.attributes?.target || '_blank';\r\n\r\n // Base classes with optical border effect\r\n const baseClasses = `\r\n inline-flex items-center justify-center font-medium rounded-lg \r\n transition-all duration-200 ease-out\r\n focus:outline-none focus:ring-2 focus:ring-offset-2\r\n disabled:opacity-50 disabled:cursor-not-allowed disabled:pointer-events-none\r\n transform hover:scale-[1.02] active:scale-[0.98]\r\n shadow-sm hover:shadow-md active:shadow-sm\r\n border border-transparent\r\n relative overflow-hidden\r\n before:absolute before:inset-0 before:rounded-lg\r\n before:bg-gradient-to-br before:from-white/20 before:to-transparent\r\n before:opacity-0 hover:before:opacity-100 before:transition-opacity before:duration-200\r\n `.replace(/\\s+/g, ' ').trim();\r\n\r\n // Size classes\r\n const sizeClasses: Record<string, string> = {\r\n sm: 'px-3 py-1.5 text-sm gap-1.5',\r\n md: 'px-4 py-2 text-base gap-2',\r\n lg: 'px-6 py-3 text-lg gap-2.5'\r\n };\r\n\r\n // Style classes with optical borders using box-shadow\r\n const styleClasses: Record<string, string> = {\r\n default: `\r\n bg-slate-600 text-white border-slate-500\r\n hover:bg-slate-700 hover:border-slate-400\r\n focus:ring-slate-500\r\n shadow-[0_1px_0_0_rgba(255,255,255,0.1)_inset,0_1px_2px_0_rgba(0,0,0,0.1)]\r\n hover:shadow-[0_1px_0_0_rgba(255,255,255,0.15)_inset,0_2px_4px_0_rgba(0,0,0,0.15)]\r\n `,\r\n primary: `\r\n bg-blue-600 text-white border-blue-500\r\n hover:bg-blue-700 hover:border-blue-400\r\n focus:ring-blue-500\r\n shadow-[0_1px_0_0_rgba(255,255,255,0.1)_inset,0_1px_2px_0_rgba(0,0,0,0.1)]\r\n hover:shadow-[0_1px_0_0_rgba(255,255,255,0.15)_inset,0_2px_4px_0_rgba(0,0,0,0.15)]\r\n `,\r\n secondary: `\r\n bg-gray-600 text-white border-gray-500\r\n hover:bg-gray-700 hover:border-gray-400\r\n focus:ring-gray-500\r\n shadow-[0_1px_0_0_rgba(255,255,255,0.1)_inset,0_1px_2px_0_rgba(0,0,0,0.1)]\r\n hover:shadow-[0_1px_0_0_rgba(255,255,255,0.15)_inset,0_2px_4px_0_rgba(0,0,0,0.15)]\r\n `,\r\n success: `\r\n bg-green-600 text-white border-green-500\r\n hover:bg-green-700 hover:border-green-400\r\n focus:ring-green-500\r\n shadow-[0_1px_0_0_rgba(255,255,255,0.1)_inset,0_1px_2px_0_rgba(0,0,0,0.1)]\r\n hover:shadow-[0_1px_0_0_rgba(255,255,255,0.15)_inset,0_2px_4px_0_rgba(0,0,0,0.15)]\r\n `,\r\n danger: `\r\n bg-red-600 text-white border-red-500\r\n hover:bg-red-700 hover:border-red-400\r\n focus:ring-red-500\r\n shadow-[0_1px_0_0_rgba(255,255,255,0.1)_inset,0_1px_2px_0_rgba(0,0,0,0.1)]\r\n hover:shadow-[0_1px_0_0_rgba(255,255,255,0.15)_inset,0_2px_4px_0_rgba(0,0,0,0.15)]\r\n `,\r\n outline: `\r\n bg-transparent text-blue-600 border-blue-600\r\n hover:bg-blue-50 hover:border-blue-700 hover:text-blue-700\r\n focus:ring-blue-500\r\n shadow-[0_0_0_1px_rgba(59,130,246,0.5)_inset]\r\n hover:shadow-[0_0_0_1px_rgba(29,78,216,0.6)_inset,0_1px_2px_0_rgba(0,0,0,0.05)]\r\n `,\r\n ghost: `\r\n bg-transparent text-gray-700 border-transparent\r\n hover:bg-gray-100 hover:text-gray-900\r\n focus:ring-gray-500\r\n shadow-none\r\n hover:shadow-[0_1px_2px_0_rgba(0,0,0,0.05)]\r\n `\r\n };\r\n\r\n const classes = `\r\n ${baseClasses}\r\n ${sizeClasses[size] || sizeClasses.md}\r\n ${styleClasses[style] || styleClasses.primary}\r\n `.replace(/\\s+/g, ' ').trim();\r\n\r\n const targetAttr = target === '_blank' ? ' target=\"_blank\" rel=\"noopener noreferrer\"' :\r\n target === '_self' ? ' target=\"_self\"' : '';\r\n const disabledAttr = disabled ? ' aria-disabled=\"true\" tabindex=\"-1\"' : '';\r\n const externalIcon = target === '_blank' && !disabled ?\r\n `<svg class=\"w-4 h-4 ml-1 opacity-75\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\r\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M10 6H6a2 2 0 00-2 2v10a2 2 0 002 2h10a2 2 0 002-2v-4M14 4h6m0 0v6m0-6L10 14\"/>\r\n </svg>` : '';\r\n\r\n return `<a href=\"${href}\" class=\"${classes}\"${targetAttr}${disabledAttr}>\r\n <span class=\"relative z-10\">${token.content}</span>${externalIcon}\r\n </a>`;\r\n }\r\n }\r\n ]\r\n};","import type { Extension } from '../types';\r\nimport { parseOptions, extractDomain } from '../utils';\r\n\r\nexport const EmbedExtension: Extension = {\r\n name: 'embed',\r\n parseRules: [\r\n {\r\n name: 'embed',\r\n pattern: /\\[embed:(\\w+)\\]\\(([^)]+)\\)(?:\\{([^}]+)\\})?/,\r\n render: (match) => {\r\n return {\r\n type: 'embed',\r\n content: match[2] || '', // URL\r\n raw: match[0] || '',\r\n attributes: {\r\n provider: match[1] || 'generic',\r\n url: match[2] || '',\r\n options: match[3] || ''\r\n }\r\n };\r\n }\r\n }\r\n ],\r\n renderRules: [\r\n {\r\n type: 'embed',\r\n render: (token) => {\r\n const provider = token.attributes?.provider || 'generic';\r\n const url = token.attributes?.url || '';\r\n const options = token.attributes?.options || '';\r\n\r\n return renderEmbed(provider, url, options);\r\n }\r\n }\r\n ]\r\n};\r\n\r\nfunction renderEmbed(provider: string, url: string, options: string): string {\r\n const baseClasses = 'rounded-lg border bg-card text-card-foreground shadow-sm mb-6 overflow-hidden';\r\n const parsedOptions = parseOptions(options);\r\n\r\n switch (provider.toLowerCase()) {\r\n case 'youtube':\r\n return renderYouTubeEmbed(url, parsedOptions, baseClasses);\r\n case 'codepen':\r\n return renderCodePenEmbed(url, parsedOptions, baseClasses);\r\n case 'figma':\r\n return renderFigmaEmbed(url, parsedOptions, baseClasses);\r\n case 'twitter':\r\n case 'tweet':\r\n return renderTwitterEmbed(url, parsedOptions, baseClasses);\r\n case 'github':\r\n return renderGitHubEmbed(url, parsedOptions, baseClasses);\r\n case 'vimeo':\r\n return renderVimeoEmbed(url, parsedOptions, baseClasses);\r\n case 'spotify':\r\n return renderSpotifyEmbed(url, parsedOptions, baseClasses);\r\n case 'codesandbox':\r\n return renderCodeSandboxEmbed(url, parsedOptions, baseClasses);\r\n default:\r\n return renderGenericEmbed(url, parsedOptions, baseClasses);\r\n }\r\n}\r\n\r\nfunction renderYouTubeEmbed(url: string, options: Record<string, string>, classes: string): string {\r\n const videoId = extractYouTubeId(url);\r\n if (!videoId) {\r\n return createErrorEmbed('Invalid YouTube URL', url, classes);\r\n }\r\n\r\n const params = new URLSearchParams();\r\n if (options.autoplay === '1') params.set('autoplay', '1');\r\n if (options.mute === '1') params.set('mute', '1');\r\n if (options.loop === '1') {\r\n params.set('loop', '1');\r\n params.set('playlist', videoId);\r\n }\r\n if (options.controls === '0') params.set('controls', '0');\r\n if (options.start) params.set('start', options.start);\r\n\r\n params.set('rel', '0');\r\n params.set('modestbranding', '1');\r\n\r\n const embedUrl = `https://www.youtube.com/embed/${videoId}?${params.toString()}`;\r\n\r\n return `<div class=\"${classes}\">\r\n <div style=\"position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;\">\r\n <iframe \r\n style=\"position: absolute; top: 0; left: 0; width: 100%; height: 100%; border: 0;\"\r\n src=\"${embedUrl}\" \r\n title=\"YouTube video player\"\r\n frameborder=\"0\" \r\n allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share\"\r\n allowfullscreen>\r\n </iframe>\r\n </div>\r\n </div>`;\r\n}\r\n\r\nfunction renderCodePenEmbed(url: string, options: Record<string, string>, classes: string): string {\r\n const match = url.match(/codepen\\.io\\/([^\\/]+)\\/(?:pen|embed)\\/([^\\/\\?#]+)/);\r\n\r\n if (!match) {\r\n return createErrorEmbed('Invalid CodePen URL', url, classes);\r\n }\r\n\r\n const [, user, penId] = match;\r\n const height = options.height || '400';\r\n const theme = options.theme === 'light' ? 'light' : 'dark';\r\n const defaultTab = options.tab || 'result';\r\n\r\n const embedParams = new URLSearchParams({\r\n 'default-tab': defaultTab,\r\n 'theme-id': theme,\r\n 'editable': 'true'\r\n });\r\n\r\n const embedUrl = `https://codepen.io/${user}/embed/${penId}?${embedParams.toString()}`;\r\n\r\n return `<div class=\"${classes}\">\r\n <iframe \r\n height=\"${height}\" \r\n style=\"width: 100%; border: 0;\" \r\n scrolling=\"no\" \r\n title=\"CodePen Embed - ${penId}\" \r\n src=\"${embedUrl}\" \r\n frameborder=\"0\" \r\n loading=\"lazy\" \r\n allowtransparency=\"true\" \r\n allowfullscreen=\"true\">\r\n </iframe>\r\n </div>`;\r\n}\r\n\r\nfunction renderVimeoEmbed(url: string, options: Record<string, string>, classes: string): string {\r\n const videoId = extractVimeoId(url);\r\n if (!videoId) {\r\n return createErrorEmbed('Invalid Vimeo URL', url, classes);\r\n }\r\n\r\n const params = new URLSearchParams();\r\n if (options.autoplay === '1') params.set('autoplay', '1');\r\n if (options.mute === '1') params.set('muted', '1');\r\n if (options.loop === '1') params.set('loop', '1');\r\n\r\n const embedUrl = `https://player.vimeo.com/video/${videoId}?${params.toString()}`;\r\n\r\n return `<div class=\"${classes}\">\r\n <div style=\"position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;\">\r\n <iframe \r\n style=\"position: absolute; top: 0; left: 0; width: 100%; height: 100%; border: 0;\"\r\n src=\"${embedUrl}\" \r\n title=\"Vimeo video player\"\r\n frameborder=\"0\" \r\n allow=\"autoplay; fullscreen; picture-in-picture\"\r\n allowfullscreen>\r\n </iframe>\r\n </div>\r\n </div>`;\r\n}\r\n\r\nfunction renderSpotifyEmbed(url: string, options: Record<string, string>, classes: string): string {\r\n const embedUrl = url.replace('open.spotify.com', 'open.spotify.com/embed');\r\n const height = options.height || '380';\r\n\r\n return `<div class=\"${classes}\">\r\n <iframe \r\n style=\"border-radius: 12px;\" \r\n src=\"${embedUrl}\" \r\n width=\"100%\" \r\n height=\"${height}\" \r\n frameborder=\"0\" \r\n allowfullscreen=\"\" \r\n allow=\"autoplay; clipboard-write; encrypted-media; fullscreen; picture-in-picture\" \r\n loading=\"lazy\">\r\n </iframe>\r\n </div>`;\r\n}\r\n\r\nfunction renderCodeSandboxEmbed(url: string, options: Record<string, string>, classes: string): string {\r\n let embedUrl = url;\r\n if (url.includes('/s/')) {\r\n embedUrl = url.replace('/s/', '/embed/');\r\n }\r\n\r\n const height = options.height || '500';\r\n const view = options.view || 'preview';\r\n\r\n if (!embedUrl.includes('?')) {\r\n embedUrl += `?view=${view}`;\r\n }\r\n\r\n return `<div class=\"${classes}\">\r\n <iframe \r\n src=\"${embedUrl}\"\r\n style=\"width: 100%; height: ${height}px; border: 0; border-radius: 4px; overflow: hidden;\"\r\n title=\"CodeSandbox Embed\"\r\n allow=\"accelerometer; ambient-light-sensor; camera; encrypted-media; geolocation; gyroscope; hid; microphone; midi; payment; usb; vr; xr-spatial-tracking\"\r\n sandbox=\"allow-forms allow-modals allow-popups allow-presentation allow-same-origin allow-scripts\">\r\n </iframe>\r\n </div>`;\r\n}\r\n\r\nfunction renderFigmaEmbed(url: string, options: Record<string, string>, classes: string): string {\r\n const embedUrl = `https://www.figma.com/embed?embed_host=share&url=${encodeURIComponent(url)}`;\r\n const height = options.height || '450';\r\n\r\n return `<div class=\"${classes}\">\r\n <iframe \r\n style=\"border: none;\" \r\n width=\"100%\" \r\n height=\"${height}\" \r\n src=\"${embedUrl}\" \r\n allowfullscreen>\r\n </iframe>\r\n </div>`;\r\n}\r\n\r\nfunction renderTwitterEmbed(url: string, _options: Record<string, string>, classes: string): string {\r\n return `<div class=\"${classes}\">\r\n <div class=\"p-4\">\r\n <div class=\"flex items-center gap-3 mb-3\">\r\n <svg class=\"w-6 h-6 fill-current text-blue-500\" viewBox=\"0 0 24 24\">\r\n <path d=\"M23.953 4.57a10 10 0 01-2.825.775 4.958 4.958 0 002.163-2.723c-.951.555-2.005.959-3.127 1.184a4.92 4.92 0 00-8.384 4.482C7.69 8.095 4.067 6.13 1.64 3.162a4.822 4.822 0 00-.666 2.475c0 1.71.87 3.213 2.188 4.096a4.904 4.904 0 01-2.228-.616v.06a4.923 4.923 0 003.946 4.827 4.996 4.996 0 01-2.212.085 4.936 4.936 0 004.604 3.417 9.867 9.867 0 01-6.102 2.105c-.39 0-.779-.023-1.17-.067a13.995 13.995 0 007.557 2.209c9.053 0 13.998-7.496 13.998-13.985 0-.21 0-.42-.015-.63A9.935 9.935 0 0024 4.59z\"/>\r\n </svg>\r\n <div>\r\n <div class=\"font-semibold text-foreground\">Twitter Post</div>\r\n <div class=\"text-sm text-muted-foreground\">External Link</div>\r\n </div>\r\n </div>\r\n <a href=\"${url}\" target=\"_blank\" \r\n class=\"inline-flex items-center gap-2 text-primary hover:text-primary/80 font-medium transition-colors\">\r\n View on Twitter\r\n <svg class=\"w-4 h-4\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\r\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M10 6H6a2 2 0 00-2 2v10a2 2 0 002 2h10a2 2 0 002-2v-4M14 4h6m0 0v6m0-6L10 14\"/>\r\n </svg>\r\n </a>\r\n </div>\r\n </div>`;\r\n}\r\n\r\nfunction renderGitHubEmbed(url: string, _options: Record<string, string>, classes: string): string {\r\n const parts = url.replace('https://github.com/', '').split('/');\r\n const owner = parts[0];\r\n const repo = parts[1];\r\n\r\n if (!owner || !repo) {\r\n return createErrorEmbed('Invalid GitHub URL', url, classes);\r\n }\r\n\r\n return `<div class=\"${classes}\">\r\n <div class=\"p-4\">\r\n <div class=\"flex items-center gap-3 mb-3\">\r\n <svg class=\"w-6 h-6 fill-current\" viewBox=\"0 0 24 24\">\r\n <path d=\"M12 0c-6.626 0-12 5.373-12 12 0 5.302 3.438 9.8 8.207 11.387.599.111.793-.261.793-.577v-2.234c-3.338.726-4.033-1.416-4.033-1.416-.546-1.387-1.333-1.756-1.333-1.756-1.089-.745.083-.729.083-.729 1.205.084 1.839 1.237 1.839 1.237 1.07 1.834 2.807 1.304 3.492.997.107-.775.418-1.305.762-1.604-2.665-.305-5.467-1.334-5.467-5.931 0-1.311.469-2.381 1.236-3.221-.124-.303-.535-1.524.117-3.176 0 0 1.008-.322 3.301 1.23.957-.266 1.983-.399 3.003-.404 1.02.005 2.047.138 3.006.404 2.291-1.552 3.297-1.23 3.297-1.23.653 1.653.242 2.874.118 3.176.77.84 1.235 1.911 1.235 3.221 0 4.609-2.807 5.624-5.479 5.921.43.372.823 1.102.823 2.222v3.293c0 .319.192.694.801.576 4.765-1.589 8.199-6.086 8.199-11.386 0-6.627-5.373-12-12-12z\"/>\r\n </svg>\r\n <div>\r\n <div class=\"font-semibold text-foreground text-lg\">${owner}/${repo}</div>\r\n <div class=\"text-sm text-muted-foreground\">GitHub Repository</div>\r\n </div>\r\n </div>\r\n <a href=\"${url}\" target=\"_blank\" \r\n class=\"inline-flex items-center gap-2 text-primary hover:text-primary/80 font-medium transition-colors\">\r\n View on GitHub\r\n <svg class=\"w-4 h-4\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\r\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M10 6H6a2 2 0 00-2 2v10a2 2 0 002 2h10a2 2 0 002-2v-4M14 4h6m0 0v6m0-6L10 14\"/>\r\n </svg>\r\n </a>\r\n </div>\r\n </div>`;\r\n}\r\n\r\nfunction renderGenericEmbed(url: string, _options: Record<string, string>, classes: string): string {\r\n const domain = extractDomain(url);\r\n\r\n return `<div class=\"${classes}\">\r\n <div class=\"p-4\">\r\n <div class=\"flex items-center gap-3 mb-3\">\r\n <div class=\"w-10 h-10 rounded-lg bg-muted flex items-center justify-center\">\r\n <svg class=\"w-5 h-5 text-muted-foreground\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\r\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1\"/>\r\n </svg>\r\n </div>\r\n <div>\r\n <div class=\"font-semibold text-foreground\">External Link</div>\r\n <div class=\"text-sm text-muted-foreground\">${domain}</div>\r\n </div>\r\n </div>\r\n <a href=\"${url}\" target=\"_blank\" \r\n class=\"inline-flex items-center gap-2 text-primary hover:text-primary/80 font-medium transition-colors break-all\">\r\n ${url}\r\n <svg class=\"w-4 h-4 flex-shrink-0\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\r\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M10 6H6a2 2 0 00-2 2v10a2 2 0 002 2h10a2 2 0 002-2v-4M14 4h6m0 0v6m0-6L10 14\"/>\r\n </svg>\r\n </a>\r\n </div>\r\n </div>`;\r\n}\r\n\r\nfunction createErrorEmbed(error: string, url: string, classes: string): string {\r\n return `<div class=\"${classes}\">\r\n <div class=\"p-4 text-destructive\">\r\n <div class=\"font-medium flex items-center gap-2\">\r\n <svg class=\"w-5 h-5\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\r\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M12 8v4m0 4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z\"/>\r\n </svg>\r\n ${error}\r\n </div>\r\n <div class=\"text-sm text-muted-foreground mt-1 break-all\">${url}</div>\r\n </div>\r\n </div>`;\r\n}\r\n\r\n// Utility functions for extracting IDs\r\nfunction extractYouTubeId(url: string): string | null {\r\n const patterns = [\r\n /(?:youtube\\.com\\/watch\\?v=|youtu\\.be\\/|youtube\\.com\\/embed\\/|youtube\\.com\\/shorts\\/)([^&\\n?#]+)/,\r\n /youtube\\.com\\/watch\\?.*v=([^&\\n?#]+)/\r\n ];\r\n\r\n for (const pattern of patterns) {\r\n const match = url.match(pattern);\r\n if (match) return match[1] || null;\r\n }\r\n\r\n return null;\r\n}\r\n\r\nfunction extractVimeoId(url: string): string | null {\r\n const match = url.match(/vimeo\\.com\\/(?:.*\\/)?(\\d+)/);\r\n return match?.[1] ?? null;\r\n}","import { MarkdownParser } from './parser';\r\nimport { MarkdownRenderer } from './renderer';\r\nimport type {\r\n MarkdownToken,\r\n Extension,\r\n EngineConfig,\r\n ExtensionRegistration,\r\n DebugInfo,\r\n PerformanceMetrics\r\n} from './types';\r\n\r\n// Import core extensions\r\nimport { CoreExtensions } from './extensions/core';\r\n// Import feature extensions\r\nimport { AlertExtension } from './extensions/alert';\r\nimport { ButtonExtension } from './extensions/button';\r\nimport { EmbedExtension } from './extensions/embed';\r\n\r\nexport class ChangerawrMarkdown {\r\n private parser: MarkdownParser;\r\n private renderer: MarkdownRenderer;\r\n private extensions = new Map<string, Extension>();\r\n\r\n constructor(config?: EngineConfig) {\r\n this.parser = new MarkdownParser(config?.parser);\r\n this.renderer = new MarkdownRenderer(config?.renderer);\r\n\r\n // Register core extensions first (for backwards compatibility)\r\n this.registerCoreExtensions();\r\n\r\n // Register feature extensions (for backwards compatibility)\r\n this.registerFeatureExtensions();\r\n\r\n // Register custom extensions if provided\r\n if (config?.extensions) {\r\n config.extensions.forEach(extension => {\r\n this.registerExtension(extension);\r\n });\r\n }\r\n\r\n // No need for default rules - everything is extension-based now!\r\n }\r\n\r\n private registerFeatureExtensions(): void {\r\n this.registerExtension(AlertExtension);\r\n this.registerExtension(ButtonExtension);\r\n this.registerExtension(EmbedExtension);\r\n }\r\n\r\n private registerCoreExtensions(): void {\r\n CoreExtensions.forEach(extension => {\r\n this.registerExtension(extension);\r\n });\r\n }\r\n\r\n registerExtension(extension: Extension): ExtensionRegistration {\r\n try {\r\n // Validate extension before registration\r\n if (!extension.name || typeof extension.name !== 'string') {\r\n throw new Error('Extension must have a valid name');\r\n }\r\n\r\n if (!Array.isArray(extension.parseRules)) {\r\n throw new Error('Extension must have parseRules array');\r\n }\r\n\r\n if (!Array.isArray(extension.renderRules)) {\r\n throw new Error('Extension must have renderRules array');\r\n }\r\n\r\n // Validate parse rules\r\n extension.parseRules.forEach((rule, index) => {\r\n if (!rule.name || typeof rule.name !== 'string') {\r\n throw new Error(`Parse rule ${index} must have a valid name`);\r\n }\r\n if (!rule.pattern || !(rule.pattern instanceof RegExp)) {\r\n throw new Error(`Parse rule ${index} must have a valid RegExp pattern`);\r\n }\r\n if (!rule.render || typeof rule.render !== 'function') {\r\n throw new Error(`Parse rule ${index} must have a valid render function`);\r\n }\r\n });\r\n\r\n // Validate render rules\r\n extension.renderRules.forEach((rule, index) => {\r\n if (!rule.type || typeof rule.type !== 'string') {\r\n throw new Error(`Render rule ${index} must have a valid type`);\r\n }\r\n if (!rule.render || typeof rule.render !== 'function') {\r\n throw new Error(`Render rule ${index} must have a valid render function`);\r\n }\r\n });\r\n\r\n // Store extension\r\n this.extensions.set(extension.name, extension);\r\n\r\n // Add rules to parser and renderer\r\n extension.parseRules.forEach(rule => {\r\n this.parser.addRule(rule);\r\n });\r\n\r\n extension.renderRules.forEach(rule => {\r\n this.renderer.addRule(rule);\r\n });\r\n\r\n return {\r\n success: true,\r\n extensionName: extension.name\r\n };\r\n\r\n } catch (error) {\r\n const errorMessage = error instanceof Error ? error.message : String(error);\r\n\r\n return {\r\n success: false,\r\n extensionName: extension.name,\r\n error: errorMessage\r\n };\r\n }\r\n }\r\n\r\n unregisterExtension(name: string): boolean {\r\n const extension = this.extensions.get(name);\r\n if (!extension) {\r\n return false;\r\n }\r\n\r\n try {\r\n // Remove extension from map\r\n this.extensions.delete(name);\r\n\r\n // Rebuild parser and renderer to remove extension rules\r\n this.rebuildParserAndRenderer();\r\n\r\n return true;\r\n } catch {\r\n return false;\r\n }\r\n }\r\n\r\n parse(markdown: string): MarkdownToken[] {\r\n return this.parser.parse(markdown);\r\n }\r\n\r\n render(tokens: MarkdownToken[]): string {\r\n // The renderer will now recursively render children tokens\r\n // No need to inject callbacks - children are already tokenized!\r\n return this.renderer.render(tokens);\r\n }\r\n\r\n toHtml(markdown: string): string {\r\n const tokens = this.parse(markdown);\r\n return this.render(tokens);\r\n }\r\n\r\n getExtensions(): string[] {\r\n return Array.from(this.extensions.keys());\r\n }\r\n\r\n hasExtension(name: string): boolean {\r\n return this.extensions.has(name);\r\n }\r\n\r\n getWarnings(): string[] {\r\n return [...this.parser.getWarnings(), ...this.renderer.getWarnings()];\r\n }\r\n\r\n getDebugInfo(): DebugInfo | null {\r\n return {\r\n warnings: this.getWarnings(),\r\n parseTime: 0,\r\n renderTime: 0,\r\n tokenCount: 0,\r\n iterationCount: 0\r\n };\r\n }\r\n\r\n getPerformanceMetrics(): PerformanceMetrics | null {\r\n return {\r\n parseTime: 0,\r\n renderTime: 0,\r\n totalTime: 0,\r\n tokenCount: 0\r\n };\r\n }\r\n\r\n private rebuildParserAndRenderer(): void {\r\n // Get current configs\r\n const parserConfig = this.parser.getConfig();\r\n const rendererConfig = this.renderer.getConfig();\r\n\r\n // Recreate parser and renderer completely\r\n this.parser = new MarkdownParser(parserConfig);\r\n this.renderer = new MarkdownRenderer(rendererConfig);\r\n\r\n // Get the extensions that are still in the map (after removal)\r\n const extensionsToRegister = Array.from(this.extensions.values());\r\n\r\n // Re-register remaining extensions in the correct order\r\n // Feature extensions first\r\n const featureExtensions = extensionsToRegister.filter(ext =>\r\n ['alert', 'button', 'embed'].includes(ext.name)\r\n );\r\n\r\n // Core extensions second\r\n const coreExtensions = extensionsToRegister.filter(ext =>\r\n ['text', 'heading', 'bold', 'italic', 'code', 'codeblock', 'link', 'image', 'list', 'task-list', 'blockquote', 'hr', 'paragraph', 'line-break'].includes(ext.name)\r\n );\r\n\r\n // Custom extensions last\r\n const customExtensions = extensionsToRegister.filter(ext =>\r\n !['alert', 'button', 'embed', 'text', 'heading', 'bold', 'italic', 'code', 'codeblock', 'link', 'image', 'list', 'task-list', 'blockquote', 'hr', 'paragraph', 'line-break'].includes(ext.name)\r\n );\r\n\r\n // Register in correct order without going through the extension map\r\n [...featureExtensions, ...coreExtensions, ...customExtensions].forEach(extension => {\r\n // Add rules directly to parser and renderer\r\n extension.parseRules.forEach(rule => {\r\n this.parser.addRule(rule);\r\n });\r\n\r\n extension.renderRules.forEach(rule => {\r\n this.renderer.addRule(rule);\r\n });\r\n });\r\n }\r\n}\r\n\r\n// Factory functions for specific use cases\r\nexport function createMinimalEngine(config?: EngineConfig): ChangerawrMarkdown {\r\n // Create engine with NO default extensions\r\n const minimalConfig = {\r\n ...config,\r\n extensions: config?.extensions || []\r\n };\r\n\r\n const engine = new ChangerawrMarkdown();\r\n\r\n // Clear all default extensions\r\n const defaultExtensions = engine.getExtensions();\r\n defaultExtensions.forEach(ext => engine.unregisterExtension(ext));\r\n\r\n // Only add the ones specified in config\r\n if (minimalConfig.extensions) {\r\n minimalConfig.extensions.forEach(ext => engine.registerExtension(ext));\r\n }\r\n\r\n return engine;\r\n}\r\n\r\nexport function createCoreOnlyEngine(config?: EngineConfig): ChangerawrMarkdown {\r\n // Create engine with only core extensions (no alerts, buttons, embeds)\r\n const engine = new ChangerawrMarkdown();\r\n\r\n // Remove feature extensions, keep core\r\n engine.unregisterExtension('alert');\r\n engine.unregisterExtension('button');\r\n engine.unregisterExtension('embed');\r\n\r\n // Add any custom extensions\r\n if (config?.extensions) {\r\n config.extensions.forEach(ext => engine.registerExtension(ext));\r\n }\r\n\r\n return engine;\r\n}\r\n\r\n// Default instance for convenience functions\r\nexport const markdown = new ChangerawrMarkdown();\r\n\r\n// Convenience functions\r\nexport function parseMarkdown(content: string): MarkdownToken[] {\r\n return markdown.parse(content);\r\n}\r\n\r\nexport function renderMarkdown(content: string): string {\r\n return markdown.toHtml(content);\r\n}"],"mappings":"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","names":["useMemo","useEffect","markdown","markdown","MarkdownRenderer","useMemo","useEffect"]}