@mindfiredigital/ignix-lite-mcp 1.2.0 → 1.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +108 -0
- package/dist/server.js +187 -1954
- package/dist/server.js.map +1 -1
- package/dist/utils/check-api.js +2 -0
- package/dist/utils/check-api.js.map +1 -1
- package/package.json +14 -6
- package/.turbo/turbo-build.log +0 -25
- package/CHANGELOG.md +0 -7
- package/dist/manifests/accordion.json +0 -61
- package/dist/manifests/alert.json +0 -69
- package/dist/manifests/avatar.json +0 -75
- package/dist/manifests/badge.json +0 -74
- package/dist/manifests/breadcrumb.json +0 -87
- package/dist/manifests/button.json +0 -85
- package/dist/manifests/card.json +0 -91
- package/dist/manifests/checkbox.json +0 -122
- package/dist/manifests/codeblock.json +0 -63
- package/dist/manifests/combobox.json +0 -33
- package/dist/manifests/dialog.json +0 -64
- package/dist/manifests/divider.json +0 -47
- package/dist/manifests/dropdown.json +0 -105
- package/dist/manifests/form.json +0 -81
- package/dist/manifests/grid.json +0 -143
- package/dist/manifests/input.json +0 -99
- package/dist/manifests/meter.json +0 -103
- package/dist/manifests/navigation.json +0 -70
- package/dist/manifests/progress.json +0 -88
- package/dist/manifests/radio.json +0 -121
- package/dist/manifests/select.json +0 -109
- package/dist/manifests/skeleton.json +0 -101
- package/dist/manifests/tab.json +0 -88
- package/dist/manifests/table.json +0 -92
- package/dist/manifests/textarea.json +0 -117
- package/dist/manifests/toast.json +0 -157
- package/dist/manifests/tooltip.json +0 -115
- package/dist/vector-index.json +0 -14015
- package/src/context/api-context.ts +0 -14
- package/src/global.d.ts +0 -15
- package/src/manifests/accordion.json +0 -61
- package/src/manifests/alert.json +0 -69
- package/src/manifests/avatar.json +0 -75
- package/src/manifests/badge.json +0 -74
- package/src/manifests/breadcrumb.json +0 -87
- package/src/manifests/button.json +0 -85
- package/src/manifests/card.json +0 -91
- package/src/manifests/checkbox.json +0 -122
- package/src/manifests/codeblock.json +0 -63
- package/src/manifests/combobox.json +0 -33
- package/src/manifests/dialog.json +0 -64
- package/src/manifests/divider.json +0 -47
- package/src/manifests/dropdown.json +0 -105
- package/src/manifests/form.json +0 -81
- package/src/manifests/grid.json +0 -143
- package/src/manifests/index.ts +0 -45
- package/src/manifests/input.json +0 -99
- package/src/manifests/meter.json +0 -103
- package/src/manifests/navigation.json +0 -70
- package/src/manifests/progress.json +0 -88
- package/src/manifests/radio.json +0 -121
- package/src/manifests/select.json +0 -109
- package/src/manifests/skeleton.json +0 -101
- package/src/manifests/tab.json +0 -88
- package/src/manifests/table.json +0 -92
- package/src/manifests/textarea.json +0 -117
- package/src/manifests/toast.json +0 -157
- package/src/manifests/tooltip.json +0 -115
- package/src/server.ts +0 -201
- package/src/tools/build-index.ts +0 -55
- package/src/tools/check-a11y.ts +0 -106
- package/src/tools/embedder.ts +0 -18
- package/src/tools/generate-theme.ts +0 -42
- package/src/tools/get-emmet.ts +0 -64
- package/src/tools/get-manifests.ts +0 -55
- package/src/tools/intent-engine.ts +0 -197
- package/src/tools/list-components.ts +0 -20
- package/src/tools/search-index.ts +0 -66
- package/src/tools/theme-palette.ts +0 -65
- package/src/tools/theme-tokens.ts +0 -176
- package/src/tools/validator.ts +0 -367
- package/src/types.ts +0 -63
- package/src/utils/a11y-rules.ts +0 -873
- package/src/utils/a11y-types.ts +0 -15
- package/src/utils/check-api.ts +0 -13
- package/src/utils/cosine.ts +0 -15
- package/src/utils/emmet-helpers.ts +0 -171
- package/src/utils/intent-helpers.ts +0 -66
- package/src/utils/intent-parser.ts +0 -186
- package/src/utils/tokenizer.ts +0 -7
- package/tsconfig.json +0 -14
- package/tsup.config.ts +0 -13
package/dist/server.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/server.ts","../src/manifests/index.ts","../src/utils/tokenizer.ts","../src/tools/list-components.ts","../src/tools/get-manifests.ts","../src/tools/get-emmet.ts","../src/tools/validator.ts","../src/tools/search-index.ts","../src/tools/embedder.ts","../src/utils/cosine.ts","../src/utils/intent-parser.ts","../src/utils/intent-helpers.ts","../src/utils/emmet-helpers.ts","../src/tools/intent-engine.ts","../src/context/api-context.ts","../src/tools/generate-theme.ts","../src/tools/theme-palette.ts","../src/tools/theme-tokens.ts","../src/tools/check-a11y.ts","../src/utils/a11y-rules.ts"],"sourcesContent":["import { Server } from '@modelcontextprotocol/sdk/server/index.js'\nimport { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js'\nimport {\n ListToolsRequestSchema,\n CallToolRequestSchema\n} from '@modelcontextprotocol/sdk/types.js'\n\nimport { listComponents } from './tools/list-components.js'\nimport { getManifest } from './tools/get-manifests.js'\nimport { getEmmet } from './tools/get-emmet.js'\nimport { validate } from './tools/validator.js'\nimport { howToBuild } from './tools/intent-engine.js'\nimport { apiContext } from './context/api-context.js'\nimport { generateTheme } from './tools/generate-theme.js'\nimport { checkA11y } from './tools/check-a11y.js'\n\ntype ValidateArgs = {\n html?: string\n}\n\ntype IntentArgs = {\n description?: string\n}\n\ntype A11yArgs = {\n html?: string\n}\n\nconst server = new Server(\n {\n name: 'ignix-lite',\n version: '2.0.0'\n },\n\n {\n capabilities: {\n tools: {}\n }\n }\n)\n\nserver.setRequestHandler(ListToolsRequestSchema, async () => ({\n tools: [\n {\n name: 'list_components',\n description: 'List all ignix-lite components',\n inputSchema: {\n type: 'object',\n properties: {}\n }\n },\n\n {\n name: 'get_manifest',\n description: 'Get component manifest',\n inputSchema: {\n type: 'object',\n properties: {\n name: {\n type: 'string'\n }\n },\n\n required: ['name']\n }\n },\n\n {\n name: 'get_emmet',\n description: 'Get emmet pattern',\n inputSchema: {\n type: 'object',\n properties: {\n name: {\n type: 'string'\n }\n },\n required: ['name']\n }\n },\n\n {\n name: 'validate',\n description: 'Validate ignix-lite html',\n inputSchema: {\n type: 'object',\n properties: {\n html: {\n type: 'string'\n }\n },\n required: ['html']\n }\n },\n\n {\n name: 'how_to_build',\n description: 'Convert plain english to ignix-lite UI',\n inputSchema: {\n type: 'object',\n properties: {\n description: {\n type: 'string'\n }\n },\n required: ['description']\n }\n },\n {\n name: 'generate_theme',\n\n description: 'Generate ignix theme tokens',\n\n inputSchema: {\n type: 'object',\n\n properties: {\n prompt: {\n type: 'string'\n }\n },\n\n required: ['prompt']\n }\n },\n {\n name: 'check_a11y',\n\n description: 'Check accessibility',\n\n inputSchema: {\n type: 'object',\n\n properties: {\n html: {\n type: 'string'\n }\n },\n\n required: ['html']\n }\n }\n ]\n}))\n\nserver.setRequestHandler(CallToolRequestSchema, async (request) => {\n const { name, arguments: args } = request.params\n\n switch (name) {\n case 'list_components':\n return listComponents()\n\n case 'get_manifest':\n return getManifest(args)\n\n case 'get_emmet':\n return getEmmet(args)\n\n case 'validate': {\n const validateArgs = args as ValidateArgs\n\n return validate(validateArgs.html ?? '')\n }\n\n case 'how_to_build': {\n const intentArgs = args as IntentArgs\n\n return await howToBuild(intentArgs.description ?? '')\n }\n case 'generate_theme': {\n return generateTheme(args)\n }\n case 'check_a11y': {\n const a11yArgs = args as A11yArgs\n\n return checkA11y(a11yArgs.html ?? '')\n }\n\n default:\n return {\n content: [\n {\n type: 'text',\n\n text: JSON.stringify({\n error: `Unknown tool: ${name}`\n })\n }\n ]\n }\n }\n})\n\nasync function start() {\n console.log('API loaded')\n console.log(apiContext.length)\n const transport = new StdioServerTransport()\n await server.connect(transport)\n console.log('Ignix MCP started')\n}\nstart()\n","import { readFileSync } from 'fs'\nimport path from 'path'\nimport { fileURLToPath } from 'url'\nimport type { Manifest } from '../types.js'\nimport { getTokenCount } from '../utils/tokenizer.js'\n\nconst __filename = fileURLToPath(import.meta.url)\nconst __dirname = path.dirname(__filename)\n\nfunction loadManifest(file: string): Manifest {\n const manifestPath = path.resolve(__dirname, 'manifests', file)\n const manifest = JSON.parse(readFileSync(manifestPath, 'utf8')) as Manifest\n manifest.tokens = getTokenCount(manifest.emmet)\n return manifest\n}\n\nexport const manifests: Record<string, Manifest> = {\n accordion: loadManifest('accordion.json'),\n alert: loadManifest('alert.json'),\n avatar: loadManifest('avatar.json'),\n badge: loadManifest('badge.json'),\n breadcrumb: loadManifest('breadcrumb.json'),\n button: loadManifest('button.json'),\n card: loadManifest('card.json'),\n checkbox: loadManifest('checkbox.json'),\n codeblock: loadManifest('codeblock.json'),\n combobox: loadManifest('combobox.json'),\n dialog: loadManifest('dialog.json'),\n divider: loadManifest('divider.json'),\n dropdown: loadManifest('dropdown.json'),\n form: loadManifest('form.json'),\n grid: loadManifest('grid.json'),\n input: loadManifest('input.json'),\n meter: loadManifest('meter.json'),\n navigation: loadManifest('navigation.json'),\n progress: loadManifest('progress.json'),\n radio: loadManifest('radio.json'),\n select: loadManifest('select.json'),\n skeleton: loadManifest('skeleton.json'),\n tab: loadManifest('tab.json'),\n table: loadManifest('table.json'),\n textarea: loadManifest('textarea.json'),\n toast: loadManifest('toast.json'),\n tooltip: loadManifest('tooltip.json')\n}\n","import { encoding_for_model } from 'tiktoken'\n\nconst encoder = encoding_for_model('gpt-4')\n\nexport function getTokenCount(input: string): number {\n return encoder.encode(input).length\n}\n","import { manifests } from '../manifests/index.js'\n\nimport type { MCPResponse } from '../types.js'\n\nexport function listComponents(): MCPResponse {\n const components = Object.keys(manifests).sort()\n\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify({\n components,\n count: components.length,\n tokens_used: components.length\n })\n }\n ]\n }\n}\n","import { z } from 'zod'\nimport { manifests } from '../manifests/index.js'\nimport type { MCPResponse } from '../types.js'\n\nconst schema = z.object({\n name: z.string()\n})\n\nexport function getManifest(args: unknown): MCPResponse {\n const parsed = schema.safeParse(args)\n\n if (!parsed.success) {\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify({\n error: 'Invalid input',\n suggestion: 'Expected { name: string }',\n tokens_used: 2\n })\n }\n ]\n }\n }\n\n const { name } = parsed.data\n\n const manifest = manifests[name]\n\n if (!manifest) {\n return {\n content: [\n {\n type: 'text',\n\n text: JSON.stringify({\n error: `Unknown component: ${name}`,\n suggestion: 'Call list_components() first',\n tokens_used: 2\n })\n }\n ]\n }\n }\n\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify(manifest)\n }\n ]\n }\n}\n","import { z } from 'zod'\nimport { manifests } from '../manifests/index.js'\nimport type { MCPResponse } from '../types.js'\n\nconst schema = z.object({\n name: z.string()\n})\n\nexport function getEmmet(args: unknown): MCPResponse {\n const parsed = schema.safeParse(args)\n\n if (!parsed.success) {\n return {\n content: [\n {\n type: 'text',\n\n text: JSON.stringify({\n error: 'Invalid input',\n\n suggestion: 'Expected { name: string }',\n\n tokens_used: 2\n })\n }\n ]\n }\n }\n\n const { name } = parsed.data\n\n const manifest = manifests[name]\n\n if (!manifest) {\n return {\n content: [\n {\n type: 'text',\n\n text: JSON.stringify({\n error: `Unknown component: ${name}`,\n suggestion: 'Call list_components() first',\n tokens_used: 2\n })\n }\n ]\n }\n }\n\n return {\n content: [\n {\n type: 'text',\n\n text: JSON.stringify({\n component: manifest.component,\n emmet: manifest.emmet,\n tokens: manifest.tokens,\n tokens_used: 3\n })\n }\n ]\n }\n}\n","import { parse } from 'node-html-parser'\nimport { manifests } from '../manifests/index.js'\nimport type { MCPResponse } from '../types.js'\n\ntype ErrorType =\n | 'UNKNOWN_ATTRIBUTE'\n | 'INVALID_VALUE'\n | 'FORBIDDEN_CLASS'\n | 'MISSING_REQUIRED'\n | 'WRONG_ELEMENT'\n | 'PROP_EXPLOSION'\n | 'JS_ON_CSS_COMPONENT'\n | 'MISSING_SLOT'\n\ntype ValidationError = {\n element: string\n prop: string\n type: ErrorType\n message: string\n suggestion?: string\n valid_values?: string[]\n fix: string\n confidence: number\n}\n\nexport function validate(html: string): MCPResponse {\n const root = parse(html)\n\n const errors: ValidationError[] = []\n\n const elements = root.querySelectorAll('*')\n\n // SRS wrappers only\n const allowedWrappers = [\n 'label',\n 'span',\n 'p',\n 'img',\n 'small',\n 'h1',\n 'h2',\n 'h3',\n 'a',\n 'button',\n 'ul',\n 'li',\n 'thead',\n 'tbody',\n 'tr',\n 'td',\n 'th',\n 'summary'\n ]\n\n const nativeAttributes = new Set([\n 'id',\n 'role',\n 'slot',\n 'tabindex',\n\n 'aria-label',\n 'aria-live',\n 'aria-hidden',\n 'aria-expanded',\n 'aria-selected',\n 'aria-current',\n 'aria-sort',\n 'aria-invalid',\n 'aria-describedby',\n 'aria-labelledby',\n 'aria-haspopup',\n 'aria-busy',\n\n 'disabled',\n 'required',\n 'checked',\n 'multiple',\n 'readonly',\n\n 'type',\n 'value',\n 'placeholder',\n 'name',\n\n 'min',\n 'max',\n 'low',\n 'high',\n 'optimum',\n\n 'rows',\n\n 'open',\n 'hidden',\n\n 'href',\n\n 'content',\n\n 'is',\n\n 'src',\n 'alt',\n\n 'data-intent',\n 'data-position',\n 'data-variant',\n 'data-shape',\n 'data-sortable',\n 'data-open',\n 'data-lines',\n\n 'data-grid',\n 'data-gap',\n 'data-align',\n 'data-justify',\n 'data-col',\n 'data-row',\n 'data-dense'\n ])\n\n for (const el of elements) {\n const tag = el.tagName.toLowerCase()\n\n const attrs = el.attributes\n\n // ix-* support\n let manifestKey = tag.startsWith('ix-') ? tag.slice(3) : tag\n\n // built in table\n if (tag === 'table' && attrs.is === 'ix-table') {\n manifestKey = 'table'\n }\n\n // navigation\n if (tag === 'nav') {\n manifestKey = 'navigation'\n }\n\n // card\n if (tag === 'article' && el.querySelector('[slot]')) {\n manifestKey = 'card'\n }\n\n let manifest = manifests[manifestKey]\n\n // badge support\n if (!manifest) {\n if (tag === 'mark') {\n manifest = manifests.badge\n }\n\n if (tag === 'span' && attrs.role === 'status') {\n manifest = manifests.badge\n }\n }\n\n // invalid component\n if (!manifest && !allowedWrappers.includes(tag)) {\n errors.push({\n element: tag,\n prop: '',\n type: 'WRONG_ELEMENT',\n message: `<${tag}> is not a valid ignix-lite component`,\n fix: `<button>Fix me</button>`,\n confidence: 0.7\n })\n\n continue\n }\n\n // wrappers skip\n if (!manifest) continue\n\n const elementName = tag.startsWith('ix-') ? tag : manifest.element || tag\n\n // required wrapper\n if (manifest.required_wrapper) {\n const parent = el.parentNode as unknown as {\n tagName?: string\n }\n\n if (\n !parent ||\n parent.tagName?.toLowerCase() !== manifest.required_wrapper\n ) {\n errors.push({\n element: tag,\n prop: 'wrapper',\n type: 'MISSING_REQUIRED',\n message: `<${tag}> must be inside <${manifest.required_wrapper}>`,\n fix: `<${manifest.required_wrapper}><${elementName}></${elementName}></${manifest.required_wrapper}>`,\n confidence: 0.95\n })\n }\n }\n\n // badge rule\n if (\n tag === 'span' &&\n manifest.component === 'badge' &&\n attrs.role !== 'status'\n ) {\n errors.push({\n element: tag,\n\n prop: 'role',\n type: 'INVALID_VALUE',\n message: 'span badge must have role=status',\n fix: `<span role=\"status\">${el.innerText}</span>`,\n confidence: 0.9\n })\n }\n\n // class forbidden\n if ('class' in attrs) {\n errors.push({\n element: tag,\n prop: 'class',\n type: 'FORBIDDEN_CLASS',\n message: 'class attribute not allowed',\n fix: `<${elementName}>${el.innerText}</${elementName}>`,\n confidence: 0.99\n })\n }\n\n // prop explosion\n if (Object.keys(attrs).length > 4) {\n errors.push({\n element: tag,\n prop: 'multiple',\n type: 'PROP_EXPLOSION',\n message: 'Too many props',\n fix: `<${elementName}></${elementName}>`,\n confidence: 0.85\n })\n }\n\n // js handlers\n for (const attr of Object.keys(attrs)) {\n if (attr.startsWith('on')) {\n errors.push({\n element: tag,\n prop: attr,\n type: 'JS_ON_CSS_COMPONENT',\n message: 'JS handlers forbidden',\n fix: `<${elementName}></${elementName}>`,\n confidence: 0.95\n })\n }\n }\n\n // attribute validation\n for (const attr of Object.keys(attrs)) {\n if (manifest.forbidden_props?.includes(attr)) {\n errors.push({\n element: tag,\n prop: attr,\n type: 'UNKNOWN_ATTRIBUTE',\n message: `'${attr}' forbidden`,\n fix: `<${elementName}></${elementName}>`,\n confidence: 0.98\n })\n\n continue\n }\n\n if (!manifest.props?.[attr] && !nativeAttributes.has(attr)) {\n errors.push({\n element: tag,\n prop: attr,\n type: 'UNKNOWN_ATTRIBUTE',\n message: `'${attr}' invalid`,\n fix: `<${elementName}></${elementName}>`,\n confidence: 0.95\n })\n }\n }\n\n // enum validation\n for (const attr of Object.keys(attrs)) {\n const def = manifest.props?.[attr]\n\n if (def?.values) {\n const value = attrs[attr]\n\n if (!def.values.includes(value)) {\n errors.push({\n element: tag,\n prop: attr,\n type: 'INVALID_VALUE',\n message: `'${value}' invalid`,\n valid_values: def.values,\n fix: `<${elementName} ${attr}=\"${def.values[0]}\"></${elementName}>`,\n confidence: 0.97\n })\n }\n }\n }\n\n // required props\n for (const req of manifest.required_props || []) {\n if (!(req in attrs)) {\n errors.push({\n element: tag,\n prop: req,\n type: 'MISSING_REQUIRED',\n message: `Missing ${req}`,\n fix: `<${elementName} ${req}=\"\"></${elementName}>`,\n confidence: 0.9\n })\n }\n }\n\n // slot validation\n const slots = manifest.slots ?? {}\n\n for (const [slotName, slotDef] of Object.entries(slots)) {\n const child = el.querySelector(`[slot=\"${slotName}\"]`)\n\n if (slotDef.required && !child) {\n errors.push({\n element: tag,\n prop: slotName,\n type: 'MISSING_SLOT',\n message: `Missing slot ${slotName}`,\n fix: `<${elementName}><span slot=\"${slotName}\"></span></${elementName}>`,\n confidence: 0.95\n })\n }\n\n if (child && slotDef.element) {\n const childTag = child.tagName.toLowerCase()\n\n if (!slotDef.element.includes(childTag)) {\n errors.push({\n element: childTag,\n prop: slotName,\n type: 'INVALID_VALUE',\n message: `${childTag} invalid for slot ${slotName}`,\n valid_values: slotDef.element,\n fix: `<${slotDef.element[0]} slot=\"${slotName}\"></${slotDef.element[0]}>`,\n confidence: 0.95\n })\n }\n }\n }\n }\n\n const valid = errors.length === 0\n const score = valid ? 100 : Math.max(0, 100 - errors.length * 10)\n\n return {\n content: [\n {\n type: 'text',\n\n text: JSON.stringify({\n valid,\n score,\n errors,\n tokens_used: 50\n })\n }\n ]\n }\n}\n","import path from 'path'\nimport { readFileSync, existsSync } from 'fs'\nimport { fileURLToPath } from 'url'\nimport { embedText } from './embedder.js'\nimport { cosineSimilarity } from '../utils/cosine.js'\n\ntype IndexItem = {\n name: string\n emmet: string\n searchable: string\n embedding: number[]\n}\n\nconst __filename = fileURLToPath(import.meta.url)\nconst __dirname = path.dirname(__filename)\n\nlet _index: IndexItem[] | null = null\n\nfunction loadIndex(): IndexItem[] {\n if (_index) return _index\n const indexPath = path.resolve(__dirname, '../../dist/vector-index.json')\n if (!existsSync(indexPath)) {\n console.warn(\n `[search-index] dist/vector-index.json not found at: ${indexPath} - run pnpm build:index`\n )\n _index = []\n return _index\n }\n try {\n _index = JSON.parse(readFileSync(indexPath, 'utf8'))\n } catch (err) {\n console.error(`[search-index] Failed to load index from ${indexPath}:`, err)\n _index = []\n }\n return _index!\n}\n\nexport function searchIndex(description: string) {\n const index = loadIndex()\n const queryEmbedding = embedText(description)\n\n const words = description.toLowerCase().split(/\\s+/)\n const ranked = index\n .map((item) => {\n const similarity = cosineSimilarity(queryEmbedding, item.embedding)\n let boost = 0\n const searchable = item.searchable.toLowerCase()\n\n words.forEach((word) => {\n if (item.name.toLowerCase() === word) {\n boost += 2\n } else if (item.name.toLowerCase().includes(word)) {\n boost += 1\n }\n if (searchable.includes(word)) {\n boost += 0.3\n }\n })\n return {\n ...item,\n score: similarity + boost\n }\n })\n .sort((a, b) => b.score - a.score)\n return ranked.slice(0, 3)\n}\n","const VOCAB_SIZE = 512\n\nexport function embedText(text: string): number[] {\n const vector = new Array(VOCAB_SIZE).fill(0)\n const words = text\n .toLowerCase()\n .replace(/[^a-z0-9\\s]/g, ' ')\n .split(/\\s+/)\n .filter(Boolean)\n words.forEach((word) => {\n let hash = 0\n for (let i = 0; i < word.length; i++) {\n hash = (hash * 31 + word.charCodeAt(i)) % VOCAB_SIZE\n }\n vector[hash] += 1\n })\n return vector\n}\n","export function cosineSimilarity(a: number[], b: number[]): number {\n let dot = 0\n let magA = 0\n let magB = 0\n\n for (let i = 0; i < a.length; i++) {\n dot += a[i] * b[i]\n magA += a[i] * a[i]\n magB += b[i] * b[i]\n }\n\n if (magA === 0 || magB === 0) return 0\n\n return dot / (Math.sqrt(magA) * Math.sqrt(magB))\n}\n","import { readFileSync, existsSync } from 'fs'\nimport path from 'path'\nimport { fileURLToPath } from 'url'\nimport { tokenise, isSimilar } from './intent-helpers.js'\n\nexport type IntentEntry = {\n name: string // the caveman phrase (first line)\n phrases: string[] // all tokenised words from the phrase\n emmet: string // the emmet pattern from the \"- ...\" line\n category: string // section header e.g. \"DESTROY / DANGER\"\n}\n\n/**\n * Parse the INTENTS block out of api-full.txt.\n *\n * Format expected:\n * --- CATEGORY NAME ---\n * caveman phrase description\n * - emmet[pattern]{here}\n * (blank line)\n * ...\n */\nfunction parseIntents(raw: string): IntentEntry[] {\n const entries: IntentEntry[] = []\n\n // Find where the INTENTS block starts\n const intentStart = raw.indexOf('INTENTS:')\n if (intentStart === -1) return entries\n\n const block = raw.slice(intentStart)\n const lines = block.split(/\\r?\\n/)\n\n let currentCategory = 'GENERAL'\n let pendingPhrase: string | null = null\n\n for (const raw_line of lines) {\n const line = raw_line.trim()\n\n // Category header: --- DESTROY / DANGER ---\n if (line.startsWith('---') && line.endsWith('---')) {\n currentCategory = line\n .replace(/^-+\\s*/, '')\n .replace(/\\s*-+$/, '')\n .trim()\n pendingPhrase = null\n continue\n }\n\n // Skip meta comment line [caveman prompt → emmet...]\n if (line.startsWith('[') && line.endsWith(']')) continue\n\n // Skip NEVER DO section (starts with \"never use\")\n if (line.startsWith('never ')) continue\n\n // Skip blank lines and \"→\" alias lines (these are in NEVER DO)\n if (line === '' || line.startsWith('→')) continue\n\n // Emmet line: starts with \"- \"\n if (line.startsWith('- ') && pendingPhrase !== null) {\n const emmet = line.slice(2).trim()\n entries.push({\n name: pendingPhrase,\n phrases: tokenise(pendingPhrase),\n emmet,\n category: currentCategory\n })\n pendingPhrase = null\n continue\n }\n\n // Anything else is a caveman phrase (intent description)\n if (!line.startsWith('-')) {\n pendingPhrase = line\n }\n }\n\n return entries\n}\n\n// ---- Resolve the api-full.txt path relative to this package root ----\nfunction loadIntents(): IntentEntry[] {\n try {\n const currentDir = path.dirname(fileURLToPath(import.meta.url))\n\n // Try relative paths from current file structure (packages/mcp/src/utils/ or dist/utils/)\n const path1 = path.resolve(currentDir, '../../../api-full.txt')\n const path2 = path.resolve(currentDir, '../../api-full.txt')\n const path3 = path.resolve(currentDir, '../../../../api-full.txt')\n\n let txtPath = path1\n if (existsSync(path1)) {\n txtPath = path1\n } else if (existsSync(path2)) {\n txtPath = path2\n } else if (existsSync(path3)) {\n txtPath = path3\n } else {\n txtPath = path.resolve(process.cwd(), '../../api-full.txt')\n }\n\n const raw = readFileSync(txtPath, 'utf8')\n return parseIntents(raw)\n } catch {\n return []\n }\n}\n\n// Singleton - parsed once at server startup, stays in-memory (DC-13)\nlet _cache: IntentEntry[] | null = null\n\nexport function getIntentEntries(): IntentEntry[] {\n if (!_cache) {\n _cache = loadIntents()\n }\n return _cache\n}\n\nexport type ScoreResult = {\n score: number\n density: number\n}\n\n/**\n * Score a single IntentEntry against the query, tolerating minor typos.\n * Returns { score, density } for tie-breaking.\n */\nexport function scoreEntry(\n entry: IntentEntry,\n queryWords: string[]\n): ScoreResult {\n let score = 0\n const entryWords = new Set(entry.phrases)\n let matchedCount = 0\n\n for (const qw of queryWords) {\n let matched = false\n // 1. Exact match (+10)\n if (entryWords.has(qw)) {\n score += 10\n matched = true\n } else {\n // 2. Fuzzy spelling similarity match (+8)\n for (const ew of entryWords) {\n if (isSimilar(qw, ew)) {\n score += 8\n matched = true\n break\n }\n }\n // 3. Substring match fallback (+4)\n if (!matched) {\n for (const ew of entryWords) {\n if (ew.includes(qw) || qw.includes(ew)) {\n score += 4\n matched = true\n break\n }\n }\n }\n }\n if (matched) {\n matchedCount++\n }\n }\n\n // Bonus: category keyword overlap (supports fuzzy spelling matches)\n const catWords = tokenise(entry.category)\n for (const qw of queryWords) {\n if (catWords.includes(qw)) {\n score += 3\n } else {\n for (const cw of catWords) {\n if (isSimilar(qw, cw)) {\n score += 2\n break\n }\n }\n }\n }\n\n // Density = portion of the entry's phrases that were matched by the query\n const density =\n entry.phrases.length > 0 ? matchedCount / entry.phrases.length : 0\n\n return { score, density }\n}\n","export const STOP_WORDS = new Set([\n 'with',\n 'for',\n 'and',\n 'the',\n 'you',\n 'can',\n 'from',\n 'this',\n 'that',\n 'your',\n 'want',\n 'need',\n 'show',\n 'give',\n 'nice',\n 'page',\n 'here',\n 'please',\n 'make',\n 'create',\n 'build',\n 'about',\n 'using',\n 'what',\n 'should',\n 'how'\n])\n\nexport function tokenise(text: string): string[] {\n return text\n .toLowerCase()\n .replace(/[^a-z0-9\\s/]/g, ' ')\n .split(/[\\s/]+/)\n .filter((w) => w.length > 1 && !STOP_WORDS.has(w))\n}\n\nexport function editDistance(s1: string, s2: string): number {\n const costs: number[] = []\n for (let i = 0; i <= s1.length; i++) {\n let lastValue = i\n for (let j = 0; j <= s2.length; j++) {\n if (i === 0) {\n costs[j] = j\n } else {\n if (j > 0) {\n let newValue = costs[j - 1]\n if (s1.charAt(i - 1) !== s2.charAt(j - 1)) {\n newValue = Math.min(Math.min(newValue, lastValue), costs[j]) + 1\n }\n costs[j - 1] = lastValue\n lastValue = newValue\n }\n }\n }\n if (i > 0) costs[s2.length] = lastValue\n }\n return costs[s2.length]\n}\n\nexport function isSimilar(w1: string, w2: string): boolean {\n if (w1.length < 3 || w2.length < 3) return w1 === w2\n // Typo tolerance: 1 edit for 3-5 chars, 2 edits for 6+ chars\n const maxDistance = w1.length >= 6 && w2.length >= 6 ? 2 : 1\n return editDistance(w1, w2) <= maxDistance\n}\n","import emmet from 'emmet'\n\n// Expand Emmet shorthand to full HTML using the emmet npm package\nexport function expandEmmet(emmetStr: string): string {\n try {\n return emmet(emmetStr)\n } catch {\n return `<!-- expand: ${emmetStr} -->`\n }\n}\n\n// Maps HTML element names / web-component tag names → ignix-lite component names\nexport const ELEMENT_TO_COMPONENT: Record<string, string> = {\n // Native elements\n button: 'button',\n input: 'input',\n textarea: 'textarea',\n select: 'select',\n form: 'form',\n dialog: 'dialog',\n details: 'accordion',\n summary: 'accordion',\n progress: 'progress',\n meter: 'meter',\n aside: 'alert',\n mark: 'badge',\n img: 'avatar',\n article: 'card',\n nav: 'navigation',\n table: 'table',\n pre: 'codeblock',\n code: 'codeblock',\n hr: 'divider',\n label: 'input', // label wraps input/checkbox/radio\n // Web components\n 'ix-tabs': 'tab',\n 'ix-dropdown': 'dropdown',\n 'ix-combobox': 'combobox',\n 'ix-tooltip': 'tooltip',\n 'ix-toast': 'toast'\n}\n\n// Skeleton heuristic: span with aria-busy or data-shape\nexport const SKELETON_PATTERN = /span\\[[^\\]]*(?:aria-busy|data-shape)[^\\]]*\\]/i\n\n/**\n * Given an emmet string, return the unique set of ignix-lite component names\n * that the pattern uses. E.g.:\n * \"article>(img[slot=avatar])+(button{View})\" → [\"card\", \"avatar\", \"button\"]\n */\nexport function extractComponents(emmetStr: string): string[] {\n const found = new Set<string>()\n\n // Special case: skeleton uses span[aria-busy] or span[data-shape]\n if (SKELETON_PATTERN.test(emmetStr)) {\n found.add('skeleton')\n }\n\n // Special case: nav[aria-label=Breadcrumb] → breadcrumb\n if (/nav\\[[^\\]]*breadcrumb/i.test(emmetStr)) {\n found.add('breadcrumb')\n } else if (/\\bnav\\b/.test(emmetStr)) {\n found.add('navigation')\n }\n\n // Special case: label > input[type=checkbox] → checkbox\n if (/input\\[[^\\]]*type=checkbox/i.test(emmetStr)) {\n found.add('checkbox')\n }\n\n // Special case: label > input[type=radio] → radio\n if (/input\\[[^\\]]*type=radio/i.test(emmetStr)) {\n found.add('radio')\n }\n\n // Special case: section[data-grid] → grid (only when data-grid attr is present)\n if (/section\\[[^\\]]*data-grid/i.test(emmetStr)) {\n found.add('grid')\n }\n\n // General: extract all tag names from the emmet string\n const tagPattern = /(?:^|[>+(])([a-z][a-z0-9-]*)/gi\n let m: RegExpExecArray | null\n while ((m = tagPattern.exec(emmetStr)) !== null) {\n const tag = m[1].toLowerCase()\n const component = ELEMENT_TO_COMPONENT[tag]\n if (component) found.add(component)\n }\n\n return Array.from(found)\n}\n\n/**\n * Customizes standard Emmet shorthand by dynamically replacing text strings\n * and visual intent attributes based on the user prompt description.\n */\nexport function interpolateEmmet(\n emmetStr: string,\n description: string\n): string {\n let result = emmetStr\n\n // 1. Color/Intent overrides based on keywords in description\n const descLower = description.toLowerCase()\n if (/\\b(red|danger|delete|remove|destroy)\\b/.test(descLower)) {\n // replace any data-intent of primary/neutral/ghost with danger\n result = result.replace(\n /data-intent=(?:primary|neutral|ghost)/g,\n 'data-intent=danger'\n )\n } else if (/\\b(green|success|work|done)\\b/.test(descLower)) {\n result = result.replace(\n /data-intent=(?:primary|neutral|ghost)/g,\n 'data-intent=success'\n )\n } else if (/\\b(yellow|orange|warning|risky)\\b/.test(descLower)) {\n result = result.replace(\n /data-intent=(?:primary|neutral|ghost)/g,\n 'data-intent=warning'\n )\n }\n\n // 2. Extract quoted strings for label/text overrides\n const matches = [...description.matchAll(/['\"]([^'\"]+)['\"]/g)]\n const quotedStrings = matches\n .map((m) => m[1].trim())\n .filter((s) => s.length > 0)\n\n if (quotedStrings.length > 0) {\n const hasButtonMention = /\\b(button|says|labeled|action|click)\\b/i.test(\n description\n )\n\n // We only replace the button text if:\n // - There are multiple quoted strings (so the last one is assumed to be the button), OR\n // - There is only one quoted string, but the prompt explicitly mentions a button/action\n const shouldReplaceButton =\n quotedStrings.length >= 2 ||\n (quotedStrings.length === 1 && hasButtonMention)\n\n if (shouldReplaceButton) {\n const buttonRegex = /(button[^}]*)\\{([^}]+)\\}/g\n const buttonMatches = [...result.matchAll(buttonRegex)]\n\n if (buttonMatches.length > 0) {\n const buttonLabel = quotedStrings[quotedStrings.length - 1]\n result = result.replace(buttonRegex, (match, p1) => {\n return `${p1}{${buttonLabel}}`\n })\n quotedStrings.pop()\n }\n }\n\n // Replace label text in order with the remaining quoted strings\n const labelRegex = /label\\{([^}]+)\\}/g\n let quoteIndex = 0\n result = result.replace(labelRegex, (match) => {\n if (quoteIndex < quotedStrings.length) {\n return `label{${quotedStrings[quoteIndex++]}}`\n }\n return match\n })\n\n // Auto-adapt input type: if label contains \"username\", change type=email to type=text\n if (/label\\{username\\}/i.test(result)) {\n result = result.replace(/type=email/g, 'type=text')\n }\n }\n\n return result\n}\n","import { searchIndex } from './search-index.js'\nimport { getIntentEntries, scoreEntry } from '../utils/intent-parser.js'\nimport { getTokenCount } from '../utils/tokenizer.js'\nimport { tokenise } from '../utils/intent-helpers.js'\nimport {\n expandEmmet,\n extractComponents,\n interpolateEmmet\n} from '../utils/emmet-helpers.js'\n\nimport type { IntentEntry } from '../utils/intent-parser.js'\n\n// ─── Layer 1: api-full.txt INTENTS lookup ───────────────────────────────────\n\ntype IntentMatch = {\n name: string\n emmet: string\n score: number\n source: 'intent-table' | 'vector-index'\n}\n\nconst LAYER1_THRESHOLD = 8 // minimum score to trust an intent-table hit\n\nfunction searchIntentTable(description: string): IntentMatch | null {\n const entries = getIntentEntries()\n if (entries.length === 0) return null\n\n const queryWords = tokenise(description)\n\n // Find all matches meeting the threshold\n const candidates: {\n entry: IntentEntry\n score: number\n density: number\n components: string[]\n }[] = []\n let bestSingle: (IntentMatch & { density: number }) | null = null\n\n for (const entry of entries) {\n const { score, density } = scoreEntry(entry, queryWords)\n if (score >= LAYER1_THRESHOLD) {\n const components = extractComponents(entry.emmet)\n candidates.push({ entry, score, density, components })\n\n const isBetter =\n !bestSingle ||\n score > bestSingle.score ||\n (score === bestSingle.score && density > bestSingle.density)\n if (isBetter) {\n bestSingle = {\n name: entry.name,\n emmet: entry.emmet,\n score,\n density,\n source: 'intent-table'\n }\n }\n }\n }\n\n // If a single template matches with exceptionally high score, trust it directly\n if (bestSingle && bestSingle.score >= 18) {\n return bestSingle\n }\n\n // Check if the user explicitly requested stitching using conjunction words (and, plus, +, comma)\n const isStitchRequested =\n /\\b(and|plus|\\+)\\b/i.test(description) || description.includes(',')\n\n // Otherwise, check if we can stitch multiple distinct components together (synthesis)\n if (isStitchRequested && candidates.length >= 2) {\n // Sort candidates by score (descending)\n candidates.sort((a, b) => b.score - a.score || b.density - a.density)\n\n const selected: typeof candidates = []\n const usedComponents = new Set<string>()\n\n for (const c of candidates) {\n // Check if this candidate is disjoint from the already selected components\n const hasOverlap = c.components.some((comp) => usedComponents.has(comp))\n if (!hasOverlap) {\n selected.push(c)\n c.components.forEach((comp) => usedComponents.add(comp))\n }\n }\n\n // If we gathered at least 2 distinct templates, stitch them!\n if (selected.length >= 2) {\n // Re-sort selected in the order they appear in the user description to look natural\n selected.sort((a, b) => {\n const indexA = description\n .toLowerCase()\n .indexOf(tokenise(a.entry.name)[0])\n const indexB = description\n .toLowerCase()\n .indexOf(tokenise(b.entry.name)[0])\n return indexA - indexB\n })\n\n const combinedEmmet = selected.map((s) => s.entry.emmet).join('+')\n const totalScore = selected.reduce((sum, s) => sum + s.score, 0)\n\n return {\n name: selected.map((s) => s.entry.name).join(' and '),\n emmet: combinedEmmet,\n score: totalScore,\n source: 'intent-table'\n }\n }\n }\n\n return bestSingle\n}\n\n// ─── Layer 2: vector-index fallback ─────────────────────────────────────────\n\nfunction searchVectorLayer(description: string): IntentMatch | null {\n const results = searchIndex(description)\n if (results.length === 0) return null\n const top = results[0]\n return {\n name: top.name,\n emmet: top.emmet,\n score: top.score,\n source: 'vector-index'\n }\n}\n\n// ─── Public: howToBuild ──────────────────────────────────────────────────────\n\nexport async function howToBuild(description: string) {\n let cleanDesc = description.trim()\n if (cleanDesc.startsWith('{') && cleanDesc.endsWith('}')) {\n try {\n const parsed = JSON.parse(cleanDesc)\n if (parsed && typeof parsed.description === 'string') {\n cleanDesc = parsed.description\n } else if (parsed && typeof parsed.text === 'string') {\n cleanDesc = parsed.text\n }\n } catch {\n // Ignore parsing errors, keep original string\n }\n }\n\n // Layer 1 — fast, deterministic, hand-crafted intent table\n let match = searchIntentTable(cleanDesc)\n\n // Layer 2 — vector index fallback for novel / unknown queries\n if (!match) {\n match = searchVectorLayer(cleanDesc)\n }\n\n if (!match) {\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify({\n emmet: '',\n html: '',\n components_used: [],\n confidence: 0,\n tokens: 0,\n tokens_used: 15,\n source: 'no-match',\n suggestion:\n 'Call list_components() to see all available components, or try a different description.'\n })\n }\n ]\n }\n }\n\n // Apply dynamic interpolation to customize labels, types, and colors on the fly\n const emmet = interpolateEmmet(match.emmet, cleanDesc)\n const components_used = extractComponents(emmet)\n\n const confidence = Math.min(1, match.score / 40)\n\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify({\n emmet,\n html: expandEmmet(emmet),\n components_used,\n confidence: Number(confidence.toFixed(2)),\n tokens: getTokenCount(emmet),\n tokens_used: 15,\n source: match.source // tells caller which layer matched\n })\n }\n ]\n }\n}\n","import { readFileSync, existsSync } from 'fs'\nimport path from 'path'\nimport { fileURLToPath } from 'url'\n\nconst __filename = fileURLToPath(import.meta.url)\nconst __dirname = path.dirname(__filename)\n\n// Dynamically handle both bundled dist/ and source src/context/ contexts\nlet apiPath = path.resolve(__dirname, '../../../api-full.txt')\nif (!existsSync(apiPath)) {\n apiPath = path.resolve(__dirname, '../../../../api-full.txt')\n}\n\nexport const apiContext = readFileSync(apiPath, 'utf8')\n","import { z } from 'zod'\nimport type { MCPResponse } from '../types.js'\nimport { resolveTokens, buildCss } from './theme-tokens.js'\n\nconst schema = z.object({ prompt: z.string().min(1) })\n\nexport function generateTheme(args: unknown): MCPResponse {\n const parsed = schema.safeParse(args)\n\n if (!parsed.success) {\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify({\n error: 'Invalid input',\n suggestion: 'Expected { prompt: string }',\n tokens_used: 2\n })\n }\n ]\n }\n }\n\n const { prompt } = parsed.data\n const tokens = resolveTokens(prompt.toLowerCase().trim())\n\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify({\n prompt,\n primary: tokens.resolvedPrimary,\n isDark: tokens.isDark,\n css: buildCss(tokens),\n tokens_used: 10\n })\n }\n ]\n }\n}\n","export interface ColorEntry {\n primary: string\n contrast: string\n}\n\nexport const PALETTE: Record<string, ColorEntry> = {\n red: { primary: '#ef4444', contrast: '#ffffff' },\n orange: { primary: '#f97316', contrast: '#ffffff' },\n amber: { primary: '#f59e0b', contrast: '#111827' },\n yellow: { primary: '#eab308', contrast: '#111827' },\n lime: { primary: '#84cc16', contrast: '#111827' },\n green: { primary: '#22c55e', contrast: '#ffffff' },\n emerald: { primary: '#10b981', contrast: '#ffffff' },\n teal: { primary: '#14b8a6', contrast: '#ffffff' },\n cyan: { primary: '#06b6d4', contrast: '#111827' },\n sky: { primary: '#0ea5e9', contrast: '#111827' },\n blue: { primary: '#3b82f6', contrast: '#ffffff' },\n indigo: { primary: '#6366f1', contrast: '#ffffff' },\n violet: { primary: '#8b5cf6', contrast: '#ffffff' },\n purple: { primary: '#a855f7', contrast: '#ffffff' },\n fuchsia: { primary: '#d946ef', contrast: '#ffffff' },\n pink: { primary: '#ec4899', contrast: '#ffffff' },\n rose: { primary: '#f43f5e', contrast: '#ffffff' },\n cyberpunk: { primary: '#ec4899', contrast: '#ffffff' },\n neon: { primary: '#d946ef', contrast: '#ffffff' },\n eco: { primary: '#10b981', contrast: '#ffffff' },\n forest: { primary: '#0f766e', contrast: '#ffffff' },\n coffee: { primary: '#78350f', contrast: '#ffffff' },\n ocean: { primary: '#0284c7', contrast: '#ffffff' },\n sunset: { primary: '#f97316', contrast: '#ffffff' },\n midnight: { primary: '#3730a3', contrast: '#ffffff' },\n lavender: { primary: '#8b5cf6', contrast: '#ffffff' },\n coral: { primary: '#f43f5e', contrast: '#ffffff' },\n slate: { primary: '#64748b', contrast: '#ffffff' },\n gold: { primary: '#d97706', contrast: '#111827' },\n silver: { primary: '#94a3b8', contrast: '#111827' }\n}\n\nexport function expandHex(hex: string): string {\n const h = hex.replace('#', '')\n return h.length === 3 ? '#' + h[0] + h[0] + h[1] + h[1] + h[2] + h[2] : hex\n}\n\nexport function contrastFor(hex6: string): string {\n const h = hex6.replace('#', '')\n const r = parseInt(h.substring(0, 2), 16)\n const g = parseInt(h.substring(2, 4), 16)\n const b = parseInt(h.substring(4, 6), 16)\n return (r * 299 + g * 587 + b * 114) / 1000 > 165 ? '#111827' : '#ffffff'\n}\n\nexport function resolveColor(query: string): ColorEntry {\n const hexMatch = query.match(/#([0-9a-fA-F]{6}|[0-9a-fA-F]{3})\\b/)\n if (hexMatch) {\n const primary = expandHex(hexMatch[0])\n return { primary, contrast: contrastFor(primary) }\n }\n\n const sorted = Object.keys(PALETTE).sort((a, b) => b.length - a.length)\n for (const name of sorted) {\n if (query.includes(name)) return PALETTE[name]\n }\n\n return { primary: '#6366f1', contrast: '#ffffff' }\n}\n","import { resolveColor } from './theme-palette.js'\n\nexport interface ThemeTokens {\n primary: string\n primaryHover: string\n primaryContrast: string\n primaryBg: string\n\n danger: string\n dangerText: string\n dangerBg: string\n\n warning: string\n warningBg: string\n\n success: string\n successBg: string\n\n infoBg: string\n neutral: string\n divider: string\n\n surface: string\n surfaceRaised: string\n\n text: string\n textMuted: string\n border: string\n\n radius: string\n radiusLg: string\n badgeRadius: string\n\n skeletonBg: string\n skeletonShimmer: string\n\n gradientStart: string\n gradientEnd: string\n gradientBgEnd: string\n\n isDark: boolean\n resolvedPrimary: string\n resolvedContrast: string\n}\n\nexport function resolveTokens(query: string): ThemeTokens {\n const { primary, contrast } = resolveColor(query)\n\n const isDark =\n query.includes('dark') ||\n query.includes('night') ||\n query.includes('midnight') ||\n query.includes('cyberpunk') ||\n query.includes('dim')\n\n const sharp =\n query.includes('sharp') ||\n query.includes('flat') ||\n query.includes('square')\n const round =\n query.includes('round') || query.includes('pill') || query.includes('soft')\n\n return {\n resolvedPrimary: primary,\n resolvedContrast: contrast,\n isDark,\n\n primary,\n primaryHover: isDark\n ? 'color-mix(in srgb, var(--ix-primary) 75%, white)'\n : 'color-mix(in srgb, var(--ix-primary) 85%, black)',\n primaryContrast: isDark\n ? 'color-mix(in srgb, var(--ix-primary) 40%, white)'\n : contrast,\n primaryBg: isDark\n ? 'color-mix(in srgb, var(--ix-primary) 20%, #0f172a)'\n : 'color-mix(in srgb, var(--ix-primary) 15%, white)',\n\n danger: '#ef4444',\n dangerText: isDark ? '#f87171' : '#ef4444',\n dangerBg: isDark ? '#3f1d1d' : '#fee2e2',\n\n warning: isDark ? '#fbbf24' : '#f59e0b',\n warningBg: isDark ? '#3f2e05' : '#fef3c7',\n\n success: '#22c55e',\n successBg: isDark ? '#052e16' : '#dcfce7',\n\n infoBg: isDark ? '#1e293b' : '#f3f4f6',\n neutral: isDark ? '#9ca3af' : '#6b7280',\n divider: isDark ? '#475569' : '#9ca3af',\n\n surface: isDark ? '#0f172a' : '#f9fafb',\n surfaceRaised: isDark ? '#1e293b' : '#ffffff',\n\n text: isDark ? '#f9fafb' : '#111827',\n textMuted: isDark ? '#94a3b8' : '#6b7280',\n border: isDark ? '#334155' : '#e5e7eb',\n\n radius: sharp ? '0px' : round ? '0.75rem' : '0.375rem',\n radiusLg: sharp ? '0px' : round ? '1rem' : '0.5rem',\n badgeRadius: '999px',\n\n skeletonBg: isDark ? '#1e293b' : '#e5e7eb',\n skeletonShimmer: isDark ? 'rgba(255,255,255,0.1)' : 'rgba(255,255,255,0.6)',\n\n gradientStart: primary,\n gradientEnd: '#fffbd5',\n gradientBgEnd: isDark ? '#aba67a' : '#d7d4bc'\n }\n}\n\nexport function buildCss(t: ThemeTokens): string {\n return `:root {\n --ix-primary: ${t.primary};\n --ix-primary-hover: ${t.primaryHover};\n --ix-primary-contrast: ${t.primaryContrast};\n\n --ix-danger: ${t.danger};\n --ix-danger-text: ${t.dangerText};\n\n --ix-warning: ${t.warning};\n --ix-success: ${t.success};\n --ix-neutral: ${t.neutral};\n --ix-ghost: transparent;\n\n --ix-primary-bg: ${t.primaryBg};\n --ix-danger-bg: ${t.dangerBg};\n --ix-warning-bg: ${t.warningBg};\n --ix-success-bg: ${t.successBg};\n --ix-info-bg: ${t.infoBg};\n\n --ix-on-danger: #ffffff;\n --ix-on-warning: #000000;\n --ix-on-success: #ffffff;\n --ix-on-primary: ${t.resolvedContrast};\n\n --ix-divider: ${t.divider};\n\n --ix-surface: ${t.surface};\n --ix-surface-raised: ${t.surfaceRaised};\n\n --ix-text: ${t.text};\n --ix-text-muted: ${t.textMuted};\n\n --ix-border: ${t.border};\n --ix-focus: 2px solid var(--ix-primary);\n\n --ix-font: 'Segoe UI Variable', 'Segoe UI', 'Roboto', 'Noto Sans', system-ui, sans-serif;\n --ix-font-mono: 'JetBrains Mono', 'SFMono-Regular', Consolas, monospace;\n\n --ix-size-xs: 0.75rem;\n --ix-size-sm: 0.875rem;\n --ix-size-md: 1rem;\n --ix-size-lg: 1.125rem;\n --ix-size-xl: 1.25rem;\n\n --ix-line-height: 1.5;\n\n --ix-space-sm: 0.5rem;\n --ix-space-md: 1rem;\n --ix-space-lg: 1.5rem;\n\n --ix-radius: ${t.radius};\n --ix-radius-lg: ${t.radiusLg};\n --ix-badge-radius: ${t.badgeRadius};\n\n --ix-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);\n\n --ix-gradient: linear-gradient(to right, ${t.gradientStart}, ${t.gradientEnd});\n --ix-gradient-bg: linear-gradient(to right, ${t.gradientStart}, ${t.gradientBgEnd});\n\n --ix-skeleton-bg: ${t.skeletonBg};\n --ix-skeleton-shimmer: ${t.skeletonShimmer};\n}`\n}\n","import { parse } from 'node-html-parser'\nimport type { MCPResponse } from '../types.js'\nimport type { A11yIssue, RuleResult } from '../utils/a11y-types.js'\nimport {\n checkImages,\n checkFormLabels,\n checkEmptyLabels,\n checkButtons,\n checkLinks,\n checkAriaStates,\n checkDuplicateIds,\n checkTabIndex,\n checkHeadings,\n checkTables,\n checkDialogs,\n checkRoles,\n checkAutocomplete,\n checkFocusStyle,\n checkLang\n} from '../utils/a11y-rules.js'\n\n// Rule-specific confidence scores to avoid arbitrary hardcoding (addresses CodeRabbit feedback)\nconst RULE_CONFIDENCES: Record<string, { error: number; warning: number }> = {\n 'WCAG 1.1.1 Non-text Content': { error: 0.99, warning: 0.80 },\n 'WCAG 1.3.1 Form Labels': { error: 0.98, warning: 0.78 },\n 'WCAG 2.4.6 Empty Labels': { error: 0.95, warning: 0.75 },\n 'WCAG 4.1.2 Button Names': { error: 0.99, warning: 0.80 },\n 'WCAG 2.4.4 Link Purpose': { error: 0.97, warning: 0.75 },\n 'WCAG 3.3.1 Error Identification': { error: 0.98, warning: 0.75 },\n 'WCAG 4.1.2 ARIA State Values': { error: 0.96, warning: 0.75 },\n 'WCAG 4.1.1 Parsing': { error: 0.99, warning: 0.80 },\n 'WCAG 2.1.1 Keyboard': { error: 0.95, warning: 0.75 },\n 'WCAG 2.4.6 Heading Hierarchy': { error: 0.95, warning: 0.75 },\n 'WCAG 1.3.1 Table Structure': { error: 0.97, warning: 0.75 },\n 'WCAG 4.1.2 Dialog Accessibility': { error: 0.98, warning: 0.75 },\n 'WCAG 4.1.2 ARIA Role Requirements': { error: 0.98, warning: 0.75 },\n 'WCAG 1.3.5 Input Purpose': { error: 0.95, warning: 0.75 },\n 'WCAG 2.4.7 Focus Visible': { error: 0.95, warning: 0.75 },\n 'WCAG 3.1.1 Language of Page': { error: 0.99, warning: 0.80 }\n}\n\nfunction getConfidenceForRule(\n ruleName: string,\n type: 'error' | 'warning'\n): number {\n const conf = RULE_CONFIDENCES[ruleName]\n if (conf) {\n return type === 'error' ? conf.error : conf.warning\n }\n return type === 'error' ? 0.98 : 0.75\n}\n\nfunction computeScore(issues: A11yIssue[]): number {\n const errors = issues.filter((i) => i.type === 'error').length\n const warnings = issues.filter((i) => i.type === 'warning').length\n return Math.max(0, 100 - errors * 10 - warnings * 3)\n}\n\nfunction getPassingRules(results: RuleResult[]): string[] {\n return results.filter((r) => r.issues.length === 0).map((r) => r.ruleName)\n}\n\nexport function checkA11y(html: string): MCPResponse {\n const root = parse(html)\n\n const results: RuleResult[] = [\n checkImages(root),\n checkFormLabels(root),\n checkEmptyLabels(root),\n checkButtons(root),\n checkLinks(root),\n checkAriaStates(root),\n checkDuplicateIds(root),\n checkTabIndex(root),\n checkHeadings(root),\n checkTables(root),\n checkDialogs(root),\n checkRoles(root),\n checkAutocomplete(root),\n checkFocusStyle(root),\n checkLang(root)\n ]\n\n const rawIssues = results.flatMap((r) => r.issues)\n const issues: A11yIssue[] = rawIssues.map((i) => ({\n ...i,\n confidence: getConfidenceForRule(i.rule, i.type)\n }))\n const passes = getPassingRules(results)\n const score = computeScore(issues)\n\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify({\n score,\n passes,\n issues,\n wcag: 'AA',\n tokens_used: Math.min(60, 20 + issues.length * 3)\n })\n }\n ]\n }\n}\n","import type { HTMLElement } from 'node-html-parser'\nimport type { A11yIssue, RuleResult } from './a11y-types.js'\n\nfunction injectAttr(outerHTML: string, attr: string, value: string): string {\n return outerHTML.replace(/^(<[a-zA-Z][a-zA-Z0-9-]*)/, `$1 ${attr}=\"${value}\"`)\n}\n\nfunction clip(str: string, max = 200): string {\n return str.length > max ? str.slice(0, max) + '...' : str\n}\n\nfunction isDecorative(img: HTMLElement): boolean {\n const role = img.getAttribute('role')\n const ariaHidden = img.getAttribute('aria-hidden')\n return role === 'presentation' || role === 'none' || ariaHidden === 'true'\n}\n\n// Returns IDs from an ARIA reference attribute that do not exist in the DOM\nfunction findBrokenAriaRefs(\n el: HTMLElement,\n attr: string,\n root: HTMLElement\n): string[] {\n const val = el.getAttribute(attr)\n if (!val?.trim()) return []\n return val\n .trim()\n .split(/\\s+/)\n .filter((id) => !root.querySelector(`[id=\"${id}\"]`))\n}\n\n// Walks child nodes skipping any subtree rooted at aria-hidden=\"true\"\nfunction getVisibleText(el: HTMLElement): string {\n if (el.getAttribute('aria-hidden') === 'true') return ''\n let result = ''\n for (const child of el.childNodes) {\n if (child.nodeType === 1) {\n result += getVisibleText(child as HTMLElement)\n } else if (child.nodeType === 3) {\n result += child.text ?? ''\n }\n }\n return result\n}\n\nfunction getAccessibleName(el: HTMLElement, root: HTMLElement): string {\n const text = getVisibleText(el).trim()\n if (text) return text\n\n const ariaLabel = el.getAttribute('aria-label')?.trim()\n if (ariaLabel) return ariaLabel\n\n const title = el.getAttribute('title')?.trim()\n if (title) return title\n\n const childImg = el.querySelector('img')\n const childAlt = childImg?.getAttribute('alt')?.trim()\n if (childAlt) return childAlt\n\n const labelledBy = el.getAttribute('aria-labelledby')\n if (labelledBy) {\n const name = labelledBy\n .trim()\n .split(/\\s+/)\n .map((id) => root.querySelector(`[id=\"${id}\"]`)?.text.trim() ?? '')\n .join(' ')\n .trim()\n if (name) return name\n }\n\n return ''\n}\n\nexport function checkImages(root: HTMLElement): RuleResult {\n const ruleName = 'WCAG 1.1.1 Non-text Content'\n const issues: A11yIssue[] = []\n\n root.querySelectorAll('img').forEach((img) => {\n const alt = img.getAttribute('alt')\n const ariaLabel = img.getAttribute('aria-label')?.trim()\n const labelledBy = img.getAttribute('aria-labelledby')\n const hasAriaName = !!(ariaLabel || labelledBy)\n\n if (alt === undefined) {\n if (hasAriaName) {\n issues.push({\n type: 'warning',\n rule: ruleName,\n element: clip(img.outerHTML),\n message:\n '<img> uses aria-label/aria-labelledby but the alt attribute is recommended for broader screen reader compatibility',\n fix: injectAttr(\n img.outerHTML,\n 'alt',\n ariaLabel ?? '[Describe the image]'\n )\n })\n } else {\n issues.push({\n type: 'error',\n rule: ruleName,\n element: clip(img.outerHTML),\n message: '<img> is missing the alt attribute',\n fix: injectAttr(img.outerHTML, 'alt', '[Describe the image]')\n })\n }\n return\n }\n\n if (alt.trim() === '' && !isDecorative(img)) {\n issues.push({\n type: 'warning',\n rule: ruleName,\n element: clip(img.outerHTML),\n message:\n '<img> has an empty alt but is not marked as decorative - add role=\"presentation\" or provide a description',\n fix: injectAttr(img.outerHTML, 'role', 'presentation')\n })\n }\n })\n\n return { ruleName, issues }\n}\n\nexport function checkFormLabels(root: HTMLElement): RuleResult {\n const ruleName = 'WCAG 1.3.1 Form Labels'\n const issues: A11yIssue[] = []\n const UNLABELED_SKIP = new Set([\n 'hidden',\n 'submit',\n 'reset',\n 'button',\n 'image'\n ])\n\n for (const tag of ['input', 'select', 'textarea'] as const) {\n root.querySelectorAll(tag).forEach((el) => {\n if (tag === 'input') {\n const type = (el.getAttribute('type') ?? 'text').toLowerCase()\n if (UNLABELED_SKIP.has(type)) return\n }\n\n const id = el.getAttribute('id')\n const hasExplicit = id\n ? !!root.querySelector(`label[for=\"${id}\"]`)\n : false\n const hasImplicit = !!el.closest('label')\n const ariaLabel = el.getAttribute('aria-label')?.trim()\n const ariaLabelledBy = el.getAttribute('aria-labelledby')\n const hasTitle = !!el.getAttribute('title')?.trim()\n\n if (\n !hasExplicit &&\n !hasImplicit &&\n !ariaLabel &&\n !ariaLabelledBy &&\n !hasTitle\n ) {\n issues.push({\n type: 'error',\n rule: ruleName,\n element: clip(el.outerHTML),\n message: `<${tag}> is not associated with a <label> - use for/id, wrapping label, or aria-label`,\n fix: id\n ? `<label for=\"${id}\">[Label text]</label>\\n${el.outerHTML}`\n : `<label>[Label text] ${el.outerHTML}</label>`\n })\n return\n }\n\n // Verify aria-labelledby targets actually exist in the DOM\n if (ariaLabelledBy) {\n const broken = findBrokenAriaRefs(el, 'aria-labelledby', root)\n if (broken.length > 0) {\n issues.push({\n type: 'error',\n rule: ruleName,\n element: clip(el.outerHTML),\n message: `<${tag}> aria-labelledby references non-existent element(s): ${broken.map((id) => `#${id}`).join(', ')}`,\n fix: `Ensure element(s) with id=\"${broken.join('\", \"')}\" exist in the DOM, or use aria-label instead`\n })\n }\n }\n })\n }\n\n root.querySelectorAll('fieldset').forEach((fieldset) => {\n const legend = fieldset.querySelector('legend')\n if (!legend || !legend.text.trim()) {\n issues.push({\n type: 'error',\n rule: ruleName,\n element: '<fieldset>',\n message:\n '<fieldset> must have a non-empty <legend> to group related form controls',\n fix: `<fieldset>\\n <legend>[Group label]</legend>\\n ...\\n</fieldset>`\n })\n }\n })\n\n return { ruleName, issues }\n}\n\nexport function checkEmptyLabels(root: HTMLElement): RuleResult {\n const ruleName = 'WCAG 2.4.6 Empty Labels'\n const issues: A11yIssue[] = []\n\n root.querySelectorAll('label').forEach((label) => {\n const hasText = !!label.text.trim()\n const hasAriaLabel = !!label.getAttribute('aria-label')?.trim()\n\n if (!hasText && !hasAriaLabel) {\n issues.push({\n type: 'warning',\n rule: ruleName,\n element: clip(label.outerHTML),\n message:\n '<label> is empty and provides no accessible name for its control',\n fix: label.outerHTML.replace('</label>', '[Label text]</label>')\n })\n }\n\n // Check broken label[for] association\n const forAttr = label.getAttribute('for')\n if (forAttr && !root.querySelector(`[id=\"${forAttr}\"]`)) {\n issues.push({\n type: 'error',\n rule: ruleName,\n element: clip(label.outerHTML),\n message: `<label for=\"${forAttr}\"> references id=\"${forAttr}\" which does not exist in the DOM`,\n fix: `Add id=\"${forAttr}\" to the target form element, or correct the for attribute`\n })\n }\n })\n\n return { ruleName, issues }\n}\n\nexport function checkButtons(root: HTMLElement): RuleResult {\n const ruleName = 'WCAG 4.1.2 Button Names'\n const issues: A11yIssue[] = []\n\n root.querySelectorAll('button').forEach((button) => {\n if (!getAccessibleName(button, root)) {\n issues.push({\n type: 'error',\n rule: ruleName,\n element: clip(button.outerHTML),\n message:\n '<button> has no accessible name - add text content, aria-label, or a child <img> with alt',\n fix: injectAttr(button.outerHTML, 'aria-label', '[Action description]')\n })\n }\n })\n\n return { ruleName, issues }\n}\n\nexport function checkLinks(root: HTMLElement): RuleResult {\n const ruleName = 'WCAG 2.4.4 Link Purpose'\n const issues: A11yIssue[] = []\n const VAGUE = new Set([\n 'click here',\n 'here',\n 'read more',\n 'more',\n 'link',\n 'click',\n 'learn more',\n 'details',\n 'info'\n ])\n\n root.querySelectorAll('a').forEach((link) => {\n const name = getAccessibleName(link, root)\n const href = link.getAttribute('href')\n const isButtonRole = link.getAttribute('role') === 'button'\n\n if (!name) {\n issues.push({\n type: 'error',\n rule: ruleName,\n element: clip(link.outerHTML),\n message:\n '<a> has no accessible name - add text, aria-label, or a child <img> with alt',\n fix: injectAttr(\n link.outerHTML,\n 'aria-label',\n '[Describe the link destination]'\n )\n })\n return\n }\n\n if (VAGUE.has(name.toLowerCase())) {\n issues.push({\n type: 'warning',\n rule: ruleName,\n element: clip(link.outerHTML),\n message: `<a> has non-descriptive text \"${name}\" - use aria-label to clarify the destination`,\n fix: injectAttr(\n link.outerHTML,\n 'aria-label',\n '[Describe where this link goes]'\n )\n })\n }\n\n if (!href && !isButtonRole) {\n issues.push({\n type: 'warning',\n rule: ruleName,\n element: clip(link.outerHTML),\n message:\n '<a> has no href - use <button> for actions, or add a valid href',\n fix: link.outerHTML.replace(/^<a\\b/, '<a href=\"#\"')\n })\n }\n })\n\n return { ruleName, issues }\n}\n\nexport function checkAriaStates(root: HTMLElement): RuleResult {\n const ruleName = 'WCAG 3.3.1 Error Identification'\n const issues: A11yIssue[] = []\n\n // aria-invalid=\"true\" must have aria-describedby pointing to an existing element\n root.querySelectorAll('[aria-invalid]').forEach((el) => {\n const invalidVal = el.getAttribute('aria-invalid')\n const VALID_INVALID_VALUES = new Set([\n 'false',\n 'true',\n 'grammar',\n 'spelling'\n ])\n\n if (!VALID_INVALID_VALUES.has(invalidVal ?? '')) {\n issues.push({\n type: 'warning',\n rule: 'WCAG 4.1.2 ARIA State Values',\n element: clip(el.outerHTML),\n message: `aria-invalid=\"${invalidVal}\" is not valid - use \"true\", \"false\", \"grammar\", or \"spelling\"`,\n fix: el.outerHTML.replace(\n `aria-invalid=\"${invalidVal}\"`,\n 'aria-invalid=\"true\"'\n )\n })\n return\n }\n\n if (invalidVal === 'true') {\n const describedBy = el.getAttribute('aria-describedby')\n if (!describedBy) {\n issues.push({\n type: 'error',\n rule: ruleName,\n element: clip(el.outerHTML),\n message:\n 'Element with aria-invalid=\"true\" must have aria-describedby pointing to the error message element',\n fix: injectAttr(el.outerHTML, 'aria-describedby', 'error-message-id')\n })\n } else {\n // Verify the describedby target exists\n const broken = findBrokenAriaRefs(el, 'aria-describedby', root)\n if (broken.length > 0) {\n issues.push({\n type: 'error',\n rule: ruleName,\n element: clip(el.outerHTML),\n message: `aria-describedby references non-existent element(s): ${broken.map((id) => `#${id}`).join(', ')}`,\n fix: `Ensure element(s) with id=\"${broken.join('\", \"')}\" exist in the DOM`\n })\n }\n }\n }\n })\n\n // Strictly boolean ARIA attributes (only \"true\" or \"false\" valid)\n const BOOLEAN_ARIA_ATTRS = [\n 'aria-busy',\n 'aria-expanded',\n 'aria-selected',\n 'aria-pressed'\n ]\n for (const attr of BOOLEAN_ARIA_ATTRS) {\n root.querySelectorAll(`[${attr}]`).forEach((el) => {\n const val = el.getAttribute(attr)\n if (val !== 'true' && val !== 'false') {\n issues.push({\n type: 'warning',\n rule: 'WCAG 4.1.2 ARIA State Values',\n element: clip(el.outerHTML),\n message: `${attr} must be \"true\" or \"false\", got \"${val}\"`,\n fix: el.outerHTML.replace(`${attr}=\"${val}\"`, `${attr}=\"true\"`)\n })\n }\n })\n }\n\n // aria-checked also allows \"mixed\" for tri-state checkboxes (WAI-ARIA spec)\n root.querySelectorAll('[aria-checked]').forEach((el) => {\n const val = el.getAttribute('aria-checked')\n if (val !== 'true' && val !== 'false' && val !== 'mixed') {\n issues.push({\n type: 'warning',\n rule: 'WCAG 4.1.2 ARIA State Values',\n element: clip(el.outerHTML),\n message: `aria-checked must be \"true\", \"false\", or \"mixed\" (for tri-state), got \"${val}\"`,\n fix: el.outerHTML.replace(\n `aria-checked=\"${val}\"`,\n 'aria-checked=\"false\"'\n )\n })\n }\n })\n\n // aria-live with invalid value\n const VALID_ARIA_LIVE = new Set(['off', 'polite', 'assertive'])\n root.querySelectorAll('[aria-live]').forEach((el) => {\n const val = el.getAttribute('aria-live') ?? ''\n if (!VALID_ARIA_LIVE.has(val)) {\n issues.push({\n type: 'warning',\n rule: 'WCAG 4.1.2 ARIA State Values',\n element: clip(el.outerHTML),\n message: `aria-live=\"${val}\" is not valid - use \"off\", \"polite\", or \"assertive\"`,\n fix: el.outerHTML.replace(`aria-live=\"${val}\"`, 'aria-live=\"polite\"')\n })\n }\n })\n\n return { ruleName, issues }\n}\n\nexport function checkDuplicateIds(root: HTMLElement): RuleResult {\n const ruleName = 'WCAG 4.1.1 Parsing'\n const issues: A11yIssue[] = []\n const seen = new Map<string, number>()\n\n root.querySelectorAll('[id]').forEach((el) => {\n const id = el.getAttribute('id')\n\n // Empty id is invalid HTML and breaks all ARIA references\n if (id !== undefined && id.trim() === '') {\n issues.push({\n type: 'error',\n rule: ruleName,\n element: clip(el.outerHTML),\n message: 'id=\"\" is an empty ID - IDs must have a non-empty value',\n fix: el.outerHTML.replace('id=\"\"', 'id=\"[unique-id]\"')\n })\n return\n }\n\n if (id) seen.set(id, (seen.get(id) ?? 0) + 1)\n })\n\n seen.forEach((count, id) => {\n if (count > 1) {\n issues.push({\n type: 'error',\n rule: ruleName,\n element: `id=\"${id}\"`,\n message: `id=\"${id}\" is used ${count} times - IDs must be unique within a document`,\n fix: `Keep one element with id=\"${id}\" and rename all duplicates to unique IDs`\n })\n }\n })\n\n return { ruleName, issues }\n}\n\nexport function checkTabIndex(root: HTMLElement): RuleResult {\n const ruleName = 'WCAG 2.1.1 Keyboard'\n const issues: A11yIssue[] = []\n\n root.querySelectorAll('[tabindex]').forEach((el) => {\n const raw = el.getAttribute('tabindex') ?? ''\n const val = parseInt(raw, 10)\n\n if (isNaN(val)) {\n issues.push({\n type: 'warning',\n rule: ruleName,\n element: clip(el.outerHTML),\n message: `tabindex=\"${raw}\" is not a valid integer`,\n fix: el.outerHTML.replace(`tabindex=\"${raw}\"`, 'tabindex=\"0\"')\n })\n return\n }\n\n if (val > 0) {\n issues.push({\n type: 'warning',\n rule: ruleName,\n element: clip(el.outerHTML),\n message: `tabindex=\"${val}\" disrupts natural tab order - use tabindex=\"0\" or rely on DOM order`,\n fix: el.outerHTML.replace(`tabindex=\"${val}\"`, 'tabindex=\"0\"')\n })\n }\n })\n\n return { ruleName, issues }\n}\n\nexport function checkHeadings(root: HTMLElement): RuleResult {\n const ruleName = 'WCAG 2.4.6 Heading Hierarchy'\n const issues: A11yIssue[] = []\n const headings = root.querySelectorAll('h1, h2, h3, h4, h5, h6')\n\n let lastLevel = 0\n let h1Count = 0\n\n headings.forEach((h) => {\n const tag = h.tagName.toLowerCase()\n const level = parseInt(h.tagName.slice(1), 10)\n\n if (!h.text.trim()) {\n issues.push({\n type: 'error',\n rule: ruleName,\n element: clip(h.outerHTML),\n message: `<${tag}> is empty - headings must have descriptive text`,\n fix: `<${tag}>[Heading text]</${tag}>`\n })\n }\n\n if (level === 1) h1Count++\n\n if (lastLevel > 0 && level > lastLevel + 1) {\n issues.push({\n type: 'warning',\n rule: ruleName,\n element: clip(h.outerHTML),\n message: `Heading skips from h${lastLevel} to h${level} - use h${lastLevel + 1} to maintain document outline`,\n fix: `<h${lastLevel + 1}>${h.text.trim()}</h${lastLevel + 1}>`\n })\n }\n\n lastLevel = level\n })\n\n if (h1Count > 1) {\n issues.push({\n type: 'warning',\n rule: ruleName,\n element: 'h1',\n message: `${h1Count} <h1> elements found - a page should have exactly one <h1>`,\n fix: 'Demote additional <h1> elements to <h2> or lower'\n })\n }\n\n return { ruleName, issues }\n}\n\nexport function checkTables(root: HTMLElement): RuleResult {\n const ruleName = 'WCAG 1.3.1 Table Structure'\n const issues: A11yIssue[] = []\n\n root.querySelectorAll('table').forEach((table) => {\n // Layout/presentational tables do not need captions or headers\n const role = table.getAttribute('role')\n if (role === 'presentation' || role === 'none') return\n\n const caption = table.querySelector('caption')\n const ariaLabel = table.getAttribute('aria-label')\n const ariaLabelledBy = table.getAttribute('aria-labelledby')\n\n if (!caption && !ariaLabel && !ariaLabelledBy) {\n issues.push({\n type: 'warning',\n rule: ruleName,\n element: '<table>',\n message:\n '<table> has no caption, aria-label, or aria-labelledby - screen readers cannot identify its purpose',\n fix: injectAttr('<table>', 'aria-label', '[Describe the table]')\n })\n }\n\n // Empty caption is as bad as no caption\n if (caption && !caption.text.trim()) {\n issues.push({\n type: 'warning',\n rule: ruleName,\n element: clip(caption.outerHTML),\n message:\n '<caption> is empty - provide a meaningful description of the table',\n fix: caption.outerHTML.replace(\n '</caption>',\n '[Table description]</caption>'\n )\n })\n }\n\n table.querySelectorAll('th').forEach((th) => {\n if (!th.getAttribute('scope')) {\n issues.push({\n type: 'warning',\n rule: ruleName,\n element: clip(th.outerHTML),\n message:\n '<th> is missing the scope attribute - use scope=\"col\" for column headers or scope=\"row\" for row headers',\n fix: injectAttr(th.outerHTML, 'scope', 'col')\n })\n }\n })\n })\n\n return { ruleName, issues }\n}\n\nexport function checkDialogs(root: HTMLElement): RuleResult {\n const ruleName = 'WCAG 4.1.2 Dialog Accessibility'\n const issues: A11yIssue[] = []\n\n root.querySelectorAll('dialog').forEach((dialog) => {\n const id = dialog.getAttribute('id')\n const ariaLabel = dialog.getAttribute('aria-label')\n const ariaLabelledBy = dialog.getAttribute('aria-labelledby')\n\n if (!id) {\n issues.push({\n type: 'warning',\n rule: ruleName,\n element: '<dialog>',\n message:\n '<dialog> has no id - required by the ignix-lite button[onclick=\"dialogId.showModal()\"] pattern',\n fix: injectAttr('<dialog>', 'id', 'dialog-id')\n })\n }\n\n if (!ariaLabel && !ariaLabelledBy) {\n issues.push({\n type: 'warning',\n rule: ruleName,\n element: '<dialog>',\n message:\n '<dialog> has no accessible name - add aria-labelledby pointing to a heading inside, or aria-label',\n fix: id\n ? `<dialog id=\"${id}\" aria-labelledby=\"dialog-title\">...</dialog>`\n : `<dialog aria-label=\"[Dialog purpose]\">...</dialog>`\n })\n } else if (ariaLabelledBy) {\n // Verify the labelledby target exists\n const broken = findBrokenAriaRefs(dialog, 'aria-labelledby', root)\n if (broken.length > 0) {\n issues.push({\n type: 'error',\n rule: ruleName,\n element: '<dialog>',\n message: `dialog aria-labelledby references non-existent element(s): ${broken.map((id) => `#${id}`).join(', ')}`,\n fix: `Ensure element(s) with id=\"${broken.join('\", \"')}\" exist inside the dialog`\n })\n }\n }\n })\n\n return { ruleName, issues }\n}\n\nexport function checkRoles(root: HTMLElement): RuleResult {\n const ruleName = 'WCAG 4.1.2 ARIA Role Requirements'\n const issues: A11yIssue[] = []\n const NATIVELY_INTERACTIVE = new Set([\n 'a',\n 'button',\n 'input',\n 'select',\n 'textarea',\n 'details',\n 'summary'\n ])\n\n root.querySelectorAll('[role=\"button\"]').forEach((el) => {\n const tag = el.tagName.toLowerCase()\n const tabIndex = el.getAttribute('tabindex')\n if (!NATIVELY_INTERACTIVE.has(tag) && tabIndex !== '0') {\n issues.push({\n type: 'error',\n rule: ruleName,\n element: clip(el.outerHTML),\n message:\n 'Element with role=\"button\" must have tabindex=\"0\" to be keyboard-accessible',\n fix: injectAttr(el.outerHTML, 'tabindex', '0')\n })\n }\n })\n\n // Roles requiring aria-checked\n for (const role of [\n 'checkbox',\n 'radio',\n 'menuitemcheckbox',\n 'menuitemradio'\n ] as const) {\n root.querySelectorAll(`[role=\"${role}\"]`).forEach((el) => {\n if (!el.getAttribute('aria-checked')) {\n issues.push({\n type: 'error',\n rule: ruleName,\n element: clip(el.outerHTML),\n message: `role=\"${role}\" requires aria-checked attribute (values: \"true\", \"false\"${role === 'checkbox' ? ', \"mixed\"' : ''})`,\n fix: injectAttr(el.outerHTML, 'aria-checked', 'false')\n })\n }\n })\n }\n\n root.querySelectorAll('[role=\"combobox\"]').forEach((el) => {\n if (!el.getAttribute('aria-expanded')) {\n issues.push({\n type: 'error',\n rule: ruleName,\n element: clip(el.outerHTML),\n message: 'role=\"combobox\" requires aria-expanded attribute',\n fix: injectAttr(el.outerHTML, 'aria-expanded', 'false')\n })\n }\n })\n\n // Roles requiring aria-selected\n for (const role of ['tab', 'option', 'treeitem', 'gridcell'] as const) {\n root.querySelectorAll(`[role=\"${role}\"]`).forEach((el) => {\n if (!el.getAttribute('aria-selected')) {\n issues.push({\n type: 'error',\n rule: ruleName,\n element: clip(el.outerHTML),\n message: `role=\"${role}\" requires aria-selected attribute`,\n fix: injectAttr(el.outerHTML, 'aria-selected', 'false')\n })\n }\n })\n }\n\n root.querySelectorAll('[role=\"slider\"]').forEach((el) => {\n const required = ['aria-valuenow', 'aria-valuemin', 'aria-valuemax']\n const missing = required.filter((attr) => !el.getAttribute(attr))\n if (missing.length > 0) {\n issues.push({\n type: 'error',\n rule: ruleName,\n element: clip(el.outerHTML),\n message: `role=\"slider\" is missing required attributes: ${missing.join(', ')}`,\n fix: 'Add aria-valuenow=\"50\" aria-valuemin=\"0\" aria-valuemax=\"100\" to the element'\n })\n }\n })\n\n root.querySelectorAll('[role=\"progressbar\"]').forEach((el) => {\n if (\n !el.getAttribute('aria-valuenow') &&\n !el.getAttribute('aria-valuetext')\n ) {\n issues.push({\n type: 'warning',\n rule: ruleName,\n element: clip(el.outerHTML),\n message:\n 'role=\"progressbar\" should have aria-valuenow or aria-valuetext to communicate current progress',\n fix: injectAttr(el.outerHTML, 'aria-valuenow', '0')\n })\n }\n })\n\n root.querySelectorAll('[role=\"listbox\"]').forEach((el) => {\n if (!getAccessibleName(el, root)) {\n issues.push({\n type: 'warning',\n rule: ruleName,\n element: clip(el.outerHTML),\n message:\n 'role=\"listbox\" should have an accessible name via aria-label or aria-labelledby',\n fix: injectAttr(\n el.outerHTML,\n 'aria-label',\n '[Describe the list options]'\n )\n })\n }\n })\n\n return { ruleName, issues }\n}\n\nexport function checkAutocomplete(root: HTMLElement): RuleResult {\n const ruleName = 'WCAG 1.3.5 Input Purpose'\n const issues: A11yIssue[] = []\n\n const TYPE_AUTOCOMPLETE: Record<string, string> = {\n email: 'email',\n tel: 'tel',\n url: 'url'\n }\n\n root.querySelectorAll('input').forEach((input) => {\n const type = (input.getAttribute('type') ?? 'text').toLowerCase()\n const expected = TYPE_AUTOCOMPLETE[type]\n\n if (expected && !input.getAttribute('autocomplete')) {\n issues.push({\n type: 'warning',\n rule: ruleName,\n element: clip(input.outerHTML),\n message: `<input type=\"${type}\"> should have autocomplete=\"${expected}\" to assist users with autofill`,\n fix: injectAttr(input.outerHTML, 'autocomplete', expected)\n })\n }\n\n if (type === 'password' && !input.getAttribute('autocomplete')) {\n issues.push({\n type: 'warning',\n rule: ruleName,\n element: clip(input.outerHTML),\n message:\n '<input type=\"password\"> should have autocomplete=\"current-password\" or autocomplete=\"new-password\"',\n fix: injectAttr(input.outerHTML, 'autocomplete', 'current-password')\n })\n }\n })\n\n return { ruleName, issues }\n}\n\nexport function checkFocusStyle(root: HTMLElement): RuleResult {\n const ruleName = 'WCAG 2.4.7 Focus Visible'\n const issues: A11yIssue[] = []\n const KILLS_FOCUS = [\n /outline\\s*:\\s*none/i,\n /outline\\s*:\\s*0(?:px)?/i,\n /outline-width\\s*:\\s*0/i\n ]\n\n root.querySelectorAll('[style]').forEach((el) => {\n const style = el.getAttribute('style') ?? ''\n if (KILLS_FOCUS.some((rx) => rx.test(style))) {\n issues.push({\n type: 'warning',\n rule: ruleName,\n element: clip(el.outerHTML),\n message:\n 'Inline style removes the focus outline - keyboard users cannot see the focus indicator',\n fix: el.outerHTML\n .replace(/outline\\s*:\\s*(none|0(?:px)?)\\s*;?/gi, '')\n .replace(/outline-width\\s*:\\s*0\\s*;?/gi, '')\n })\n }\n })\n\n return { ruleName, issues }\n}\n\nexport function checkLang(root: HTMLElement): RuleResult {\n const ruleName = 'WCAG 3.1.1 Language of Page'\n const issues: A11yIssue[] = []\n\n const htmlEl = root.querySelector('html')\n if (htmlEl && !htmlEl.getAttribute('lang')?.trim()) {\n issues.push({\n type: 'error',\n rule: ruleName,\n element: '<html>',\n message:\n '<html> is missing the lang attribute - screen readers need this to select the correct voice/language',\n fix: '<html lang=\"en\">'\n })\n }\n\n return { ruleName, issues }\n}\n\n\n"],"mappings":";AAAA,SAAS,cAAc;AACvB,SAAS,4BAA4B;AACrC;AAAA,EACE;AAAA,EACA;AAAA,OACK;;;ACLP,SAAS,oBAAoB;AAC7B,OAAO,UAAU;AACjB,SAAS,qBAAqB;;;ACF9B,SAAS,0BAA0B;AAEnC,IAAM,UAAU,mBAAmB,OAAO;AAEnC,SAAS,cAAc,OAAuB;AACnD,SAAO,QAAQ,OAAO,KAAK,EAAE;AAC/B;;;ADAA,IAAM,aAAa,cAAc,YAAY,GAAG;AAChD,IAAM,YAAY,KAAK,QAAQ,UAAU;AAEzC,SAAS,aAAa,MAAwB;AAC5C,QAAM,eAAe,KAAK,QAAQ,WAAW,aAAa,IAAI;AAC9D,QAAM,WAAW,KAAK,MAAM,aAAa,cAAc,MAAM,CAAC;AAC9D,WAAS,SAAS,cAAc,SAAS,KAAK;AAC9C,SAAO;AACT;AAEO,IAAM,YAAsC;AAAA,EACjD,WAAW,aAAa,gBAAgB;AAAA,EACxC,OAAO,aAAa,YAAY;AAAA,EAChC,QAAQ,aAAa,aAAa;AAAA,EAClC,OAAO,aAAa,YAAY;AAAA,EAChC,YAAY,aAAa,iBAAiB;AAAA,EAC1C,QAAQ,aAAa,aAAa;AAAA,EAClC,MAAM,aAAa,WAAW;AAAA,EAC9B,UAAU,aAAa,eAAe;AAAA,EACtC,WAAW,aAAa,gBAAgB;AAAA,EACxC,UAAU,aAAa,eAAe;AAAA,EACtC,QAAQ,aAAa,aAAa;AAAA,EAClC,SAAS,aAAa,cAAc;AAAA,EACpC,UAAU,aAAa,eAAe;AAAA,EACtC,MAAM,aAAa,WAAW;AAAA,EAC9B,MAAM,aAAa,WAAW;AAAA,EAC9B,OAAO,aAAa,YAAY;AAAA,EAChC,OAAO,aAAa,YAAY;AAAA,EAChC,YAAY,aAAa,iBAAiB;AAAA,EAC1C,UAAU,aAAa,eAAe;AAAA,EACtC,OAAO,aAAa,YAAY;AAAA,EAChC,QAAQ,aAAa,aAAa;AAAA,EAClC,UAAU,aAAa,eAAe;AAAA,EACtC,KAAK,aAAa,UAAU;AAAA,EAC5B,OAAO,aAAa,YAAY;AAAA,EAChC,UAAU,aAAa,eAAe;AAAA,EACtC,OAAO,aAAa,YAAY;AAAA,EAChC,SAAS,aAAa,cAAc;AACtC;;;AExCO,SAAS,iBAA8B;AAC5C,QAAM,aAAa,OAAO,KAAK,SAAS,EAAE,KAAK;AAE/C,SAAO;AAAA,IACL,SAAS;AAAA,MACP;AAAA,QACE,MAAM;AAAA,QACN,MAAM,KAAK,UAAU;AAAA,UACnB;AAAA,UACA,OAAO,WAAW;AAAA,UAClB,aAAa,WAAW;AAAA,QAC1B,CAAC;AAAA,MACH;AAAA,IACF;AAAA,EACF;AACF;;;ACnBA,SAAS,SAAS;AAIlB,IAAM,SAAS,EAAE,OAAO;AAAA,EACtB,MAAM,EAAE,OAAO;AACjB,CAAC;AAEM,SAAS,YAAY,MAA4B;AACtD,QAAM,SAAS,OAAO,UAAU,IAAI;AAEpC,MAAI,CAAC,OAAO,SAAS;AACnB,WAAO;AAAA,MACL,SAAS;AAAA,QACP;AAAA,UACE,MAAM;AAAA,UACN,MAAM,KAAK,UAAU;AAAA,YACnB,OAAO;AAAA,YACP,YAAY;AAAA,YACZ,aAAa;AAAA,UACf,CAAC;AAAA,QACH;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,QAAM,EAAE,KAAK,IAAI,OAAO;AAExB,QAAM,WAAW,UAAU,IAAI;AAE/B,MAAI,CAAC,UAAU;AACb,WAAO;AAAA,MACL,SAAS;AAAA,QACP;AAAA,UACE,MAAM;AAAA,UAEN,MAAM,KAAK,UAAU;AAAA,YACnB,OAAO,sBAAsB,IAAI;AAAA,YACjC,YAAY;AAAA,YACZ,aAAa;AAAA,UACf,CAAC;AAAA,QACH;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AAAA,IACL,SAAS;AAAA,MACP;AAAA,QACE,MAAM;AAAA,QACN,MAAM,KAAK,UAAU,QAAQ;AAAA,MAC/B;AAAA,IACF;AAAA,EACF;AACF;;;ACtDA,SAAS,KAAAA,UAAS;AAIlB,IAAMC,UAASC,GAAE,OAAO;AAAA,EACtB,MAAMA,GAAE,OAAO;AACjB,CAAC;AAEM,SAAS,SAAS,MAA4B;AACnD,QAAM,SAASD,QAAO,UAAU,IAAI;AAEpC,MAAI,CAAC,OAAO,SAAS;AACnB,WAAO;AAAA,MACL,SAAS;AAAA,QACP;AAAA,UACE,MAAM;AAAA,UAEN,MAAM,KAAK,UAAU;AAAA,YACnB,OAAO;AAAA,YAEP,YAAY;AAAA,YAEZ,aAAa;AAAA,UACf,CAAC;AAAA,QACH;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,QAAM,EAAE,KAAK,IAAI,OAAO;AAExB,QAAM,WAAW,UAAU,IAAI;AAE/B,MAAI,CAAC,UAAU;AACb,WAAO;AAAA,MACL,SAAS;AAAA,QACP;AAAA,UACE,MAAM;AAAA,UAEN,MAAM,KAAK,UAAU;AAAA,YACnB,OAAO,sBAAsB,IAAI;AAAA,YACjC,YAAY;AAAA,YACZ,aAAa;AAAA,UACf,CAAC;AAAA,QACH;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AAAA,IACL,SAAS;AAAA,MACP;AAAA,QACE,MAAM;AAAA,QAEN,MAAM,KAAK,UAAU;AAAA,UACnB,WAAW,SAAS;AAAA,UACpB,OAAO,SAAS;AAAA,UAChB,QAAQ,SAAS;AAAA,UACjB,aAAa;AAAA,QACf,CAAC;AAAA,MACH;AAAA,IACF;AAAA,EACF;AACF;;;AC/DA,SAAS,aAAa;AAyBf,SAAS,SAAS,MAA2B;AAClD,QAAM,OAAO,MAAM,IAAI;AAEvB,QAAM,SAA4B,CAAC;AAEnC,QAAM,WAAW,KAAK,iBAAiB,GAAG;AAG1C,QAAM,kBAAkB;AAAA,IACtB;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAEA,QAAM,mBAAmB,oBAAI,IAAI;AAAA,IAC/B;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IAEA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IAEA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IAEA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IAEA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IAEA;AAAA,IAEA;AAAA,IACA;AAAA,IAEA;AAAA,IAEA;AAAA,IAEA;AAAA,IAEA;AAAA,IACA;AAAA,IAEA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IAEA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,CAAC;AAED,aAAW,MAAM,UAAU;AACzB,UAAM,MAAM,GAAG,QAAQ,YAAY;AAEnC,UAAM,QAAQ,GAAG;AAGjB,QAAI,cAAc,IAAI,WAAW,KAAK,IAAI,IAAI,MAAM,CAAC,IAAI;AAGzD,QAAI,QAAQ,WAAW,MAAM,OAAO,YAAY;AAC9C,oBAAc;AAAA,IAChB;AAGA,QAAI,QAAQ,OAAO;AACjB,oBAAc;AAAA,IAChB;AAGA,QAAI,QAAQ,aAAa,GAAG,cAAc,QAAQ,GAAG;AACnD,oBAAc;AAAA,IAChB;AAEA,QAAI,WAAW,UAAU,WAAW;AAGpC,QAAI,CAAC,UAAU;AACb,UAAI,QAAQ,QAAQ;AAClB,mBAAW,UAAU;AAAA,MACvB;AAEA,UAAI,QAAQ,UAAU,MAAM,SAAS,UAAU;AAC7C,mBAAW,UAAU;AAAA,MACvB;AAAA,IACF;AAGA,QAAI,CAAC,YAAY,CAAC,gBAAgB,SAAS,GAAG,GAAG;AAC/C,aAAO,KAAK;AAAA,QACV,SAAS;AAAA,QACT,MAAM;AAAA,QACN,MAAM;AAAA,QACN,SAAS,IAAI,GAAG;AAAA,QAChB,KAAK;AAAA,QACL,YAAY;AAAA,MACd,CAAC;AAED;AAAA,IACF;AAGA,QAAI,CAAC,SAAU;AAEf,UAAM,cAAc,IAAI,WAAW,KAAK,IAAI,MAAM,SAAS,WAAW;AAGtE,QAAI,SAAS,kBAAkB;AAC7B,YAAM,SAAS,GAAG;AAIlB,UACE,CAAC,UACD,OAAO,SAAS,YAAY,MAAM,SAAS,kBAC3C;AACA,eAAO,KAAK;AAAA,UACV,SAAS;AAAA,UACT,MAAM;AAAA,UACN,MAAM;AAAA,UACN,SAAS,IAAI,GAAG,qBAAqB,SAAS,gBAAgB;AAAA,UAC9D,KAAK,IAAI,SAAS,gBAAgB,KAAK,WAAW,MAAM,WAAW,MAAM,SAAS,gBAAgB;AAAA,UAClG,YAAY;AAAA,QACd,CAAC;AAAA,MACH;AAAA,IACF;AAGA,QACE,QAAQ,UACR,SAAS,cAAc,WACvB,MAAM,SAAS,UACf;AACA,aAAO,KAAK;AAAA,QACV,SAAS;AAAA,QAET,MAAM;AAAA,QACN,MAAM;AAAA,QACN,SAAS;AAAA,QACT,KAAK,uBAAuB,GAAG,SAAS;AAAA,QACxC,YAAY;AAAA,MACd,CAAC;AAAA,IACH;AAGA,QAAI,WAAW,OAAO;AACpB,aAAO,KAAK;AAAA,QACV,SAAS;AAAA,QACT,MAAM;AAAA,QACN,MAAM;AAAA,QACN,SAAS;AAAA,QACT,KAAK,IAAI,WAAW,IAAI,GAAG,SAAS,KAAK,WAAW;AAAA,QACpD,YAAY;AAAA,MACd,CAAC;AAAA,IACH;AAGA,QAAI,OAAO,KAAK,KAAK,EAAE,SAAS,GAAG;AACjC,aAAO,KAAK;AAAA,QACV,SAAS;AAAA,QACT,MAAM;AAAA,QACN,MAAM;AAAA,QACN,SAAS;AAAA,QACT,KAAK,IAAI,WAAW,MAAM,WAAW;AAAA,QACrC,YAAY;AAAA,MACd,CAAC;AAAA,IACH;AAGA,eAAW,QAAQ,OAAO,KAAK,KAAK,GAAG;AACrC,UAAI,KAAK,WAAW,IAAI,GAAG;AACzB,eAAO,KAAK;AAAA,UACV,SAAS;AAAA,UACT,MAAM;AAAA,UACN,MAAM;AAAA,UACN,SAAS;AAAA,UACT,KAAK,IAAI,WAAW,MAAM,WAAW;AAAA,UACrC,YAAY;AAAA,QACd,CAAC;AAAA,MACH;AAAA,IACF;AAGA,eAAW,QAAQ,OAAO,KAAK,KAAK,GAAG;AACrC,UAAI,SAAS,iBAAiB,SAAS,IAAI,GAAG;AAC5C,eAAO,KAAK;AAAA,UACV,SAAS;AAAA,UACT,MAAM;AAAA,UACN,MAAM;AAAA,UACN,SAAS,IAAI,IAAI;AAAA,UACjB,KAAK,IAAI,WAAW,MAAM,WAAW;AAAA,UACrC,YAAY;AAAA,QACd,CAAC;AAED;AAAA,MACF;AAEA,UAAI,CAAC,SAAS,QAAQ,IAAI,KAAK,CAAC,iBAAiB,IAAI,IAAI,GAAG;AAC1D,eAAO,KAAK;AAAA,UACV,SAAS;AAAA,UACT,MAAM;AAAA,UACN,MAAM;AAAA,UACN,SAAS,IAAI,IAAI;AAAA,UACjB,KAAK,IAAI,WAAW,MAAM,WAAW;AAAA,UACrC,YAAY;AAAA,QACd,CAAC;AAAA,MACH;AAAA,IACF;AAGA,eAAW,QAAQ,OAAO,KAAK,KAAK,GAAG;AACrC,YAAM,MAAM,SAAS,QAAQ,IAAI;AAEjC,UAAI,KAAK,QAAQ;AACf,cAAM,QAAQ,MAAM,IAAI;AAExB,YAAI,CAAC,IAAI,OAAO,SAAS,KAAK,GAAG;AAC/B,iBAAO,KAAK;AAAA,YACV,SAAS;AAAA,YACT,MAAM;AAAA,YACN,MAAM;AAAA,YACN,SAAS,IAAI,KAAK;AAAA,YAClB,cAAc,IAAI;AAAA,YAClB,KAAK,IAAI,WAAW,IAAI,IAAI,KAAK,IAAI,OAAO,CAAC,CAAC,OAAO,WAAW;AAAA,YAChE,YAAY;AAAA,UACd,CAAC;AAAA,QACH;AAAA,MACF;AAAA,IACF;AAGA,eAAW,OAAO,SAAS,kBAAkB,CAAC,GAAG;AAC/C,UAAI,EAAE,OAAO,QAAQ;AACnB,eAAO,KAAK;AAAA,UACV,SAAS;AAAA,UACT,MAAM;AAAA,UACN,MAAM;AAAA,UACN,SAAS,WAAW,GAAG;AAAA,UACvB,KAAK,IAAI,WAAW,IAAI,GAAG,SAAS,WAAW;AAAA,UAC/C,YAAY;AAAA,QACd,CAAC;AAAA,MACH;AAAA,IACF;AAGA,UAAM,QAAQ,SAAS,SAAS,CAAC;AAEjC,eAAW,CAAC,UAAU,OAAO,KAAK,OAAO,QAAQ,KAAK,GAAG;AACvD,YAAM,QAAQ,GAAG,cAAc,UAAU,QAAQ,IAAI;AAErD,UAAI,QAAQ,YAAY,CAAC,OAAO;AAC9B,eAAO,KAAK;AAAA,UACV,SAAS;AAAA,UACT,MAAM;AAAA,UACN,MAAM;AAAA,UACN,SAAS,gBAAgB,QAAQ;AAAA,UACjC,KAAK,IAAI,WAAW,gBAAgB,QAAQ,cAAc,WAAW;AAAA,UACrE,YAAY;AAAA,QACd,CAAC;AAAA,MACH;AAEA,UAAI,SAAS,QAAQ,SAAS;AAC5B,cAAM,WAAW,MAAM,QAAQ,YAAY;AAE3C,YAAI,CAAC,QAAQ,QAAQ,SAAS,QAAQ,GAAG;AACvC,iBAAO,KAAK;AAAA,YACV,SAAS;AAAA,YACT,MAAM;AAAA,YACN,MAAM;AAAA,YACN,SAAS,GAAG,QAAQ,qBAAqB,QAAQ;AAAA,YACjD,cAAc,QAAQ;AAAA,YACtB,KAAK,IAAI,QAAQ,QAAQ,CAAC,CAAC,UAAU,QAAQ,OAAO,QAAQ,QAAQ,CAAC,CAAC;AAAA,YACtE,YAAY;AAAA,UACd,CAAC;AAAA,QACH;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,QAAM,QAAQ,OAAO,WAAW;AAChC,QAAM,QAAQ,QAAQ,MAAM,KAAK,IAAI,GAAG,MAAM,OAAO,SAAS,EAAE;AAEhE,SAAO;AAAA,IACL,SAAS;AAAA,MACP;AAAA,QACE,MAAM;AAAA,QAEN,MAAM,KAAK,UAAU;AAAA,UACnB;AAAA,UACA;AAAA,UACA;AAAA,UACA,aAAa;AAAA,QACf,CAAC;AAAA,MACH;AAAA,IACF;AAAA,EACF;AACF;;;AC9WA,OAAOE,WAAU;AACjB,SAAS,gBAAAC,eAAc,kBAAkB;AACzC,SAAS,iBAAAC,sBAAqB;;;ACF9B,IAAM,aAAa;AAEZ,SAAS,UAAU,MAAwB;AAChD,QAAM,SAAS,IAAI,MAAM,UAAU,EAAE,KAAK,CAAC;AAC3C,QAAM,QAAQ,KACX,YAAY,EACZ,QAAQ,gBAAgB,GAAG,EAC3B,MAAM,KAAK,EACX,OAAO,OAAO;AACjB,QAAM,QAAQ,CAAC,SAAS;AACtB,QAAI,OAAO;AACX,aAAS,IAAI,GAAG,IAAI,KAAK,QAAQ,KAAK;AACpC,cAAQ,OAAO,KAAK,KAAK,WAAW,CAAC,KAAK;AAAA,IAC5C;AACA,WAAO,IAAI,KAAK;AAAA,EAClB,CAAC;AACD,SAAO;AACT;;;ACjBO,SAAS,iBAAiB,GAAa,GAAqB;AACjE,MAAI,MAAM;AACV,MAAI,OAAO;AACX,MAAI,OAAO;AAEX,WAAS,IAAI,GAAG,IAAI,EAAE,QAAQ,KAAK;AACjC,WAAO,EAAE,CAAC,IAAI,EAAE,CAAC;AACjB,YAAQ,EAAE,CAAC,IAAI,EAAE,CAAC;AAClB,YAAQ,EAAE,CAAC,IAAI,EAAE,CAAC;AAAA,EACpB;AAEA,MAAI,SAAS,KAAK,SAAS,EAAG,QAAO;AAErC,SAAO,OAAO,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,IAAI;AAChD;;;AFDA,IAAMC,cAAaC,eAAc,YAAY,GAAG;AAChD,IAAMC,aAAYC,MAAK,QAAQH,WAAU;AAEzC,IAAI,SAA6B;AAEjC,SAAS,YAAyB;AAChC,MAAI,OAAQ,QAAO;AACnB,QAAM,YAAYG,MAAK,QAAQD,YAAW,8BAA8B;AACxE,MAAI,CAAC,WAAW,SAAS,GAAG;AAC1B,YAAQ;AAAA,MACN,uDAAuD,SAAS;AAAA,IAClE;AACA,aAAS,CAAC;AACV,WAAO;AAAA,EACT;AACA,MAAI;AACF,aAAS,KAAK,MAAME,cAAa,WAAW,MAAM,CAAC;AAAA,EACrD,SAAS,KAAK;AACZ,YAAQ,MAAM,4CAA4C,SAAS,KAAK,GAAG;AAC3E,aAAS,CAAC;AAAA,EACZ;AACA,SAAO;AACT;AAEO,SAAS,YAAY,aAAqB;AAC/C,QAAM,QAAQ,UAAU;AACxB,QAAM,iBAAiB,UAAU,WAAW;AAE5C,QAAM,QAAQ,YAAY,YAAY,EAAE,MAAM,KAAK;AACnD,QAAM,SAAS,MACZ,IAAI,CAAC,SAAS;AACb,UAAM,aAAa,iBAAiB,gBAAgB,KAAK,SAAS;AAClE,QAAI,QAAQ;AACZ,UAAM,aAAa,KAAK,WAAW,YAAY;AAE/C,UAAM,QAAQ,CAAC,SAAS;AACtB,UAAI,KAAK,KAAK,YAAY,MAAM,MAAM;AACpC,iBAAS;AAAA,MACX,WAAW,KAAK,KAAK,YAAY,EAAE,SAAS,IAAI,GAAG;AACjD,iBAAS;AAAA,MACX;AACA,UAAI,WAAW,SAAS,IAAI,GAAG;AAC7B,iBAAS;AAAA,MACX;AAAA,IACF,CAAC;AACD,WAAO;AAAA,MACL,GAAG;AAAA,MACH,OAAO,aAAa;AAAA,IACtB;AAAA,EACF,CAAC,EACA,KAAK,CAAC,GAAG,MAAM,EAAE,QAAQ,EAAE,KAAK;AACnC,SAAO,OAAO,MAAM,GAAG,CAAC;AAC1B;;;AGjEA,SAAS,gBAAAC,eAAc,cAAAC,mBAAkB;AACzC,OAAOC,WAAU;AACjB,SAAS,iBAAAC,sBAAqB;;;ACFvB,IAAM,aAAa,oBAAI,IAAI;AAAA,EAChC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,CAAC;AAEM,SAAS,SAAS,MAAwB;AAC/C,SAAO,KACJ,YAAY,EACZ,QAAQ,iBAAiB,GAAG,EAC5B,MAAM,QAAQ,EACd,OAAO,CAAC,MAAM,EAAE,SAAS,KAAK,CAAC,WAAW,IAAI,CAAC,CAAC;AACrD;AAEO,SAAS,aAAa,IAAY,IAAoB;AAC3D,QAAM,QAAkB,CAAC;AACzB,WAAS,IAAI,GAAG,KAAK,GAAG,QAAQ,KAAK;AACnC,QAAI,YAAY;AAChB,aAAS,IAAI,GAAG,KAAK,GAAG,QAAQ,KAAK;AACnC,UAAI,MAAM,GAAG;AACX,cAAM,CAAC,IAAI;AAAA,MACb,OAAO;AACL,YAAI,IAAI,GAAG;AACT,cAAI,WAAW,MAAM,IAAI,CAAC;AAC1B,cAAI,GAAG,OAAO,IAAI,CAAC,MAAM,GAAG,OAAO,IAAI,CAAC,GAAG;AACzC,uBAAW,KAAK,IAAI,KAAK,IAAI,UAAU,SAAS,GAAG,MAAM,CAAC,CAAC,IAAI;AAAA,UACjE;AACA,gBAAM,IAAI,CAAC,IAAI;AACf,sBAAY;AAAA,QACd;AAAA,MACF;AAAA,IACF;AACA,QAAI,IAAI,EAAG,OAAM,GAAG,MAAM,IAAI;AAAA,EAChC;AACA,SAAO,MAAM,GAAG,MAAM;AACxB;AAEO,SAAS,UAAU,IAAY,IAAqB;AACzD,MAAI,GAAG,SAAS,KAAK,GAAG,SAAS,EAAG,QAAO,OAAO;AAElD,QAAM,cAAc,GAAG,UAAU,KAAK,GAAG,UAAU,IAAI,IAAI;AAC3D,SAAO,aAAa,IAAI,EAAE,KAAK;AACjC;;;AD3CA,SAAS,aAAa,KAA4B;AAChD,QAAM,UAAyB,CAAC;AAGhC,QAAM,cAAc,IAAI,QAAQ,UAAU;AAC1C,MAAI,gBAAgB,GAAI,QAAO;AAE/B,QAAM,QAAQ,IAAI,MAAM,WAAW;AACnC,QAAM,QAAQ,MAAM,MAAM,OAAO;AAEjC,MAAI,kBAAkB;AACtB,MAAI,gBAA+B;AAEnC,aAAW,YAAY,OAAO;AAC5B,UAAM,OAAO,SAAS,KAAK;AAG3B,QAAI,KAAK,WAAW,KAAK,KAAK,KAAK,SAAS,KAAK,GAAG;AAClD,wBAAkB,KACf,QAAQ,UAAU,EAAE,EACpB,QAAQ,UAAU,EAAE,EACpB,KAAK;AACR,sBAAgB;AAChB;AAAA,IACF;AAGA,QAAI,KAAK,WAAW,GAAG,KAAK,KAAK,SAAS,GAAG,EAAG;AAGhD,QAAI,KAAK,WAAW,QAAQ,EAAG;AAG/B,QAAI,SAAS,MAAM,KAAK,WAAW,QAAG,EAAG;AAGzC,QAAI,KAAK,WAAW,IAAI,KAAK,kBAAkB,MAAM;AACnD,YAAMC,SAAQ,KAAK,MAAM,CAAC,EAAE,KAAK;AACjC,cAAQ,KAAK;AAAA,QACX,MAAM;AAAA,QACN,SAAS,SAAS,aAAa;AAAA,QAC/B,OAAAA;AAAA,QACA,UAAU;AAAA,MACZ,CAAC;AACD,sBAAgB;AAChB;AAAA,IACF;AAGA,QAAI,CAAC,KAAK,WAAW,GAAG,GAAG;AACzB,sBAAgB;AAAA,IAClB;AAAA,EACF;AAEA,SAAO;AACT;AAGA,SAAS,cAA6B;AACpC,MAAI;AACF,UAAM,aAAaC,MAAK,QAAQC,eAAc,YAAY,GAAG,CAAC;AAG9D,UAAM,QAAQD,MAAK,QAAQ,YAAY,uBAAuB;AAC9D,UAAME,SAAQF,MAAK,QAAQ,YAAY,oBAAoB;AAC3D,UAAMG,SAAQH,MAAK,QAAQ,YAAY,0BAA0B;AAEjE,QAAI,UAAU;AACd,QAAII,YAAW,KAAK,GAAG;AACrB,gBAAU;AAAA,IACZ,WAAWA,YAAWF,MAAK,GAAG;AAC5B,gBAAUA;AAAA,IACZ,WAAWE,YAAWD,MAAK,GAAG;AAC5B,gBAAUA;AAAA,IACZ,OAAO;AACL,gBAAUH,MAAK,QAAQ,QAAQ,IAAI,GAAG,oBAAoB;AAAA,IAC5D;AAEA,UAAM,MAAMK,cAAa,SAAS,MAAM;AACxC,WAAO,aAAa,GAAG;AAAA,EACzB,QAAQ;AACN,WAAO,CAAC;AAAA,EACV;AACF;AAGA,IAAI,SAA+B;AAE5B,SAAS,mBAAkC;AAChD,MAAI,CAAC,QAAQ;AACX,aAAS,YAAY;AAAA,EACvB;AACA,SAAO;AACT;AAWO,SAAS,WACd,OACA,YACa;AACb,MAAI,QAAQ;AACZ,QAAM,aAAa,IAAI,IAAI,MAAM,OAAO;AACxC,MAAI,eAAe;AAEnB,aAAW,MAAM,YAAY;AAC3B,QAAI,UAAU;AAEd,QAAI,WAAW,IAAI,EAAE,GAAG;AACtB,eAAS;AACT,gBAAU;AAAA,IACZ,OAAO;AAEL,iBAAW,MAAM,YAAY;AAC3B,YAAI,UAAU,IAAI,EAAE,GAAG;AACrB,mBAAS;AACT,oBAAU;AACV;AAAA,QACF;AAAA,MACF;AAEA,UAAI,CAAC,SAAS;AACZ,mBAAW,MAAM,YAAY;AAC3B,cAAI,GAAG,SAAS,EAAE,KAAK,GAAG,SAAS,EAAE,GAAG;AACtC,qBAAS;AACT,sBAAU;AACV;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAAA,IACF;AACA,QAAI,SAAS;AACX;AAAA,IACF;AAAA,EACF;AAGA,QAAM,WAAW,SAAS,MAAM,QAAQ;AACxC,aAAW,MAAM,YAAY;AAC3B,QAAI,SAAS,SAAS,EAAE,GAAG;AACzB,eAAS;AAAA,IACX,OAAO;AACL,iBAAW,MAAM,UAAU;AACzB,YAAI,UAAU,IAAI,EAAE,GAAG;AACrB,mBAAS;AACT;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAGA,QAAM,UACJ,MAAM,QAAQ,SAAS,IAAI,eAAe,MAAM,QAAQ,SAAS;AAEnE,SAAO,EAAE,OAAO,QAAQ;AAC1B;;;AEzLA,OAAO,WAAW;AAGX,SAAS,YAAY,UAA0B;AACpD,MAAI;AACF,WAAO,MAAM,QAAQ;AAAA,EACvB,QAAQ;AACN,WAAO,gBAAgB,QAAQ;AAAA,EACjC;AACF;AAGO,IAAM,uBAA+C;AAAA;AAAA,EAE1D,QAAQ;AAAA,EACR,OAAO;AAAA,EACP,UAAU;AAAA,EACV,QAAQ;AAAA,EACR,MAAM;AAAA,EACN,QAAQ;AAAA,EACR,SAAS;AAAA,EACT,SAAS;AAAA,EACT,UAAU;AAAA,EACV,OAAO;AAAA,EACP,OAAO;AAAA,EACP,MAAM;AAAA,EACN,KAAK;AAAA,EACL,SAAS;AAAA,EACT,KAAK;AAAA,EACL,OAAO;AAAA,EACP,KAAK;AAAA,EACL,MAAM;AAAA,EACN,IAAI;AAAA,EACJ,OAAO;AAAA;AAAA;AAAA,EAEP,WAAW;AAAA,EACX,eAAe;AAAA,EACf,eAAe;AAAA,EACf,cAAc;AAAA,EACd,YAAY;AACd;AAGO,IAAM,mBAAmB;AAOzB,SAAS,kBAAkB,UAA4B;AAC5D,QAAM,QAAQ,oBAAI,IAAY;AAG9B,MAAI,iBAAiB,KAAK,QAAQ,GAAG;AACnC,UAAM,IAAI,UAAU;AAAA,EACtB;AAGA,MAAI,yBAAyB,KAAK,QAAQ,GAAG;AAC3C,UAAM,IAAI,YAAY;AAAA,EACxB,WAAW,UAAU,KAAK,QAAQ,GAAG;AACnC,UAAM,IAAI,YAAY;AAAA,EACxB;AAGA,MAAI,8BAA8B,KAAK,QAAQ,GAAG;AAChD,UAAM,IAAI,UAAU;AAAA,EACtB;AAGA,MAAI,2BAA2B,KAAK,QAAQ,GAAG;AAC7C,UAAM,IAAI,OAAO;AAAA,EACnB;AAGA,MAAI,4BAA4B,KAAK,QAAQ,GAAG;AAC9C,UAAM,IAAI,MAAM;AAAA,EAClB;AAGA,QAAM,aAAa;AACnB,MAAI;AACJ,UAAQ,IAAI,WAAW,KAAK,QAAQ,OAAO,MAAM;AAC/C,UAAM,MAAM,EAAE,CAAC,EAAE,YAAY;AAC7B,UAAM,YAAY,qBAAqB,GAAG;AAC1C,QAAI,UAAW,OAAM,IAAI,SAAS;AAAA,EACpC;AAEA,SAAO,MAAM,KAAK,KAAK;AACzB;AAMO,SAAS,iBACd,UACA,aACQ;AACR,MAAI,SAAS;AAGb,QAAM,YAAY,YAAY,YAAY;AAC1C,MAAI,yCAAyC,KAAK,SAAS,GAAG;AAE5D,aAAS,OAAO;AAAA,MACd;AAAA,MACA;AAAA,IACF;AAAA,EACF,WAAW,gCAAgC,KAAK,SAAS,GAAG;AAC1D,aAAS,OAAO;AAAA,MACd;AAAA,MACA;AAAA,IACF;AAAA,EACF,WAAW,oCAAoC,KAAK,SAAS,GAAG;AAC9D,aAAS,OAAO;AAAA,MACd;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAGA,QAAM,UAAU,CAAC,GAAG,YAAY,SAAS,mBAAmB,CAAC;AAC7D,QAAM,gBAAgB,QACnB,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE,KAAK,CAAC,EACtB,OAAO,CAAC,MAAM,EAAE,SAAS,CAAC;AAE7B,MAAI,cAAc,SAAS,GAAG;AAC5B,UAAM,mBAAmB,0CAA0C;AAAA,MACjE;AAAA,IACF;AAKA,UAAM,sBACJ,cAAc,UAAU,KACvB,cAAc,WAAW,KAAK;AAEjC,QAAI,qBAAqB;AACvB,YAAM,cAAc;AACpB,YAAM,gBAAgB,CAAC,GAAG,OAAO,SAAS,WAAW,CAAC;AAEtD,UAAI,cAAc,SAAS,GAAG;AAC5B,cAAM,cAAc,cAAc,cAAc,SAAS,CAAC;AAC1D,iBAAS,OAAO,QAAQ,aAAa,CAAC,OAAO,OAAO;AAClD,iBAAO,GAAG,EAAE,IAAI,WAAW;AAAA,QAC7B,CAAC;AACD,sBAAc,IAAI;AAAA,MACpB;AAAA,IACF;AAGA,UAAM,aAAa;AACnB,QAAI,aAAa;AACjB,aAAS,OAAO,QAAQ,YAAY,CAAC,UAAU;AAC7C,UAAI,aAAa,cAAc,QAAQ;AACrC,eAAO,SAAS,cAAc,YAAY,CAAC;AAAA,MAC7C;AACA,aAAO;AAAA,IACT,CAAC;AAGD,QAAI,qBAAqB,KAAK,MAAM,GAAG;AACrC,eAAS,OAAO,QAAQ,eAAe,WAAW;AAAA,IACpD;AAAA,EACF;AAEA,SAAO;AACT;;;ACrJA,IAAM,mBAAmB;AAEzB,SAAS,kBAAkB,aAAyC;AAClE,QAAM,UAAU,iBAAiB;AACjC,MAAI,QAAQ,WAAW,EAAG,QAAO;AAEjC,QAAM,aAAa,SAAS,WAAW;AAGvC,QAAM,aAKA,CAAC;AACP,MAAI,aAAyD;AAE7D,aAAW,SAAS,SAAS;AAC3B,UAAM,EAAE,OAAO,QAAQ,IAAI,WAAW,OAAO,UAAU;AACvD,QAAI,SAAS,kBAAkB;AAC7B,YAAM,aAAa,kBAAkB,MAAM,KAAK;AAChD,iBAAW,KAAK,EAAE,OAAO,OAAO,SAAS,WAAW,CAAC;AAErD,YAAM,WACJ,CAAC,cACD,QAAQ,WAAW,SAClB,UAAU,WAAW,SAAS,UAAU,WAAW;AACtD,UAAI,UAAU;AACZ,qBAAa;AAAA,UACX,MAAM,MAAM;AAAA,UACZ,OAAO,MAAM;AAAA,UACb;AAAA,UACA;AAAA,UACA,QAAQ;AAAA,QACV;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAGA,MAAI,cAAc,WAAW,SAAS,IAAI;AACxC,WAAO;AAAA,EACT;AAGA,QAAM,oBACJ,qBAAqB,KAAK,WAAW,KAAK,YAAY,SAAS,GAAG;AAGpE,MAAI,qBAAqB,WAAW,UAAU,GAAG;AAE/C,eAAW,KAAK,CAAC,GAAG,MAAM,EAAE,QAAQ,EAAE,SAAS,EAAE,UAAU,EAAE,OAAO;AAEpE,UAAM,WAA8B,CAAC;AACrC,UAAM,iBAAiB,oBAAI,IAAY;AAEvC,eAAW,KAAK,YAAY;AAE1B,YAAM,aAAa,EAAE,WAAW,KAAK,CAAC,SAAS,eAAe,IAAI,IAAI,CAAC;AACvE,UAAI,CAAC,YAAY;AACf,iBAAS,KAAK,CAAC;AACf,UAAE,WAAW,QAAQ,CAAC,SAAS,eAAe,IAAI,IAAI,CAAC;AAAA,MACzD;AAAA,IACF;AAGA,QAAI,SAAS,UAAU,GAAG;AAExB,eAAS,KAAK,CAAC,GAAG,MAAM;AACtB,cAAM,SAAS,YACZ,YAAY,EACZ,QAAQ,SAAS,EAAE,MAAM,IAAI,EAAE,CAAC,CAAC;AACpC,cAAM,SAAS,YACZ,YAAY,EACZ,QAAQ,SAAS,EAAE,MAAM,IAAI,EAAE,CAAC,CAAC;AACpC,eAAO,SAAS;AAAA,MAClB,CAAC;AAED,YAAM,gBAAgB,SAAS,IAAI,CAAC,MAAM,EAAE,MAAM,KAAK,EAAE,KAAK,GAAG;AACjE,YAAM,aAAa,SAAS,OAAO,CAAC,KAAK,MAAM,MAAM,EAAE,OAAO,CAAC;AAE/D,aAAO;AAAA,QACL,MAAM,SAAS,IAAI,CAAC,MAAM,EAAE,MAAM,IAAI,EAAE,KAAK,OAAO;AAAA,QACpD,OAAO;AAAA,QACP,OAAO;AAAA,QACP,QAAQ;AAAA,MACV;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AACT;AAIA,SAAS,kBAAkB,aAAyC;AAClE,QAAM,UAAU,YAAY,WAAW;AACvC,MAAI,QAAQ,WAAW,EAAG,QAAO;AACjC,QAAM,MAAM,QAAQ,CAAC;AACrB,SAAO;AAAA,IACL,MAAM,IAAI;AAAA,IACV,OAAO,IAAI;AAAA,IACX,OAAO,IAAI;AAAA,IACX,QAAQ;AAAA,EACV;AACF;AAIA,eAAsB,WAAW,aAAqB;AACpD,MAAI,YAAY,YAAY,KAAK;AACjC,MAAI,UAAU,WAAW,GAAG,KAAK,UAAU,SAAS,GAAG,GAAG;AACxD,QAAI;AACF,YAAM,SAAS,KAAK,MAAM,SAAS;AACnC,UAAI,UAAU,OAAO,OAAO,gBAAgB,UAAU;AACpD,oBAAY,OAAO;AAAA,MACrB,WAAW,UAAU,OAAO,OAAO,SAAS,UAAU;AACpD,oBAAY,OAAO;AAAA,MACrB;AAAA,IACF,QAAQ;AAAA,IAER;AAAA,EACF;AAGA,MAAI,QAAQ,kBAAkB,SAAS;AAGvC,MAAI,CAAC,OAAO;AACV,YAAQ,kBAAkB,SAAS;AAAA,EACrC;AAEA,MAAI,CAAC,OAAO;AACV,WAAO;AAAA,MACL,SAAS;AAAA,QACP;AAAA,UACE,MAAM;AAAA,UACN,MAAM,KAAK,UAAU;AAAA,YACnB,OAAO;AAAA,YACP,MAAM;AAAA,YACN,iBAAiB,CAAC;AAAA,YAClB,YAAY;AAAA,YACZ,QAAQ;AAAA,YACR,aAAa;AAAA,YACb,QAAQ;AAAA,YACR,YACE;AAAA,UACJ,CAAC;AAAA,QACH;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAGA,QAAMC,SAAQ,iBAAiB,MAAM,OAAO,SAAS;AACrD,QAAM,kBAAkB,kBAAkBA,MAAK;AAE/C,QAAM,aAAa,KAAK,IAAI,GAAG,MAAM,QAAQ,EAAE;AAE/C,SAAO;AAAA,IACL,SAAS;AAAA,MACP;AAAA,QACE,MAAM;AAAA,QACN,MAAM,KAAK,UAAU;AAAA,UACnB,OAAAA;AAAA,UACA,MAAM,YAAYA,MAAK;AAAA,UACvB;AAAA,UACA,YAAY,OAAO,WAAW,QAAQ,CAAC,CAAC;AAAA,UACxC,QAAQ,cAAcA,MAAK;AAAA,UAC3B,aAAa;AAAA,UACb,QAAQ,MAAM;AAAA;AAAA,QAChB,CAAC;AAAA,MACH;AAAA,IACF;AAAA,EACF;AACF;;;ACpMA,SAAS,gBAAAC,eAAc,cAAAC,mBAAkB;AACzC,OAAOC,WAAU;AACjB,SAAS,iBAAAC,sBAAqB;AAE9B,IAAMC,cAAaD,eAAc,YAAY,GAAG;AAChD,IAAME,aAAYH,MAAK,QAAQE,WAAU;AAGzC,IAAI,UAAUF,MAAK,QAAQG,YAAW,uBAAuB;AAC7D,IAAI,CAACJ,YAAW,OAAO,GAAG;AACxB,YAAUC,MAAK,QAAQG,YAAW,0BAA0B;AAC9D;AAEO,IAAM,aAAaL,cAAa,SAAS,MAAM;;;ACbtD,SAAS,KAAAM,UAAS;;;ACKX,IAAM,UAAsC;AAAA,EACjD,KAAK,EAAE,SAAS,WAAW,UAAU,UAAU;AAAA,EAC/C,QAAQ,EAAE,SAAS,WAAW,UAAU,UAAU;AAAA,EAClD,OAAO,EAAE,SAAS,WAAW,UAAU,UAAU;AAAA,EACjD,QAAQ,EAAE,SAAS,WAAW,UAAU,UAAU;AAAA,EAClD,MAAM,EAAE,SAAS,WAAW,UAAU,UAAU;AAAA,EAChD,OAAO,EAAE,SAAS,WAAW,UAAU,UAAU;AAAA,EACjD,SAAS,EAAE,SAAS,WAAW,UAAU,UAAU;AAAA,EACnD,MAAM,EAAE,SAAS,WAAW,UAAU,UAAU;AAAA,EAChD,MAAM,EAAE,SAAS,WAAW,UAAU,UAAU;AAAA,EAChD,KAAK,EAAE,SAAS,WAAW,UAAU,UAAU;AAAA,EAC/C,MAAM,EAAE,SAAS,WAAW,UAAU,UAAU;AAAA,EAChD,QAAQ,EAAE,SAAS,WAAW,UAAU,UAAU;AAAA,EAClD,QAAQ,EAAE,SAAS,WAAW,UAAU,UAAU;AAAA,EAClD,QAAQ,EAAE,SAAS,WAAW,UAAU,UAAU;AAAA,EAClD,SAAS,EAAE,SAAS,WAAW,UAAU,UAAU;AAAA,EACnD,MAAM,EAAE,SAAS,WAAW,UAAU,UAAU;AAAA,EAChD,MAAM,EAAE,SAAS,WAAW,UAAU,UAAU;AAAA,EAChD,WAAW,EAAE,SAAS,WAAW,UAAU,UAAU;AAAA,EACrD,MAAM,EAAE,SAAS,WAAW,UAAU,UAAU;AAAA,EAChD,KAAK,EAAE,SAAS,WAAW,UAAU,UAAU;AAAA,EAC/C,QAAQ,EAAE,SAAS,WAAW,UAAU,UAAU;AAAA,EAClD,QAAQ,EAAE,SAAS,WAAW,UAAU,UAAU;AAAA,EAClD,OAAO,EAAE,SAAS,WAAW,UAAU,UAAU;AAAA,EACjD,QAAQ,EAAE,SAAS,WAAW,UAAU,UAAU;AAAA,EAClD,UAAU,EAAE,SAAS,WAAW,UAAU,UAAU;AAAA,EACpD,UAAU,EAAE,SAAS,WAAW,UAAU,UAAU;AAAA,EACpD,OAAO,EAAE,SAAS,WAAW,UAAU,UAAU;AAAA,EACjD,OAAO,EAAE,SAAS,WAAW,UAAU,UAAU;AAAA,EACjD,MAAM,EAAE,SAAS,WAAW,UAAU,UAAU;AAAA,EAChD,QAAQ,EAAE,SAAS,WAAW,UAAU,UAAU;AACpD;AAEO,SAAS,UAAU,KAAqB;AAC7C,QAAM,IAAI,IAAI,QAAQ,KAAK,EAAE;AAC7B,SAAO,EAAE,WAAW,IAAI,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC,IAAI,EAAE,CAAC,IAAI,EAAE,CAAC,IAAI,EAAE,CAAC,IAAI,EAAE,CAAC,IAAI;AAC1E;AAEO,SAAS,YAAY,MAAsB;AAChD,QAAM,IAAI,KAAK,QAAQ,KAAK,EAAE;AAC9B,QAAM,IAAI,SAAS,EAAE,UAAU,GAAG,CAAC,GAAG,EAAE;AACxC,QAAM,IAAI,SAAS,EAAE,UAAU,GAAG,CAAC,GAAG,EAAE;AACxC,QAAM,IAAI,SAAS,EAAE,UAAU,GAAG,CAAC,GAAG,EAAE;AACxC,UAAQ,IAAI,MAAM,IAAI,MAAM,IAAI,OAAO,MAAO,MAAM,YAAY;AAClE;AAEO,SAAS,aAAa,OAA2B;AACtD,QAAM,WAAW,MAAM,MAAM,oCAAoC;AACjE,MAAI,UAAU;AACZ,UAAM,UAAU,UAAU,SAAS,CAAC,CAAC;AACrC,WAAO,EAAE,SAAS,UAAU,YAAY,OAAO,EAAE;AAAA,EACnD;AAEA,QAAM,SAAS,OAAO,KAAK,OAAO,EAAE,KAAK,CAAC,GAAG,MAAM,EAAE,SAAS,EAAE,MAAM;AACtE,aAAW,QAAQ,QAAQ;AACzB,QAAI,MAAM,SAAS,IAAI,EAAG,QAAO,QAAQ,IAAI;AAAA,EAC/C;AAEA,SAAO,EAAE,SAAS,WAAW,UAAU,UAAU;AACnD;;;ACnBO,SAAS,cAAc,OAA4B;AACxD,QAAM,EAAE,SAAS,SAAS,IAAI,aAAa,KAAK;AAEhD,QAAM,SACJ,MAAM,SAAS,MAAM,KACrB,MAAM,SAAS,OAAO,KACtB,MAAM,SAAS,UAAU,KACzB,MAAM,SAAS,WAAW,KAC1B,MAAM,SAAS,KAAK;AAEtB,QAAM,QACJ,MAAM,SAAS,OAAO,KACtB,MAAM,SAAS,MAAM,KACrB,MAAM,SAAS,QAAQ;AACzB,QAAM,QACJ,MAAM,SAAS,OAAO,KAAK,MAAM,SAAS,MAAM,KAAK,MAAM,SAAS,MAAM;AAE5E,SAAO;AAAA,IACL,iBAAiB;AAAA,IACjB,kBAAkB;AAAA,IAClB;AAAA,IAEA;AAAA,IACA,cAAc,SACV,qDACA;AAAA,IACJ,iBAAiB,SACb,qDACA;AAAA,IACJ,WAAW,SACP,uDACA;AAAA,IAEJ,QAAQ;AAAA,IACR,YAAY,SAAS,YAAY;AAAA,IACjC,UAAU,SAAS,YAAY;AAAA,IAE/B,SAAS,SAAS,YAAY;AAAA,IAC9B,WAAW,SAAS,YAAY;AAAA,IAEhC,SAAS;AAAA,IACT,WAAW,SAAS,YAAY;AAAA,IAEhC,QAAQ,SAAS,YAAY;AAAA,IAC7B,SAAS,SAAS,YAAY;AAAA,IAC9B,SAAS,SAAS,YAAY;AAAA,IAE9B,SAAS,SAAS,YAAY;AAAA,IAC9B,eAAe,SAAS,YAAY;AAAA,IAEpC,MAAM,SAAS,YAAY;AAAA,IAC3B,WAAW,SAAS,YAAY;AAAA,IAChC,QAAQ,SAAS,YAAY;AAAA,IAE7B,QAAQ,QAAQ,QAAQ,QAAQ,YAAY;AAAA,IAC5C,UAAU,QAAQ,QAAQ,QAAQ,SAAS;AAAA,IAC3C,aAAa;AAAA,IAEb,YAAY,SAAS,YAAY;AAAA,IACjC,iBAAiB,SAAS,0BAA0B;AAAA,IAEpD,eAAe;AAAA,IACf,aAAa;AAAA,IACb,eAAe,SAAS,YAAY;AAAA,EACtC;AACF;AAEO,SAAS,SAAS,GAAwB;AAC/C,SAAO;AAAA,2BACkB,EAAE,OAAO;AAAA,2BACT,EAAE,YAAY;AAAA,2BACd,EAAE,eAAe;AAAA;AAAA,sBAEtB,EAAE,MAAM;AAAA,sBACR,EAAE,UAAU;AAAA;AAAA,kBAEhB,EAAE,OAAO;AAAA,kBACT,EAAE,OAAO;AAAA,kBACT,EAAE,OAAO;AAAA;AAAA;AAAA,qBAGN,EAAE,SAAS;AAAA,qBACX,EAAE,QAAQ;AAAA,qBACV,EAAE,SAAS;AAAA,qBACX,EAAE,SAAS;AAAA,qBACX,EAAE,MAAM;AAAA;AAAA;AAAA;AAAA;AAAA,qBAKR,EAAE,gBAAgB;AAAA;AAAA,kBAErB,EAAE,OAAO;AAAA;AAAA,yBAEF,EAAE,OAAO;AAAA,yBACT,EAAE,aAAa;AAAA;AAAA,qBAEnB,EAAE,IAAI;AAAA,qBACN,EAAE,SAAS;AAAA;AAAA,iBAEf,EAAE,MAAM;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,uBAkBF,EAAE,MAAM;AAAA,uBACR,EAAE,QAAQ;AAAA,uBACV,EAAE,WAAW;AAAA;AAAA;AAAA;AAAA,gDAIY,EAAE,aAAa,KAAK,EAAE,WAAW;AAAA,gDACjC,EAAE,aAAa,KAAK,EAAE,aAAa;AAAA;AAAA,2BAExD,EAAE,UAAU;AAAA,2BACZ,EAAE,eAAe;AAAA;AAE5C;;;AF3KA,IAAMC,UAASC,GAAE,OAAO,EAAE,QAAQA,GAAE,OAAO,EAAE,IAAI,CAAC,EAAE,CAAC;AAE9C,SAAS,cAAc,MAA4B;AACxD,QAAM,SAASD,QAAO,UAAU,IAAI;AAEpC,MAAI,CAAC,OAAO,SAAS;AACnB,WAAO;AAAA,MACL,SAAS;AAAA,QACP;AAAA,UACE,MAAM;AAAA,UACN,MAAM,KAAK,UAAU;AAAA,YACnB,OAAO;AAAA,YACP,YAAY;AAAA,YACZ,aAAa;AAAA,UACf,CAAC;AAAA,QACH;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,QAAM,EAAE,OAAO,IAAI,OAAO;AAC1B,QAAM,SAAS,cAAc,OAAO,YAAY,EAAE,KAAK,CAAC;AAExD,SAAO;AAAA,IACL,SAAS;AAAA,MACP;AAAA,QACE,MAAM;AAAA,QACN,MAAM,KAAK,UAAU;AAAA,UACnB;AAAA,UACA,SAAS,OAAO;AAAA,UAChB,QAAQ,OAAO;AAAA,UACf,KAAK,SAAS,MAAM;AAAA,UACpB,aAAa;AAAA,QACf,CAAC;AAAA,MACH;AAAA,IACF;AAAA,EACF;AACF;;;AGzCA,SAAS,SAAAE,cAAa;;;ACGtB,SAAS,WAAW,WAAmB,MAAc,OAAuB;AAC1E,SAAO,UAAU,QAAQ,6BAA6B,MAAM,IAAI,KAAK,KAAK,GAAG;AAC/E;AAEA,SAAS,KAAK,KAAa,MAAM,KAAa;AAC5C,SAAO,IAAI,SAAS,MAAM,IAAI,MAAM,GAAG,GAAG,IAAI,QAAQ;AACxD;AAEA,SAAS,aAAa,KAA2B;AAC/C,QAAM,OAAO,IAAI,aAAa,MAAM;AACpC,QAAM,aAAa,IAAI,aAAa,aAAa;AACjD,SAAO,SAAS,kBAAkB,SAAS,UAAU,eAAe;AACtE;AAGA,SAAS,mBACP,IACA,MACA,MACU;AACV,QAAM,MAAM,GAAG,aAAa,IAAI;AAChC,MAAI,CAAC,KAAK,KAAK,EAAG,QAAO,CAAC;AAC1B,SAAO,IACJ,KAAK,EACL,MAAM,KAAK,EACX,OAAO,CAAC,OAAO,CAAC,KAAK,cAAc,QAAQ,EAAE,IAAI,CAAC;AACvD;AAGA,SAAS,eAAe,IAAyB;AAC/C,MAAI,GAAG,aAAa,aAAa,MAAM,OAAQ,QAAO;AACtD,MAAI,SAAS;AACb,aAAW,SAAS,GAAG,YAAY;AACjC,QAAI,MAAM,aAAa,GAAG;AACxB,gBAAU,eAAe,KAAoB;AAAA,IAC/C,WAAW,MAAM,aAAa,GAAG;AAC/B,gBAAU,MAAM,QAAQ;AAAA,IAC1B;AAAA,EACF;AACA,SAAO;AACT;AAEA,SAAS,kBAAkB,IAAiB,MAA2B;AACrE,QAAM,OAAO,eAAe,EAAE,EAAE,KAAK;AACrC,MAAI,KAAM,QAAO;AAEjB,QAAM,YAAY,GAAG,aAAa,YAAY,GAAG,KAAK;AACtD,MAAI,UAAW,QAAO;AAEtB,QAAM,QAAQ,GAAG,aAAa,OAAO,GAAG,KAAK;AAC7C,MAAI,MAAO,QAAO;AAElB,QAAM,WAAW,GAAG,cAAc,KAAK;AACvC,QAAM,WAAW,UAAU,aAAa,KAAK,GAAG,KAAK;AACrD,MAAI,SAAU,QAAO;AAErB,QAAM,aAAa,GAAG,aAAa,iBAAiB;AACpD,MAAI,YAAY;AACd,UAAM,OAAO,WACV,KAAK,EACL,MAAM,KAAK,EACX,IAAI,CAAC,OAAO,KAAK,cAAc,QAAQ,EAAE,IAAI,GAAG,KAAK,KAAK,KAAK,EAAE,EACjE,KAAK,GAAG,EACR,KAAK;AACR,QAAI,KAAM,QAAO;AAAA,EACnB;AAEA,SAAO;AACT;AAEO,SAAS,YAAY,MAA+B;AACzD,QAAM,WAAW;AACjB,QAAM,SAAsB,CAAC;AAE7B,OAAK,iBAAiB,KAAK,EAAE,QAAQ,CAAC,QAAQ;AAC5C,UAAM,MAAM,IAAI,aAAa,KAAK;AAClC,UAAM,YAAY,IAAI,aAAa,YAAY,GAAG,KAAK;AACvD,UAAM,aAAa,IAAI,aAAa,iBAAiB;AACrD,UAAM,cAAc,CAAC,EAAE,aAAa;AAEpC,QAAI,QAAQ,QAAW;AACrB,UAAI,aAAa;AACf,eAAO,KAAK;AAAA,UACV,MAAM;AAAA,UACN,MAAM;AAAA,UACN,SAAS,KAAK,IAAI,SAAS;AAAA,UAC3B,SACE;AAAA,UACF,KAAK;AAAA,YACH,IAAI;AAAA,YACJ;AAAA,YACA,aAAa;AAAA,UACf;AAAA,QACF,CAAC;AAAA,MACH,OAAO;AACL,eAAO,KAAK;AAAA,UACV,MAAM;AAAA,UACN,MAAM;AAAA,UACN,SAAS,KAAK,IAAI,SAAS;AAAA,UAC3B,SAAS;AAAA,UACT,KAAK,WAAW,IAAI,WAAW,OAAO,sBAAsB;AAAA,QAC9D,CAAC;AAAA,MACH;AACA;AAAA,IACF;AAEA,QAAI,IAAI,KAAK,MAAM,MAAM,CAAC,aAAa,GAAG,GAAG;AAC3C,aAAO,KAAK;AAAA,QACV,MAAM;AAAA,QACN,MAAM;AAAA,QACN,SAAS,KAAK,IAAI,SAAS;AAAA,QAC3B,SACE;AAAA,QACF,KAAK,WAAW,IAAI,WAAW,QAAQ,cAAc;AAAA,MACvD,CAAC;AAAA,IACH;AAAA,EACF,CAAC;AAED,SAAO,EAAE,UAAU,OAAO;AAC5B;AAEO,SAAS,gBAAgB,MAA+B;AAC7D,QAAM,WAAW;AACjB,QAAM,SAAsB,CAAC;AAC7B,QAAM,iBAAiB,oBAAI,IAAI;AAAA,IAC7B;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,CAAC;AAED,aAAW,OAAO,CAAC,SAAS,UAAU,UAAU,GAAY;AAC1D,SAAK,iBAAiB,GAAG,EAAE,QAAQ,CAAC,OAAO;AACzC,UAAI,QAAQ,SAAS;AACnB,cAAM,QAAQ,GAAG,aAAa,MAAM,KAAK,QAAQ,YAAY;AAC7D,YAAI,eAAe,IAAI,IAAI,EAAG;AAAA,MAChC;AAEA,YAAM,KAAK,GAAG,aAAa,IAAI;AAC/B,YAAM,cAAc,KAChB,CAAC,CAAC,KAAK,cAAc,cAAc,EAAE,IAAI,IACzC;AACJ,YAAM,cAAc,CAAC,CAAC,GAAG,QAAQ,OAAO;AACxC,YAAM,YAAY,GAAG,aAAa,YAAY,GAAG,KAAK;AACtD,YAAM,iBAAiB,GAAG,aAAa,iBAAiB;AACxD,YAAM,WAAW,CAAC,CAAC,GAAG,aAAa,OAAO,GAAG,KAAK;AAElD,UACE,CAAC,eACD,CAAC,eACD,CAAC,aACD,CAAC,kBACD,CAAC,UACD;AACA,eAAO,KAAK;AAAA,UACV,MAAM;AAAA,UACN,MAAM;AAAA,UACN,SAAS,KAAK,GAAG,SAAS;AAAA,UAC1B,SAAS,IAAI,GAAG;AAAA,UAChB,KAAK,KACD,eAAe,EAAE;AAAA,EAA2B,GAAG,SAAS,KACxD,uBAAuB,GAAG,SAAS;AAAA,QACzC,CAAC;AACD;AAAA,MACF;AAGA,UAAI,gBAAgB;AAClB,cAAM,SAAS,mBAAmB,IAAI,mBAAmB,IAAI;AAC7D,YAAI,OAAO,SAAS,GAAG;AACrB,iBAAO,KAAK;AAAA,YACV,MAAM;AAAA,YACN,MAAM;AAAA,YACN,SAAS,KAAK,GAAG,SAAS;AAAA,YAC1B,SAAS,IAAI,GAAG,yDAAyD,OAAO,IAAI,CAACC,QAAO,IAAIA,GAAE,EAAE,EAAE,KAAK,IAAI,CAAC;AAAA,YAChH,KAAK,8BAA8B,OAAO,KAAK,MAAM,CAAC;AAAA,UACxD,CAAC;AAAA,QACH;AAAA,MACF;AAAA,IACF,CAAC;AAAA,EACH;AAEA,OAAK,iBAAiB,UAAU,EAAE,QAAQ,CAAC,aAAa;AACtD,UAAM,SAAS,SAAS,cAAc,QAAQ;AAC9C,QAAI,CAAC,UAAU,CAAC,OAAO,KAAK,KAAK,GAAG;AAClC,aAAO,KAAK;AAAA,QACV,MAAM;AAAA,QACN,MAAM;AAAA,QACN,SAAS;AAAA,QACT,SACE;AAAA,QACF,KAAK;AAAA;AAAA;AAAA;AAAA,MACP,CAAC;AAAA,IACH;AAAA,EACF,CAAC;AAED,SAAO,EAAE,UAAU,OAAO;AAC5B;AAEO,SAAS,iBAAiB,MAA+B;AAC9D,QAAM,WAAW;AACjB,QAAM,SAAsB,CAAC;AAE7B,OAAK,iBAAiB,OAAO,EAAE,QAAQ,CAAC,UAAU;AAChD,UAAM,UAAU,CAAC,CAAC,MAAM,KAAK,KAAK;AAClC,UAAM,eAAe,CAAC,CAAC,MAAM,aAAa,YAAY,GAAG,KAAK;AAE9D,QAAI,CAAC,WAAW,CAAC,cAAc;AAC7B,aAAO,KAAK;AAAA,QACV,MAAM;AAAA,QACN,MAAM;AAAA,QACN,SAAS,KAAK,MAAM,SAAS;AAAA,QAC7B,SACE;AAAA,QACF,KAAK,MAAM,UAAU,QAAQ,YAAY,sBAAsB;AAAA,MACjE,CAAC;AAAA,IACH;AAGA,UAAM,UAAU,MAAM,aAAa,KAAK;AACxC,QAAI,WAAW,CAAC,KAAK,cAAc,QAAQ,OAAO,IAAI,GAAG;AACvD,aAAO,KAAK;AAAA,QACV,MAAM;AAAA,QACN,MAAM;AAAA,QACN,SAAS,KAAK,MAAM,SAAS;AAAA,QAC7B,SAAS,eAAe,OAAO,qBAAqB,OAAO;AAAA,QAC3D,KAAK,WAAW,OAAO;AAAA,MACzB,CAAC;AAAA,IACH;AAAA,EACF,CAAC;AAED,SAAO,EAAE,UAAU,OAAO;AAC5B;AAEO,SAAS,aAAa,MAA+B;AAC1D,QAAM,WAAW;AACjB,QAAM,SAAsB,CAAC;AAE7B,OAAK,iBAAiB,QAAQ,EAAE,QAAQ,CAAC,WAAW;AAClD,QAAI,CAAC,kBAAkB,QAAQ,IAAI,GAAG;AACpC,aAAO,KAAK;AAAA,QACV,MAAM;AAAA,QACN,MAAM;AAAA,QACN,SAAS,KAAK,OAAO,SAAS;AAAA,QAC9B,SACE;AAAA,QACF,KAAK,WAAW,OAAO,WAAW,cAAc,sBAAsB;AAAA,MACxE,CAAC;AAAA,IACH;AAAA,EACF,CAAC;AAED,SAAO,EAAE,UAAU,OAAO;AAC5B;AAEO,SAAS,WAAW,MAA+B;AACxD,QAAM,WAAW;AACjB,QAAM,SAAsB,CAAC;AAC7B,QAAM,QAAQ,oBAAI,IAAI;AAAA,IACpB;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,CAAC;AAED,OAAK,iBAAiB,GAAG,EAAE,QAAQ,CAAC,SAAS;AAC3C,UAAM,OAAO,kBAAkB,MAAM,IAAI;AACzC,UAAM,OAAO,KAAK,aAAa,MAAM;AACrC,UAAM,eAAe,KAAK,aAAa,MAAM,MAAM;AAEnD,QAAI,CAAC,MAAM;AACT,aAAO,KAAK;AAAA,QACV,MAAM;AAAA,QACN,MAAM;AAAA,QACN,SAAS,KAAK,KAAK,SAAS;AAAA,QAC5B,SACE;AAAA,QACF,KAAK;AAAA,UACH,KAAK;AAAA,UACL;AAAA,UACA;AAAA,QACF;AAAA,MACF,CAAC;AACD;AAAA,IACF;AAEA,QAAI,MAAM,IAAI,KAAK,YAAY,CAAC,GAAG;AACjC,aAAO,KAAK;AAAA,QACV,MAAM;AAAA,QACN,MAAM;AAAA,QACN,SAAS,KAAK,KAAK,SAAS;AAAA,QAC5B,SAAS,iCAAiC,IAAI;AAAA,QAC9C,KAAK;AAAA,UACH,KAAK;AAAA,UACL;AAAA,UACA;AAAA,QACF;AAAA,MACF,CAAC;AAAA,IACH;AAEA,QAAI,CAAC,QAAQ,CAAC,cAAc;AAC1B,aAAO,KAAK;AAAA,QACV,MAAM;AAAA,QACN,MAAM;AAAA,QACN,SAAS,KAAK,KAAK,SAAS;AAAA,QAC5B,SACE;AAAA,QACF,KAAK,KAAK,UAAU,QAAQ,SAAS,aAAa;AAAA,MACpD,CAAC;AAAA,IACH;AAAA,EACF,CAAC;AAED,SAAO,EAAE,UAAU,OAAO;AAC5B;AAEO,SAAS,gBAAgB,MAA+B;AAC7D,QAAM,WAAW;AACjB,QAAM,SAAsB,CAAC;AAG7B,OAAK,iBAAiB,gBAAgB,EAAE,QAAQ,CAAC,OAAO;AACtD,UAAM,aAAa,GAAG,aAAa,cAAc;AACjD,UAAM,uBAAuB,oBAAI,IAAI;AAAA,MACnC;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF,CAAC;AAED,QAAI,CAAC,qBAAqB,IAAI,cAAc,EAAE,GAAG;AAC/C,aAAO,KAAK;AAAA,QACV,MAAM;AAAA,QACN,MAAM;AAAA,QACN,SAAS,KAAK,GAAG,SAAS;AAAA,QAC1B,SAAS,iBAAiB,UAAU;AAAA,QACpC,KAAK,GAAG,UAAU;AAAA,UAChB,iBAAiB,UAAU;AAAA,UAC3B;AAAA,QACF;AAAA,MACF,CAAC;AACD;AAAA,IACF;AAEA,QAAI,eAAe,QAAQ;AACzB,YAAM,cAAc,GAAG,aAAa,kBAAkB;AACtD,UAAI,CAAC,aAAa;AAChB,eAAO,KAAK;AAAA,UACV,MAAM;AAAA,UACN,MAAM;AAAA,UACN,SAAS,KAAK,GAAG,SAAS;AAAA,UAC1B,SACE;AAAA,UACF,KAAK,WAAW,GAAG,WAAW,oBAAoB,kBAAkB;AAAA,QACtE,CAAC;AAAA,MACH,OAAO;AAEL,cAAM,SAAS,mBAAmB,IAAI,oBAAoB,IAAI;AAC9D,YAAI,OAAO,SAAS,GAAG;AACrB,iBAAO,KAAK;AAAA,YACV,MAAM;AAAA,YACN,MAAM;AAAA,YACN,SAAS,KAAK,GAAG,SAAS;AAAA,YAC1B,SAAS,wDAAwD,OAAO,IAAI,CAAC,OAAO,IAAI,EAAE,EAAE,EAAE,KAAK,IAAI,CAAC;AAAA,YACxG,KAAK,8BAA8B,OAAO,KAAK,MAAM,CAAC;AAAA,UACxD,CAAC;AAAA,QACH;AAAA,MACF;AAAA,IACF;AAAA,EACF,CAAC;AAGD,QAAM,qBAAqB;AAAA,IACzB;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACA,aAAW,QAAQ,oBAAoB;AACrC,SAAK,iBAAiB,IAAI,IAAI,GAAG,EAAE,QAAQ,CAAC,OAAO;AACjD,YAAM,MAAM,GAAG,aAAa,IAAI;AAChC,UAAI,QAAQ,UAAU,QAAQ,SAAS;AACrC,eAAO,KAAK;AAAA,UACV,MAAM;AAAA,UACN,MAAM;AAAA,UACN,SAAS,KAAK,GAAG,SAAS;AAAA,UAC1B,SAAS,GAAG,IAAI,oCAAoC,GAAG;AAAA,UACvD,KAAK,GAAG,UAAU,QAAQ,GAAG,IAAI,KAAK,GAAG,KAAK,GAAG,IAAI,SAAS;AAAA,QAChE,CAAC;AAAA,MACH;AAAA,IACF,CAAC;AAAA,EACH;AAGA,OAAK,iBAAiB,gBAAgB,EAAE,QAAQ,CAAC,OAAO;AACtD,UAAM,MAAM,GAAG,aAAa,cAAc;AAC1C,QAAI,QAAQ,UAAU,QAAQ,WAAW,QAAQ,SAAS;AACxD,aAAO,KAAK;AAAA,QACV,MAAM;AAAA,QACN,MAAM;AAAA,QACN,SAAS,KAAK,GAAG,SAAS;AAAA,QAC1B,SAAS,0EAA0E,GAAG;AAAA,QACtF,KAAK,GAAG,UAAU;AAAA,UAChB,iBAAiB,GAAG;AAAA,UACpB;AAAA,QACF;AAAA,MACF,CAAC;AAAA,IACH;AAAA,EACF,CAAC;AAGD,QAAM,kBAAkB,oBAAI,IAAI,CAAC,OAAO,UAAU,WAAW,CAAC;AAC9D,OAAK,iBAAiB,aAAa,EAAE,QAAQ,CAAC,OAAO;AACnD,UAAM,MAAM,GAAG,aAAa,WAAW,KAAK;AAC5C,QAAI,CAAC,gBAAgB,IAAI,GAAG,GAAG;AAC7B,aAAO,KAAK;AAAA,QACV,MAAM;AAAA,QACN,MAAM;AAAA,QACN,SAAS,KAAK,GAAG,SAAS;AAAA,QAC1B,SAAS,cAAc,GAAG;AAAA,QAC1B,KAAK,GAAG,UAAU,QAAQ,cAAc,GAAG,KAAK,oBAAoB;AAAA,MACtE,CAAC;AAAA,IACH;AAAA,EACF,CAAC;AAED,SAAO,EAAE,UAAU,OAAO;AAC5B;AAEO,SAAS,kBAAkB,MAA+B;AAC/D,QAAM,WAAW;AACjB,QAAM,SAAsB,CAAC;AAC7B,QAAM,OAAO,oBAAI,IAAoB;AAErC,OAAK,iBAAiB,MAAM,EAAE,QAAQ,CAAC,OAAO;AAC5C,UAAM,KAAK,GAAG,aAAa,IAAI;AAG/B,QAAI,OAAO,UAAa,GAAG,KAAK,MAAM,IAAI;AACxC,aAAO,KAAK;AAAA,QACV,MAAM;AAAA,QACN,MAAM;AAAA,QACN,SAAS,KAAK,GAAG,SAAS;AAAA,QAC1B,SAAS;AAAA,QACT,KAAK,GAAG,UAAU,QAAQ,SAAS,kBAAkB;AAAA,MACvD,CAAC;AACD;AAAA,IACF;AAEA,QAAI,GAAI,MAAK,IAAI,KAAK,KAAK,IAAI,EAAE,KAAK,KAAK,CAAC;AAAA,EAC9C,CAAC;AAED,OAAK,QAAQ,CAAC,OAAO,OAAO;AAC1B,QAAI,QAAQ,GAAG;AACb,aAAO,KAAK;AAAA,QACV,MAAM;AAAA,QACN,MAAM;AAAA,QACN,SAAS,OAAO,EAAE;AAAA,QAClB,SAAS,OAAO,EAAE,aAAa,KAAK;AAAA,QACpC,KAAK,6BAA6B,EAAE;AAAA,MACtC,CAAC;AAAA,IACH;AAAA,EACF,CAAC;AAED,SAAO,EAAE,UAAU,OAAO;AAC5B;AAEO,SAAS,cAAc,MAA+B;AAC3D,QAAM,WAAW;AACjB,QAAM,SAAsB,CAAC;AAE7B,OAAK,iBAAiB,YAAY,EAAE,QAAQ,CAAC,OAAO;AAClD,UAAM,MAAM,GAAG,aAAa,UAAU,KAAK;AAC3C,UAAM,MAAM,SAAS,KAAK,EAAE;AAE5B,QAAI,MAAM,GAAG,GAAG;AACd,aAAO,KAAK;AAAA,QACV,MAAM;AAAA,QACN,MAAM;AAAA,QACN,SAAS,KAAK,GAAG,SAAS;AAAA,QAC1B,SAAS,aAAa,GAAG;AAAA,QACzB,KAAK,GAAG,UAAU,QAAQ,aAAa,GAAG,KAAK,cAAc;AAAA,MAC/D,CAAC;AACD;AAAA,IACF;AAEA,QAAI,MAAM,GAAG;AACX,aAAO,KAAK;AAAA,QACV,MAAM;AAAA,QACN,MAAM;AAAA,QACN,SAAS,KAAK,GAAG,SAAS;AAAA,QAC1B,SAAS,aAAa,GAAG;AAAA,QACzB,KAAK,GAAG,UAAU,QAAQ,aAAa,GAAG,KAAK,cAAc;AAAA,MAC/D,CAAC;AAAA,IACH;AAAA,EACF,CAAC;AAED,SAAO,EAAE,UAAU,OAAO;AAC5B;AAEO,SAAS,cAAc,MAA+B;AAC3D,QAAM,WAAW;AACjB,QAAM,SAAsB,CAAC;AAC7B,QAAM,WAAW,KAAK,iBAAiB,wBAAwB;AAE/D,MAAI,YAAY;AAChB,MAAI,UAAU;AAEd,WAAS,QAAQ,CAAC,MAAM;AACtB,UAAM,MAAM,EAAE,QAAQ,YAAY;AAClC,UAAM,QAAQ,SAAS,EAAE,QAAQ,MAAM,CAAC,GAAG,EAAE;AAE7C,QAAI,CAAC,EAAE,KAAK,KAAK,GAAG;AAClB,aAAO,KAAK;AAAA,QACV,MAAM;AAAA,QACN,MAAM;AAAA,QACN,SAAS,KAAK,EAAE,SAAS;AAAA,QACzB,SAAS,IAAI,GAAG;AAAA,QAChB,KAAK,IAAI,GAAG,oBAAoB,GAAG;AAAA,MACrC,CAAC;AAAA,IACH;AAEA,QAAI,UAAU,EAAG;AAEjB,QAAI,YAAY,KAAK,QAAQ,YAAY,GAAG;AAC1C,aAAO,KAAK;AAAA,QACV,MAAM;AAAA,QACN,MAAM;AAAA,QACN,SAAS,KAAK,EAAE,SAAS;AAAA,QACzB,SAAS,uBAAuB,SAAS,QAAQ,KAAK,WAAW,YAAY,CAAC;AAAA,QAC9E,KAAK,KAAK,YAAY,CAAC,IAAI,EAAE,KAAK,KAAK,CAAC,MAAM,YAAY,CAAC;AAAA,MAC7D,CAAC;AAAA,IACH;AAEA,gBAAY;AAAA,EACd,CAAC;AAED,MAAI,UAAU,GAAG;AACf,WAAO,KAAK;AAAA,MACV,MAAM;AAAA,MACN,MAAM;AAAA,MACN,SAAS;AAAA,MACT,SAAS,GAAG,OAAO;AAAA,MACnB,KAAK;AAAA,IACP,CAAC;AAAA,EACH;AAEA,SAAO,EAAE,UAAU,OAAO;AAC5B;AAEO,SAAS,YAAY,MAA+B;AACzD,QAAM,WAAW;AACjB,QAAM,SAAsB,CAAC;AAE7B,OAAK,iBAAiB,OAAO,EAAE,QAAQ,CAAC,UAAU;AAEhD,UAAM,OAAO,MAAM,aAAa,MAAM;AACtC,QAAI,SAAS,kBAAkB,SAAS,OAAQ;AAEhD,UAAM,UAAU,MAAM,cAAc,SAAS;AAC7C,UAAM,YAAY,MAAM,aAAa,YAAY;AACjD,UAAM,iBAAiB,MAAM,aAAa,iBAAiB;AAE3D,QAAI,CAAC,WAAW,CAAC,aAAa,CAAC,gBAAgB;AAC7C,aAAO,KAAK;AAAA,QACV,MAAM;AAAA,QACN,MAAM;AAAA,QACN,SAAS;AAAA,QACT,SACE;AAAA,QACF,KAAK,WAAW,WAAW,cAAc,sBAAsB;AAAA,MACjE,CAAC;AAAA,IACH;AAGA,QAAI,WAAW,CAAC,QAAQ,KAAK,KAAK,GAAG;AACnC,aAAO,KAAK;AAAA,QACV,MAAM;AAAA,QACN,MAAM;AAAA,QACN,SAAS,KAAK,QAAQ,SAAS;AAAA,QAC/B,SACE;AAAA,QACF,KAAK,QAAQ,UAAU;AAAA,UACrB;AAAA,UACA;AAAA,QACF;AAAA,MACF,CAAC;AAAA,IACH;AAEA,UAAM,iBAAiB,IAAI,EAAE,QAAQ,CAAC,OAAO;AAC3C,UAAI,CAAC,GAAG,aAAa,OAAO,GAAG;AAC7B,eAAO,KAAK;AAAA,UACV,MAAM;AAAA,UACN,MAAM;AAAA,UACN,SAAS,KAAK,GAAG,SAAS;AAAA,UAC1B,SACE;AAAA,UACF,KAAK,WAAW,GAAG,WAAW,SAAS,KAAK;AAAA,QAC9C,CAAC;AAAA,MACH;AAAA,IACF,CAAC;AAAA,EACH,CAAC;AAED,SAAO,EAAE,UAAU,OAAO;AAC5B;AAEO,SAAS,aAAa,MAA+B;AAC1D,QAAM,WAAW;AACjB,QAAM,SAAsB,CAAC;AAE7B,OAAK,iBAAiB,QAAQ,EAAE,QAAQ,CAAC,WAAW;AAClD,UAAM,KAAK,OAAO,aAAa,IAAI;AACnC,UAAM,YAAY,OAAO,aAAa,YAAY;AAClD,UAAM,iBAAiB,OAAO,aAAa,iBAAiB;AAE5D,QAAI,CAAC,IAAI;AACP,aAAO,KAAK;AAAA,QACV,MAAM;AAAA,QACN,MAAM;AAAA,QACN,SAAS;AAAA,QACT,SACE;AAAA,QACF,KAAK,WAAW,YAAY,MAAM,WAAW;AAAA,MAC/C,CAAC;AAAA,IACH;AAEA,QAAI,CAAC,aAAa,CAAC,gBAAgB;AACjC,aAAO,KAAK;AAAA,QACV,MAAM;AAAA,QACN,MAAM;AAAA,QACN,SAAS;AAAA,QACT,SACE;AAAA,QACF,KAAK,KACD,eAAe,EAAE,kDACjB;AAAA,MACN,CAAC;AAAA,IACH,WAAW,gBAAgB;AAEzB,YAAM,SAAS,mBAAmB,QAAQ,mBAAmB,IAAI;AACjE,UAAI,OAAO,SAAS,GAAG;AACrB,eAAO,KAAK;AAAA,UACV,MAAM;AAAA,UACN,MAAM;AAAA,UACN,SAAS;AAAA,UACT,SAAS,8DAA8D,OAAO,IAAI,CAACA,QAAO,IAAIA,GAAE,EAAE,EAAE,KAAK,IAAI,CAAC;AAAA,UAC9G,KAAK,8BAA8B,OAAO,KAAK,MAAM,CAAC;AAAA,QACxD,CAAC;AAAA,MACH;AAAA,IACF;AAAA,EACF,CAAC;AAED,SAAO,EAAE,UAAU,OAAO;AAC5B;AAEO,SAAS,WAAW,MAA+B;AACxD,QAAM,WAAW;AACjB,QAAM,SAAsB,CAAC;AAC7B,QAAM,uBAAuB,oBAAI,IAAI;AAAA,IACnC;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,CAAC;AAED,OAAK,iBAAiB,iBAAiB,EAAE,QAAQ,CAAC,OAAO;AACvD,UAAM,MAAM,GAAG,QAAQ,YAAY;AACnC,UAAM,WAAW,GAAG,aAAa,UAAU;AAC3C,QAAI,CAAC,qBAAqB,IAAI,GAAG,KAAK,aAAa,KAAK;AACtD,aAAO,KAAK;AAAA,QACV,MAAM;AAAA,QACN,MAAM;AAAA,QACN,SAAS,KAAK,GAAG,SAAS;AAAA,QAC1B,SACE;AAAA,QACF,KAAK,WAAW,GAAG,WAAW,YAAY,GAAG;AAAA,MAC/C,CAAC;AAAA,IACH;AAAA,EACF,CAAC;AAGD,aAAW,QAAQ;AAAA,IACjB;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,GAAY;AACV,SAAK,iBAAiB,UAAU,IAAI,IAAI,EAAE,QAAQ,CAAC,OAAO;AACxD,UAAI,CAAC,GAAG,aAAa,cAAc,GAAG;AACpC,eAAO,KAAK;AAAA,UACV,MAAM;AAAA,UACN,MAAM;AAAA,UACN,SAAS,KAAK,GAAG,SAAS;AAAA,UAC1B,SAAS,SAAS,IAAI,6DAA6D,SAAS,aAAa,cAAc,EAAE;AAAA,UACzH,KAAK,WAAW,GAAG,WAAW,gBAAgB,OAAO;AAAA,QACvD,CAAC;AAAA,MACH;AAAA,IACF,CAAC;AAAA,EACH;AAEA,OAAK,iBAAiB,mBAAmB,EAAE,QAAQ,CAAC,OAAO;AACzD,QAAI,CAAC,GAAG,aAAa,eAAe,GAAG;AACrC,aAAO,KAAK;AAAA,QACV,MAAM;AAAA,QACN,MAAM;AAAA,QACN,SAAS,KAAK,GAAG,SAAS;AAAA,QAC1B,SAAS;AAAA,QACT,KAAK,WAAW,GAAG,WAAW,iBAAiB,OAAO;AAAA,MACxD,CAAC;AAAA,IACH;AAAA,EACF,CAAC;AAGD,aAAW,QAAQ,CAAC,OAAO,UAAU,YAAY,UAAU,GAAY;AACrE,SAAK,iBAAiB,UAAU,IAAI,IAAI,EAAE,QAAQ,CAAC,OAAO;AACxD,UAAI,CAAC,GAAG,aAAa,eAAe,GAAG;AACrC,eAAO,KAAK;AAAA,UACV,MAAM;AAAA,UACN,MAAM;AAAA,UACN,SAAS,KAAK,GAAG,SAAS;AAAA,UAC1B,SAAS,SAAS,IAAI;AAAA,UACtB,KAAK,WAAW,GAAG,WAAW,iBAAiB,OAAO;AAAA,QACxD,CAAC;AAAA,MACH;AAAA,IACF,CAAC;AAAA,EACH;AAEA,OAAK,iBAAiB,iBAAiB,EAAE,QAAQ,CAAC,OAAO;AACvD,UAAM,WAAW,CAAC,iBAAiB,iBAAiB,eAAe;AACnE,UAAM,UAAU,SAAS,OAAO,CAAC,SAAS,CAAC,GAAG,aAAa,IAAI,CAAC;AAChE,QAAI,QAAQ,SAAS,GAAG;AACtB,aAAO,KAAK;AAAA,QACV,MAAM;AAAA,QACN,MAAM;AAAA,QACN,SAAS,KAAK,GAAG,SAAS;AAAA,QAC1B,SAAS,iDAAiD,QAAQ,KAAK,IAAI,CAAC;AAAA,QAC5E,KAAK;AAAA,MACP,CAAC;AAAA,IACH;AAAA,EACF,CAAC;AAED,OAAK,iBAAiB,sBAAsB,EAAE,QAAQ,CAAC,OAAO;AAC5D,QACE,CAAC,GAAG,aAAa,eAAe,KAChC,CAAC,GAAG,aAAa,gBAAgB,GACjC;AACA,aAAO,KAAK;AAAA,QACV,MAAM;AAAA,QACN,MAAM;AAAA,QACN,SAAS,KAAK,GAAG,SAAS;AAAA,QAC1B,SACE;AAAA,QACF,KAAK,WAAW,GAAG,WAAW,iBAAiB,GAAG;AAAA,MACpD,CAAC;AAAA,IACH;AAAA,EACF,CAAC;AAED,OAAK,iBAAiB,kBAAkB,EAAE,QAAQ,CAAC,OAAO;AACxD,QAAI,CAAC,kBAAkB,IAAI,IAAI,GAAG;AAChC,aAAO,KAAK;AAAA,QACV,MAAM;AAAA,QACN,MAAM;AAAA,QACN,SAAS,KAAK,GAAG,SAAS;AAAA,QAC1B,SACE;AAAA,QACF,KAAK;AAAA,UACH,GAAG;AAAA,UACH;AAAA,UACA;AAAA,QACF;AAAA,MACF,CAAC;AAAA,IACH;AAAA,EACF,CAAC;AAED,SAAO,EAAE,UAAU,OAAO;AAC5B;AAEO,SAAS,kBAAkB,MAA+B;AAC/D,QAAM,WAAW;AACjB,QAAM,SAAsB,CAAC;AAE7B,QAAM,oBAA4C;AAAA,IAChD,OAAO;AAAA,IACP,KAAK;AAAA,IACL,KAAK;AAAA,EACP;AAEA,OAAK,iBAAiB,OAAO,EAAE,QAAQ,CAAC,UAAU;AAChD,UAAM,QAAQ,MAAM,aAAa,MAAM,KAAK,QAAQ,YAAY;AAChE,UAAM,WAAW,kBAAkB,IAAI;AAEvC,QAAI,YAAY,CAAC,MAAM,aAAa,cAAc,GAAG;AACnD,aAAO,KAAK;AAAA,QACV,MAAM;AAAA,QACN,MAAM;AAAA,QACN,SAAS,KAAK,MAAM,SAAS;AAAA,QAC7B,SAAS,gBAAgB,IAAI,gCAAgC,QAAQ;AAAA,QACrE,KAAK,WAAW,MAAM,WAAW,gBAAgB,QAAQ;AAAA,MAC3D,CAAC;AAAA,IACH;AAEA,QAAI,SAAS,cAAc,CAAC,MAAM,aAAa,cAAc,GAAG;AAC9D,aAAO,KAAK;AAAA,QACV,MAAM;AAAA,QACN,MAAM;AAAA,QACN,SAAS,KAAK,MAAM,SAAS;AAAA,QAC7B,SACE;AAAA,QACF,KAAK,WAAW,MAAM,WAAW,gBAAgB,kBAAkB;AAAA,MACrE,CAAC;AAAA,IACH;AAAA,EACF,CAAC;AAED,SAAO,EAAE,UAAU,OAAO;AAC5B;AAEO,SAAS,gBAAgB,MAA+B;AAC7D,QAAM,WAAW;AACjB,QAAM,SAAsB,CAAC;AAC7B,QAAM,cAAc;AAAA,IAClB;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAEA,OAAK,iBAAiB,SAAS,EAAE,QAAQ,CAAC,OAAO;AAC/C,UAAM,QAAQ,GAAG,aAAa,OAAO,KAAK;AAC1C,QAAI,YAAY,KAAK,CAAC,OAAO,GAAG,KAAK,KAAK,CAAC,GAAG;AAC5C,aAAO,KAAK;AAAA,QACV,MAAM;AAAA,QACN,MAAM;AAAA,QACN,SAAS,KAAK,GAAG,SAAS;AAAA,QAC1B,SACE;AAAA,QACF,KAAK,GAAG,UACL,QAAQ,wCAAwC,EAAE,EAClD,QAAQ,gCAAgC,EAAE;AAAA,MAC/C,CAAC;AAAA,IACH;AAAA,EACF,CAAC;AAED,SAAO,EAAE,UAAU,OAAO;AAC5B;AAEO,SAAS,UAAU,MAA+B;AACvD,QAAM,WAAW;AACjB,QAAM,SAAsB,CAAC;AAE7B,QAAM,SAAS,KAAK,cAAc,MAAM;AACxC,MAAI,UAAU,CAAC,OAAO,aAAa,MAAM,GAAG,KAAK,GAAG;AAClD,WAAO,KAAK;AAAA,MACV,MAAM;AAAA,MACN,MAAM;AAAA,MACN,SAAS;AAAA,MACT,SACE;AAAA,MACF,KAAK;AAAA,IACP,CAAC;AAAA,EACH;AAEA,SAAO,EAAE,UAAU,OAAO;AAC5B;;;ADh1BA,IAAM,mBAAuE;AAAA,EAC3E,+BAA+B,EAAE,OAAO,MAAM,SAAS,IAAK;AAAA,EAC5D,0BAA0B,EAAE,OAAO,MAAM,SAAS,KAAK;AAAA,EACvD,2BAA2B,EAAE,OAAO,MAAM,SAAS,KAAK;AAAA,EACxD,2BAA2B,EAAE,OAAO,MAAM,SAAS,IAAK;AAAA,EACxD,2BAA2B,EAAE,OAAO,MAAM,SAAS,KAAK;AAAA,EACxD,mCAAmC,EAAE,OAAO,MAAM,SAAS,KAAK;AAAA,EAChE,gCAAgC,EAAE,OAAO,MAAM,SAAS,KAAK;AAAA,EAC7D,sBAAsB,EAAE,OAAO,MAAM,SAAS,IAAK;AAAA,EACnD,uBAAuB,EAAE,OAAO,MAAM,SAAS,KAAK;AAAA,EACpD,gCAAgC,EAAE,OAAO,MAAM,SAAS,KAAK;AAAA,EAC7D,8BAA8B,EAAE,OAAO,MAAM,SAAS,KAAK;AAAA,EAC3D,mCAAmC,EAAE,OAAO,MAAM,SAAS,KAAK;AAAA,EAChE,qCAAqC,EAAE,OAAO,MAAM,SAAS,KAAK;AAAA,EAClE,4BAA4B,EAAE,OAAO,MAAM,SAAS,KAAK;AAAA,EACzD,4BAA4B,EAAE,OAAO,MAAM,SAAS,KAAK;AAAA,EACzD,+BAA+B,EAAE,OAAO,MAAM,SAAS,IAAK;AAC9D;AAEA,SAAS,qBACP,UACA,MACQ;AACR,QAAM,OAAO,iBAAiB,QAAQ;AACtC,MAAI,MAAM;AACR,WAAO,SAAS,UAAU,KAAK,QAAQ,KAAK;AAAA,EAC9C;AACA,SAAO,SAAS,UAAU,OAAO;AACnC;AAEA,SAAS,aAAa,QAA6B;AACjD,QAAM,SAAS,OAAO,OAAO,CAAC,MAAM,EAAE,SAAS,OAAO,EAAE;AACxD,QAAM,WAAW,OAAO,OAAO,CAAC,MAAM,EAAE,SAAS,SAAS,EAAE;AAC5D,SAAO,KAAK,IAAI,GAAG,MAAM,SAAS,KAAK,WAAW,CAAC;AACrD;AAEA,SAAS,gBAAgB,SAAiC;AACxD,SAAO,QAAQ,OAAO,CAAC,MAAM,EAAE,OAAO,WAAW,CAAC,EAAE,IAAI,CAAC,MAAM,EAAE,QAAQ;AAC3E;AAEO,SAAS,UAAU,MAA2B;AACnD,QAAM,OAAOC,OAAM,IAAI;AAEvB,QAAM,UAAwB;AAAA,IAC5B,YAAY,IAAI;AAAA,IAChB,gBAAgB,IAAI;AAAA,IACpB,iBAAiB,IAAI;AAAA,IACrB,aAAa,IAAI;AAAA,IACjB,WAAW,IAAI;AAAA,IACf,gBAAgB,IAAI;AAAA,IACpB,kBAAkB,IAAI;AAAA,IACtB,cAAc,IAAI;AAAA,IAClB,cAAc,IAAI;AAAA,IAClB,YAAY,IAAI;AAAA,IAChB,aAAa,IAAI;AAAA,IACjB,WAAW,IAAI;AAAA,IACf,kBAAkB,IAAI;AAAA,IACtB,gBAAgB,IAAI;AAAA,IACpB,UAAU,IAAI;AAAA,EAChB;AAEA,QAAM,YAAY,QAAQ,QAAQ,CAAC,MAAM,EAAE,MAAM;AACjD,QAAM,SAAsB,UAAU,IAAI,CAAC,OAAO;AAAA,IAChD,GAAG;AAAA,IACH,YAAY,qBAAqB,EAAE,MAAM,EAAE,IAAI;AAAA,EACjD,EAAE;AACF,QAAM,SAAS,gBAAgB,OAAO;AACtC,QAAM,QAAQ,aAAa,MAAM;AAEjC,SAAO;AAAA,IACL,SAAS;AAAA,MACP;AAAA,QACE,MAAM;AAAA,QACN,MAAM,KAAK,UAAU;AAAA,UACnB;AAAA,UACA;AAAA,UACA;AAAA,UACA,MAAM;AAAA,UACN,aAAa,KAAK,IAAI,IAAI,KAAK,OAAO,SAAS,CAAC;AAAA,QAClD,CAAC;AAAA,MACH;AAAA,IACF;AAAA,EACF;AACF;;;AlB7EA,IAAM,SAAS,IAAI;AAAA,EACjB;AAAA,IACE,MAAM;AAAA,IACN,SAAS;AAAA,EACX;AAAA,EAEA;AAAA,IACE,cAAc;AAAA,MACZ,OAAO,CAAC;AAAA,IACV;AAAA,EACF;AACF;AAEA,OAAO,kBAAkB,wBAAwB,aAAa;AAAA,EAC5D,OAAO;AAAA,IACL;AAAA,MACE,MAAM;AAAA,MACN,aAAa;AAAA,MACb,aAAa;AAAA,QACX,MAAM;AAAA,QACN,YAAY,CAAC;AAAA,MACf;AAAA,IACF;AAAA,IAEA;AAAA,MACE,MAAM;AAAA,MACN,aAAa;AAAA,MACb,aAAa;AAAA,QACX,MAAM;AAAA,QACN,YAAY;AAAA,UACV,MAAM;AAAA,YACJ,MAAM;AAAA,UACR;AAAA,QACF;AAAA,QAEA,UAAU,CAAC,MAAM;AAAA,MACnB;AAAA,IACF;AAAA,IAEA;AAAA,MACE,MAAM;AAAA,MACN,aAAa;AAAA,MACb,aAAa;AAAA,QACX,MAAM;AAAA,QACN,YAAY;AAAA,UACV,MAAM;AAAA,YACJ,MAAM;AAAA,UACR;AAAA,QACF;AAAA,QACA,UAAU,CAAC,MAAM;AAAA,MACnB;AAAA,IACF;AAAA,IAEA;AAAA,MACE,MAAM;AAAA,MACN,aAAa;AAAA,MACb,aAAa;AAAA,QACX,MAAM;AAAA,QACN,YAAY;AAAA,UACV,MAAM;AAAA,YACJ,MAAM;AAAA,UACR;AAAA,QACF;AAAA,QACA,UAAU,CAAC,MAAM;AAAA,MACnB;AAAA,IACF;AAAA,IAEA;AAAA,MACE,MAAM;AAAA,MACN,aAAa;AAAA,MACb,aAAa;AAAA,QACX,MAAM;AAAA,QACN,YAAY;AAAA,UACV,aAAa;AAAA,YACX,MAAM;AAAA,UACR;AAAA,QACF;AAAA,QACA,UAAU,CAAC,aAAa;AAAA,MAC1B;AAAA,IACF;AAAA,IACA;AAAA,MACE,MAAM;AAAA,MAEN,aAAa;AAAA,MAEb,aAAa;AAAA,QACX,MAAM;AAAA,QAEN,YAAY;AAAA,UACV,QAAQ;AAAA,YACN,MAAM;AAAA,UACR;AAAA,QACF;AAAA,QAEA,UAAU,CAAC,QAAQ;AAAA,MACrB;AAAA,IACF;AAAA,IACA;AAAA,MACE,MAAM;AAAA,MAEN,aAAa;AAAA,MAEb,aAAa;AAAA,QACX,MAAM;AAAA,QAEN,YAAY;AAAA,UACV,MAAM;AAAA,YACJ,MAAM;AAAA,UACR;AAAA,QACF;AAAA,QAEA,UAAU,CAAC,MAAM;AAAA,MACnB;AAAA,IACF;AAAA,EACF;AACF,EAAE;AAEF,OAAO,kBAAkB,uBAAuB,OAAO,YAAY;AACjE,QAAM,EAAE,MAAM,WAAW,KAAK,IAAI,QAAQ;AAE1C,UAAQ,MAAM;AAAA,IACZ,KAAK;AACH,aAAO,eAAe;AAAA,IAExB,KAAK;AACH,aAAO,YAAY,IAAI;AAAA,IAEzB,KAAK;AACH,aAAO,SAAS,IAAI;AAAA,IAEtB,KAAK,YAAY;AACf,YAAM,eAAe;AAErB,aAAO,SAAS,aAAa,QAAQ,EAAE;AAAA,IACzC;AAAA,IAEA,KAAK,gBAAgB;AACnB,YAAM,aAAa;AAEnB,aAAO,MAAM,WAAW,WAAW,eAAe,EAAE;AAAA,IACtD;AAAA,IACA,KAAK,kBAAkB;AACrB,aAAO,cAAc,IAAI;AAAA,IAC3B;AAAA,IACA,KAAK,cAAc;AACjB,YAAM,WAAW;AAEjB,aAAO,UAAU,SAAS,QAAQ,EAAE;AAAA,IACtC;AAAA,IAEA;AACE,aAAO;AAAA,QACL,SAAS;AAAA,UACP;AAAA,YACE,MAAM;AAAA,YAEN,MAAM,KAAK,UAAU;AAAA,cACnB,OAAO,iBAAiB,IAAI;AAAA,YAC9B,CAAC;AAAA,UACH;AAAA,QACF;AAAA,MACF;AAAA,EACJ;AACF,CAAC;AAED,eAAe,QAAQ;AACrB,UAAQ,IAAI,YAAY;AACxB,UAAQ,IAAI,WAAW,MAAM;AAC7B,QAAM,YAAY,IAAI,qBAAqB;AAC3C,QAAM,OAAO,QAAQ,SAAS;AAC9B,UAAQ,IAAI,mBAAmB;AACjC;AACA,MAAM;","names":["z","schema","z","path","readFileSync","fileURLToPath","__filename","fileURLToPath","__dirname","path","readFileSync","readFileSync","existsSync","path","fileURLToPath","emmet","path","fileURLToPath","path2","path3","existsSync","readFileSync","emmet","readFileSync","existsSync","path","fileURLToPath","__filename","__dirname","z","schema","z","parse","id","parse"]}
|
|
1
|
+
{"version":3,"sources":["../src/server.ts","../src/context/api-context.ts"],"sourcesContent":["import { Server } from '@modelcontextprotocol/sdk/server/index.js'\nimport { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js'\nimport {\n ListToolsRequestSchema,\n CallToolRequestSchema\n} from '@modelcontextprotocol/sdk/types.js'\n\nimport type { MCPResponse } from './types.js'\nimport { apiContext } from './context/api-context.js'\nimport {\n listComponents,\n getManifest,\n getEmmet,\n validateHtml,\n howToBuild,\n generateTheme,\n auditA11y,\n preview,\n getTokenSummary,\n recordCall,\n createHandoff,\n applyHandoff\n} from '@mindfiredigital/ignix-lite-engine'\n\ntype ValidateArgs = {\n html?: string\n}\n\ntype IntentArgs = {\n description?: string\n}\n\ntype A11yArgs = {\n html?: string\n}\n\ntype PreviewArgs = {\n input: string\n options?: {\n width?: number\n theme?: string\n scale?: number\n }\n}\n\ntype CreateHandoffArgs = {\n rendered_html: string\n metadata?: Record<string, unknown>\n}\n\ntype ApplyHandoffArgs = {\n handoff_id: string\n changes: Array<{\n selector: string\n action: 'update' | 'add' | 'remove'\n emmet?: string\n html?: string\n }>\n}\n\nconst server = new Server(\n {\n name: 'ignix-lite',\n version: '2.0.0'\n },\n {\n capabilities: {\n tools: {}\n }\n }\n)\n\nserver.setRequestHandler(ListToolsRequestSchema, async () => ({\n tools: [\n {\n name: 'list_components',\n description: 'List all ignix-lite components',\n inputSchema: {\n type: 'object',\n properties: {}\n }\n },\n {\n name: 'get_manifest',\n description: 'Get component manifest',\n inputSchema: {\n type: 'object',\n properties: {\n name: {\n type: 'string'\n }\n },\n required: ['name']\n }\n },\n {\n name: 'get_emmet',\n description: 'Get emmet pattern',\n inputSchema: {\n type: 'object',\n properties: {\n name: {\n type: 'string'\n }\n },\n required: ['name']\n }\n },\n {\n name: 'validate',\n description: 'Validate ignix-lite html',\n inputSchema: {\n type: 'object',\n properties: {\n html: {\n type: 'string'\n }\n },\n required: ['html']\n }\n },\n {\n name: 'how_to_build',\n description: 'Convert plain english to ignix-lite UI',\n inputSchema: {\n type: 'object',\n properties: {\n description: {\n type: 'string'\n }\n },\n required: ['description']\n }\n },\n {\n name: 'generate_theme',\n description: 'Generate ignix theme tokens',\n inputSchema: {\n type: 'object',\n properties: {\n prompt: {\n type: 'string'\n }\n },\n required: ['prompt']\n }\n },\n {\n name: 'check_a11y',\n description: 'Check accessibility',\n inputSchema: {\n type: 'object',\n properties: {\n html: {\n type: 'string'\n }\n },\n required: ['html']\n }\n },\n {\n name: 'preview',\n description: 'Render visual preview to PNG',\n inputSchema: {\n type: 'object',\n properties: {\n input: {\n type: 'string'\n },\n options: {\n type: 'object',\n properties: {\n width: {\n type: 'number'\n },\n theme: {\n type: 'string'\n },\n scale: {\n type: 'number'\n }\n }\n }\n },\n required: ['input']\n }\n },\n {\n name: 'get_token_summary',\n description: 'Get session token summary and budget details',\n inputSchema: {\n type: 'object',\n properties: {\n context_window: {\n type: 'number',\n description: 'Optional model context window size'\n }\n }\n }\n },\n {\n name: 'create_handoff',\n description: 'Create multi-agent handoff snapshot',\n inputSchema: {\n type: 'object',\n properties: {\n rendered_html: {\n type: 'string'\n },\n metadata: {\n type: 'object'\n }\n },\n required: ['rendered_html']\n }\n },\n {\n name: 'apply_handoff',\n description: 'Apply changes to an existing handoff snapshot',\n inputSchema: {\n type: 'object',\n properties: {\n handoff_id: {\n type: 'string'\n },\n changes: {\n type: 'array',\n items: {\n type: 'object',\n properties: {\n selector: {\n type: 'string'\n },\n action: {\n type: 'string',\n enum: ['update', 'add', 'remove']\n },\n emmet: {\n type: 'string'\n },\n html: {\n type: 'string'\n }\n },\n required: ['selector', 'action']\n }\n }\n },\n required: ['handoff_id', 'changes']\n }\n }\n ]\n}))\n\nserver.setRequestHandler(CallToolRequestSchema, async (request) => {\n const { name, arguments: args } = request.params\n console.error('TOOL CALLED:', name)\n let response: MCPResponse\n\n switch (name) {\n case 'list_components':\n response = listComponents()\n break\n\n case 'get_manifest':\n response = getManifest(args)\n break\n\n case 'get_emmet':\n response = getEmmet(args)\n break\n\n case 'validate': {\n const validateArgs = args as ValidateArgs\n const result = validateHtml(validateArgs.html ?? '')\n response = {\n content: [\n {\n type: 'text',\n text: JSON.stringify({\n ...result,\n tokens_used: 50\n })\n }\n ]\n }\n break\n }\n\n case 'how_to_build': {\n const intentArgs = args as IntentArgs\n response = await howToBuild(intentArgs.description ?? '')\n break\n }\n\n case 'generate_theme':\n response = generateTheme(args)\n break\n\n case 'check_a11y': {\n const a11yArgs = args as A11yArgs\n const result = auditA11y(a11yArgs.html ?? '')\n response = {\n content: [\n {\n type: 'text',\n text: JSON.stringify({\n ...result,\n tokens_used: Math.min(60, 20 + result.issues.length * 3)\n })\n }\n ]\n }\n break\n }\n\n case 'preview': {\n const previewArgs = args as PreviewArgs\n response = await preview(previewArgs)\n break\n }\n\n case 'get_token_summary': {\n const tokenArgs = args as { context_window?: number }\n response = getTokenSummary(tokenArgs)\n break\n }\n\n case 'create_handoff': {\n const handoffArgs = args as CreateHandoffArgs\n response = createHandoff(handoffArgs)\n break\n }\n\n case 'apply_handoff': {\n const applyArgs = args as ApplyHandoffArgs\n response = applyHandoff(applyArgs)\n break\n }\n\n default:\n response = {\n content: [\n {\n type: 'text',\n text: JSON.stringify({\n error: `Unknown tool: ${name}`\n })\n }\n ]\n }\n break\n }\n\n // Intercept and record tokens_used if present in the response\n if (\n response &&\n response.content &&\n response.content[0] &&\n response.content[0].text\n ) {\n try {\n const parsed = JSON.parse(response.content[0].text)\n if (parsed && typeof parsed.tokens_used === 'number') {\n recordCall(name, parsed.tokens_used)\n }\n } catch {\n // Ignore if response text is not valid JSON\n }\n }\n\n return response\n})\n\nasync function start() {\n console.error('API loaded')\n console.error(apiContext.length)\n const transport = new StdioServerTransport()\n await server.connect(transport)\n console.error('Ignix MCP started')\n}\n\nstart()\n","import { readFileSync, existsSync } from 'fs'\nimport path from 'path'\nimport { fileURLToPath } from 'url'\n\nconst __filename = fileURLToPath(import.meta.url)\nconst __dirname = path.dirname(__filename)\n\n// Dynamically handle both bundled dist/ and source src/context/ contexts\nlet apiPath = path.resolve(__dirname, '../../../api-full.txt')\nif (!existsSync(apiPath)) {\n apiPath = path.resolve(__dirname, '../../../../api-full.txt')\n}\n\nexport const apiContext = readFileSync(apiPath, 'utf8')\n"],"mappings":"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","names":[]}
|
package/dist/utils/check-api.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/utils/check-api.ts"],"sourcesContent":["import { readFileSync } from 'fs'\nimport { encoding_for_model } from 'tiktoken'\nimport path from 'path'\n\nconst encoder = encoding_for_model('gpt-4')\n\nconst files = ['../../api-full.txt']\n\nfor (const file of files) {\n const text = readFileSync(path.resolve(file), 'utf-8')\n\n console.log(file, '=', encoder.encode(text).length, 'tokens')\n}\n"],"mappings":"
|
|
1
|
+
{"version":3,"sources":["../../src/utils/check-api.ts"],"sourcesContent":["import { readFileSync } from 'fs'\nimport { encoding_for_model } from 'tiktoken'\nimport path from 'path'\n\nconst encoder = encoding_for_model('gpt-4')\n\nconst files = ['../../api-full.txt']\n\nfor (const file of files) {\n const text = readFileSync(path.resolve(file), 'utf-8')\n\n console.log(file, '=', encoder.encode(text).length, 'tokens')\n}\n"],"mappings":";;;AAAA,SAAS,oBAAoB;AAC7B,SAAS,0BAA0B;AACnC,OAAO,UAAU;AAEjB,IAAM,UAAU,mBAAmB,OAAO;AAE1C,IAAM,QAAQ,CAAC,oBAAoB;AAEnC,WAAW,QAAQ,OAAO;AACxB,QAAM,OAAO,aAAa,KAAK,QAAQ,IAAI,GAAG,OAAO;AAErD,UAAQ,IAAI,MAAM,KAAK,QAAQ,OAAO,IAAI,EAAE,QAAQ,QAAQ;AAC9D;","names":[]}
|
package/package.json
CHANGED
|
@@ -1,16 +1,22 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mindfiredigital/ignix-lite-mcp",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.4.0",
|
|
4
4
|
"description": "",
|
|
5
5
|
"type": "module",
|
|
6
|
-
"main": "
|
|
6
|
+
"main": "./dist/server.js",
|
|
7
|
+
"bin": {
|
|
8
|
+
"ignix-lite-mcp": "./dist/server.js"
|
|
9
|
+
},
|
|
10
|
+
"files": [
|
|
11
|
+
"dist",
|
|
12
|
+
"README.md"
|
|
13
|
+
],
|
|
7
14
|
"scripts": {
|
|
8
15
|
"test": "vitest run",
|
|
9
|
-
"dev": "tsup src/server.ts --watch --format esm --no-clean
|
|
16
|
+
"dev": "tsup src/server.ts --watch --format esm --no-clean",
|
|
10
17
|
"lint": "eslint .",
|
|
11
18
|
"format": "prettier --write .",
|
|
12
|
-
"build": "tsup
|
|
13
|
-
"build:index": "tsx src/tools/build-index.ts"
|
|
19
|
+
"build": "tsup"
|
|
14
20
|
},
|
|
15
21
|
"keywords": [],
|
|
16
22
|
"author": "",
|
|
@@ -30,9 +36,11 @@
|
|
|
30
36
|
"vitest": "^4.1.4"
|
|
31
37
|
},
|
|
32
38
|
"dependencies": {
|
|
39
|
+
"@mindfiredigital/ignix-lite-engine": "workspace:*",
|
|
33
40
|
"@modelcontextprotocol/sdk": "^1.29.0",
|
|
34
41
|
"emmet": "^2.4.11",
|
|
35
42
|
"node-html-parser": "^7.1.0",
|
|
43
|
+
"playwright": "^1.60.0",
|
|
36
44
|
"zod": "^4.4.3"
|
|
37
45
|
}
|
|
38
|
-
}
|
|
46
|
+
}
|
package/.turbo/turbo-build.log
DELETED
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
|
|
2
|
-
> @mindfiredigital/ignix-lite-mcp@1.2.0 build /home/runner/work/ignix-lite/ignix-lite/packages/mcp
|
|
3
|
-
> tsup && copyfiles -u 2 src/manifests/*.json dist/manifests && pnpm build:index
|
|
4
|
-
|
|
5
|
-
[34mCLI[39m Building entry: src/server.ts, src/utils/check-api.ts
|
|
6
|
-
[34mCLI[39m Using tsconfig: tsconfig.json
|
|
7
|
-
[34mCLI[39m tsup v8.5.1
|
|
8
|
-
[34mCLI[39m Using tsup config: /home/runner/work/ignix-lite/ignix-lite/packages/mcp/tsup.config.ts
|
|
9
|
-
[34mCLI[39m Target: es2020
|
|
10
|
-
[34mCLI[39m Cleaning output folder
|
|
11
|
-
[34mESM[39m Build start
|
|
12
|
-
[32mESM[39m [1mdist/server.js [22m[32m62.14 KB[39m
|
|
13
|
-
[32mESM[39m [1mdist/utils/check-api.js [22m[32m402.00 B[39m
|
|
14
|
-
[32mESM[39m [1mdist/server.js.map [22m[32m119.01 KB[39m
|
|
15
|
-
[32mESM[39m [1mdist/utils/check-api.js.map [22m[32m693.00 B[39m
|
|
16
|
-
[32mESM[39m ⚡️ Build success in 108ms
|
|
17
|
-
[34mDTS[39m Build start
|
|
18
|
-
[32mDTS[39m ⚡️ Build success in 5366ms
|
|
19
|
-
[32mDTS[39m [1mdist/server.d.ts [22m[32m13.00 B[39m
|
|
20
|
-
[32mDTS[39m [1mdist/utils/check-api.d.ts [22m[32m13.00 B[39m
|
|
21
|
-
|
|
22
|
-
> @mindfiredigital/ignix-lite-mcp@1.2.0 build:index /home/runner/work/ignix-lite/ignix-lite/packages/mcp
|
|
23
|
-
> tsx src/tools/build-index.ts
|
|
24
|
-
|
|
25
|
-
Vector index built
|
package/CHANGELOG.md
DELETED
|
@@ -1,61 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"component": "accordion",
|
|
3
|
-
"version": "2.0",
|
|
4
|
-
|
|
5
|
-
"description": "Displays expandable content sections using native HTML details and summary elements. Works without JavaScript and is accessible by default.",
|
|
6
|
-
|
|
7
|
-
"element": "details",
|
|
8
|
-
|
|
9
|
-
"emmet": "details[open?]>summary{title}+p{content}",
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
"props": {
|
|
13
|
-
"open": {
|
|
14
|
-
"type": "boolean",
|
|
15
|
-
"native": true,
|
|
16
|
-
"agent_hint": "Use open to keep accordion expanded by default."
|
|
17
|
-
}
|
|
18
|
-
},
|
|
19
|
-
|
|
20
|
-
"states": ["open"],
|
|
21
|
-
|
|
22
|
-
"forbidden_props": ["expanded", "isOpen", "collapsed", "variant", "class"],
|
|
23
|
-
|
|
24
|
-
"required_props": [],
|
|
25
|
-
|
|
26
|
-
"required_slots": [],
|
|
27
|
-
|
|
28
|
-
"required_children": ["summary"],
|
|
29
|
-
|
|
30
|
-
"do": [
|
|
31
|
-
"Use summary as the accordion trigger",
|
|
32
|
-
"Use open to expand by default",
|
|
33
|
-
"Use native details element for accessibility"
|
|
34
|
-
],
|
|
35
|
-
|
|
36
|
-
"dont": [
|
|
37
|
-
"Do not replace details with div",
|
|
38
|
-
"Do not use JavaScript for open state",
|
|
39
|
-
"Do not use class attribute"
|
|
40
|
-
],
|
|
41
|
-
|
|
42
|
-
"examples": [
|
|
43
|
-
{
|
|
44
|
-
"label": "Default accordion",
|
|
45
|
-
"emmet": "details>summary{What is ignix-lite?}+p{Lightweight semantic UI library}",
|
|
46
|
-
"html": "<details><summary>What is ignix-lite?</summary><p>Lightweight semantic UI library</p></details>"
|
|
47
|
-
},
|
|
48
|
-
|
|
49
|
-
{
|
|
50
|
-
"label": "Open by default",
|
|
51
|
-
"emmet": "details[open]>summary{How does this work?}+p{Uses native browser behavior}",
|
|
52
|
-
"html": "<details open><summary>How does this work?</summary><p>Uses native browser behavior</p></details>"
|
|
53
|
-
},
|
|
54
|
-
|
|
55
|
-
{
|
|
56
|
-
"label": "FAQ item",
|
|
57
|
-
"emmet": "details>summary{Does it require JS?}+p{No, it works without JavaScript}",
|
|
58
|
-
"html": "<details><summary>Does it require JS?</summary><p>No, it works without JavaScript</p></details>"
|
|
59
|
-
}
|
|
60
|
-
]
|
|
61
|
-
}
|
|
@@ -1,69 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"component": "alert",
|
|
3
|
-
"version": "2.0",
|
|
4
|
-
|
|
5
|
-
"description": "Displays semantic feedback messages using native <aside> element for warnings, errors, success messages, and informational updates.",
|
|
6
|
-
|
|
7
|
-
"element": "aside",
|
|
8
|
-
|
|
9
|
-
"emmet": "aside[data-intent=?]{message}",
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
"props": {
|
|
13
|
-
"data-intent": {
|
|
14
|
-
"type": "enum",
|
|
15
|
-
"values": ["danger", "warning", "success", "info"],
|
|
16
|
-
"default": "info",
|
|
17
|
-
"native": false,
|
|
18
|
-
"agent_hint": "Use danger for errors, warning for cautions, success for confirmations, info for updates."
|
|
19
|
-
}
|
|
20
|
-
},
|
|
21
|
-
|
|
22
|
-
"states": [],
|
|
23
|
-
|
|
24
|
-
"forbidden_props": [
|
|
25
|
-
"variant",
|
|
26
|
-
"color",
|
|
27
|
-
"appearance",
|
|
28
|
-
"colorScheme",
|
|
29
|
-
"severity",
|
|
30
|
-
"status",
|
|
31
|
-
"class"
|
|
32
|
-
],
|
|
33
|
-
|
|
34
|
-
"required_props": [],
|
|
35
|
-
|
|
36
|
-
"required_slots": [],
|
|
37
|
-
|
|
38
|
-
"do": [
|
|
39
|
-
"Use data-intent='danger' for error states",
|
|
40
|
-
"Use data-intent='warning' for caution messages",
|
|
41
|
-
"Use native aside element for semantic alerts"
|
|
42
|
-
],
|
|
43
|
-
|
|
44
|
-
"dont": [
|
|
45
|
-
"Do not use div instead of aside",
|
|
46
|
-
"Do not use variant or severity props",
|
|
47
|
-
"Do not use class attribute"
|
|
48
|
-
],
|
|
49
|
-
|
|
50
|
-
"examples": [
|
|
51
|
-
{
|
|
52
|
-
"label": "Danger alert",
|
|
53
|
-
"emmet": "aside[data-intent=danger]{Something went wrong}",
|
|
54
|
-
"html": "<aside data-intent=\"danger\">Something went wrong</aside>"
|
|
55
|
-
},
|
|
56
|
-
|
|
57
|
-
{
|
|
58
|
-
"label": "Warning alert",
|
|
59
|
-
"emmet": "aside[data-intent=warning]{Session expires soon}",
|
|
60
|
-
"html": "<aside data-intent=\"warning\">Session expires soon</aside>"
|
|
61
|
-
},
|
|
62
|
-
|
|
63
|
-
{
|
|
64
|
-
"label": "Success alert",
|
|
65
|
-
"emmet": "aside[data-intent=success]{Saved successfully}",
|
|
66
|
-
"html": "<aside data-intent=\"success\">Saved successfully</aside>"
|
|
67
|
-
}
|
|
68
|
-
]
|
|
69
|
-
}
|