@elixpo/lixsketch 5.6.2 → 5.6.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
- "sources": ["../../src/mcp/scene.js", "../../src/mcp/templates.js", "../../src/mcp/preview.js", "../../src/mcp/server.js", "../../src/mcp/store.js"],
4
- "sourcesContent": ["const FORMAT = 'lixsketch';\nconst VERSION = 1;\nconst MAX_SHAPES = 5000;\nconst MAX_OPERATIONS = 500;\nconst SCENE_TYPES = new Set(['rectangle', 'circle', 'line', 'arrow', 'freehandStroke', 'frame', 'text', 'code', 'image', 'icon']);\nconst WRITABLE_TYPES = new Set(['rectangle', 'circle', 'line', 'arrow', 'freehandStroke', 'frame', 'text']);\n\nconst clone = (value) => JSON.parse(JSON.stringify(value));\nconst finite = (value, fallback = 0) => Number.isFinite(Number(value)) ? Number(value) : fallback;\nconst positive = (value, fallback = 1) => Math.max(1, finite(value, fallback));\n\nexport function createEmptyScene(name = 'MCP Canvas') {\n return {\n format: FORMAT,\n version: VERSION,\n sessionID: `mcp-${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 8)}`,\n name: String(name || 'MCP Canvas').trim().slice(0, 72),\n createdAt: new Date().toISOString(),\n viewport: { x: 0, y: 0, width: 1280, height: 720 },\n zoom: 1,\n mcpRevision: 0,\n shapes: [],\n };\n}\n\nexport function validateScene(scene) {\n const errors = [];\n if (!scene || typeof scene !== 'object') return { valid: false, errors: ['Scene must be an object'] };\n if (scene.format !== FORMAT) errors.push(`Scene format must be \"${FORMAT}\"`);\n if (scene.version !== VERSION) errors.push(`Scene version must be ${VERSION}`);\n if (!Array.isArray(scene.shapes)) errors.push('Scene shapes must be an array');\n if (Array.isArray(scene.shapes) && scene.shapes.length > MAX_SHAPES) errors.push(`Scene exceeds ${MAX_SHAPES} shapes`);\n const ids = new Set();\n for (const [index, shape] of (scene.shapes || []).entries()) {\n if (!shape || typeof shape !== 'object') { errors.push(`Shape ${index} must be an object`); continue; }\n if (!SCENE_TYPES.has(shape.type)) errors.push(`Shape ${index} has unsupported type \"${shape.type}\"`);\n if (!shape.shapeID || typeof shape.shapeID !== 'string') errors.push(`Shape ${index} is missing shapeID`);\n else if (ids.has(shape.shapeID)) errors.push(`Duplicate shapeID \"${shape.shapeID}\"`);\n else ids.add(shape.shapeID);\n validateShapeGeometry(shape, index, errors);\n }\n return { valid: errors.length === 0, errors };\n}\n\nfunction escapeXml(value) {\n return String(value).replaceAll('&', '&amp;').replaceAll('<', '&lt;').replaceAll('>', '&gt;').replaceAll('\"', '&quot;').replaceAll(\"'\", '&apos;');\n}\n\nfunction normalizeOptions(value = {}) {\n return {\n roughness: Math.max(0, Math.min(3, finite(value.roughness, 1.2))),\n stroke: typeof value.stroke === 'string' ? value.stroke : '#8b76d6',\n strokeWidth: Math.max(0.5, Math.min(20, finite(value.strokeWidth, 2))),\n fill: typeof value.fill === 'string' ? value.fill : 'transparent',\n fillStyle: typeof value.fillStyle === 'string' ? value.fillStyle : 'solid',\n opacity: Math.max(0, Math.min(1, finite(value.opacity, 1))),\n };\n}\n\nfunction createTextShape(input, shapeID) {\n const x = finite(input.x), y = finite(input.y), rotation = finite(input.rotation);\n const text = String(input.text || '').slice(0, 10000);\n const fontSize = Math.max(8, Math.min(160, finite(input.fontSize, 20)));\n const color = typeof input.color === 'string' ? input.color : '#e8e3f3';\n const family = typeof input.fontFamily === 'string' ? input.fontFamily.slice(0, 80) : 'lixFont';\n const transform = `translate(${x}, ${y})${rotation ? ` rotate(${rotation}, 0, 0)` : ''}`;\n const lines = text.split('\\n').map((line, index) => `<tspan x=\"0\" dy=\"${index === 0 ? 0 : '1.2em'}\">${escapeXml(line || ' ')}</tspan>`).join('');\n return {\n shapeID, type: 'text', x, y, rotation,\n mcpText: text, mcpFontSize: fontSize, mcpColor: color, mcpFontFamily: family,\n groupHTML: `<g id=\"${escapeXml(shapeID)}\" data-type=\"text-group\" data-x=\"${x}\" data-y=\"${y}\" transform=\"${transform}\"><text id=\"${escapeXml(shapeID)}-text\" x=\"0\" y=\"0\" fill=\"${escapeXml(color)}\" font-size=\"${fontSize}\" font-family=\"${escapeXml(family)}\" dominant-baseline=\"hanging\" white-space=\"pre\" pointer-events=\"painted\" data-type=\"text\" data-initial-size=\"${fontSize}\" data-initial-font=\"${escapeXml(family)}\" data-initial-color=\"${escapeXml(color)}\">${lines}</text></g>`,\n };\n}\n\nexport function normalizeShape(input, existingIds = new Set()) {\n if (!input || typeof input !== 'object') throw new Error('Shape must be an object');\n if (!WRITABLE_TYPES.has(input.type)) throw new Error(`Shape type \"${input.type}\" is read-only through MCP`);\n let shapeID = String(input.shapeID || `${input.type}-${crypto.randomUUID()}`).slice(0, 120);\n while (existingIds.has(shapeID)) shapeID = `${input.type}-${crypto.randomUUID()}`;\n const base = { shapeID, type: input.type, rotation: finite(input.rotation), options: normalizeOptions(input.options), groupId: input.groupId || null, parentFrame: input.parentFrame || null, docBlockIds: [] };\n switch (input.type) {\n case 'rectangle': return { ...base, x: finite(input.x), y: finite(input.y), width: positive(input.width, 160), height: positive(input.height, 90) };\n case 'circle': return { ...base, x: finite(input.x), y: finite(input.y), rx: positive(input.rx, 60), ry: positive(input.ry, 60) };\n case 'line': return { ...base, startPoint: point(input.startPoint), endPoint: point(input.endPoint, 120), isCurved: Boolean(input.isCurved), controlPoint: input.controlPoint ? point(input.controlPoint) : null };\n case 'arrow': return { ...base, startPoint: point(input.startPoint), endPoint: point(input.endPoint, 120), arrowHeadStyle: input.arrowHeadStyle || 'triangle', arrowOutlineStyle: input.arrowOutlineStyle || 'solid', arrowCurved: Boolean(input.arrowCurved), arrowCurveAmount: finite(input.arrowCurveAmount, 0.2) };\n case 'freehandStroke': {\n const points = (Array.isArray(input.points) ? input.points : []).slice(0, 4096).map((entry) => [finite(entry?.[0]), finite(entry?.[1]), finite(entry?.[2], 0.5)]);\n if (points.length < 2) throw new Error('freehandStroke requires at least two points');\n return { ...base, points };\n }\n case 'frame': return { ...base, x: finite(input.x), y: finite(input.y), width: positive(input.width, 640), height: positive(input.height, 360), frameName: String(input.frameName || 'Frame').slice(0, 80), fillStyle: input.fillStyle || 'transparent', fillColor: input.fillColor || '#1e1e28', gridSize: positive(input.gridSize, 20), containedShapeIDs: [] };\n case 'text': return { ...base, ...createTextShape(input, shapeID) };\n default: throw new Error(`Unsupported shape type \"${input.type}\"`);\n }\n}\n\nfunction point(value, fallbackX = 0) {\n return { x: finite(value?.x, fallbackX), y: finite(value?.y) };\n}\n\nfunction translateShape(shape, dx, dy) {\n const moved = clone(shape);\n if (moved.startPoint) { moved.startPoint.x += dx; moved.startPoint.y += dy; }\n if (moved.endPoint) { moved.endPoint.x += dx; moved.endPoint.y += dy; }\n if (moved.controlPoint) { moved.controlPoint.x += dx; moved.controlPoint.y += dy; }\n if (moved.controlPoint1) { moved.controlPoint1.x += dx; moved.controlPoint1.y += dy; }\n if (moved.controlPoint2) { moved.controlPoint2.x += dx; moved.controlPoint2.y += dy; }\n if (Array.isArray(moved.points)) moved.points = moved.points.map((p) => [p[0] + dx, p[1] + dy, ...p.slice(2)]);\n if (Number.isFinite(moved.x)) moved.x += dx;\n if (Number.isFinite(moved.y)) moved.y += dy;\n if (moved.type === 'text' && moved.groupHTML) {\n moved.groupHTML = moved.groupHTML\n .replace(/data-x=\"[^\"]*\"/, `data-x=\"${moved.x}\"`)\n .replace(/data-y=\"[^\"]*\"/, `data-y=\"${moved.y}\"`)\n .replace(/transform=\"translate\\([^)]*\\)/, `transform=\"translate(${moved.x}, ${moved.y})`);\n }\n if (moved.type === 'code' && moved.groupHTML) {\n moved.groupHTML = moved.groupHTML\n .replace(/data-x=\"[^\"]*\"/, `data-x=\"${moved.x}\"`)\n .replace(/data-y=\"[^\"]*\"/, `data-y=\"${moved.y}\"`)\n .replace(/transform=\"translate\\([^)]*\\)/, `transform=\"translate(${moved.x}, ${moved.y})`);\n }\n if (moved.type === 'icon' && moved.elementHTML) {\n moved.elementHTML = moved.elementHTML\n .replace(/\\bx=\"[^\"]*\"/, `x=\"${moved.x}\"`)\n .replace(/\\by=\"[^\"]*\"/, `y=\"${moved.y}\"`);\n }\n return moved;\n}\n\nexport function applyScenePatch(sceneInput, operations, { expectedRevision, dryRun = false } = {}) {\n const scene = clone(sceneInput);\n const check = validateScene(scene);\n if (!check.valid) throw new Error(`Invalid scene: ${check.errors.join('; ')}`);\n if (!Array.isArray(operations) || operations.length === 0) throw new Error('At least one operation is required');\n if (operations.length > MAX_OPERATIONS) throw new Error(`Patch exceeds ${MAX_OPERATIONS} operations`);\n const revision = Number(scene.mcpRevision || 0);\n if (expectedRevision !== undefined && Number(expectedRevision) !== revision) throw new Error(`Revision conflict: expected ${expectedRevision}, current ${revision}`);\n const changedIds = new Set();\n for (const operation of operations) {\n if (!operation || typeof operation !== 'object') throw new Error('Each operation must be an object');\n if (operation.op === 'add') {\n if (scene.shapes.length >= MAX_SHAPES) throw new Error(`Scene exceeds ${MAX_SHAPES} shapes`);\n const ids = new Set(scene.shapes.map((shape) => shape.shapeID));\n const shape = normalizeShape(operation.shape, ids);\n scene.shapes.push(shape); changedIds.add(shape.shapeID);\n } else if (operation.op === 'update') {\n const index = scene.shapes.findIndex((shape) => shape.shapeID === operation.shapeID);\n if (index < 0) throw new Error(`Shape \"${operation.shapeID}\" was not found`);\n const immutable = scene.shapes[index];\n scene.shapes[index] = applyShapeChanges(immutable, operation.changes || {}); changedIds.add(immutable.shapeID);\n } else if (operation.op === 'delete') {\n const ids = new Set(Array.isArray(operation.shapeIDs) ? operation.shapeIDs : [operation.shapeID]);\n const before = scene.shapes.length;\n scene.shapes = scene.shapes.filter((shape) => !ids.has(shape.shapeID));\n if (scene.shapes.length === before) throw new Error('No requested shapes were found');\n scene.shapes.forEach((shape) => {\n if (ids.has(shape.parentFrame)) shape.parentFrame = null;\n if (Array.isArray(shape.containedShapeIDs)) shape.containedShapeIDs = shape.containedShapeIDs.filter((id) => !ids.has(id));\n });\n ids.forEach((id) => changedIds.add(id));\n } else if (operation.op === 'translate') {\n const ids = new Set(operation.shapeIDs || []), dx = finite(operation.dx), dy = finite(operation.dy);\n if (!ids.size) throw new Error('translate requires shapeIDs');\n scene.shapes = scene.shapes.map((shape) => ids.has(shape.shapeID) ? translateShape(shape, dx, dy) : shape);\n ids.forEach((id) => changedIds.add(id));\n } else if (operation.op === 'rename_canvas') {\n scene.name = String(operation.name || '').trim().slice(0, 72) || scene.name;\n } else throw new Error(`Unsupported operation \"${operation.op}\"`);\n }\n scene.mcpRevision = revision + 1;\n scene.updatedAt = new Date().toISOString();\n const result = validateScene(scene);\n if (!result.valid) throw new Error(`Patch produced an invalid scene: ${result.errors.join('; ')}`);\n return { scene, revision: scene.mcpRevision, dryRun: Boolean(dryRun), changedShapeIDs: [...changedIds] };\n}\n\nfunction applyShapeChanges(shape, changes) {\n if (!changes || typeof changes !== 'object' || Array.isArray(changes)) throw new Error('Shape changes must be an object');\n const allowed = {\n rectangle: ['x', 'y', 'width', 'height', 'rotation', 'options', 'groupId', 'parentFrame'],\n circle: ['x', 'y', 'rx', 'ry', 'rotation', 'options', 'groupId', 'parentFrame'],\n line: ['startPoint', 'endPoint', 'controlPoint', 'isCurved', 'options', 'groupId', 'parentFrame'],\n arrow: ['startPoint', 'endPoint', 'controlPoint1', 'controlPoint2', 'arrowHeadStyle', 'arrowOutlineStyle', 'arrowCurved', 'arrowCurveAmount', 'options', 'groupId', 'parentFrame'],\n freehandStroke: ['points', 'rotation', 'options', 'groupId', 'parentFrame'],\n frame: ['x', 'y', 'width', 'height', 'rotation', 'frameName', 'fillStyle', 'fillColor', 'gridSize', 'options', 'groupId', 'parentFrame'],\n text: ['x', 'y', 'rotation', 'text', 'fontSize', 'color', 'fontFamily', 'groupId', 'parentFrame'],\n }[shape.type] || [];\n const rejected = Object.keys(changes).filter((key) => !allowed.includes(key));\n if (rejected.length) throw new Error(`Cannot update ${shape.type} fields: ${rejected.join(', ')}`);\n if (shape.type === 'text') {\n const text = changes.text ?? shape.mcpText ?? extractText(shape.groupHTML);\n return { ...shape, ...createTextShape({ x: changes.x ?? shape.x, y: changes.y ?? shape.y, rotation: changes.rotation ?? shape.rotation, text, fontSize: changes.fontSize ?? shape.mcpFontSize, color: changes.color ?? shape.mcpColor, fontFamily: changes.fontFamily ?? shape.mcpFontFamily }, shape.shapeID), groupId: changes.groupId ?? shape.groupId, parentFrame: changes.parentFrame ?? shape.parentFrame };\n }\n const copy = { ...clone(shape), ...clone(changes), shapeID: shape.shapeID, type: shape.type };\n if (changes.options) copy.options = { ...(shape.options || {}), ...normalizeOptions({ ...(shape.options || {}), ...changes.options }) };\n return copy;\n}\n\nfunction extractText(groupHTML = '') {\n return String(groupHTML).replace(/<[^>]+>/g, ' ').replace(/\\s+/g, ' ').trim();\n}\n\nfunction validateShapeGeometry(shape, index, errors) {\n const numbers = [];\n if (['rectangle', 'frame', 'text', 'code', 'image', 'icon'].includes(shape.type)) numbers.push(['x', shape.x], ['y', shape.y]);\n if (['rectangle', 'frame', 'image', 'icon'].includes(shape.type)) numbers.push(['width', shape.width], ['height', shape.height]);\n if (shape.type === 'circle') numbers.push(['x', shape.x], ['y', shape.y], ['rx', shape.rx], ['ry', shape.ry]);\n if (shape.startPoint) numbers.push(['startPoint.x', shape.startPoint.x], ['startPoint.y', shape.startPoint.y]);\n if (shape.endPoint) numbers.push(['endPoint.x', shape.endPoint.x], ['endPoint.y', shape.endPoint.y]);\n for (const [field, value] of numbers) if (!Number.isFinite(Number(value))) errors.push(`Shape ${index} has invalid ${field}`);\n if (['rectangle', 'frame', 'image', 'icon'].includes(shape.type) && (Number(shape.width) <= 0 || Number(shape.height) <= 0)) errors.push(`Shape ${index} must have positive dimensions`);\n if (shape.type === 'circle' && (Number(shape.rx) <= 0 || Number(shape.ry) <= 0)) errors.push(`Shape ${index} must have positive radii`);\n if (shape.type === 'freehandStroke' && (!Array.isArray(shape.points) || shape.points.length < 2 || shape.points.length > 4096)) errors.push(`Shape ${index} has invalid freehand points`);\n if (shape.type === 'text' && typeof shape.groupHTML !== 'string') errors.push(`Shape ${index} is missing text markup`);\n if (shape.type === 'code' && typeof shape.groupHTML !== 'string') errors.push(`Shape ${index} is missing code markup`);\n if (shape.type === 'image' && typeof shape.href !== 'string') errors.push(`Shape ${index} is missing image href`);\n if (shape.type === 'icon' && typeof shape.elementHTML !== 'string') errors.push(`Shape ${index} is missing icon markup`);\n}\n\nexport function getSceneSummary(scene) {\n const counts = {};\n for (const shape of scene.shapes || []) counts[shape.type] = (counts[shape.type] || 0) + 1;\n return { name: scene.name, format: scene.format, version: scene.version, revision: Number(scene.mcpRevision || 0), shapeCount: scene.shapes?.length || 0, counts, bounds: getSceneBounds(scene) };\n}\n\nexport function getSceneBounds(scene) {\n const boxes = (scene.shapes || []).map(shapeBounds).filter(Boolean);\n if (!boxes.length) return null;\n const minX = Math.min(...boxes.map((b) => b.x)), minY = Math.min(...boxes.map((b) => b.y));\n const maxX = Math.max(...boxes.map((b) => b.x + b.width)), maxY = Math.max(...boxes.map((b) => b.y + b.height));\n return { x: minX, y: minY, width: maxX - minX, height: maxY - minY };\n}\n\nexport function shapeBounds(shape) {\n if (shape.type === 'circle') return { x: shape.x - shape.rx, y: shape.y - shape.ry, width: shape.rx * 2, height: shape.ry * 2 };\n if (shape.startPoint && shape.endPoint) {\n const x = Math.min(shape.startPoint.x, shape.endPoint.x), y = Math.min(shape.startPoint.y, shape.endPoint.y);\n return { x, y, width: Math.abs(shape.endPoint.x - shape.startPoint.x), height: Math.abs(shape.endPoint.y - shape.startPoint.y) };\n }\n if (Array.isArray(shape.points) && shape.points.length) {\n const xs = shape.points.map((p) => p[0]), ys = shape.points.map((p) => p[1]);\n return { x: Math.min(...xs), y: Math.min(...ys), width: Math.max(...xs) - Math.min(...xs), height: Math.max(...ys) - Math.min(...ys) };\n }\n if (shape.type === 'text') return { x: finite(shape.x), y: finite(shape.y), width: 160, height: 32 };\n return { x: finite(shape.x), y: finite(shape.y), width: positive(shape.width), height: positive(shape.height) };\n}\n\nexport function mergeTemplateScene(sceneInput, templateInput, { x, y } = {}) {\n const scene = clone(sceneInput), template = clone(templateInput);\n const validation = validateScene(template);\n if (!validation.valid) throw new Error(`Template scene is invalid: ${validation.errors.join('; ')}`);\n if (scene.shapes.length + template.shapes.length > MAX_SHAPES) throw new Error(`Imported template would exceed ${MAX_SHAPES} shapes`);\n const bounds = getSceneBounds(template) || { x: 0, y: 0 };\n const targetX = finite(x, scene.viewport?.x || 0), targetY = finite(y, scene.viewport?.y || 0);\n const dx = targetX - bounds.x, dy = targetY - bounds.y;\n const idMap = new Map(template.shapes.map((shape) => [shape.shapeID, `${shape.type}-${crypto.randomUUID()}`]));\n const imported = template.shapes.map((shape) => {\n const moved = translateShape(shape, dx, dy);\n moved.shapeID = idMap.get(shape.shapeID);\n if (moved.parentFrame) moved.parentFrame = idMap.get(moved.parentFrame) || null;\n if (Array.isArray(moved.containedShapeIDs)) moved.containedShapeIDs = moved.containedShapeIDs.map((id) => idMap.get(id)).filter(Boolean);\n if (moved.startAttachmentID) moved.startAttachmentID = idMap.get(moved.startAttachmentID) || null;\n if (moved.endAttachmentID) moved.endAttachmentID = idMap.get(moved.endAttachmentID) || null;\n if (moved.groupHTML) moved.groupHTML = moved.groupHTML.split(shape.shapeID).join(moved.shapeID);\n if (moved.elementHTML) moved.elementHTML = moved.elementHTML.split(shape.shapeID).join(moved.shapeID);\n return moved;\n });\n scene.shapes.push(...imported);\n scene.mcpRevision = Number(scene.mcpRevision || 0) + 1;\n scene.updatedAt = new Date().toISOString();\n return { scene, revision: scene.mcpRevision, importedShapeIDs: imported.map((shape) => shape.shapeID) };\n}\n\nexport const MCP_LIMITS = Object.freeze({ maxShapes: MAX_SHAPES, maxOperations: MAX_OPERATIONS });\n", "const DEFAULT_MARKETPLACE_URL = 'https://sketch.elixpo.com';\n\nfunction decodeBase64Url(value) {\n const base64 = String(value).replaceAll('-', '+').replaceAll('_', '/');\n const padded = base64 + '='.repeat((4 - base64.length % 4) % 4);\n const binary = atob(padded);\n return Uint8Array.from(binary, (character) => character.charCodeAt(0));\n}\n\nexport async function decryptPublicTemplate(ciphertext, keyValue) {\n const keyBytes = decodeBase64Url(keyValue);\n if (keyBytes.byteLength !== 32) throw new Error('Template key is not AES-256');\n const combined = decodeBase64Url(ciphertext);\n if (combined.byteLength < 28) throw new Error('Template ciphertext is invalid');\n const key = await crypto.subtle.importKey('raw', keyBytes, { name: 'AES-GCM', length: 256 }, false, ['decrypt']);\n const plaintext = await crypto.subtle.decrypt({ name: 'AES-GCM', iv: combined.slice(0, 12) }, key, combined.slice(12));\n return JSON.parse(new TextDecoder().decode(plaintext));\n}\n\nexport class MarketplaceTemplateProvider {\n constructor({ baseUrl = DEFAULT_MARKETPLACE_URL, fetchImpl = globalThis.fetch } = {}) {\n if (typeof fetchImpl !== 'function') throw new Error('MarketplaceTemplateProvider requires fetch');\n this.baseUrl = String(baseUrl).replace(/\\/$/, '');\n this.fetch = fetchImpl;\n }\n\n async search({ query = '', tag = '', limit = 12 } = {}) {\n const url = new URL('/api/templates', this.baseUrl);\n if (query) url.searchParams.set('q', String(query).slice(0, 80));\n if (tag) url.searchParams.set('tag', String(tag).slice(0, 24));\n url.searchParams.set('limit', String(Math.min(24, Math.max(1, Number(limit) || 12))));\n const response = await this.fetch(url, { headers: { accept: 'application/json' } });\n const body = await response.json();\n if (!response.ok) throw new Error(body.error || `Marketplace request failed (${response.status})`);\n return body.templates || [];\n }\n\n async load(slug) {\n const safeSlug = String(slug || '').trim();\n if (!/^[a-z0-9-]{1,80}$/.test(safeSlug)) throw new Error('Template slug is invalid');\n const url = new URL(`/api/templates/${encodeURIComponent(safeSlug)}`, this.baseUrl);\n url.searchParams.set('snapshot', '1');\n const response = await this.fetch(url, { headers: { accept: 'application/json' } });\n const body = await response.json();\n if (!response.ok) throw new Error(body.error || `Template request failed (${response.status})`);\n const template = body.template;\n if (!template?.encryptedData || !template?.publicKey) throw new Error('Template snapshot is unavailable');\n return { metadata: { ...template, encryptedData: undefined, publicKey: undefined, encryptedDocData: undefined }, scene: await decryptPublicTemplate(template.encryptedData, template.publicKey) };\n }\n}\n\n", "import { getSceneBounds } from './scene.js';\n\nconst MAX_PREVIEW_BYTES = 5 * 1024 * 1024;\n\nconst esc = (value) => String(value ?? '').replaceAll('&', '&amp;').replaceAll('<', '&lt;').replaceAll('>', '&gt;').replaceAll('\"', '&quot;');\nconst color = (value, fallback) => typeof value === 'string' && /^#[0-9a-f]{3,8}$/i.test(value) ? value : fallback;\n\nfunction options(shape) {\n return {\n stroke: color(shape.options?.stroke, '#8b76d6'),\n fill: shape.options?.fill === 'transparent' ? 'none' : color(shape.options?.fill, 'none'),\n width: Math.max(0.5, Math.min(20, Number(shape.options?.strokeWidth) || 2)),\n opacity: Math.max(0, Math.min(1, Number(shape.options?.opacity) || 1)),\n };\n}\n\nfunction renderShape(shape) {\n const style = options(shape);\n const attrs = `stroke=\"${style.stroke}\" stroke-width=\"${style.width}\" fill=\"${style.fill}\" opacity=\"${style.opacity}\"`;\n if (shape.type === 'rectangle') return `<rect x=\"${shape.x}\" y=\"${shape.y}\" width=\"${shape.width}\" height=\"${shape.height}\" rx=\"6\" ${attrs}/>`;\n if (shape.type === 'circle') return `<ellipse cx=\"${shape.x}\" cy=\"${shape.y}\" rx=\"${shape.rx}\" ry=\"${shape.ry}\" ${attrs}/>`;\n if (shape.type === 'line') return `<line x1=\"${shape.startPoint.x}\" y1=\"${shape.startPoint.y}\" x2=\"${shape.endPoint.x}\" y2=\"${shape.endPoint.y}\" ${attrs}/>`;\n if (shape.type === 'arrow') return `<line x1=\"${shape.startPoint.x}\" y1=\"${shape.startPoint.y}\" x2=\"${shape.endPoint.x}\" y2=\"${shape.endPoint.y}\" ${attrs} marker-end=\"url(#arrowhead)\"/>`;\n if (shape.type === 'freehandStroke') return `<polyline points=\"${shape.points.map((p) => `${p[0]},${p[1]}`).join(' ')}\" ${attrs} fill=\"none\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>`;\n if (shape.type === 'frame') return `<g><rect x=\"${shape.x}\" y=\"${shape.y}\" width=\"${shape.width}\" height=\"${shape.height}\" ${attrs} stroke-dasharray=\"6 5\"/><text x=\"${shape.x + 8}\" y=\"${shape.y - 8}\" fill=\"#9f94b5\" font-size=\"14\">${esc(shape.frameName || 'Frame')}</text></g>`;\n if (shape.type === 'text') return `<text x=\"${shape.x}\" y=\"${shape.y}\" fill=\"${color(shape.mcpColor, '#e8e3f3')}\" font-size=\"${Number(shape.mcpFontSize) || 20}\" font-family=\"sans-serif\">${esc(shape.mcpText || String(shape.groupHTML || '').replace(/<[^>]+>/g, ' ').trim())}</text>`;\n return '';\n}\n\nexport function renderSceneSvg(scene, { background = '#15111f', padding = 40 } = {}) {\n const bounds = getSceneBounds(scene) || { x: 0, y: 0, width: 1280, height: 720 };\n const pad = Math.max(0, Math.min(200, Number(padding) || 0));\n const viewBox = { x: bounds.x - pad, y: bounds.y - pad, width: Math.max(1, bounds.width + pad * 2), height: Math.max(1, bounds.height + pad * 2) };\n const svg = `<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"${viewBox.x} ${viewBox.y} ${viewBox.width} ${viewBox.height}\" width=\"${Math.ceil(viewBox.width)}\" height=\"${Math.ceil(viewBox.height)}\"><defs><marker id=\"arrowhead\" markerWidth=\"10\" markerHeight=\"7\" refX=\"9\" refY=\"3.5\" orient=\"auto\"><polygon points=\"0 0,10 3.5,0 7\" fill=\"#8b76d6\"/></marker></defs><rect x=\"${viewBox.x}\" y=\"${viewBox.y}\" width=\"${viewBox.width}\" height=\"${viewBox.height}\" fill=\"${color(background, '#15111f')}\"/>${(scene.shapes || []).map(renderShape).join('')}</svg>`;\n if (new TextEncoder().encode(svg).byteLength > MAX_PREVIEW_BYTES) {\n throw new Error('Canvas preview exceeds the 5 MB output limit');\n }\n return svg;\n}\n", "import { applyScenePatch, createEmptyScene, getSceneSummary, mergeTemplateScene, validateScene, MCP_LIMITS } from './scene.js';\nimport { MarketplaceTemplateProvider } from './templates.js';\nimport { renderSceneSvg } from './preview.js';\n\nconst SERVER_NAME = 'lixsketch';\nconst SERVER_VERSION = '1.0.0';\nconst PROTOCOL_VERSION = '2025-11-25';\nconst SUPPORTED_PROTOCOL_VERSIONS = new Set([PROTOCOL_VERSION, '2025-06-18', '2024-11-05']);\n\nconst PATCH_OPERATION_SCHEMA = {\n oneOf: [\n { type: 'object', required: ['op', 'shape'], properties: { op: { const: 'add' }, shape: { type: 'object', description: 'A rectangle, circle, line, arrow, frame, freehandStroke, or text shape.' } } },\n { type: 'object', required: ['op', 'shapeID', 'changes'], properties: { op: { const: 'update' }, shapeID: { type: 'string' }, changes: { type: 'object' } } },\n { type: 'object', required: ['op'], properties: { op: { const: 'delete' }, shapeID: { type: 'string' }, shapeIDs: { type: 'array', items: { type: 'string' } } } },\n { type: 'object', required: ['op', 'shapeIDs', 'dx', 'dy'], properties: { op: { const: 'translate' }, shapeIDs: { type: 'array', items: { type: 'string' } }, dx: { type: 'number' }, dy: { type: 'number' } } },\n { type: 'object', required: ['op', 'name'], properties: { op: { const: 'rename_canvas' }, name: { type: 'string', maxLength: 72 } } },\n ],\n};\n\nexport const LIXSKETCH_MCP_TOOLS = Object.freeze([\n {\n name: 'canvas_get',\n title: 'Read LixSketch canvas',\n description: 'Return the canvas summary and optionally its editable scene shapes. Read this before mutation to obtain the current revision.',\n inputSchema: { type: 'object', properties: { includeShapes: { type: 'boolean', default: false }, shapeIDs: { type: 'array', maxItems: 500, items: { type: 'string' } } }, additionalProperties: false },\n annotations: { readOnlyHint: true, destructiveHint: false, idempotentHint: true },\n },\n {\n name: 'canvas_apply_patch',\n title: 'Apply atomic canvas patch',\n description: `Atomically add, update, translate, or delete shapes. Supports ${MCP_LIMITS.maxOperations} operations per call, optimistic revision checks, and dry runs.`,\n inputSchema: { type: 'object', required: ['operations'], properties: { expectedRevision: { type: 'integer', minimum: 0 }, dryRun: { type: 'boolean', default: false }, operations: { type: 'array', minItems: 1, maxItems: MCP_LIMITS.maxOperations, items: PATCH_OPERATION_SCHEMA } }, additionalProperties: false },\n annotations: { readOnlyHint: false, destructiveHint: true, idempotentHint: false },\n },\n {\n name: 'canvas_validate',\n title: 'Validate LixSketch canvas',\n description: 'Validate the current scene format, supported shapes, unique IDs, and package limits.',\n inputSchema: { type: 'object', properties: {}, additionalProperties: false },\n annotations: { readOnlyHint: true, destructiveHint: false, idempotentHint: true },\n },\n {\n name: 'canvas_preview',\n title: 'Render canvas preview',\n description: 'Render a lightweight SVG preview of the current scene for visual inspection before or after edits.',\n inputSchema: { type: 'object', properties: { background: { type: 'string', pattern: '^#[0-9a-fA-F]{3,8}$' }, padding: { type: 'number', minimum: 0, maximum: 200, default: 40 } }, additionalProperties: false },\n annotations: { readOnlyHint: true, destructiveHint: false, idempotentHint: true },\n },\n {\n name: 'canvas_new',\n title: 'Create blank LixSketch canvas',\n description: 'Replace the current scene with a blank canvas. Requires explicit confirmation.',\n inputSchema: { type: 'object', required: ['confirm'], properties: { name: { type: 'string', maxLength: 72 }, confirm: { const: true } }, additionalProperties: false },\n annotations: { readOnlyHint: false, destructiveHint: true, idempotentHint: false },\n },\n {\n name: 'templates_search',\n title: 'Search LixSketch templates',\n description: 'Search published workspace and component templates in the LixSketch marketplace.',\n inputSchema: { type: 'object', properties: { query: { type: 'string', maxLength: 80 }, tag: { type: 'string', maxLength: 24 }, limit: { type: 'integer', minimum: 1, maximum: 24, default: 12 } }, additionalProperties: false },\n annotations: { readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: true },\n },\n {\n name: 'template_insert',\n title: 'Insert LixSketch template',\n description: 'Insert a published template into the current canvas, remapping every shape and relationship ID. The operation is atomic and supports a dry run.',\n inputSchema: { type: 'object', required: ['slug'], properties: { slug: { type: 'string', pattern: '^[a-z0-9-]{1,80}$' }, x: { type: 'number' }, y: { type: 'number' }, expectedRevision: { type: 'integer', minimum: 0 }, dryRun: { type: 'boolean', default: false } }, additionalProperties: false },\n annotations: { readOnlyHint: false, destructiveHint: false, idempotentHint: false, openWorldHint: true },\n },\n]);\n\nfunction toolResult(value, message) {\n return {\n content: [{ type: 'text', text: message || JSON.stringify(value, null, 2) }],\n structuredContent: value,\n };\n}\n\nfunction toolError(error) {\n const message = error instanceof Error ? error.message : String(error);\n return { isError: true, content: [{ type: 'text', text: message }], structuredContent: { error: message } };\n}\n\nexport class LixSketchMcpServer {\n constructor({ store, templateProvider = new MarketplaceTemplateProvider(), serverInfo = {} } = {}) {\n if (!store?.read || !store?.write) throw new Error('createLixSketchMcpServer requires a scene store with read() and write()');\n this.store = store;\n this.templateProvider = templateProvider;\n this.serverInfo = { name: SERVER_NAME, version: SERVER_VERSION, ...serverInfo };\n this.mutationChain = Promise.resolve();\n }\n\n listTools() {\n return LIXSKETCH_MCP_TOOLS;\n }\n\n async callTool(name, args = {}) {\n try {\n switch (name) {\n case 'canvas_get': {\n const scene = await this.store.read();\n let shapes;\n if (args.includeShapes) {\n const ids = new Set(args.shapeIDs || []);\n shapes = ids.size ? scene.shapes.filter((shape) => ids.has(shape.shapeID)) : scene.shapes;\n }\n return toolResult({ summary: getSceneSummary(scene), ...(shapes ? { shapes } : {}) });\n }\n case 'canvas_validate': {\n const scene = await this.store.read();\n const validation = validateScene(scene);\n return toolResult({ ...validation, summary: getSceneSummary(scene), limits: MCP_LIMITS });\n }\n case 'canvas_preview': {\n const scene = await this.store.read();\n const svg = renderSceneSvg(scene, args);\n return toolResult({ svg, dataUrl: `data:image/svg+xml;base64,${encodeBase64(svg)}`, summary: getSceneSummary(scene) }, svg);\n }\n case 'templates_search': {\n const templates = await this.templateProvider.search(args);\n return toolResult({ templates: templates.map(safeTemplateMetadata) });\n }\n case 'canvas_apply_patch':\n return await this.enqueueMutation(async () => {\n const scene = await this.store.read();\n const result = applyScenePatch(scene, args.operations, args);\n if (!args.dryRun) await this.store.write(result.scene);\n return toolResult({ revision: result.revision, dryRun: result.dryRun, changedShapeIDs: result.changedShapeIDs, summary: getSceneSummary(result.scene) }, args.dryRun ? 'Canvas patch is valid. No changes were saved.' : `Canvas patch saved at revision ${result.revision}.`);\n });\n case 'canvas_new':\n if (args.confirm !== true) throw new Error('canvas_new requires confirm=true');\n return await this.enqueueMutation(async () => {\n const scene = createEmptyScene(args.name);\n await this.store.write(scene);\n return toolResult({ summary: getSceneSummary(scene) }, 'Blank canvas created.');\n });\n case 'template_insert':\n return await this.enqueueMutation(async () => {\n const scene = await this.store.read();\n const revision = Number(scene.mcpRevision || 0);\n if (args.expectedRevision !== undefined && Number(args.expectedRevision) !== revision) throw new Error(`Revision conflict: expected ${args.expectedRevision}, current ${revision}`);\n const template = await this.templateProvider.load(args.slug);\n const result = mergeTemplateScene(scene, template.scene, args);\n if (!args.dryRun) await this.store.write(result.scene);\n return toolResult({ template: safeTemplateMetadata(template.metadata), revision: result.revision, dryRun: Boolean(args.dryRun), importedShapeIDs: result.importedShapeIDs, summary: getSceneSummary(result.scene) }, args.dryRun ? 'Template import is valid. No changes were saved.' : `Template inserted with ${result.importedShapeIDs.length} shapes.`);\n });\n default: throw new Error(`Unknown tool \"${name}\"`);\n }\n } catch (error) {\n return toolError(error);\n }\n }\n\n enqueueMutation(operation) {\n const pending = this.mutationChain.then(operation, operation);\n this.mutationChain = pending.catch(() => {});\n return pending;\n }\n\n async handleRequest(request) {\n const method = request?.method;\n if (method === 'initialize') {\n const requested = request.params?.protocolVersion;\n const protocolVersion = SUPPORTED_PROTOCOL_VERSIONS.has(requested) ? requested : PROTOCOL_VERSION;\n return { protocolVersion, capabilities: { tools: { listChanged: false }, resources: { subscribe: false, listChanged: false } }, serverInfo: this.serverInfo, instructions: 'Read canvas_get before mutations. Use expectedRevision and dryRun for safe edits. Prefer template_insert for reusable component packs.' };\n }\n if (method === 'ping') return {};\n if (method === 'tools/list') return { tools: this.listTools() };\n if (method === 'tools/call') return this.callTool(request.params?.name, request.params?.arguments || {});\n if (method === 'resources/list') return { resources: [{ uri: 'lixsketch://canvas', name: 'Current LixSketch canvas', description: 'The active editable .lixjson scene', mimeType: 'application/vnd.lixsketch+json' }, { uri: 'lixsketch://canvas/preview.svg', name: 'Current canvas preview', description: 'A lightweight SVG preview of the current scene', mimeType: 'image/svg+xml' }] };\n if (method === 'resources/read') {\n const scene = await this.store.read();\n if (request.params?.uri === 'lixsketch://canvas') return { contents: [{ uri: 'lixsketch://canvas', mimeType: 'application/vnd.lixsketch+json', text: JSON.stringify(scene) }] };\n if (request.params?.uri === 'lixsketch://canvas/preview.svg') return { contents: [{ uri: 'lixsketch://canvas/preview.svg', mimeType: 'image/svg+xml', text: renderSceneSvg(scene) }] };\n throw Object.assign(new Error('Resource not found'), { code: -32002 });\n }\n if (method?.startsWith('notifications/')) return undefined;\n throw Object.assign(new Error(`Method not found: ${method}`), { code: -32601 });\n }\n}\n\nfunction safeTemplateMetadata(template = {}) {\n return { id: template.id, slug: template.slug, title: template.title, description: template.description || '', tags: template.tags || [], publisher: template.publisher, views: template.views, forks: template.forks, clones: template.clones, publishedAt: template.publishedAt, updatedAt: template.updatedAt };\n}\n\nfunction encodeBase64(value) {\n if (typeof btoa === 'function') return btoa(unescape(encodeURIComponent(value)));\n return Buffer.from(value, 'utf8').toString('base64');\n}\n\nexport function createLixSketchMcpServer(options) {\n return new LixSketchMcpServer(options);\n}\n\nexport { PROTOCOL_VERSION as LIXSKETCH_MCP_PROTOCOL_VERSION };\n", "import { createEmptyScene, validateScene } from './scene.js';\n\nexport class MemorySceneStore {\n #scene;\n\n constructor(scene = createEmptyScene()) {\n const validation = validateScene(scene);\n if (!validation.valid) throw new Error(`Invalid initial scene: ${validation.errors.join('; ')}`);\n this.#scene = structuredClone(scene);\n }\n\n async read() {\n return structuredClone(this.#scene);\n }\n\n async write(scene) {\n const validation = validateScene(scene);\n if (!validation.valid) throw new Error(`Refusing to store invalid scene: ${validation.errors.join('; ')}`);\n this.#scene = structuredClone(scene);\n return this.read();\n }\n}\n\n"],
5
- "mappings": ";AAAA,IAAM,SAAS;AACf,IAAM,UAAU;AAChB,IAAM,aAAa;AACnB,IAAM,iBAAiB;AACvB,IAAM,cAAc,oBAAI,IAAI,CAAC,aAAa,UAAU,QAAQ,SAAS,kBAAkB,SAAS,QAAQ,QAAQ,SAAS,MAAM,CAAC;AAChI,IAAM,iBAAiB,oBAAI,IAAI,CAAC,aAAa,UAAU,QAAQ,SAAS,kBAAkB,SAAS,MAAM,CAAC;AAE1G,IAAM,QAAQ,CAAC,UAAU,KAAK,MAAM,KAAK,UAAU,KAAK,CAAC;AACzD,IAAM,SAAS,CAAC,OAAO,WAAW,MAAM,OAAO,SAAS,OAAO,KAAK,CAAC,IAAI,OAAO,KAAK,IAAI;AACzF,IAAM,WAAW,CAAC,OAAO,WAAW,MAAM,KAAK,IAAI,GAAG,OAAO,OAAO,QAAQ,CAAC;AAEtE,SAAS,iBAAiB,OAAO,cAAc;AACpD,SAAO;AAAA,IACL,QAAQ;AAAA,IACR,SAAS;AAAA,IACT,WAAW,OAAO,KAAK,IAAI,EAAE,SAAS,EAAE,CAAC,IAAI,KAAK,OAAO,EAAE,SAAS,EAAE,EAAE,MAAM,GAAG,CAAC,CAAC;AAAA,IACnF,MAAM,OAAO,QAAQ,YAAY,EAAE,KAAK,EAAE,MAAM,GAAG,EAAE;AAAA,IACrD,YAAW,oBAAI,KAAK,GAAE,YAAY;AAAA,IAClC,UAAU,EAAE,GAAG,GAAG,GAAG,GAAG,OAAO,MAAM,QAAQ,IAAI;AAAA,IACjD,MAAM;AAAA,IACN,aAAa;AAAA,IACb,QAAQ,CAAC;AAAA,EACX;AACF;AAEO,SAAS,cAAc,OAAO;AACnC,QAAM,SAAS,CAAC;AAChB,MAAI,CAAC,SAAS,OAAO,UAAU,SAAU,QAAO,EAAE,OAAO,OAAO,QAAQ,CAAC,yBAAyB,EAAE;AACpG,MAAI,MAAM,WAAW,OAAQ,QAAO,KAAK,yBAAyB,MAAM,GAAG;AAC3E,MAAI,MAAM,YAAY,QAAS,QAAO,KAAK,yBAAyB,OAAO,EAAE;AAC7E,MAAI,CAAC,MAAM,QAAQ,MAAM,MAAM,EAAG,QAAO,KAAK,+BAA+B;AAC7E,MAAI,MAAM,QAAQ,MAAM,MAAM,KAAK,MAAM,OAAO,SAAS,WAAY,QAAO,KAAK,iBAAiB,UAAU,SAAS;AACrH,QAAM,MAAM,oBAAI,IAAI;AACpB,aAAW,CAAC,OAAO,KAAK,MAAM,MAAM,UAAU,CAAC,GAAG,QAAQ,GAAG;AAC3D,QAAI,CAAC,SAAS,OAAO,UAAU,UAAU;AAAE,aAAO,KAAK,SAAS,KAAK,oBAAoB;AAAG;AAAA,IAAU;AACtG,QAAI,CAAC,YAAY,IAAI,MAAM,IAAI,EAAG,QAAO,KAAK,SAAS,KAAK,0BAA0B,MAAM,IAAI,GAAG;AACnG,QAAI,CAAC,MAAM,WAAW,OAAO,MAAM,YAAY,SAAU,QAAO,KAAK,SAAS,KAAK,qBAAqB;AAAA,aAC/F,IAAI,IAAI,MAAM,OAAO,EAAG,QAAO,KAAK,sBAAsB,MAAM,OAAO,GAAG;AAAA,QAC9E,KAAI,IAAI,MAAM,OAAO;AAC1B,0BAAsB,OAAO,OAAO,MAAM;AAAA,EAC5C;AACA,SAAO,EAAE,OAAO,OAAO,WAAW,GAAG,OAAO;AAC9C;AAEA,SAAS,UAAU,OAAO;AACxB,SAAO,OAAO,KAAK,EAAE,WAAW,KAAK,OAAO,EAAE,WAAW,KAAK,MAAM,EAAE,WAAW,KAAK,MAAM,EAAE,WAAW,KAAK,QAAQ,EAAE,WAAW,KAAK,QAAQ;AAClJ;AAEA,SAAS,iBAAiB,QAAQ,CAAC,GAAG;AACpC,SAAO;AAAA,IACL,WAAW,KAAK,IAAI,GAAG,KAAK,IAAI,GAAG,OAAO,MAAM,WAAW,GAAG,CAAC,CAAC;AAAA,IAChE,QAAQ,OAAO,MAAM,WAAW,WAAW,MAAM,SAAS;AAAA,IAC1D,aAAa,KAAK,IAAI,KAAK,KAAK,IAAI,IAAI,OAAO,MAAM,aAAa,CAAC,CAAC,CAAC;AAAA,IACrE,MAAM,OAAO,MAAM,SAAS,WAAW,MAAM,OAAO;AAAA,IACpD,WAAW,OAAO,MAAM,cAAc,WAAW,MAAM,YAAY;AAAA,IACnE,SAAS,KAAK,IAAI,GAAG,KAAK,IAAI,GAAG,OAAO,MAAM,SAAS,CAAC,CAAC,CAAC;AAAA,EAC5D;AACF;AAEA,SAAS,gBAAgB,OAAO,SAAS;AACvC,QAAM,IAAI,OAAO,MAAM,CAAC,GAAG,IAAI,OAAO,MAAM,CAAC,GAAG,WAAW,OAAO,MAAM,QAAQ;AAChF,QAAM,OAAO,OAAO,MAAM,QAAQ,EAAE,EAAE,MAAM,GAAG,GAAK;AACpD,QAAM,WAAW,KAAK,IAAI,GAAG,KAAK,IAAI,KAAK,OAAO,MAAM,UAAU,EAAE,CAAC,CAAC;AACtE,QAAMA,SAAQ,OAAO,MAAM,UAAU,WAAW,MAAM,QAAQ;AAC9D,QAAM,SAAS,OAAO,MAAM,eAAe,WAAW,MAAM,WAAW,MAAM,GAAG,EAAE,IAAI;AACtF,QAAM,YAAY,aAAa,CAAC,KAAK,CAAC,IAAI,WAAW,WAAW,QAAQ,YAAY,EAAE;AACtF,QAAM,QAAQ,KAAK,MAAM,IAAI,EAAE,IAAI,CAAC,MAAM,UAAU,oBAAoB,UAAU,IAAI,IAAI,OAAO,KAAK,UAAU,QAAQ,GAAG,CAAC,UAAU,EAAE,KAAK,EAAE;AAC/I,SAAO;AAAA,IACL;AAAA,IAAS,MAAM;AAAA,IAAQ;AAAA,IAAG;AAAA,IAAG;AAAA,IAC7B,SAAS;AAAA,IAAM,aAAa;AAAA,IAAU,UAAUA;AAAA,IAAO,eAAe;AAAA,IACtE,WAAW,UAAU,UAAU,OAAO,CAAC,oCAAoC,CAAC,aAAa,CAAC,gBAAgB,SAAS,eAAe,UAAU,OAAO,CAAC,4BAA4B,UAAUA,MAAK,CAAC,gBAAgB,QAAQ,kBAAkB,UAAU,MAAM,CAAC,gHAAgH,QAAQ,wBAAwB,UAAU,MAAM,CAAC,yBAAyB,UAAUA,MAAK,CAAC,KAAK,KAAK;AAAA,EACjd;AACF;AAEO,SAAS,eAAe,OAAO,cAAc,oBAAI,IAAI,GAAG;AAC7D,MAAI,CAAC,SAAS,OAAO,UAAU,SAAU,OAAM,IAAI,MAAM,yBAAyB;AAClF,MAAI,CAAC,eAAe,IAAI,MAAM,IAAI,EAAG,OAAM,IAAI,MAAM,eAAe,MAAM,IAAI,4BAA4B;AAC1G,MAAI,UAAU,OAAO,MAAM,WAAW,GAAG,MAAM,IAAI,IAAI,OAAO,WAAW,CAAC,EAAE,EAAE,MAAM,GAAG,GAAG;AAC1F,SAAO,YAAY,IAAI,OAAO,EAAG,WAAU,GAAG,MAAM,IAAI,IAAI,OAAO,WAAW,CAAC;AAC/E,QAAM,OAAO,EAAE,SAAS,MAAM,MAAM,MAAM,UAAU,OAAO,MAAM,QAAQ,GAAG,SAAS,iBAAiB,MAAM,OAAO,GAAG,SAAS,MAAM,WAAW,MAAM,aAAa,MAAM,eAAe,MAAM,aAAa,CAAC,EAAE;AAC9M,UAAQ,MAAM,MAAM;AAAA,IAClB,KAAK;AAAa,aAAO,EAAE,GAAG,MAAM,GAAG,OAAO,MAAM,CAAC,GAAG,GAAG,OAAO,MAAM,CAAC,GAAG,OAAO,SAAS,MAAM,OAAO,GAAG,GAAG,QAAQ,SAAS,MAAM,QAAQ,EAAE,EAAE;AAAA,IAClJ,KAAK;AAAU,aAAO,EAAE,GAAG,MAAM,GAAG,OAAO,MAAM,CAAC,GAAG,GAAG,OAAO,MAAM,CAAC,GAAG,IAAI,SAAS,MAAM,IAAI,EAAE,GAAG,IAAI,SAAS,MAAM,IAAI,EAAE,EAAE;AAAA,IAChI,KAAK;AAAQ,aAAO,EAAE,GAAG,MAAM,YAAY,MAAM,MAAM,UAAU,GAAG,UAAU,MAAM,MAAM,UAAU,GAAG,GAAG,UAAU,QAAQ,MAAM,QAAQ,GAAG,cAAc,MAAM,eAAe,MAAM,MAAM,YAAY,IAAI,KAAK;AAAA,IACjN,KAAK;AAAS,aAAO,EAAE,GAAG,MAAM,YAAY,MAAM,MAAM,UAAU,GAAG,UAAU,MAAM,MAAM,UAAU,GAAG,GAAG,gBAAgB,MAAM,kBAAkB,YAAY,mBAAmB,MAAM,qBAAqB,SAAS,aAAa,QAAQ,MAAM,WAAW,GAAG,kBAAkB,OAAO,MAAM,kBAAkB,GAAG,EAAE;AAAA,IACrT,KAAK,kBAAkB;AACrB,YAAM,UAAU,MAAM,QAAQ,MAAM,MAAM,IAAI,MAAM,SAAS,CAAC,GAAG,MAAM,GAAG,IAAI,EAAE,IAAI,CAAC,UAAU,CAAC,OAAO,QAAQ,CAAC,CAAC,GAAG,OAAO,QAAQ,CAAC,CAAC,GAAG,OAAO,QAAQ,CAAC,GAAG,GAAG,CAAC,CAAC;AAChK,UAAI,OAAO,SAAS,EAAG,OAAM,IAAI,MAAM,6CAA6C;AACpF,aAAO,EAAE,GAAG,MAAM,OAAO;AAAA,IAC3B;AAAA,IACA,KAAK;AAAS,aAAO,EAAE,GAAG,MAAM,GAAG,OAAO,MAAM,CAAC,GAAG,GAAG,OAAO,MAAM,CAAC,GAAG,OAAO,SAAS,MAAM,OAAO,GAAG,GAAG,QAAQ,SAAS,MAAM,QAAQ,GAAG,GAAG,WAAW,OAAO,MAAM,aAAa,OAAO,EAAE,MAAM,GAAG,EAAE,GAAG,WAAW,MAAM,aAAa,eAAe,WAAW,MAAM,aAAa,WAAW,UAAU,SAAS,MAAM,UAAU,EAAE,GAAG,mBAAmB,CAAC,EAAE;AAAA,IAChW,KAAK;AAAQ,aAAO,EAAE,GAAG,MAAM,GAAG,gBAAgB,OAAO,OAAO,EAAE;AAAA,IAClE;AAAS,YAAM,IAAI,MAAM,2BAA2B,MAAM,IAAI,GAAG;AAAA,EACnE;AACF;AAEA,SAAS,MAAM,OAAO,YAAY,GAAG;AACnC,SAAO,EAAE,GAAG,OAAO,OAAO,GAAG,SAAS,GAAG,GAAG,OAAO,OAAO,CAAC,EAAE;AAC/D;AAEA,SAAS,eAAe,OAAO,IAAI,IAAI;AACrC,QAAM,QAAQ,MAAM,KAAK;AACzB,MAAI,MAAM,YAAY;AAAE,UAAM,WAAW,KAAK;AAAI,UAAM,WAAW,KAAK;AAAA,EAAI;AAC5E,MAAI,MAAM,UAAU;AAAE,UAAM,SAAS,KAAK;AAAI,UAAM,SAAS,KAAK;AAAA,EAAI;AACtE,MAAI,MAAM,cAAc;AAAE,UAAM,aAAa,KAAK;AAAI,UAAM,aAAa,KAAK;AAAA,EAAI;AAClF,MAAI,MAAM,eAAe;AAAE,UAAM,cAAc,KAAK;AAAI,UAAM,cAAc,KAAK;AAAA,EAAI;AACrF,MAAI,MAAM,eAAe;AAAE,UAAM,cAAc,KAAK;AAAI,UAAM,cAAc,KAAK;AAAA,EAAI;AACrF,MAAI,MAAM,QAAQ,MAAM,MAAM,EAAG,OAAM,SAAS,MAAM,OAAO,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,IAAI,IAAI,EAAE,CAAC,IAAI,IAAI,GAAG,EAAE,MAAM,CAAC,CAAC,CAAC;AAC7G,MAAI,OAAO,SAAS,MAAM,CAAC,EAAG,OAAM,KAAK;AACzC,MAAI,OAAO,SAAS,MAAM,CAAC,EAAG,OAAM,KAAK;AACzC,MAAI,MAAM,SAAS,UAAU,MAAM,WAAW;AAC5C,UAAM,YAAY,MAAM,UACrB,QAAQ,kBAAkB,WAAW,MAAM,CAAC,GAAG,EAC/C,QAAQ,kBAAkB,WAAW,MAAM,CAAC,GAAG,EAC/C,QAAQ,iCAAiC,wBAAwB,MAAM,CAAC,KAAK,MAAM,CAAC,GAAG;AAAA,EAC5F;AACA,MAAI,MAAM,SAAS,UAAU,MAAM,WAAW;AAC5C,UAAM,YAAY,MAAM,UACrB,QAAQ,kBAAkB,WAAW,MAAM,CAAC,GAAG,EAC/C,QAAQ,kBAAkB,WAAW,MAAM,CAAC,GAAG,EAC/C,QAAQ,iCAAiC,wBAAwB,MAAM,CAAC,KAAK,MAAM,CAAC,GAAG;AAAA,EAC5F;AACA,MAAI,MAAM,SAAS,UAAU,MAAM,aAAa;AAC9C,UAAM,cAAc,MAAM,YACvB,QAAQ,eAAe,MAAM,MAAM,CAAC,GAAG,EACvC,QAAQ,eAAe,MAAM,MAAM,CAAC,GAAG;AAAA,EAC5C;AACA,SAAO;AACT;AAEO,SAAS,gBAAgB,YAAY,YAAY,EAAE,kBAAkB,SAAS,MAAM,IAAI,CAAC,GAAG;AACjG,QAAM,QAAQ,MAAM,UAAU;AAC9B,QAAM,QAAQ,cAAc,KAAK;AACjC,MAAI,CAAC,MAAM,MAAO,OAAM,IAAI,MAAM,kBAAkB,MAAM,OAAO,KAAK,IAAI,CAAC,EAAE;AAC7E,MAAI,CAAC,MAAM,QAAQ,UAAU,KAAK,WAAW,WAAW,EAAG,OAAM,IAAI,MAAM,oCAAoC;AAC/G,MAAI,WAAW,SAAS,eAAgB,OAAM,IAAI,MAAM,iBAAiB,cAAc,aAAa;AACpG,QAAM,WAAW,OAAO,MAAM,eAAe,CAAC;AAC9C,MAAI,qBAAqB,UAAa,OAAO,gBAAgB,MAAM,SAAU,OAAM,IAAI,MAAM,+BAA+B,gBAAgB,aAAa,QAAQ,EAAE;AACnK,QAAM,aAAa,oBAAI,IAAI;AAC3B,aAAW,aAAa,YAAY;AAClC,QAAI,CAAC,aAAa,OAAO,cAAc,SAAU,OAAM,IAAI,MAAM,kCAAkC;AACnG,QAAI,UAAU,OAAO,OAAO;AAC1B,UAAI,MAAM,OAAO,UAAU,WAAY,OAAM,IAAI,MAAM,iBAAiB,UAAU,SAAS;AAC3F,YAAM,MAAM,IAAI,IAAI,MAAM,OAAO,IAAI,CAACC,WAAUA,OAAM,OAAO,CAAC;AAC9D,YAAM,QAAQ,eAAe,UAAU,OAAO,GAAG;AACjD,YAAM,OAAO,KAAK,KAAK;AAAG,iBAAW,IAAI,MAAM,OAAO;AAAA,IACxD,WAAW,UAAU,OAAO,UAAU;AACpC,YAAM,QAAQ,MAAM,OAAO,UAAU,CAAC,UAAU,MAAM,YAAY,UAAU,OAAO;AACnF,UAAI,QAAQ,EAAG,OAAM,IAAI,MAAM,UAAU,UAAU,OAAO,iBAAiB;AAC3E,YAAM,YAAY,MAAM,OAAO,KAAK;AACpC,YAAM,OAAO,KAAK,IAAI,kBAAkB,WAAW,UAAU,WAAW,CAAC,CAAC;AAAG,iBAAW,IAAI,UAAU,OAAO;AAAA,IAC/G,WAAW,UAAU,OAAO,UAAU;AACpC,YAAM,MAAM,IAAI,IAAI,MAAM,QAAQ,UAAU,QAAQ,IAAI,UAAU,WAAW,CAAC,UAAU,OAAO,CAAC;AAChG,YAAM,SAAS,MAAM,OAAO;AAC5B,YAAM,SAAS,MAAM,OAAO,OAAO,CAAC,UAAU,CAAC,IAAI,IAAI,MAAM,OAAO,CAAC;AACrE,UAAI,MAAM,OAAO,WAAW,OAAQ,OAAM,IAAI,MAAM,gCAAgC;AACpF,YAAM,OAAO,QAAQ,CAAC,UAAU;AAC9B,YAAI,IAAI,IAAI,MAAM,WAAW,EAAG,OAAM,cAAc;AACpD,YAAI,MAAM,QAAQ,MAAM,iBAAiB,EAAG,OAAM,oBAAoB,MAAM,kBAAkB,OAAO,CAAC,OAAO,CAAC,IAAI,IAAI,EAAE,CAAC;AAAA,MAC3H,CAAC;AACD,UAAI,QAAQ,CAAC,OAAO,WAAW,IAAI,EAAE,CAAC;AAAA,IACxC,WAAW,UAAU,OAAO,aAAa;AACvC,YAAM,MAAM,IAAI,IAAI,UAAU,YAAY,CAAC,CAAC,GAAG,KAAK,OAAO,UAAU,EAAE,GAAG,KAAK,OAAO,UAAU,EAAE;AAClG,UAAI,CAAC,IAAI,KAAM,OAAM,IAAI,MAAM,6BAA6B;AAC5D,YAAM,SAAS,MAAM,OAAO,IAAI,CAAC,UAAU,IAAI,IAAI,MAAM,OAAO,IAAI,eAAe,OAAO,IAAI,EAAE,IAAI,KAAK;AACzG,UAAI,QAAQ,CAAC,OAAO,WAAW,IAAI,EAAE,CAAC;AAAA,IACxC,WAAW,UAAU,OAAO,iBAAiB;AAC3C,YAAM,OAAO,OAAO,UAAU,QAAQ,EAAE,EAAE,KAAK,EAAE,MAAM,GAAG,EAAE,KAAK,MAAM;AAAA,IACzE,MAAO,OAAM,IAAI,MAAM,0BAA0B,UAAU,EAAE,GAAG;AAAA,EAClE;AACA,QAAM,cAAc,WAAW;AAC/B,QAAM,aAAY,oBAAI,KAAK,GAAE,YAAY;AACzC,QAAM,SAAS,cAAc,KAAK;AAClC,MAAI,CAAC,OAAO,MAAO,OAAM,IAAI,MAAM,oCAAoC,OAAO,OAAO,KAAK,IAAI,CAAC,EAAE;AACjG,SAAO,EAAE,OAAO,UAAU,MAAM,aAAa,QAAQ,QAAQ,MAAM,GAAG,iBAAiB,CAAC,GAAG,UAAU,EAAE;AACzG;AAEA,SAAS,kBAAkB,OAAO,SAAS;AACzC,MAAI,CAAC,WAAW,OAAO,YAAY,YAAY,MAAM,QAAQ,OAAO,EAAG,OAAM,IAAI,MAAM,iCAAiC;AACxH,QAAM,UAAU;AAAA,IACd,WAAW,CAAC,KAAK,KAAK,SAAS,UAAU,YAAY,WAAW,WAAW,aAAa;AAAA,IACxF,QAAQ,CAAC,KAAK,KAAK,MAAM,MAAM,YAAY,WAAW,WAAW,aAAa;AAAA,IAC9E,MAAM,CAAC,cAAc,YAAY,gBAAgB,YAAY,WAAW,WAAW,aAAa;AAAA,IAChG,OAAO,CAAC,cAAc,YAAY,iBAAiB,iBAAiB,kBAAkB,qBAAqB,eAAe,oBAAoB,WAAW,WAAW,aAAa;AAAA,IACjL,gBAAgB,CAAC,UAAU,YAAY,WAAW,WAAW,aAAa;AAAA,IAC1E,OAAO,CAAC,KAAK,KAAK,SAAS,UAAU,YAAY,aAAa,aAAa,aAAa,YAAY,WAAW,WAAW,aAAa;AAAA,IACvI,MAAM,CAAC,KAAK,KAAK,YAAY,QAAQ,YAAY,SAAS,cAAc,WAAW,aAAa;AAAA,EAClG,EAAE,MAAM,IAAI,KAAK,CAAC;AAClB,QAAM,WAAW,OAAO,KAAK,OAAO,EAAE,OAAO,CAAC,QAAQ,CAAC,QAAQ,SAAS,GAAG,CAAC;AAC5E,MAAI,SAAS,OAAQ,OAAM,IAAI,MAAM,iBAAiB,MAAM,IAAI,YAAY,SAAS,KAAK,IAAI,CAAC,EAAE;AACjG,MAAI,MAAM,SAAS,QAAQ;AACzB,UAAM,OAAO,QAAQ,QAAQ,MAAM,WAAW,YAAY,MAAM,SAAS;AACzE,WAAO,EAAE,GAAG,OAAO,GAAG,gBAAgB,EAAE,GAAG,QAAQ,KAAK,MAAM,GAAG,GAAG,QAAQ,KAAK,MAAM,GAAG,UAAU,QAAQ,YAAY,MAAM,UAAU,MAAM,UAAU,QAAQ,YAAY,MAAM,aAAa,OAAO,QAAQ,SAAS,MAAM,UAAU,YAAY,QAAQ,cAAc,MAAM,cAAc,GAAG,MAAM,OAAO,GAAG,SAAS,QAAQ,WAAW,MAAM,SAAS,aAAa,QAAQ,eAAe,MAAM,YAAY;AAAA,EACnZ;AACA,QAAM,OAAO,EAAE,GAAG,MAAM,KAAK,GAAG,GAAG,MAAM,OAAO,GAAG,SAAS,MAAM,SAAS,MAAM,MAAM,KAAK;AAC5F,MAAI,QAAQ,QAAS,MAAK,UAAU,EAAE,GAAI,MAAM,WAAW,CAAC,GAAI,GAAG,iBAAiB,EAAE,GAAI,MAAM,WAAW,CAAC,GAAI,GAAG,QAAQ,QAAQ,CAAC,EAAE;AACtI,SAAO;AACT;AAEA,SAAS,YAAY,YAAY,IAAI;AACnC,SAAO,OAAO,SAAS,EAAE,QAAQ,YAAY,GAAG,EAAE,QAAQ,QAAQ,GAAG,EAAE,KAAK;AAC9E;AAEA,SAAS,sBAAsB,OAAO,OAAO,QAAQ;AACnD,QAAM,UAAU,CAAC;AACjB,MAAI,CAAC,aAAa,SAAS,QAAQ,QAAQ,SAAS,MAAM,EAAE,SAAS,MAAM,IAAI,EAAG,SAAQ,KAAK,CAAC,KAAK,MAAM,CAAC,GAAG,CAAC,KAAK,MAAM,CAAC,CAAC;AAC7H,MAAI,CAAC,aAAa,SAAS,SAAS,MAAM,EAAE,SAAS,MAAM,IAAI,EAAG,SAAQ,KAAK,CAAC,SAAS,MAAM,KAAK,GAAG,CAAC,UAAU,MAAM,MAAM,CAAC;AAC/H,MAAI,MAAM,SAAS,SAAU,SAAQ,KAAK,CAAC,KAAK,MAAM,CAAC,GAAG,CAAC,KAAK,MAAM,CAAC,GAAG,CAAC,MAAM,MAAM,EAAE,GAAG,CAAC,MAAM,MAAM,EAAE,CAAC;AAC5G,MAAI,MAAM,WAAY,SAAQ,KAAK,CAAC,gBAAgB,MAAM,WAAW,CAAC,GAAG,CAAC,gBAAgB,MAAM,WAAW,CAAC,CAAC;AAC7G,MAAI,MAAM,SAAU,SAAQ,KAAK,CAAC,cAAc,MAAM,SAAS,CAAC,GAAG,CAAC,cAAc,MAAM,SAAS,CAAC,CAAC;AACnG,aAAW,CAAC,OAAO,KAAK,KAAK,QAAS,KAAI,CAAC,OAAO,SAAS,OAAO,KAAK,CAAC,EAAG,QAAO,KAAK,SAAS,KAAK,gBAAgB,KAAK,EAAE;AAC5H,MAAI,CAAC,aAAa,SAAS,SAAS,MAAM,EAAE,SAAS,MAAM,IAAI,MAAM,OAAO,MAAM,KAAK,KAAK,KAAK,OAAO,MAAM,MAAM,KAAK,GAAI,QAAO,KAAK,SAAS,KAAK,gCAAgC;AACvL,MAAI,MAAM,SAAS,aAAa,OAAO,MAAM,EAAE,KAAK,KAAK,OAAO,MAAM,EAAE,KAAK,GAAI,QAAO,KAAK,SAAS,KAAK,2BAA2B;AACtI,MAAI,MAAM,SAAS,qBAAqB,CAAC,MAAM,QAAQ,MAAM,MAAM,KAAK,MAAM,OAAO,SAAS,KAAK,MAAM,OAAO,SAAS,MAAO,QAAO,KAAK,SAAS,KAAK,8BAA8B;AACxL,MAAI,MAAM,SAAS,UAAU,OAAO,MAAM,cAAc,SAAU,QAAO,KAAK,SAAS,KAAK,yBAAyB;AACrH,MAAI,MAAM,SAAS,UAAU,OAAO,MAAM,cAAc,SAAU,QAAO,KAAK,SAAS,KAAK,yBAAyB;AACrH,MAAI,MAAM,SAAS,WAAW,OAAO,MAAM,SAAS,SAAU,QAAO,KAAK,SAAS,KAAK,wBAAwB;AAChH,MAAI,MAAM,SAAS,UAAU,OAAO,MAAM,gBAAgB,SAAU,QAAO,KAAK,SAAS,KAAK,yBAAyB;AACzH;AAEO,SAAS,gBAAgB,OAAO;AACrC,QAAM,SAAS,CAAC;AAChB,aAAW,SAAS,MAAM,UAAU,CAAC,EAAG,QAAO,MAAM,IAAI,KAAK,OAAO,MAAM,IAAI,KAAK,KAAK;AACzF,SAAO,EAAE,MAAM,MAAM,MAAM,QAAQ,MAAM,QAAQ,SAAS,MAAM,SAAS,UAAU,OAAO,MAAM,eAAe,CAAC,GAAG,YAAY,MAAM,QAAQ,UAAU,GAAG,QAAQ,QAAQ,eAAe,KAAK,EAAE;AAClM;AAEO,SAAS,eAAe,OAAO;AACpC,QAAM,SAAS,MAAM,UAAU,CAAC,GAAG,IAAI,WAAW,EAAE,OAAO,OAAO;AAClE,MAAI,CAAC,MAAM,OAAQ,QAAO;AAC1B,QAAM,OAAO,KAAK,IAAI,GAAG,MAAM,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC,GAAG,OAAO,KAAK,IAAI,GAAG,MAAM,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC;AACzF,QAAM,OAAO,KAAK,IAAI,GAAG,MAAM,IAAI,CAAC,MAAM,EAAE,IAAI,EAAE,KAAK,CAAC,GAAG,OAAO,KAAK,IAAI,GAAG,MAAM,IAAI,CAAC,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC;AAC9G,SAAO,EAAE,GAAG,MAAM,GAAG,MAAM,OAAO,OAAO,MAAM,QAAQ,OAAO,KAAK;AACrE;AAEO,SAAS,YAAY,OAAO;AACjC,MAAI,MAAM,SAAS,SAAU,QAAO,EAAE,GAAG,MAAM,IAAI,MAAM,IAAI,GAAG,MAAM,IAAI,MAAM,IAAI,OAAO,MAAM,KAAK,GAAG,QAAQ,MAAM,KAAK,EAAE;AAC9H,MAAI,MAAM,cAAc,MAAM,UAAU;AACtC,UAAM,IAAI,KAAK,IAAI,MAAM,WAAW,GAAG,MAAM,SAAS,CAAC,GAAG,IAAI,KAAK,IAAI,MAAM,WAAW,GAAG,MAAM,SAAS,CAAC;AAC3G,WAAO,EAAE,GAAG,GAAG,OAAO,KAAK,IAAI,MAAM,SAAS,IAAI,MAAM,WAAW,CAAC,GAAG,QAAQ,KAAK,IAAI,MAAM,SAAS,IAAI,MAAM,WAAW,CAAC,EAAE;AAAA,EACjI;AACA,MAAI,MAAM,QAAQ,MAAM,MAAM,KAAK,MAAM,OAAO,QAAQ;AACtD,UAAM,KAAK,MAAM,OAAO,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC,GAAG,KAAK,MAAM,OAAO,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC;AAC3E,WAAO,EAAE,GAAG,KAAK,IAAI,GAAG,EAAE,GAAG,GAAG,KAAK,IAAI,GAAG,EAAE,GAAG,OAAO,KAAK,IAAI,GAAG,EAAE,IAAI,KAAK,IAAI,GAAG,EAAE,GAAG,QAAQ,KAAK,IAAI,GAAG,EAAE,IAAI,KAAK,IAAI,GAAG,EAAE,EAAE;AAAA,EACvI;AACA,MAAI,MAAM,SAAS,OAAQ,QAAO,EAAE,GAAG,OAAO,MAAM,CAAC,GAAG,GAAG,OAAO,MAAM,CAAC,GAAG,OAAO,KAAK,QAAQ,GAAG;AACnG,SAAO,EAAE,GAAG,OAAO,MAAM,CAAC,GAAG,GAAG,OAAO,MAAM,CAAC,GAAG,OAAO,SAAS,MAAM,KAAK,GAAG,QAAQ,SAAS,MAAM,MAAM,EAAE;AAChH;AAEO,SAAS,mBAAmB,YAAY,eAAe,EAAE,GAAG,EAAE,IAAI,CAAC,GAAG;AAC3E,QAAM,QAAQ,MAAM,UAAU,GAAG,WAAW,MAAM,aAAa;AAC/D,QAAM,aAAa,cAAc,QAAQ;AACzC,MAAI,CAAC,WAAW,MAAO,OAAM,IAAI,MAAM,8BAA8B,WAAW,OAAO,KAAK,IAAI,CAAC,EAAE;AACnG,MAAI,MAAM,OAAO,SAAS,SAAS,OAAO,SAAS,WAAY,OAAM,IAAI,MAAM,kCAAkC,UAAU,SAAS;AACpI,QAAM,SAAS,eAAe,QAAQ,KAAK,EAAE,GAAG,GAAG,GAAG,EAAE;AACxD,QAAM,UAAU,OAAO,GAAG,MAAM,UAAU,KAAK,CAAC,GAAG,UAAU,OAAO,GAAG,MAAM,UAAU,KAAK,CAAC;AAC7F,QAAM,KAAK,UAAU,OAAO,GAAG,KAAK,UAAU,OAAO;AACrD,QAAM,QAAQ,IAAI,IAAI,SAAS,OAAO,IAAI,CAAC,UAAU,CAAC,MAAM,SAAS,GAAG,MAAM,IAAI,IAAI,OAAO,WAAW,CAAC,EAAE,CAAC,CAAC;AAC7G,QAAM,WAAW,SAAS,OAAO,IAAI,CAAC,UAAU;AAC9C,UAAM,QAAQ,eAAe,OAAO,IAAI,EAAE;AAC1C,UAAM,UAAU,MAAM,IAAI,MAAM,OAAO;AACvC,QAAI,MAAM,YAAa,OAAM,cAAc,MAAM,IAAI,MAAM,WAAW,KAAK;AAC3E,QAAI,MAAM,QAAQ,MAAM,iBAAiB,EAAG,OAAM,oBAAoB,MAAM,kBAAkB,IAAI,CAAC,OAAO,MAAM,IAAI,EAAE,CAAC,EAAE,OAAO,OAAO;AACvI,QAAI,MAAM,kBAAmB,OAAM,oBAAoB,MAAM,IAAI,MAAM,iBAAiB,KAAK;AAC7F,QAAI,MAAM,gBAAiB,OAAM,kBAAkB,MAAM,IAAI,MAAM,eAAe,KAAK;AACvF,QAAI,MAAM,UAAW,OAAM,YAAY,MAAM,UAAU,MAAM,MAAM,OAAO,EAAE,KAAK,MAAM,OAAO;AAC9F,QAAI,MAAM,YAAa,OAAM,cAAc,MAAM,YAAY,MAAM,MAAM,OAAO,EAAE,KAAK,MAAM,OAAO;AACpG,WAAO;AAAA,EACT,CAAC;AACD,QAAM,OAAO,KAAK,GAAG,QAAQ;AAC7B,QAAM,cAAc,OAAO,MAAM,eAAe,CAAC,IAAI;AACrD,QAAM,aAAY,oBAAI,KAAK,GAAE,YAAY;AACzC,SAAO,EAAE,OAAO,UAAU,MAAM,aAAa,kBAAkB,SAAS,IAAI,CAAC,UAAU,MAAM,OAAO,EAAE;AACxG;AAEO,IAAM,aAAa,OAAO,OAAO,EAAE,WAAW,YAAY,eAAe,eAAe,CAAC;;;AClRhG,IAAM,0BAA0B;AAEhC,SAAS,gBAAgB,OAAO;AAC9B,QAAM,SAAS,OAAO,KAAK,EAAE,WAAW,KAAK,GAAG,EAAE,WAAW,KAAK,GAAG;AACrE,QAAM,SAAS,SAAS,IAAI,QAAQ,IAAI,OAAO,SAAS,KAAK,CAAC;AAC9D,QAAM,SAAS,KAAK,MAAM;AAC1B,SAAO,WAAW,KAAK,QAAQ,CAAC,cAAc,UAAU,WAAW,CAAC,CAAC;AACvE;AAEA,eAAsB,sBAAsB,YAAY,UAAU;AAChE,QAAM,WAAW,gBAAgB,QAAQ;AACzC,MAAI,SAAS,eAAe,GAAI,OAAM,IAAI,MAAM,6BAA6B;AAC7E,QAAM,WAAW,gBAAgB,UAAU;AAC3C,MAAI,SAAS,aAAa,GAAI,OAAM,IAAI,MAAM,gCAAgC;AAC9E,QAAM,MAAM,MAAM,OAAO,OAAO,UAAU,OAAO,UAAU,EAAE,MAAM,WAAW,QAAQ,IAAI,GAAG,OAAO,CAAC,SAAS,CAAC;AAC/G,QAAM,YAAY,MAAM,OAAO,OAAO,QAAQ,EAAE,MAAM,WAAW,IAAI,SAAS,MAAM,GAAG,EAAE,EAAE,GAAG,KAAK,SAAS,MAAM,EAAE,CAAC;AACrH,SAAO,KAAK,MAAM,IAAI,YAAY,EAAE,OAAO,SAAS,CAAC;AACvD;AAEO,IAAM,8BAAN,MAAkC;AAAA,EACvC,YAAY,EAAE,UAAU,yBAAyB,YAAY,WAAW,MAAM,IAAI,CAAC,GAAG;AACpF,QAAI,OAAO,cAAc,WAAY,OAAM,IAAI,MAAM,4CAA4C;AACjG,SAAK,UAAU,OAAO,OAAO,EAAE,QAAQ,OAAO,EAAE;AAChD,SAAK,QAAQ;AAAA,EACf;AAAA,EAEA,MAAM,OAAO,EAAE,QAAQ,IAAI,MAAM,IAAI,QAAQ,GAAG,IAAI,CAAC,GAAG;AACtD,UAAM,MAAM,IAAI,IAAI,kBAAkB,KAAK,OAAO;AAClD,QAAI,MAAO,KAAI,aAAa,IAAI,KAAK,OAAO,KAAK,EAAE,MAAM,GAAG,EAAE,CAAC;AAC/D,QAAI,IAAK,KAAI,aAAa,IAAI,OAAO,OAAO,GAAG,EAAE,MAAM,GAAG,EAAE,CAAC;AAC7D,QAAI,aAAa,IAAI,SAAS,OAAO,KAAK,IAAI,IAAI,KAAK,IAAI,GAAG,OAAO,KAAK,KAAK,EAAE,CAAC,CAAC,CAAC;AACpF,UAAM,WAAW,MAAM,KAAK,MAAM,KAAK,EAAE,SAAS,EAAE,QAAQ,mBAAmB,EAAE,CAAC;AAClF,UAAM,OAAO,MAAM,SAAS,KAAK;AACjC,QAAI,CAAC,SAAS,GAAI,OAAM,IAAI,MAAM,KAAK,SAAS,+BAA+B,SAAS,MAAM,GAAG;AACjG,WAAO,KAAK,aAAa,CAAC;AAAA,EAC5B;AAAA,EAEA,MAAM,KAAK,MAAM;AACf,UAAM,WAAW,OAAO,QAAQ,EAAE,EAAE,KAAK;AACzC,QAAI,CAAC,oBAAoB,KAAK,QAAQ,EAAG,OAAM,IAAI,MAAM,0BAA0B;AACnF,UAAM,MAAM,IAAI,IAAI,kBAAkB,mBAAmB,QAAQ,CAAC,IAAI,KAAK,OAAO;AAClF,QAAI,aAAa,IAAI,YAAY,GAAG;AACpC,UAAM,WAAW,MAAM,KAAK,MAAM,KAAK,EAAE,SAAS,EAAE,QAAQ,mBAAmB,EAAE,CAAC;AAClF,UAAM,OAAO,MAAM,SAAS,KAAK;AACjC,QAAI,CAAC,SAAS,GAAI,OAAM,IAAI,MAAM,KAAK,SAAS,4BAA4B,SAAS,MAAM,GAAG;AAC9F,UAAM,WAAW,KAAK;AACtB,QAAI,CAAC,UAAU,iBAAiB,CAAC,UAAU,UAAW,OAAM,IAAI,MAAM,kCAAkC;AACxG,WAAO,EAAE,UAAU,EAAE,GAAG,UAAU,eAAe,QAAW,WAAW,QAAW,kBAAkB,OAAU,GAAG,OAAO,MAAM,sBAAsB,SAAS,eAAe,SAAS,SAAS,EAAE;AAAA,EAClM;AACF;;;AC/CA,IAAM,oBAAoB,IAAI,OAAO;AAErC,IAAM,MAAM,CAAC,UAAU,OAAO,SAAS,EAAE,EAAE,WAAW,KAAK,OAAO,EAAE,WAAW,KAAK,MAAM,EAAE,WAAW,KAAK,MAAM,EAAE,WAAW,KAAK,QAAQ;AAC5I,IAAM,QAAQ,CAAC,OAAO,aAAa,OAAO,UAAU,YAAY,oBAAoB,KAAK,KAAK,IAAI,QAAQ;AAE1G,SAAS,QAAQ,OAAO;AACtB,SAAO;AAAA,IACL,QAAQ,MAAM,MAAM,SAAS,QAAQ,SAAS;AAAA,IAC9C,MAAM,MAAM,SAAS,SAAS,gBAAgB,SAAS,MAAM,MAAM,SAAS,MAAM,MAAM;AAAA,IACxF,OAAO,KAAK,IAAI,KAAK,KAAK,IAAI,IAAI,OAAO,MAAM,SAAS,WAAW,KAAK,CAAC,CAAC;AAAA,IAC1E,SAAS,KAAK,IAAI,GAAG,KAAK,IAAI,GAAG,OAAO,MAAM,SAAS,OAAO,KAAK,CAAC,CAAC;AAAA,EACvE;AACF;AAEA,SAAS,YAAY,OAAO;AAC1B,QAAM,QAAQ,QAAQ,KAAK;AAC3B,QAAM,QAAQ,WAAW,MAAM,MAAM,mBAAmB,MAAM,KAAK,WAAW,MAAM,IAAI,cAAc,MAAM,OAAO;AACnH,MAAI,MAAM,SAAS,YAAa,QAAO,YAAY,MAAM,CAAC,QAAQ,MAAM,CAAC,YAAY,MAAM,KAAK,aAAa,MAAM,MAAM,YAAY,KAAK;AAC1I,MAAI,MAAM,SAAS,SAAU,QAAO,gBAAgB,MAAM,CAAC,SAAS,MAAM,CAAC,SAAS,MAAM,EAAE,SAAS,MAAM,EAAE,KAAK,KAAK;AACvH,MAAI,MAAM,SAAS,OAAQ,QAAO,aAAa,MAAM,WAAW,CAAC,SAAS,MAAM,WAAW,CAAC,SAAS,MAAM,SAAS,CAAC,SAAS,MAAM,SAAS,CAAC,KAAK,KAAK;AACxJ,MAAI,MAAM,SAAS,QAAS,QAAO,aAAa,MAAM,WAAW,CAAC,SAAS,MAAM,WAAW,CAAC,SAAS,MAAM,SAAS,CAAC,SAAS,MAAM,SAAS,CAAC,KAAK,KAAK;AACzJ,MAAI,MAAM,SAAS,iBAAkB,QAAO,qBAAqB,MAAM,OAAO,IAAI,CAAC,MAAM,GAAG,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,EAAE,EAAE,KAAK,GAAG,CAAC,KAAK,KAAK;AAC/H,MAAI,MAAM,SAAS,QAAS,QAAO,eAAe,MAAM,CAAC,QAAQ,MAAM,CAAC,YAAY,MAAM,KAAK,aAAa,MAAM,MAAM,KAAK,KAAK,qCAAqC,MAAM,IAAI,CAAC,QAAQ,MAAM,IAAI,CAAC,mCAAmC,IAAI,MAAM,aAAa,OAAO,CAAC;AACvQ,MAAI,MAAM,SAAS,OAAQ,QAAO,YAAY,MAAM,CAAC,QAAQ,MAAM,CAAC,WAAW,MAAM,MAAM,UAAU,SAAS,CAAC,gBAAgB,OAAO,MAAM,WAAW,KAAK,EAAE,8BAA8B,IAAI,MAAM,WAAW,OAAO,MAAM,aAAa,EAAE,EAAE,QAAQ,YAAY,GAAG,EAAE,KAAK,CAAC,CAAC;AAC/Q,SAAO;AACT;AAEO,SAAS,eAAe,OAAO,EAAE,aAAa,WAAW,UAAU,GAAG,IAAI,CAAC,GAAG;AACnF,QAAM,SAAS,eAAe,KAAK,KAAK,EAAE,GAAG,GAAG,GAAG,GAAG,OAAO,MAAM,QAAQ,IAAI;AAC/E,QAAM,MAAM,KAAK,IAAI,GAAG,KAAK,IAAI,KAAK,OAAO,OAAO,KAAK,CAAC,CAAC;AAC3D,QAAM,UAAU,EAAE,GAAG,OAAO,IAAI,KAAK,GAAG,OAAO,IAAI,KAAK,OAAO,KAAK,IAAI,GAAG,OAAO,QAAQ,MAAM,CAAC,GAAG,QAAQ,KAAK,IAAI,GAAG,OAAO,SAAS,MAAM,CAAC,EAAE;AACjJ,QAAM,MAAM,oDAAoD,QAAQ,CAAC,IAAI,QAAQ,CAAC,IAAI,QAAQ,KAAK,IAAI,QAAQ,MAAM,YAAY,KAAK,KAAK,QAAQ,KAAK,CAAC,aAAa,KAAK,KAAK,QAAQ,MAAM,CAAC,gLAAgL,QAAQ,CAAC,QAAQ,QAAQ,CAAC,YAAY,QAAQ,KAAK,aAAa,QAAQ,MAAM,WAAW,MAAM,YAAY,SAAS,CAAC,OAAO,MAAM,UAAU,CAAC,GAAG,IAAI,WAAW,EAAE,KAAK,EAAE,CAAC;AAC5hB,MAAI,IAAI,YAAY,EAAE,OAAO,GAAG,EAAE,aAAa,mBAAmB;AAChE,UAAM,IAAI,MAAM,8CAA8C;AAAA,EAChE;AACA,SAAO;AACT;;;AClCA,IAAM,cAAc;AACpB,IAAM,iBAAiB;AACvB,IAAM,mBAAmB;AACzB,IAAM,8BAA8B,oBAAI,IAAI,CAAC,kBAAkB,cAAc,YAAY,CAAC;AAE1F,IAAM,yBAAyB;AAAA,EAC7B,OAAO;AAAA,IACL,EAAE,MAAM,UAAU,UAAU,CAAC,MAAM,OAAO,GAAG,YAAY,EAAE,IAAI,EAAE,OAAO,MAAM,GAAG,OAAO,EAAE,MAAM,UAAU,aAAa,0EAA0E,EAAE,EAAE;AAAA,IACrM,EAAE,MAAM,UAAU,UAAU,CAAC,MAAM,WAAW,SAAS,GAAG,YAAY,EAAE,IAAI,EAAE,OAAO,SAAS,GAAG,SAAS,EAAE,MAAM,SAAS,GAAG,SAAS,EAAE,MAAM,SAAS,EAAE,EAAE;AAAA,IAC5J,EAAE,MAAM,UAAU,UAAU,CAAC,IAAI,GAAG,YAAY,EAAE,IAAI,EAAE,OAAO,SAAS,GAAG,SAAS,EAAE,MAAM,SAAS,GAAG,UAAU,EAAE,MAAM,SAAS,OAAO,EAAE,MAAM,SAAS,EAAE,EAAE,EAAE;AAAA,IACjK,EAAE,MAAM,UAAU,UAAU,CAAC,MAAM,YAAY,MAAM,IAAI,GAAG,YAAY,EAAE,IAAI,EAAE,OAAO,YAAY,GAAG,UAAU,EAAE,MAAM,SAAS,OAAO,EAAE,MAAM,SAAS,EAAE,GAAG,IAAI,EAAE,MAAM,SAAS,GAAG,IAAI,EAAE,MAAM,SAAS,EAAE,EAAE;AAAA,IAC/M,EAAE,MAAM,UAAU,UAAU,CAAC,MAAM,MAAM,GAAG,YAAY,EAAE,IAAI,EAAE,OAAO,gBAAgB,GAAG,MAAM,EAAE,MAAM,UAAU,WAAW,GAAG,EAAE,EAAE;AAAA,EACtI;AACF;AAEO,IAAM,sBAAsB,OAAO,OAAO;AAAA,EAC/C;AAAA,IACE,MAAM;AAAA,IACN,OAAO;AAAA,IACP,aAAa;AAAA,IACb,aAAa,EAAE,MAAM,UAAU,YAAY,EAAE,eAAe,EAAE,MAAM,WAAW,SAAS,MAAM,GAAG,UAAU,EAAE,MAAM,SAAS,UAAU,KAAK,OAAO,EAAE,MAAM,SAAS,EAAE,EAAE,GAAG,sBAAsB,MAAM;AAAA,IACtM,aAAa,EAAE,cAAc,MAAM,iBAAiB,OAAO,gBAAgB,KAAK;AAAA,EAClF;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,OAAO;AAAA,IACP,aAAa,iEAAiE,WAAW,aAAa;AAAA,IACtG,aAAa,EAAE,MAAM,UAAU,UAAU,CAAC,YAAY,GAAG,YAAY,EAAE,kBAAkB,EAAE,MAAM,WAAW,SAAS,EAAE,GAAG,QAAQ,EAAE,MAAM,WAAW,SAAS,MAAM,GAAG,YAAY,EAAE,MAAM,SAAS,UAAU,GAAG,UAAU,WAAW,eAAe,OAAO,uBAAuB,EAAE,GAAG,sBAAsB,MAAM;AAAA,IACpT,aAAa,EAAE,cAAc,OAAO,iBAAiB,MAAM,gBAAgB,MAAM;AAAA,EACnF;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,OAAO;AAAA,IACP,aAAa;AAAA,IACb,aAAa,EAAE,MAAM,UAAU,YAAY,CAAC,GAAG,sBAAsB,MAAM;AAAA,IAC3E,aAAa,EAAE,cAAc,MAAM,iBAAiB,OAAO,gBAAgB,KAAK;AAAA,EAClF;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,OAAO;AAAA,IACP,aAAa;AAAA,IACb,aAAa,EAAE,MAAM,UAAU,YAAY,EAAE,YAAY,EAAE,MAAM,UAAU,SAAS,sBAAsB,GAAG,SAAS,EAAE,MAAM,UAAU,SAAS,GAAG,SAAS,KAAK,SAAS,GAAG,EAAE,GAAG,sBAAsB,MAAM;AAAA,IAC/M,aAAa,EAAE,cAAc,MAAM,iBAAiB,OAAO,gBAAgB,KAAK;AAAA,EAClF;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,OAAO;AAAA,IACP,aAAa;AAAA,IACb,aAAa,EAAE,MAAM,UAAU,UAAU,CAAC,SAAS,GAAG,YAAY,EAAE,MAAM,EAAE,MAAM,UAAU,WAAW,GAAG,GAAG,SAAS,EAAE,OAAO,KAAK,EAAE,GAAG,sBAAsB,MAAM;AAAA,IACrK,aAAa,EAAE,cAAc,OAAO,iBAAiB,MAAM,gBAAgB,MAAM;AAAA,EACnF;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,OAAO;AAAA,IACP,aAAa;AAAA,IACb,aAAa,EAAE,MAAM,UAAU,YAAY,EAAE,OAAO,EAAE,MAAM,UAAU,WAAW,GAAG,GAAG,KAAK,EAAE,MAAM,UAAU,WAAW,GAAG,GAAG,OAAO,EAAE,MAAM,WAAW,SAAS,GAAG,SAAS,IAAI,SAAS,GAAG,EAAE,GAAG,sBAAsB,MAAM;AAAA,IAC/N,aAAa,EAAE,cAAc,MAAM,iBAAiB,OAAO,gBAAgB,MAAM,eAAe,KAAK;AAAA,EACvG;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,OAAO;AAAA,IACP,aAAa;AAAA,IACb,aAAa,EAAE,MAAM,UAAU,UAAU,CAAC,MAAM,GAAG,YAAY,EAAE,MAAM,EAAE,MAAM,UAAU,SAAS,oBAAoB,GAAG,GAAG,EAAE,MAAM,SAAS,GAAG,GAAG,EAAE,MAAM,SAAS,GAAG,kBAAkB,EAAE,MAAM,WAAW,SAAS,EAAE,GAAG,QAAQ,EAAE,MAAM,WAAW,SAAS,MAAM,EAAE,GAAG,sBAAsB,MAAM;AAAA,IACrS,aAAa,EAAE,cAAc,OAAO,iBAAiB,OAAO,gBAAgB,OAAO,eAAe,KAAK;AAAA,EACzG;AACF,CAAC;AAED,SAAS,WAAW,OAAO,SAAS;AAClC,SAAO;AAAA,IACL,SAAS,CAAC,EAAE,MAAM,QAAQ,MAAM,WAAW,KAAK,UAAU,OAAO,MAAM,CAAC,EAAE,CAAC;AAAA,IAC3E,mBAAmB;AAAA,EACrB;AACF;AAEA,SAAS,UAAU,OAAO;AACxB,QAAM,UAAU,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AACrE,SAAO,EAAE,SAAS,MAAM,SAAS,CAAC,EAAE,MAAM,QAAQ,MAAM,QAAQ,CAAC,GAAG,mBAAmB,EAAE,OAAO,QAAQ,EAAE;AAC5G;AAEO,IAAM,qBAAN,MAAyB;AAAA,EAC9B,YAAY,EAAE,OAAO,mBAAmB,IAAI,4BAA4B,GAAG,aAAa,CAAC,EAAE,IAAI,CAAC,GAAG;AACjG,QAAI,CAAC,OAAO,QAAQ,CAAC,OAAO,MAAO,OAAM,IAAI,MAAM,yEAAyE;AAC5H,SAAK,QAAQ;AACb,SAAK,mBAAmB;AACxB,SAAK,aAAa,EAAE,MAAM,aAAa,SAAS,gBAAgB,GAAG,WAAW;AAC9E,SAAK,gBAAgB,QAAQ,QAAQ;AAAA,EACvC;AAAA,EAEA,YAAY;AACV,WAAO;AAAA,EACT;AAAA,EAEA,MAAM,SAAS,MAAM,OAAO,CAAC,GAAG;AAC9B,QAAI;AACF,cAAQ,MAAM;AAAA,QACZ,KAAK,cAAc;AACjB,gBAAM,QAAQ,MAAM,KAAK,MAAM,KAAK;AACpC,cAAI;AACJ,cAAI,KAAK,eAAe;AACtB,kBAAM,MAAM,IAAI,IAAI,KAAK,YAAY,CAAC,CAAC;AACvC,qBAAS,IAAI,OAAO,MAAM,OAAO,OAAO,CAAC,UAAU,IAAI,IAAI,MAAM,OAAO,CAAC,IAAI,MAAM;AAAA,UACrF;AACA,iBAAO,WAAW,EAAE,SAAS,gBAAgB,KAAK,GAAG,GAAI,SAAS,EAAE,OAAO,IAAI,CAAC,EAAG,CAAC;AAAA,QACtF;AAAA,QACA,KAAK,mBAAmB;AACtB,gBAAM,QAAQ,MAAM,KAAK,MAAM,KAAK;AACpC,gBAAM,aAAa,cAAc,KAAK;AACtC,iBAAO,WAAW,EAAE,GAAG,YAAY,SAAS,gBAAgB,KAAK,GAAG,QAAQ,WAAW,CAAC;AAAA,QAC1F;AAAA,QACA,KAAK,kBAAkB;AACrB,gBAAM,QAAQ,MAAM,KAAK,MAAM,KAAK;AACpC,gBAAM,MAAM,eAAe,OAAO,IAAI;AACtC,iBAAO,WAAW,EAAE,KAAK,SAAS,6BAA6B,aAAa,GAAG,CAAC,IAAI,SAAS,gBAAgB,KAAK,EAAE,GAAG,GAAG;AAAA,QAC5H;AAAA,QACA,KAAK,oBAAoB;AACvB,gBAAM,YAAY,MAAM,KAAK,iBAAiB,OAAO,IAAI;AACzD,iBAAO,WAAW,EAAE,WAAW,UAAU,IAAI,oBAAoB,EAAE,CAAC;AAAA,QACtE;AAAA,QACA,KAAK;AACH,iBAAO,MAAM,KAAK,gBAAgB,YAAY;AAC5C,kBAAM,QAAQ,MAAM,KAAK,MAAM,KAAK;AACpC,kBAAM,SAAS,gBAAgB,OAAO,KAAK,YAAY,IAAI;AAC3D,gBAAI,CAAC,KAAK,OAAQ,OAAM,KAAK,MAAM,MAAM,OAAO,KAAK;AACrD,mBAAO,WAAW,EAAE,UAAU,OAAO,UAAU,QAAQ,OAAO,QAAQ,iBAAiB,OAAO,iBAAiB,SAAS,gBAAgB,OAAO,KAAK,EAAE,GAAG,KAAK,SAAS,kDAAkD,kCAAkC,OAAO,QAAQ,GAAG;AAAA,UAC/Q,CAAC;AAAA,QACH,KAAK;AACH,cAAI,KAAK,YAAY,KAAM,OAAM,IAAI,MAAM,kCAAkC;AAC7E,iBAAO,MAAM,KAAK,gBAAgB,YAAY;AAC5C,kBAAM,QAAQ,iBAAiB,KAAK,IAAI;AACxC,kBAAM,KAAK,MAAM,MAAM,KAAK;AAC5B,mBAAO,WAAW,EAAE,SAAS,gBAAgB,KAAK,EAAE,GAAG,uBAAuB;AAAA,UAChF,CAAC;AAAA,QACH,KAAK;AACH,iBAAO,MAAM,KAAK,gBAAgB,YAAY;AAC5C,kBAAM,QAAQ,MAAM,KAAK,MAAM,KAAK;AACpC,kBAAM,WAAW,OAAO,MAAM,eAAe,CAAC;AAC9C,gBAAI,KAAK,qBAAqB,UAAa,OAAO,KAAK,gBAAgB,MAAM,SAAU,OAAM,IAAI,MAAM,+BAA+B,KAAK,gBAAgB,aAAa,QAAQ,EAAE;AAClL,kBAAM,WAAW,MAAM,KAAK,iBAAiB,KAAK,KAAK,IAAI;AAC3D,kBAAM,SAAS,mBAAmB,OAAO,SAAS,OAAO,IAAI;AAC7D,gBAAI,CAAC,KAAK,OAAQ,OAAM,KAAK,MAAM,MAAM,OAAO,KAAK;AACrD,mBAAO,WAAW,EAAE,UAAU,qBAAqB,SAAS,QAAQ,GAAG,UAAU,OAAO,UAAU,QAAQ,QAAQ,KAAK,MAAM,GAAG,kBAAkB,OAAO,kBAAkB,SAAS,gBAAgB,OAAO,KAAK,EAAE,GAAG,KAAK,SAAS,qDAAqD,0BAA0B,OAAO,iBAAiB,MAAM,UAAU;AAAA,UAC5V,CAAC;AAAA,QACH;AAAS,gBAAM,IAAI,MAAM,iBAAiB,IAAI,GAAG;AAAA,MACnD;AAAA,IACF,SAAS,OAAO;AACd,aAAO,UAAU,KAAK;AAAA,IACxB;AAAA,EACF;AAAA,EAEA,gBAAgB,WAAW;AACzB,UAAM,UAAU,KAAK,cAAc,KAAK,WAAW,SAAS;AAC5D,SAAK,gBAAgB,QAAQ,MAAM,MAAM;AAAA,IAAC,CAAC;AAC3C,WAAO;AAAA,EACT;AAAA,EAEA,MAAM,cAAc,SAAS;AAC3B,UAAM,SAAS,SAAS;AACxB,QAAI,WAAW,cAAc;AAC3B,YAAM,YAAY,QAAQ,QAAQ;AAClC,YAAM,kBAAkB,4BAA4B,IAAI,SAAS,IAAI,YAAY;AACjF,aAAO,EAAE,iBAAiB,cAAc,EAAE,OAAO,EAAE,aAAa,MAAM,GAAG,WAAW,EAAE,WAAW,OAAO,aAAa,MAAM,EAAE,GAAG,YAAY,KAAK,YAAY,cAAc,yIAAyI;AAAA,IACtT;AACA,QAAI,WAAW,OAAQ,QAAO,CAAC;AAC/B,QAAI,WAAW,aAAc,QAAO,EAAE,OAAO,KAAK,UAAU,EAAE;AAC9D,QAAI,WAAW,aAAc,QAAO,KAAK,SAAS,QAAQ,QAAQ,MAAM,QAAQ,QAAQ,aAAa,CAAC,CAAC;AACvG,QAAI,WAAW,iBAAkB,QAAO,EAAE,WAAW,CAAC,EAAE,KAAK,sBAAsB,MAAM,4BAA4B,aAAa,sCAAsC,UAAU,iCAAiC,GAAG,EAAE,KAAK,kCAAkC,MAAM,0BAA0B,aAAa,kDAAkD,UAAU,gBAAgB,CAAC,EAAE;AAC3X,QAAI,WAAW,kBAAkB;AAC/B,YAAM,QAAQ,MAAM,KAAK,MAAM,KAAK;AACpC,UAAI,QAAQ,QAAQ,QAAQ,qBAAsB,QAAO,EAAE,UAAU,CAAC,EAAE,KAAK,sBAAsB,UAAU,kCAAkC,MAAM,KAAK,UAAU,KAAK,EAAE,CAAC,EAAE;AAC9K,UAAI,QAAQ,QAAQ,QAAQ,iCAAkC,QAAO,EAAE,UAAU,CAAC,EAAE,KAAK,kCAAkC,UAAU,iBAAiB,MAAM,eAAe,KAAK,EAAE,CAAC,EAAE;AACrL,YAAM,OAAO,OAAO,IAAI,MAAM,oBAAoB,GAAG,EAAE,MAAM,OAAO,CAAC;AAAA,IACvE;AACA,QAAI,QAAQ,WAAW,gBAAgB,EAAG,QAAO;AACjD,UAAM,OAAO,OAAO,IAAI,MAAM,qBAAqB,MAAM,EAAE,GAAG,EAAE,MAAM,OAAO,CAAC;AAAA,EAChF;AACF;AAEA,SAAS,qBAAqB,WAAW,CAAC,GAAG;AAC3C,SAAO,EAAE,IAAI,SAAS,IAAI,MAAM,SAAS,MAAM,OAAO,SAAS,OAAO,aAAa,SAAS,eAAe,IAAI,MAAM,SAAS,QAAQ,CAAC,GAAG,WAAW,SAAS,WAAW,OAAO,SAAS,OAAO,OAAO,SAAS,OAAO,QAAQ,SAAS,QAAQ,aAAa,SAAS,aAAa,WAAW,SAAS,UAAU;AACnT;AAEA,SAAS,aAAa,OAAO;AAC3B,MAAI,OAAO,SAAS,WAAY,QAAO,KAAK,SAAS,mBAAmB,KAAK,CAAC,CAAC;AAC/E,SAAO,OAAO,KAAK,OAAO,MAAM,EAAE,SAAS,QAAQ;AACrD;AAEO,SAAS,yBAAyBC,UAAS;AAChD,SAAO,IAAI,mBAAmBA,QAAO;AACvC;;;AC9LO,IAAM,mBAAN,MAAuB;AAAA,EAC5B;AAAA,EAEA,YAAY,QAAQ,iBAAiB,GAAG;AACtC,UAAM,aAAa,cAAc,KAAK;AACtC,QAAI,CAAC,WAAW,MAAO,OAAM,IAAI,MAAM,0BAA0B,WAAW,OAAO,KAAK,IAAI,CAAC,EAAE;AAC/F,SAAK,SAAS,gBAAgB,KAAK;AAAA,EACrC;AAAA,EAEA,MAAM,OAAO;AACX,WAAO,gBAAgB,KAAK,MAAM;AAAA,EACpC;AAAA,EAEA,MAAM,MAAM,OAAO;AACjB,UAAM,aAAa,cAAc,KAAK;AACtC,QAAI,CAAC,WAAW,MAAO,OAAM,IAAI,MAAM,oCAAoC,WAAW,OAAO,KAAK,IAAI,CAAC,EAAE;AACzG,SAAK,SAAS,gBAAgB,KAAK;AACnC,WAAO,KAAK,KAAK;AAAA,EACnB;AACF;",
6
- "names": ["color", "shape", "options"]
3
+ "sources": ["../../src/mcp/scene.js", "../../src/mcp/templates.js", "../../src/mcp/preview.js", "../../src/core/LixScriptParser.js", "../../src/mcp/lixscript.js", "../../src/mcp/server.js", "../../src/mcp/store.js", "../../src/mcp/remoteStore.js"],
4
+ "sourcesContent": ["const FORMAT = 'lixsketch';\nconst VERSION = 1;\nconst MAX_SHAPES = 5000;\nconst MAX_OPERATIONS = 500;\nconst SCENE_TYPES = new Set(['rectangle', 'circle', 'line', 'arrow', 'freehandStroke', 'frame', 'text', 'code', 'image', 'icon']);\nconst WRITABLE_TYPES = new Set(['rectangle', 'circle', 'line', 'arrow', 'freehandStroke', 'frame', 'text']);\n\nconst clone = (value) => JSON.parse(JSON.stringify(value));\nconst finite = (value, fallback = 0) => Number.isFinite(Number(value)) ? Number(value) : fallback;\nconst positive = (value, fallback = 1) => Math.max(1, finite(value, fallback));\n\nexport function createEmptyScene(name = 'MCP Canvas') {\n return {\n format: FORMAT,\n version: VERSION,\n sessionID: `mcp-${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 8)}`,\n name: String(name || 'MCP Canvas').trim().slice(0, 72),\n createdAt: new Date().toISOString(),\n viewport: { x: 0, y: 0, width: 1280, height: 720 },\n zoom: 1,\n mcpRevision: 0,\n shapes: [],\n };\n}\n\nexport function validateScene(scene) {\n const errors = [];\n if (!scene || typeof scene !== 'object') return { valid: false, errors: ['Scene must be an object'] };\n if (scene.format !== FORMAT) errors.push(`Scene format must be \"${FORMAT}\"`);\n if (scene.version !== VERSION) errors.push(`Scene version must be ${VERSION}`);\n if (!Array.isArray(scene.shapes)) errors.push('Scene shapes must be an array');\n if (Array.isArray(scene.shapes) && scene.shapes.length > MAX_SHAPES) errors.push(`Scene exceeds ${MAX_SHAPES} shapes`);\n const ids = new Set();\n for (const [index, shape] of (scene.shapes || []).entries()) {\n if (!shape || typeof shape !== 'object') { errors.push(`Shape ${index} must be an object`); continue; }\n if (!SCENE_TYPES.has(shape.type)) errors.push(`Shape ${index} has unsupported type \"${shape.type}\"`);\n if (!shape.shapeID || typeof shape.shapeID !== 'string') errors.push(`Shape ${index} is missing shapeID`);\n else if (ids.has(shape.shapeID)) errors.push(`Duplicate shapeID \"${shape.shapeID}\"`);\n else ids.add(shape.shapeID);\n validateShapeGeometry(shape, index, errors);\n }\n return { valid: errors.length === 0, errors };\n}\n\nfunction escapeXml(value) {\n return String(value).replaceAll('&', '&amp;').replaceAll('<', '&lt;').replaceAll('>', '&gt;').replaceAll('\"', '&quot;').replaceAll(\"'\", '&apos;');\n}\n\nfunction normalizeOptions(value = {}) {\n return {\n roughness: Math.max(0, Math.min(3, finite(value.roughness, 1.2))),\n stroke: typeof value.stroke === 'string' ? value.stroke : '#8b76d6',\n strokeWidth: Math.max(0.5, Math.min(20, finite(value.strokeWidth, 2))),\n fill: typeof value.fill === 'string' ? value.fill : 'transparent',\n fillStyle: typeof value.fillStyle === 'string' ? value.fillStyle : 'solid',\n opacity: Math.max(0, Math.min(1, finite(value.opacity, 1))),\n };\n}\n\nfunction createTextShape(input, shapeID) {\n const x = finite(input.x), y = finite(input.y), rotation = finite(input.rotation);\n const text = String(input.text || '').slice(0, 10000);\n const fontSize = Math.max(8, Math.min(160, finite(input.fontSize, 20)));\n const color = typeof input.color === 'string' ? input.color : '#e8e3f3';\n const family = typeof input.fontFamily === 'string' ? input.fontFamily.slice(0, 80) : 'lixFont';\n const transform = `translate(${x}, ${y})${rotation ? ` rotate(${rotation}, 0, 0)` : ''}`;\n const lines = text.split('\\n').map((line, index) => `<tspan x=\"0\" dy=\"${index === 0 ? 0 : '1.2em'}\">${escapeXml(line || ' ')}</tspan>`).join('');\n return {\n shapeID, type: 'text', x, y, rotation,\n mcpText: text, mcpFontSize: fontSize, mcpColor: color, mcpFontFamily: family,\n groupHTML: `<g id=\"${escapeXml(shapeID)}\" data-type=\"text-group\" data-x=\"${x}\" data-y=\"${y}\" transform=\"${transform}\"><text id=\"${escapeXml(shapeID)}-text\" x=\"0\" y=\"0\" fill=\"${escapeXml(color)}\" font-size=\"${fontSize}\" font-family=\"${escapeXml(family)}\" dominant-baseline=\"hanging\" white-space=\"pre\" pointer-events=\"painted\" data-type=\"text\" data-initial-size=\"${fontSize}\" data-initial-font=\"${escapeXml(family)}\" data-initial-color=\"${escapeXml(color)}\">${lines}</text></g>`,\n };\n}\n\nexport function normalizeShape(input, existingIds = new Set()) {\n if (!input || typeof input !== 'object') throw new Error('Shape must be an object');\n if (!WRITABLE_TYPES.has(input.type)) throw new Error(`Shape type \"${input.type}\" is read-only through MCP`);\n let shapeID = String(input.shapeID || `${input.type}-${crypto.randomUUID()}`).slice(0, 120);\n while (existingIds.has(shapeID)) shapeID = `${input.type}-${crypto.randomUUID()}`;\n const base = { shapeID, type: input.type, rotation: finite(input.rotation), options: normalizeOptions(input.options), groupId: input.groupId || null, parentFrame: input.parentFrame || null, docBlockIds: [] };\n switch (input.type) {\n case 'rectangle': return { ...base, x: finite(input.x), y: finite(input.y), width: positive(input.width, 160), height: positive(input.height, 90) };\n case 'circle': return { ...base, x: finite(input.x), y: finite(input.y), rx: positive(input.rx, 60), ry: positive(input.ry, 60) };\n case 'line': return { ...base, startPoint: point(input.startPoint), endPoint: point(input.endPoint, 120), isCurved: Boolean(input.isCurved), controlPoint: input.controlPoint ? point(input.controlPoint) : null };\n case 'arrow': return { ...base, startPoint: point(input.startPoint), endPoint: point(input.endPoint, 120), arrowHeadStyle: input.arrowHeadStyle || 'triangle', arrowOutlineStyle: input.arrowOutlineStyle || 'solid', arrowCurved: Boolean(input.arrowCurved), arrowCurveAmount: finite(input.arrowCurveAmount, 0.2) };\n case 'freehandStroke': {\n const points = (Array.isArray(input.points) ? input.points : []).slice(0, 4096).map((entry) => [finite(entry?.[0]), finite(entry?.[1]), finite(entry?.[2], 0.5)]);\n if (points.length < 2) throw new Error('freehandStroke requires at least two points');\n return { ...base, points };\n }\n case 'frame': return { ...base, x: finite(input.x), y: finite(input.y), width: positive(input.width, 640), height: positive(input.height, 360), frameName: String(input.frameName || 'Frame').slice(0, 80), fillStyle: input.fillStyle || 'transparent', fillColor: input.fillColor || '#1e1e28', gridSize: positive(input.gridSize, 20), containedShapeIDs: [] };\n case 'text': return { ...base, ...createTextShape(input, shapeID) };\n default: throw new Error(`Unsupported shape type \"${input.type}\"`);\n }\n}\n\nfunction point(value, fallbackX = 0) {\n return { x: finite(value?.x, fallbackX), y: finite(value?.y) };\n}\n\nfunction translateShape(shape, dx, dy) {\n const moved = clone(shape);\n if (moved.startPoint) { moved.startPoint.x += dx; moved.startPoint.y += dy; }\n if (moved.endPoint) { moved.endPoint.x += dx; moved.endPoint.y += dy; }\n if (moved.controlPoint) { moved.controlPoint.x += dx; moved.controlPoint.y += dy; }\n if (moved.controlPoint1) { moved.controlPoint1.x += dx; moved.controlPoint1.y += dy; }\n if (moved.controlPoint2) { moved.controlPoint2.x += dx; moved.controlPoint2.y += dy; }\n if (Array.isArray(moved.points)) moved.points = moved.points.map((p) => [p[0] + dx, p[1] + dy, ...p.slice(2)]);\n if (Number.isFinite(moved.x)) moved.x += dx;\n if (Number.isFinite(moved.y)) moved.y += dy;\n if (moved.type === 'text' && moved.groupHTML) {\n moved.groupHTML = moved.groupHTML\n .replace(/data-x=\"[^\"]*\"/, `data-x=\"${moved.x}\"`)\n .replace(/data-y=\"[^\"]*\"/, `data-y=\"${moved.y}\"`)\n .replace(/transform=\"translate\\([^)]*\\)/, `transform=\"translate(${moved.x}, ${moved.y})`);\n }\n if (moved.type === 'code' && moved.groupHTML) {\n moved.groupHTML = moved.groupHTML\n .replace(/data-x=\"[^\"]*\"/, `data-x=\"${moved.x}\"`)\n .replace(/data-y=\"[^\"]*\"/, `data-y=\"${moved.y}\"`)\n .replace(/transform=\"translate\\([^)]*\\)/, `transform=\"translate(${moved.x}, ${moved.y})`);\n }\n if (moved.type === 'icon' && moved.elementHTML) {\n moved.elementHTML = moved.elementHTML\n .replace(/\\bx=\"[^\"]*\"/, `x=\"${moved.x}\"`)\n .replace(/\\by=\"[^\"]*\"/, `y=\"${moved.y}\"`);\n }\n return moved;\n}\n\nexport function applyScenePatch(sceneInput, operations, { expectedRevision, dryRun = false } = {}) {\n const scene = clone(sceneInput);\n const check = validateScene(scene);\n if (!check.valid) throw new Error(`Invalid scene: ${check.errors.join('; ')}`);\n if (!Array.isArray(operations) || operations.length === 0) throw new Error('At least one operation is required');\n if (operations.length > MAX_OPERATIONS) throw new Error(`Patch exceeds ${MAX_OPERATIONS} operations`);\n const revision = Number(scene.mcpRevision || 0);\n if (expectedRevision !== undefined && Number(expectedRevision) !== revision) throw new Error(`Revision conflict: expected ${expectedRevision}, current ${revision}`);\n const changedIds = new Set();\n for (const operation of operations) {\n if (!operation || typeof operation !== 'object') throw new Error('Each operation must be an object');\n if (operation.op === 'add') {\n if (scene.shapes.length >= MAX_SHAPES) throw new Error(`Scene exceeds ${MAX_SHAPES} shapes`);\n const ids = new Set(scene.shapes.map((shape) => shape.shapeID));\n const shape = normalizeShape(operation.shape, ids);\n scene.shapes.push(shape); changedIds.add(shape.shapeID);\n } else if (operation.op === 'update') {\n const index = scene.shapes.findIndex((shape) => shape.shapeID === operation.shapeID);\n if (index < 0) throw new Error(`Shape \"${operation.shapeID}\" was not found`);\n const immutable = scene.shapes[index];\n scene.shapes[index] = applyShapeChanges(immutable, operation.changes || {}); changedIds.add(immutable.shapeID);\n } else if (operation.op === 'delete') {\n const ids = new Set(Array.isArray(operation.shapeIDs) ? operation.shapeIDs : [operation.shapeID]);\n const before = scene.shapes.length;\n scene.shapes = scene.shapes.filter((shape) => !ids.has(shape.shapeID));\n if (scene.shapes.length === before) throw new Error('No requested shapes were found');\n scene.shapes.forEach((shape) => {\n if (ids.has(shape.parentFrame)) shape.parentFrame = null;\n if (Array.isArray(shape.containedShapeIDs)) shape.containedShapeIDs = shape.containedShapeIDs.filter((id) => !ids.has(id));\n });\n ids.forEach((id) => changedIds.add(id));\n } else if (operation.op === 'translate') {\n const ids = new Set(operation.shapeIDs || []), dx = finite(operation.dx), dy = finite(operation.dy);\n if (!ids.size) throw new Error('translate requires shapeIDs');\n scene.shapes = scene.shapes.map((shape) => ids.has(shape.shapeID) ? translateShape(shape, dx, dy) : shape);\n ids.forEach((id) => changedIds.add(id));\n } else if (operation.op === 'rename_canvas') {\n scene.name = String(operation.name || '').trim().slice(0, 72) || scene.name;\n } else throw new Error(`Unsupported operation \"${operation.op}\"`);\n }\n reconcileFrameContainment(scene);\n scene.mcpRevision = revision + 1;\n scene.updatedAt = new Date().toISOString();\n const result = validateScene(scene);\n if (!result.valid) throw new Error(`Patch produced an invalid scene: ${result.errors.join('; ')}`);\n return { scene, revision: scene.mcpRevision, dryRun: Boolean(dryRun), changedShapeIDs: [...changedIds] };\n}\n\nfunction reconcileFrameContainment(scene) {\n const frames = new Map(scene.shapes.filter((shape) => shape.type === 'frame').map((shape) => [shape.shapeID, shape]));\n for (const frame of frames.values()) frame.containedShapeIDs = [];\n for (const shape of scene.shapes) {\n if (!shape.parentFrame) continue;\n const frame = frames.get(shape.parentFrame);\n if (!frame) throw new Error(`Shape \"${shape.shapeID}\" references missing frame \"${shape.parentFrame}\"`);\n frame.containedShapeIDs.push(shape.shapeID);\n }\n}\n\nfunction applyShapeChanges(shape, changes) {\n if (!changes || typeof changes !== 'object' || Array.isArray(changes)) throw new Error('Shape changes must be an object');\n const allowed = {\n rectangle: ['x', 'y', 'width', 'height', 'rotation', 'options', 'groupId', 'parentFrame'],\n circle: ['x', 'y', 'rx', 'ry', 'rotation', 'options', 'groupId', 'parentFrame'],\n line: ['startPoint', 'endPoint', 'controlPoint', 'isCurved', 'options', 'groupId', 'parentFrame'],\n arrow: ['startPoint', 'endPoint', 'controlPoint1', 'controlPoint2', 'arrowHeadStyle', 'arrowOutlineStyle', 'arrowCurved', 'arrowCurveAmount', 'options', 'groupId', 'parentFrame'],\n freehandStroke: ['points', 'rotation', 'options', 'groupId', 'parentFrame'],\n frame: ['x', 'y', 'width', 'height', 'rotation', 'frameName', 'fillStyle', 'fillColor', 'gridSize', 'options', 'groupId', 'parentFrame'],\n text: ['x', 'y', 'rotation', 'text', 'fontSize', 'color', 'fontFamily', 'groupId', 'parentFrame'],\n }[shape.type] || [];\n const rejected = Object.keys(changes).filter((key) => !allowed.includes(key));\n if (rejected.length) throw new Error(`Cannot update ${shape.type} fields: ${rejected.join(', ')}`);\n if (shape.type === 'text') {\n const text = changes.text ?? shape.mcpText ?? extractText(shape.groupHTML);\n return { ...shape, ...createTextShape({ x: changes.x ?? shape.x, y: changes.y ?? shape.y, rotation: changes.rotation ?? shape.rotation, text, fontSize: changes.fontSize ?? shape.mcpFontSize, color: changes.color ?? shape.mcpColor, fontFamily: changes.fontFamily ?? shape.mcpFontFamily }, shape.shapeID), groupId: changes.groupId ?? shape.groupId, parentFrame: changes.parentFrame ?? shape.parentFrame };\n }\n const copy = { ...clone(shape), ...clone(changes), shapeID: shape.shapeID, type: shape.type };\n if (changes.options) copy.options = { ...(shape.options || {}), ...normalizeOptions({ ...(shape.options || {}), ...changes.options }) };\n return copy;\n}\n\nfunction extractText(groupHTML = '') {\n return String(groupHTML).replace(/<[^>]+>/g, ' ').replace(/\\s+/g, ' ').trim();\n}\n\nfunction validateShapeGeometry(shape, index, errors) {\n const numbers = [];\n if (['rectangle', 'frame', 'text', 'code', 'image', 'icon'].includes(shape.type)) numbers.push(['x', shape.x], ['y', shape.y]);\n if (['rectangle', 'frame', 'image', 'icon'].includes(shape.type)) numbers.push(['width', shape.width], ['height', shape.height]);\n if (shape.type === 'circle') numbers.push(['x', shape.x], ['y', shape.y], ['rx', shape.rx], ['ry', shape.ry]);\n if (shape.startPoint) numbers.push(['startPoint.x', shape.startPoint.x], ['startPoint.y', shape.startPoint.y]);\n if (shape.endPoint) numbers.push(['endPoint.x', shape.endPoint.x], ['endPoint.y', shape.endPoint.y]);\n for (const [field, value] of numbers) if (!Number.isFinite(Number(value))) errors.push(`Shape ${index} has invalid ${field}`);\n if (['rectangle', 'frame', 'image', 'icon'].includes(shape.type) && (Number(shape.width) <= 0 || Number(shape.height) <= 0)) errors.push(`Shape ${index} must have positive dimensions`);\n if (shape.type === 'circle' && (Number(shape.rx) <= 0 || Number(shape.ry) <= 0)) errors.push(`Shape ${index} must have positive radii`);\n if (shape.type === 'freehandStroke' && (!Array.isArray(shape.points) || shape.points.length < 2 || shape.points.length > 4096)) errors.push(`Shape ${index} has invalid freehand points`);\n if (shape.type === 'text' && typeof shape.groupHTML !== 'string') errors.push(`Shape ${index} is missing text markup`);\n if (shape.type === 'code' && typeof shape.groupHTML !== 'string') errors.push(`Shape ${index} is missing code markup`);\n if (shape.type === 'image' && typeof shape.href !== 'string') errors.push(`Shape ${index} is missing image href`);\n if (shape.type === 'icon' && typeof shape.elementHTML !== 'string') errors.push(`Shape ${index} is missing icon markup`);\n}\n\nexport function getSceneSummary(scene) {\n const counts = {};\n for (const shape of scene.shapes || []) counts[shape.type] = (counts[shape.type] || 0) + 1;\n return { name: scene.name, format: scene.format, version: scene.version, revision: Number(scene.mcpRevision || 0), shapeCount: scene.shapes?.length || 0, counts, bounds: getSceneBounds(scene) };\n}\n\nexport function getSceneBounds(scene) {\n const boxes = (scene.shapes || []).map(shapeBounds).filter(Boolean);\n if (!boxes.length) return null;\n const minX = Math.min(...boxes.map((b) => b.x)), minY = Math.min(...boxes.map((b) => b.y));\n const maxX = Math.max(...boxes.map((b) => b.x + b.width)), maxY = Math.max(...boxes.map((b) => b.y + b.height));\n return { x: minX, y: minY, width: maxX - minX, height: maxY - minY };\n}\n\nexport function shapeBounds(shape) {\n if (shape.type === 'circle') return { x: shape.x - shape.rx, y: shape.y - shape.ry, width: shape.rx * 2, height: shape.ry * 2 };\n if (shape.startPoint && shape.endPoint) {\n const x = Math.min(shape.startPoint.x, shape.endPoint.x), y = Math.min(shape.startPoint.y, shape.endPoint.y);\n return { x, y, width: Math.abs(shape.endPoint.x - shape.startPoint.x), height: Math.abs(shape.endPoint.y - shape.startPoint.y) };\n }\n if (Array.isArray(shape.points) && shape.points.length) {\n const xs = shape.points.map((p) => p[0]), ys = shape.points.map((p) => p[1]);\n return { x: Math.min(...xs), y: Math.min(...ys), width: Math.max(...xs) - Math.min(...xs), height: Math.max(...ys) - Math.min(...ys) };\n }\n if (shape.type === 'text') return { x: finite(shape.x), y: finite(shape.y), width: 160, height: 32 };\n return { x: finite(shape.x), y: finite(shape.y), width: positive(shape.width), height: positive(shape.height) };\n}\n\nexport function mergeTemplateScene(sceneInput, templateInput, { x, y } = {}) {\n const scene = clone(sceneInput), template = clone(templateInput);\n const validation = validateScene(template);\n if (!validation.valid) throw new Error(`Template scene is invalid: ${validation.errors.join('; ')}`);\n if (scene.shapes.length + template.shapes.length > MAX_SHAPES) throw new Error(`Imported template would exceed ${MAX_SHAPES} shapes`);\n const bounds = getSceneBounds(template) || { x: 0, y: 0 };\n const targetX = finite(x, scene.viewport?.x || 0), targetY = finite(y, scene.viewport?.y || 0);\n const dx = targetX - bounds.x, dy = targetY - bounds.y;\n const idMap = new Map(template.shapes.map((shape) => [shape.shapeID, `${shape.type}-${crypto.randomUUID()}`]));\n const imported = template.shapes.map((shape) => {\n const moved = translateShape(shape, dx, dy);\n moved.shapeID = idMap.get(shape.shapeID);\n if (moved.parentFrame) moved.parentFrame = idMap.get(moved.parentFrame) || null;\n if (Array.isArray(moved.containedShapeIDs)) moved.containedShapeIDs = moved.containedShapeIDs.map((id) => idMap.get(id)).filter(Boolean);\n if (moved.startAttachmentID) moved.startAttachmentID = idMap.get(moved.startAttachmentID) || null;\n if (moved.endAttachmentID) moved.endAttachmentID = idMap.get(moved.endAttachmentID) || null;\n if (moved.groupHTML) moved.groupHTML = moved.groupHTML.split(shape.shapeID).join(moved.shapeID);\n if (moved.elementHTML) moved.elementHTML = moved.elementHTML.split(shape.shapeID).join(moved.shapeID);\n return moved;\n });\n scene.shapes.push(...imported);\n scene.mcpRevision = Number(scene.mcpRevision || 0) + 1;\n scene.updatedAt = new Date().toISOString();\n return { scene, revision: scene.mcpRevision, importedShapeIDs: imported.map((shape) => shape.shapeID) };\n}\n\nexport const MCP_LIMITS = Object.freeze({ maxShapes: MAX_SHAPES, maxOperations: MAX_OPERATIONS });\n", "const DEFAULT_MARKETPLACE_URL = 'https://sketch.elixpo.com';\n\nfunction decodeBase64Url(value) {\n const base64 = String(value).replaceAll('-', '+').replaceAll('_', '/');\n const padded = base64 + '='.repeat((4 - base64.length % 4) % 4);\n const binary = atob(padded);\n return Uint8Array.from(binary, (character) => character.charCodeAt(0));\n}\n\nexport async function decryptPublicTemplate(ciphertext, keyValue) {\n const keyBytes = decodeBase64Url(keyValue);\n if (keyBytes.byteLength !== 32) throw new Error('Template key is not AES-256');\n const combined = decodeBase64Url(ciphertext);\n if (combined.byteLength < 28) throw new Error('Template ciphertext is invalid');\n const key = await crypto.subtle.importKey('raw', keyBytes, { name: 'AES-GCM', length: 256 }, false, ['decrypt']);\n const plaintext = await crypto.subtle.decrypt({ name: 'AES-GCM', iv: combined.slice(0, 12) }, key, combined.slice(12));\n return JSON.parse(new TextDecoder().decode(plaintext));\n}\n\nexport class MarketplaceTemplateProvider {\n constructor({ baseUrl = DEFAULT_MARKETPLACE_URL, fetchImpl = globalThis.fetch } = {}) {\n if (typeof fetchImpl !== 'function') throw new Error('MarketplaceTemplateProvider requires fetch');\n this.baseUrl = String(baseUrl).replace(/\\/$/, '');\n this.fetch = fetchImpl;\n }\n\n async search({ query = '', tag = '', limit = 12 } = {}) {\n const url = new URL('/api/templates', this.baseUrl);\n if (query) url.searchParams.set('q', String(query).slice(0, 80));\n if (tag) url.searchParams.set('tag', String(tag).slice(0, 24));\n url.searchParams.set('limit', String(Math.min(24, Math.max(1, Number(limit) || 12))));\n const response = await this.fetch(url, { headers: { accept: 'application/json' } });\n const body = await response.json();\n if (!response.ok) throw new Error(body.error || `Marketplace request failed (${response.status})`);\n return body.templates || [];\n }\n\n async load(slug) {\n const safeSlug = String(slug || '').trim();\n if (!/^[a-z0-9-]{1,80}$/.test(safeSlug)) throw new Error('Template slug is invalid');\n const url = new URL(`/api/templates/${encodeURIComponent(safeSlug)}`, this.baseUrl);\n url.searchParams.set('snapshot', '1');\n const response = await this.fetch(url, { headers: { accept: 'application/json' } });\n const body = await response.json();\n if (!response.ok) throw new Error(body.error || `Template request failed (${response.status})`);\n const template = body.template;\n if (!template?.encryptedData || !template?.publicKey) throw new Error('Template snapshot is unavailable');\n return { metadata: { ...template, encryptedData: undefined, publicKey: undefined, encryptedDocData: undefined }, scene: await decryptPublicTemplate(template.encryptedData, template.publicKey) };\n }\n}\n\n", "import { getSceneBounds } from './scene.js';\n\nconst MAX_PREVIEW_BYTES = 5 * 1024 * 1024;\n\nconst esc = (value) => String(value ?? '').replaceAll('&', '&amp;').replaceAll('<', '&lt;').replaceAll('>', '&gt;').replaceAll('\"', '&quot;');\nconst color = (value, fallback) => typeof value === 'string' && /^#[0-9a-f]{3,8}$/i.test(value) ? value : fallback;\n\nfunction options(shape) {\n return {\n stroke: color(shape.options?.stroke, '#8b76d6'),\n fill: shape.options?.fill === 'transparent' ? 'none' : color(shape.options?.fill, 'none'),\n width: Math.max(0.5, Math.min(20, Number(shape.options?.strokeWidth) || 2)),\n opacity: Math.max(0, Math.min(1, Number(shape.options?.opacity) || 1)),\n };\n}\n\nfunction renderShape(shape) {\n const style = options(shape);\n const attrs = `stroke=\"${style.stroke}\" stroke-width=\"${style.width}\" fill=\"${style.fill}\" opacity=\"${style.opacity}\"`;\n if (shape.type === 'rectangle') return `<rect x=\"${shape.x}\" y=\"${shape.y}\" width=\"${shape.width}\" height=\"${shape.height}\" rx=\"6\" ${attrs}/>`;\n if (shape.type === 'circle') return `<ellipse cx=\"${shape.x}\" cy=\"${shape.y}\" rx=\"${shape.rx}\" ry=\"${shape.ry}\" ${attrs}/>`;\n if (shape.type === 'line') return `<line x1=\"${shape.startPoint.x}\" y1=\"${shape.startPoint.y}\" x2=\"${shape.endPoint.x}\" y2=\"${shape.endPoint.y}\" ${attrs}/>`;\n if (shape.type === 'arrow') return `<line x1=\"${shape.startPoint.x}\" y1=\"${shape.startPoint.y}\" x2=\"${shape.endPoint.x}\" y2=\"${shape.endPoint.y}\" ${attrs} marker-end=\"url(#arrowhead)\"/>`;\n if (shape.type === 'freehandStroke') return `<polyline points=\"${shape.points.map((p) => `${p[0]},${p[1]}`).join(' ')}\" ${attrs} fill=\"none\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>`;\n if (shape.type === 'frame') return `<g><rect x=\"${shape.x}\" y=\"${shape.y}\" width=\"${shape.width}\" height=\"${shape.height}\" ${attrs} stroke-dasharray=\"6 5\"/><text x=\"${shape.x + 8}\" y=\"${shape.y - 8}\" fill=\"#9f94b5\" font-size=\"14\">${esc(shape.frameName || 'Frame')}</text></g>`;\n if (shape.type === 'text') return `<text x=\"${shape.x}\" y=\"${shape.y}\" fill=\"${color(shape.mcpColor, '#e8e3f3')}\" font-size=\"${Number(shape.mcpFontSize) || 20}\" font-family=\"sans-serif\">${esc(shape.mcpText || String(shape.groupHTML || '').replace(/<[^>]+>/g, ' ').trim())}</text>`;\n return '';\n}\n\nexport function renderSceneSvg(scene, { background = '#15111f', padding = 40 } = {}) {\n const bounds = getSceneBounds(scene) || { x: 0, y: 0, width: 1280, height: 720 };\n const pad = Math.max(0, Math.min(200, Number(padding) || 0));\n const viewBox = { x: bounds.x - pad, y: bounds.y - pad, width: Math.max(1, bounds.width + pad * 2), height: Math.max(1, bounds.height + pad * 2) };\n const svg = `<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"${viewBox.x} ${viewBox.y} ${viewBox.width} ${viewBox.height}\" width=\"${Math.ceil(viewBox.width)}\" height=\"${Math.ceil(viewBox.height)}\"><defs><marker id=\"arrowhead\" markerWidth=\"10\" markerHeight=\"7\" refX=\"9\" refY=\"3.5\" orient=\"auto\"><polygon points=\"0 0,10 3.5,0 7\" fill=\"#8b76d6\"/></marker></defs><rect x=\"${viewBox.x}\" y=\"${viewBox.y}\" width=\"${viewBox.width}\" height=\"${viewBox.height}\" fill=\"${color(background, '#15111f')}\"/>${(scene.shapes || []).map(renderShape).join('')}</svg>`;\n if (new TextEncoder().encode(svg).byteLength > MAX_PREVIEW_BYTES) {\n throw new Error('Canvas preview exceeds the 5 MB output limit');\n }\n return svg;\n}\n", "/* eslint-disable */\n/**\n * LixScript \u2014 Programmatic diagram DSL for LixSketch\n *\n * Parses a text-based language into canvas shapes with full control over\n * properties, positions, connections, and grouping.\n *\n * Usage:\n * const result = parseLixScript(source)\n * if (result.errors.length) { ... }\n * renderLixScript(result)\n */\n\nconst NS = 'http://www.w3.org/2000/svg'\n\n// ============================================================\n// TOKENIZER\n// ============================================================\n\n/**\n * Tokenize a LixScript source string into a flat list of tokens.\n * Each token: { type, value, line }\n */\nfunction tokenize(source) {\n const tokens = []\n const lines = source.split('\\n')\n\n for (let i = 0; i < lines.length; i++) {\n const raw = lines[i]\n const lineNum = i + 1\n\n // Strip comments\n const commentIdx = raw.indexOf('//')\n const line = commentIdx !== -1 ? raw.slice(0, commentIdx) : raw\n const trimmed = line.trim()\n if (!trimmed) continue\n\n tokens.push({ type: 'LINE', value: trimmed, line: lineNum })\n }\n\n return tokens\n}\n\n// ============================================================\n// PARSER\n// ============================================================\n\n/**\n * Parse LixScript source into an AST.\n * Returns { variables, shapes, errors }\n */\nexport function parseLixScript(source) {\n const tokens = tokenize(source)\n const variables = {}\n const shapes = []\n const errors = []\n\n let i = 0\n\n while (i < tokens.length) {\n const token = tokens[i]\n const line = token.value\n const lineNum = token.line\n\n try {\n // Variable assignment: $name = value\n if (line.startsWith('$')) {\n const match = line.match(/^\\$(\\w+)\\s*=\\s*(.+)$/)\n if (match) {\n variables[match[1]] = match[2].trim()\n } else {\n errors.push({ line: lineNum, message: `Invalid variable syntax: ${line}` })\n }\n i++\n continue\n }\n\n // Shape declarations\n const shapeMatch = line.match(/^(rect|circle|ellipse|arrow|line|text|frame|freehand|image|icon)\\s+(\\w+)\\s+(.+)$/)\n if (shapeMatch) {\n const [, type, id, rest] = shapeMatch\n const shape = parseShapeDeclaration(type, id, rest, lineNum, errors, variables)\n\n // Check for property block { ... }\n if (rest.includes('{') && !rest.includes('}')) {\n // Multi-line property block \u2014 consume lines until closing }\n i++\n const props = []\n while (i < tokens.length && !tokens[i].value.startsWith('}')) {\n props.push(tokens[i].value)\n i++\n }\n if (i < tokens.length) i++ // skip closing }\n parseProperties(shape, props, variables, errors)\n } else if (rest.includes('{') && rest.includes('}')) {\n // Inline property block\n const blockMatch = rest.match(/\\{([^}]*)\\}/)\n if (blockMatch) {\n const props = blockMatch[1].split(/[,;]/).map(s => s.trim()).filter(Boolean)\n parseProperties(shape, props, variables, errors)\n }\n i++ // advance past this single line\n } else {\n // No property block\n i++\n }\n\n shapes.push(shape)\n continue\n }\n\n errors.push({ line: lineNum, message: `Unrecognized syntax: ${line}` })\n i++\n } catch (err) {\n errors.push({ line: lineNum, message: err.message })\n i++\n }\n }\n\n return { variables, shapes, errors }\n}\n\n/**\n * Parse the declaration part (after type and id) of a shape.\n */\nfunction parseShapeDeclaration(type, id, rest, lineNum, errors, variables) {\n const shape = { type, id, line: lineNum, props: {} }\n\n // Extract position: at X, Y or from ... to ...\n if (type === 'arrow' || type === 'line') {\n // from source[.side] to target[.side]\n // from X, Y to X, Y\n const connMatch = rest.match(/from\\s+(.+?)\\s+to\\s+(.+?)(?:\\s*\\{|$)/)\n if (connMatch) {\n shape.from = parsePointOrRef(connMatch[1].trim(), variables)\n shape.to = parsePointOrRef(connMatch[2].trim(), variables)\n } else {\n errors.push({ line: lineNum, message: `${type} requires 'from ... to ...' syntax` })\n }\n } else {\n // at X, Y\n const atMatch = rest.match(/at\\s+([\\w$.+\\-*\\s]+?),\\s*([\\w$.+\\-*\\s]+?)(?:\\s+size|\\s*\\{|$)/)\n if (atMatch) {\n shape.x = parseExpr(atMatch[1].trim(), variables)\n shape.y = parseExpr(atMatch[2].trim(), variables)\n } else if (type !== 'frame') {\n errors.push({ line: lineNum, message: `${type} requires 'at X, Y' syntax` })\n }\n\n // size WxH\n const sizeMatch = rest.match(/size\\s+([\\w$.+\\-*]+)\\s*x\\s*([\\w$.+\\-*]+)/)\n if (sizeMatch) {\n shape.width = parseExpr(sizeMatch[1].trim(), variables)\n shape.height = parseExpr(sizeMatch[2].trim(), variables)\n }\n }\n\n return shape\n}\n\n/**\n * Parse a point reference \u2014 either a coordinate pair \"X, Y\" or\n * a shape reference \"shapeId.side\" or \"shapeId.side + offset\"\n */\nfunction parsePointOrRef(str, variables) {\n // shapeId.side [+/- offset]\n const refMatch = str.match(/^(\\w+)\\.(\\w+)(?:\\s*([+-])\\s*([\\d.]+))?$/)\n if (refMatch) {\n return {\n ref: refMatch[1],\n side: refMatch[2],\n offset: refMatch[3] ? parseFloat((refMatch[3] === '-' ? '-' : '') + refMatch[4]) : 0,\n }\n }\n\n // X, Y coordinate pair\n const coordMatch = str.match(/^([\\d.]+)\\s*,?\\s*([\\d.]+)$/)\n if (coordMatch) {\n return { x: parseFloat(coordMatch[1]), y: parseFloat(coordMatch[2]) }\n }\n\n // Just a shape reference (center)\n if (/^\\w+$/.test(str)) {\n return { ref: str, side: 'center', offset: 0 }\n }\n\n return { x: 0, y: 0 }\n}\n\n/**\n * Parse a numeric expression, resolving variables.\n * Supports: numbers, $var, shapeId.prop, simple +/- arithmetic\n */\nfunction parseExpr(str, variables) {\n // Replace $variables\n let resolved = str.replace(/\\$(\\w+)/g, (_, name) => {\n return variables[name] !== undefined ? variables[name] : '0'\n })\n\n // If it's a simple number, return it\n const num = parseFloat(resolved)\n if (!isNaN(num) && String(num) === resolved.trim()) {\n return num\n }\n\n // If it contains a shape reference like shapeId.prop, return as deferred\n if (/\\w+\\.\\w+/.test(resolved)) {\n return { expr: resolved }\n }\n\n // Try simple arithmetic (A + B, A - B)\n const arithMatch = resolved.match(/^([\\d.]+)\\s*([+-])\\s*([\\d.]+)$/)\n if (arithMatch) {\n const a = parseFloat(arithMatch[1])\n const b = parseFloat(arithMatch[3])\n return arithMatch[2] === '+' ? a + b : a - b\n }\n\n return isNaN(num) ? 0 : num\n}\n\n/**\n * Parse property lines into shape.props\n */\nfunction parseProperties(shape, lines, variables, errors) {\n for (const line of lines) {\n const propMatch = line.match(/^(\\w+)\\s*:\\s*(.+)$/)\n if (!propMatch) continue\n\n let [, key, value] = propMatch\n value = value.trim()\n\n // Strip quotes from string values\n if ((value.startsWith('\"') && value.endsWith('\"')) ||\n (value.startsWith(\"'\") && value.endsWith(\"'\"))) {\n value = value.slice(1, -1)\n }\n\n // Resolve variables\n value = value.replace(/\\$(\\w+)/g, (_, name) => {\n return variables[name] !== undefined ? variables[name] : value\n })\n\n // Parse numeric values\n const num = parseFloat(value)\n if (!isNaN(num) && String(num) === value) {\n shape.props[key] = num\n } else if (value === 'true') {\n shape.props[key] = true\n } else if (value === 'false') {\n shape.props[key] = false\n } else {\n shape.props[key] = value\n }\n }\n}\n\n// ============================================================\n// RESOLVER \u2014 resolve deferred expressions & shape references\n// ============================================================\n\nexport function resolveShapeRefs(shapes) {\n const shapeMap = new Map()\n\n // Iteratively resolve deferred expressions until no more progress\n // This handles chained references like: A(absolute) \u2192 B(refs A) \u2192 C(refs B) \u2192 D(refs C)\n const MAX_PASSES = 10\n for (let pass = 0; pass < MAX_PASSES; pass++) {\n let progress = false\n\n // Collect all shapes with known (numeric) positions\n for (const s of shapes) {\n if (typeof s.x === 'number' && typeof s.y === 'number' && !shapeMap.has(s.id)) {\n shapeMap.set(s.id, s)\n progress = true\n }\n }\n\n // Try to resolve any remaining deferred expressions\n let anyUnresolved = false\n for (const s of shapes) {\n if (s.x && typeof s.x === 'object' && s.x.expr) {\n const resolved = resolveExpr(s.x.expr, shapeMap)\n if (typeof resolved === 'number' && !isNaN(resolved)) {\n s.x = resolved\n progress = true\n } else {\n anyUnresolved = true\n }\n }\n if (s.y && typeof s.y === 'object' && s.y.expr) {\n const resolved = resolveExpr(s.y.expr, shapeMap)\n if (typeof resolved === 'number' && !isNaN(resolved)) {\n s.y = resolved\n progress = true\n } else {\n anyUnresolved = true\n }\n }\n }\n\n if (!anyUnresolved || !progress) break\n }\n\n // Final fallback: force-resolve any remaining deferred expressions to 0\n for (const s of shapes) {\n if (s.x && typeof s.x === 'object' && s.x.expr) s.x = 0\n if (s.y && typeof s.y === 'object' && s.y.expr) s.y = 0\n }\n}\n\nfunction resolveExpr(expr, shapeMap) {\n // Match: shapeId.prop [+/- offset]\n const m = expr.match(/^(\\w+)\\.(\\w+)(?:\\s*([+-])\\s*([\\d.]+))?$/)\n if (!m) return NaN\n\n const [, ref, prop, op, offsetStr] = m\n const shape = shapeMap.get(ref)\n if (!shape) return NaN\n\n let val = 0\n switch (prop) {\n case 'x': val = shape.x || 0; break\n case 'y': val = shape.y || 0; break\n case 'right': val = (shape.x || 0) + (shape.width || 0); break\n case 'left': val = shape.x || 0; break\n case 'top': val = shape.y || 0; break\n case 'bottom': val = (shape.y || 0) + (shape.height || 0); break\n case 'centerX': val = (shape.x || 0) + (shape.width || 0) / 2; break\n case 'centerY': val = (shape.y || 0) + (shape.height || 0) / 2; break\n case 'width': val = shape.width || 0; break\n case 'height': val = shape.height || 0; break\n default: val = 0\n }\n\n const offset = offsetStr ? parseFloat(offsetStr) : 0\n return op === '-' ? val - offset : val + offset\n}\n\n// ============================================================\n// RENDERER \u2014 create actual canvas shapes from parsed AST\n// ============================================================\n\n/**\n * Render a parsed LixScript AST onto the canvas.\n * Returns { success, shapesCreated, errors }\n */\nexport function renderLixScript(parsed) {\n const { shapes: shapeDefs, errors } = parsed\n if (errors.length > 0) {\n return { success: false, shapesCreated: 0, errors }\n }\n\n // Resolve relative references\n resolveShapeRefs(shapeDefs)\n\n const svg = window.svg\n if (!svg) {\n return { success: false, shapesCreated: 0, errors: [{ line: 0, message: 'Canvas not initialized' }] }\n }\n\n const createdShapes = new Map() // id -> { instance, def }\n const renderErrors = []\n\n // Check if user defined a frame \u2014 if not, we auto-create one\n const userFrameDef = shapeDefs.find(s => s.type === 'frame')\n let frame = null\n let frameDef = userFrameDef\n\n if (userFrameDef) {\n // User-defined frame\n frame = createFrame(userFrameDef, renderErrors)\n if (frame) {\n createdShapes.set(userFrameDef.id, { instance: frame, def: userFrameDef })\n }\n }\n\n // Create non-connection shapes first (rect, circle, text)\n for (const def of shapeDefs) {\n if (def.type === 'frame') continue // already created\n if (def.type === 'arrow' || def.type === 'line') continue // deferred\n\n const instance = createShape(def, renderErrors)\n if (instance) {\n createdShapes.set(def.id, { instance, def })\n }\n }\n\n // Create connections (arrows, lines) \u2014 now that source/target shapes exist\n for (const def of shapeDefs) {\n if (def.type !== 'arrow' && def.type !== 'line') continue\n\n const instance = createConnection(def, createdShapes, renderErrors)\n if (instance) {\n createdShapes.set(def.id, { instance, def })\n }\n }\n\n // Auto-create wrapping frame if user didn't define one\n if (!frame && createdShapes.size > 0) {\n // Calculate bounds from all created shapes\n let minX = Infinity, minY = Infinity, maxX = -Infinity, maxY = -Infinity\n\n for (const [, { instance, def }] of createdShapes) {\n if (def.type === 'arrow' || def.type === 'line') {\n // Use the actual instance start/end coordinates\n const from = resolveConnectionPoint(def.from, createdShapes)\n const to = resolveConnectionPoint(def.to, createdShapes)\n if (from) { minX = Math.min(minX, from.x); minY = Math.min(minY, from.y); maxX = Math.max(maxX, from.x); maxY = Math.max(maxY, from.y) }\n if (to) { minX = Math.min(minX, to.x); minY = Math.min(minY, to.y); maxX = Math.max(maxX, to.x); maxY = Math.max(maxY, to.y) }\n } else if (def.type !== 'frame') {\n const x = def.x || 0\n const y = def.y || 0\n const w = def.width || 160\n const h = def.height || 60\n minX = Math.min(minX, x)\n minY = Math.min(minY, y)\n maxX = Math.max(maxX, x + w)\n maxY = Math.max(maxY, y + h)\n }\n }\n\n if (isFinite(minX)) {\n const pad = 40\n const autoFrameDef = {\n type: 'frame',\n id: '_lixscript_auto_frame',\n line: 0,\n x: minX - pad,\n y: minY - pad,\n width: (maxX - minX) + pad * 2,\n height: (maxY - minY) + pad * 2,\n props: { name: 'LixScript' }\n }\n frameDef = autoFrameDef\n frame = createFrame(autoFrameDef, renderErrors)\n if (frame) {\n createdShapes.set(autoFrameDef.id, { instance: frame, def: autoFrameDef })\n }\n }\n }\n\n // Add all shapes to frame\n if (frame) {\n for (const [id, { instance, def }] of createdShapes) {\n if (def.type === 'frame') continue // don't add frame to itself\n if (shouldAddToFrame(def, frameDef)) {\n frame.addShapeToFrame(instance)\n }\n }\n }\n\n return {\n success: renderErrors.length === 0,\n shapesCreated: createdShapes.size,\n errors: renderErrors,\n }\n}\n\n/**\n * Check if a shape should be added to the frame based on 'contains' prop.\n */\nfunction shouldAddToFrame(shapeDef, frameDef) {\n if (!frameDef || !frameDef.props.contains) return true // add all by default\n const ids = frameDef.props.contains.split(',').map(s => s.trim())\n return ids.includes(shapeDef.id)\n}\n\n/**\n * Create a Frame instance.\n */\nfunction createFrame(def, errors) {\n const Frame = window.Frame\n if (!Frame) {\n errors.push({ line: def.line, message: 'Frame class not available' })\n return null\n }\n\n try {\n const x = def.x || 0\n const y = def.y || 0\n const w = def.width || 600\n const h = def.height || 400\n\n const frame = new Frame(x, y, w, h, {\n frameName: def.props.frameName || def.props.name || def.id,\n stroke: def.props.stroke || '#555',\n strokeWidth: def.props.strokeWidth || 1,\n fill: def.props.fill || 'transparent',\n fillStyle: def.props.fillStyle || 'transparent',\n fillColor: def.props.fillColor || '#1e1e28',\n opacity: def.props.opacity || 1,\n rotation: def.props.rotation || 0,\n })\n\n window.shapes.push(frame)\n if (window.pushCreateAction) window.pushCreateAction(frame)\n\n // Tag as scripted\n frame._frameType = 'lixscript'\n frame._lixscriptSource = true\n\n // Set image from URL if provided\n if (def.props.imageURL && typeof frame.setImageFromURL === 'function') {\n frame.setImageFromURL(def.props.imageURL, def.props.imageFit || 'cover')\n }\n\n return frame\n } catch (err) {\n errors.push({ line: def.line, message: `Frame creation failed: ${err.message}` })\n return null\n }\n}\n\n/**\n * Create a shape instance from a definition.\n */\nfunction createShape(def, errors) {\n try {\n switch (def.type) {\n case 'rect': return createRect(def, errors)\n case 'circle':\n case 'ellipse': return createCircle(def, errors)\n case 'text': return createText(def, errors)\n case 'freehand': return createFreehand(def, errors)\n case 'image': return createImage(def, errors)\n case 'icon': return createIcon(def, errors)\n default:\n errors.push({ line: def.line, message: `Unknown shape type: ${def.type}` })\n return null\n }\n } catch (err) {\n errors.push({ line: def.line, message: `Shape '${def.id}' failed: ${err.message}` })\n return null\n }\n}\n\n/**\n * Create an image shape from a LixScript definition.\n * Usage: image myImg at 100, 200 size 300x200 { src: \"https://...\" }\n */\nfunction createImage(def, errors) {\n const ImageShape = window.ImageShape\n if (!ImageShape) {\n errors.push({ line: def.line, message: 'ImageShape class not available' })\n return null\n }\n\n const src = def.props.src || def.props.href || def.props.url || ''\n if (!src) {\n errors.push({ line: def.line, message: `Image '${def.id}' requires a src property` })\n return null\n }\n\n const svgEl = document.getElementById('freehand-canvas')\n if (!svgEl) return null\n\n const x = def.x || 0\n const y = def.y || 0\n const w = def.width || 200\n const h = def.height || 200\n\n const imgEl = document.createElementNS('http://www.w3.org/2000/svg', 'image')\n imgEl.setAttribute('href', src)\n imgEl.setAttribute('x', x)\n imgEl.setAttribute('y', y)\n imgEl.setAttribute('width', w)\n imgEl.setAttribute('height', h)\n imgEl.setAttribute('data-shape-x', x)\n imgEl.setAttribute('data-shape-y', y)\n imgEl.setAttribute('data-shape-width', w)\n imgEl.setAttribute('data-shape-height', h)\n imgEl.setAttribute('type', 'image')\n imgEl.setAttribute('preserveAspectRatio', def.props.fit === 'contain' ? 'xMidYMid meet' : def.props.fit === 'cover' ? 'xMidYMid slice' : 'xMidYMid meet')\n\n svgEl.appendChild(imgEl)\n const shape = new ImageShape(imgEl)\n if (def.props.rotation) shape.rotation = parseFloat(def.props.rotation)\n shape.shapeID = def.id || shape.shapeID\n\n window.shapes.push(shape)\n if (window.pushCreateAction) window.pushCreateAction(shape)\n\n return shape\n}\n\n/**\n * Create an icon shape from a LixScript definition.\n * Usage: icon myIcon at 100, 200 size 48x48 { name: \"AWS_Lambda_64\" }\n * or: icon myIcon at 100, 200 size 48x48 { svg: \"<path d='...' />\" }\n */\nfunction createIcon(def, errors) {\n const IconShape = window.IconShape\n if (!IconShape) {\n errors.push({ line: def.line, message: 'IconShape class not available' })\n return null\n }\n\n const svgEl = document.getElementById('freehand-canvas')\n if (!svgEl) return null\n\n const x = def.x || 0\n const y = def.y || 0\n const size = def.width || 48\n const color = def.props.color || def.props.fill || '#ffffff'\n\n // Build the inner SVG content\n let innerSVG = ''\n if (def.props.svg) {\n // Inline SVG path(s)\n innerSVG = def.props.svg\n } else if (def.props.name) {\n // Named icon \u2014 use a simple placeholder circle+text until loaded\n // The AI should provide inline SVG paths for reliability\n innerSVG = `<circle cx=\"12\" cy=\"12\" r=\"10\" fill=\"none\" stroke=\"${color}\" stroke-width=\"1.5\"/><text x=\"12\" y=\"16\" text-anchor=\"middle\" fill=\"${color}\" font-size=\"10\" font-family=\"sans-serif\">${(def.props.name || '?').charAt(0)}</text>`\n } else {\n errors.push({ line: def.line, message: `Icon '${def.id}' requires a name or svg property` })\n return null\n }\n\n const vbWidth = parseFloat(def.props.viewBoxWidth) || 24\n const vbHeight = parseFloat(def.props.viewBoxHeight) || 24\n const scale = size / Math.max(vbWidth, vbHeight)\n const localCenterX = size / 2 / scale\n const localCenterY = size / 2 / scale\n const rotation = def.props.rotation || 0\n\n const iconGroup = document.createElementNS('http://www.w3.org/2000/svg', 'g')\n iconGroup.setAttribute('transform', `translate(${x}, ${y}) scale(${scale}) rotate(${rotation}, ${localCenterX}, ${localCenterY})`)\n iconGroup.setAttribute('data-viewbox-width', vbWidth)\n iconGroup.setAttribute('data-viewbox-height', vbHeight)\n iconGroup.setAttribute('x', x)\n iconGroup.setAttribute('y', y)\n iconGroup.setAttribute('width', size)\n iconGroup.setAttribute('height', size)\n iconGroup.setAttribute('type', 'icon')\n iconGroup.setAttribute('data-shape-x', x)\n iconGroup.setAttribute('data-shape-y', y)\n iconGroup.setAttribute('data-shape-width', size)\n iconGroup.setAttribute('data-shape-height', size)\n iconGroup.setAttribute('data-shape-rotation', rotation)\n iconGroup.setAttribute('style', 'cursor: pointer; pointer-events: all;')\n\n // Transparent hit area\n const bgRect = document.createElementNS('http://www.w3.org/2000/svg', 'rect')\n bgRect.setAttribute('x', 0)\n bgRect.setAttribute('y', 0)\n bgRect.setAttribute('width', vbWidth)\n bgRect.setAttribute('height', vbHeight)\n bgRect.setAttribute('fill', 'transparent')\n bgRect.setAttribute('stroke', 'none')\n bgRect.setAttribute('style', 'pointer-events: all;')\n iconGroup.appendChild(bgRect)\n\n // Parse and insert SVG content\n const tempSvg = document.createElementNS('http://www.w3.org/2000/svg', 'svg')\n tempSvg.innerHTML = innerSVG\n while (tempSvg.firstChild) {\n const child = tempSvg.firstChild\n // Apply color to paths/circles/etc\n if (child.nodeType === 1) {\n const fill = child.getAttribute('fill')\n const stroke = child.getAttribute('stroke')\n if (!fill || fill === 'currentColor' || fill === '#000' || fill === '#000000' || fill === 'black') {\n child.setAttribute('fill', color)\n }\n if (stroke === 'currentColor' || stroke === '#000' || stroke === '#000000' || stroke === 'black') {\n child.setAttribute('stroke', color)\n }\n }\n iconGroup.appendChild(child)\n }\n\n svgEl.appendChild(iconGroup)\n const shape = new IconShape(iconGroup)\n shape.shapeID = def.id || shape.shapeID\n\n window.shapes.push(shape)\n if (window.pushCreateAction) window.pushCreateAction(shape)\n\n return shape\n}\n\nfunction createRect(def, errors) {\n const Rectangle = window.Rectangle\n if (!Rectangle) {\n errors.push({ line: def.line, message: 'Rectangle class not available' })\n return null\n }\n\n const x = def.x || 0\n const y = def.y || 0\n const w = def.width || 160\n const h = def.height || 60\n\n const rect = new Rectangle(x, y, w, h, {\n stroke: def.props.stroke || '#fff',\n strokeWidth: def.props.strokeWidth || 2,\n fill: def.props.fill || 'transparent',\n fillStyle: def.props.fillStyle || 'none',\n roughness: def.props.roughness !== undefined ? def.props.roughness : 1.5,\n strokeDasharray: resolveStrokeStyle(def.props.style),\n shadeColor: def.props.shadeColor || null,\n shadeOpacity: def.props.shadeOpacity !== undefined ? parseFloat(def.props.shadeOpacity) : 0.15,\n shadeDirection: def.props.shadeDirection || 'bottom',\n })\n\n if (def.props.rotation) rect.rotation = def.props.rotation\n if (def.props.label) {\n rect.setLabel(\n def.props.label,\n def.props.labelColor || '#e0e0e0',\n def.props.labelFontSize || 14\n )\n }\n\n window.shapes.push(rect)\n if (window.pushCreateAction) window.pushCreateAction(rect)\n return rect\n}\n\nfunction createCircle(def, errors) {\n const Circle = window.Circle\n if (!Circle) {\n errors.push({ line: def.line, message: 'Circle class not available' })\n return null\n }\n\n const x = def.x || 0\n const y = def.y || 0\n const w = def.width || 80\n const h = def.height || 80\n\n // Circle constructor uses (x, y, rx, ry) \u2014 center and radii\n const rx = w / 2\n const ry = h / 2\n\n const circle = new Circle(x + rx, y + ry, rx, ry, {\n stroke: def.props.stroke || '#fff',\n strokeWidth: def.props.strokeWidth || 2,\n fill: def.props.fill || 'transparent',\n fillStyle: def.props.fillStyle || 'none',\n roughness: def.props.roughness !== undefined ? def.props.roughness : 1.5,\n strokeDasharray: resolveStrokeStyle(def.props.style),\n shadeColor: def.props.shadeColor || null,\n shadeOpacity: def.props.shadeOpacity !== undefined ? parseFloat(def.props.shadeOpacity) : 0.15,\n shadeDirection: def.props.shadeDirection || 'bottom',\n })\n\n if (def.props.rotation) circle.rotation = def.props.rotation\n if (def.props.label) {\n circle.setLabel(\n def.props.label,\n def.props.labelColor || '#e0e0e0',\n def.props.labelFontSize || 14\n )\n }\n\n window.shapes.push(circle)\n if (window.pushCreateAction) window.pushCreateAction(circle)\n return circle\n}\n\nfunction createText(def, errors) {\n const TextShape = window.TextShape\n const svgEl = window.svg\n if (!TextShape || !svgEl) {\n errors.push({ line: def.line, message: 'TextShape class not available' })\n return null\n }\n\n const x = def.x || 0\n const y = def.y || 0\n const content = def.props.content || def.props.text || 'Text'\n const color = def.props.color || def.props.fill || '#fff'\n const fontSize = def.props.fontSize || 16\n\n const g = document.createElementNS(NS, 'g')\n g.setAttribute('data-type', 'text-group')\n g.setAttribute('transform', `translate(${x}, ${y})`)\n g.setAttribute('data-x', x)\n g.setAttribute('data-y', y)\n\n const t = document.createElementNS(NS, 'text')\n t.setAttribute('x', 0)\n t.setAttribute('y', 0)\n t.setAttribute('text-anchor', def.props.anchor || 'middle')\n t.setAttribute('dominant-baseline', 'central')\n t.setAttribute('fill', color)\n t.setAttribute('font-size', fontSize)\n t.setAttribute('font-family', def.props.fontFamily || 'lixFont, sans-serif')\n t.setAttribute('data-initial-font', def.props.fontFamily || 'lixFont')\n t.setAttribute('data-initial-color', color)\n t.setAttribute('data-initial-size', fontSize + 'px')\n t.textContent = content\n\n g.appendChild(t)\n svgEl.appendChild(g)\n\n const shape = new TextShape(g)\n window.shapes.push(shape)\n if (window.pushCreateAction) window.pushCreateAction(shape)\n return shape\n}\n\nfunction createFreehand(def, errors) {\n const FreehandStroke = window.FreehandStroke\n if (!FreehandStroke) {\n errors.push({ line: def.line, message: 'FreehandStroke class not available' })\n return null\n }\n\n // Points should be provided as a property: points: \"x1,y1;x2,y2;...\"\n const pointsStr = def.props.points || ''\n const points = pointsStr.split(';').map(p => {\n const [x, y, pressure] = p.split(',').map(Number)\n return [x || 0, y || 0, pressure || 0.5]\n }).filter(p => !isNaN(p[0]))\n\n if (points.length < 2) {\n errors.push({ line: def.line, message: 'Freehand requires at least 2 points' })\n return null\n }\n\n const stroke = new FreehandStroke(points, {\n stroke: def.props.stroke || def.props.color || '#fff',\n strokeWidth: def.props.strokeWidth || 3,\n thinning: def.props.thinning || 0.5,\n roughness: def.props.roughness || 'smooth',\n strokeStyle: def.props.style || 'solid',\n })\n\n window.shapes.push(stroke)\n if (window.pushCreateAction) window.pushCreateAction(stroke)\n return stroke\n}\n\n/**\n * Create a connection (arrow or line) between two points or shape references.\n */\nfunction createConnection(def, createdShapes, errors) {\n const from = resolveConnectionPoint(def.from, createdShapes)\n const to = resolveConnectionPoint(def.to, createdShapes)\n\n if (!from || !to) {\n errors.push({ line: def.line, message: `Cannot resolve connection endpoints for '${def.id}'` })\n return null\n }\n\n if (def.type === 'arrow') {\n return createArrow(def, from, to, createdShapes, errors)\n } else {\n return createLine(def, from, to, errors)\n }\n}\n\nfunction createArrow(def, from, to, createdShapes, errors) {\n const Arrow = window.Arrow\n if (!Arrow) {\n errors.push({ line: def.line, message: 'Arrow class not available' })\n return null\n }\n\n const curveMode = def.props.curve || 'straight'\n\n const arrow = new Arrow(\n { x: from.x, y: from.y },\n { x: to.x, y: to.y },\n {\n stroke: def.props.stroke || '#fff',\n strokeWidth: def.props.strokeWidth || 2,\n arrowOutlineStyle: def.props.style || 'solid',\n arrowHeadStyle: def.props.head || 'default',\n arrowHeadLength: def.props.headLength || 15,\n arrowCurved: curveMode,\n arrowCurveAmount: def.props.curveAmount || 50,\n }\n )\n\n if (def.props.label) {\n arrow.setLabel(\n def.props.label,\n def.props.labelColor || '#e0e0e0',\n def.props.labelFontSize || 12\n )\n }\n\n // Auto-attach to source/target shapes\n if (def.from && def.from.ref) {\n const sourceEntry = createdShapes.get(def.from.ref)\n if (sourceEntry) {\n autoAttach(arrow, sourceEntry.instance, true, from)\n }\n }\n if (def.to && def.to.ref) {\n const targetEntry = createdShapes.get(def.to.ref)\n if (targetEntry) {\n autoAttach(arrow, targetEntry.instance, false, to)\n }\n }\n\n window.shapes.push(arrow)\n if (window.pushCreateAction) window.pushCreateAction(arrow)\n return arrow\n}\n\nfunction createLine(def, from, to, errors) {\n const Line = window.Line\n if (!Line) {\n errors.push({ line: def.line, message: 'Line class not available' })\n return null\n }\n\n const line = new Line(\n { x: from.x, y: from.y },\n { x: to.x, y: to.y },\n {\n stroke: def.props.stroke || '#fff',\n strokeWidth: def.props.strokeWidth || 2,\n strokeDasharray: resolveStrokeStyle(def.props.style),\n }\n )\n\n if (def.props.curve === 'true' || def.props.curve === true) {\n line.isCurved = true\n line.initializeCurveControlPoint?.()\n line.draw()\n }\n\n if (def.props.label) {\n line.setLabel(\n def.props.label,\n def.props.labelColor || '#e0e0e0',\n def.props.labelFontSize || 12\n )\n }\n\n window.shapes.push(line)\n if (window.pushCreateAction) window.pushCreateAction(line)\n return line\n}\n\n// ============================================================\n// CONNECTION POINT RESOLUTION\n// ============================================================\n\n/**\n * Resolve a connection endpoint \u2014 either absolute coords or a shape reference.\n */\nfunction resolveConnectionPoint(pointDef, createdShapes) {\n if (!pointDef) return null\n\n // Absolute coordinates\n if (pointDef.x !== undefined && pointDef.y !== undefined) {\n return { x: pointDef.x, y: pointDef.y }\n }\n\n // Shape reference\n if (pointDef.ref) {\n const entry = createdShapes.get(pointDef.ref)\n if (!entry) return null\n\n const shape = entry.instance\n const def = entry.def\n const side = pointDef.side || 'center'\n const offset = pointDef.offset || 0\n\n // Get shape bounds\n const sx = shape.x !== undefined ? shape.x : (def.x || 0)\n const sy = shape.y !== undefined ? shape.y : (def.y || 0)\n const sw = shape.width || def.width || 0\n const sh = shape.height || def.height || 0\n\n // For circles, x/y is the center\n let cx, cy\n if (shape.shapeName === 'circle') {\n cx = sx\n cy = sy\n const rx = shape.rx || sw / 2\n const ry = shape.ry || sh / 2\n\n switch (side) {\n case 'top': return { x: cx + offset, y: cy - ry }\n case 'bottom': return { x: cx + offset, y: cy + ry }\n case 'left': return { x: cx - rx, y: cy + offset }\n case 'right': return { x: cx + rx, y: cy + offset }\n case 'center': return { x: cx + offset, y: cy }\n default: return { x: cx, y: cy }\n }\n }\n\n // For rectangles and other box shapes\n cx = sx + sw / 2\n cy = sy + sh / 2\n\n switch (side) {\n case 'top': return { x: cx + offset, y: sy }\n case 'bottom': return { x: cx + offset, y: sy + sh }\n case 'left': return { x: sx, y: cy + offset }\n case 'right': return { x: sx + sw, y: cy + offset }\n case 'center': return { x: cx + offset, y: cy }\n default: return { x: cx, y: cy }\n }\n }\n\n return null\n}\n\n/**\n * Auto-attach an arrow to a shape (sets attachedToStart or attachedToEnd).\n */\nfunction autoAttach(arrow, shape, isStart, connectionPoint) {\n if (!shape || !connectionPoint) return\n\n const sx = shape.x || 0\n const sy = shape.y || 0\n const sw = shape.width || 0\n const sh = shape.height || 0\n\n let cx, cy\n if (shape.shapeName === 'circle') {\n cx = sx\n cy = sy\n } else {\n cx = sx + sw / 2\n cy = sy + sh / 2\n }\n\n // Determine which side the connection point is on\n const dx = connectionPoint.x - cx\n const dy = connectionPoint.y - cy\n let side = 'bottom'\n\n if (Math.abs(dx) > Math.abs(dy)) {\n side = dx > 0 ? 'right' : 'left'\n } else {\n side = dy > 0 ? 'bottom' : 'top'\n }\n\n const attachment = { shape, side, offset: { x: 0, y: 0 } }\n\n if (isStart) {\n arrow.attachedToStart = attachment\n } else {\n arrow.attachedToEnd = attachment\n }\n}\n\n// ============================================================\n// PREVIEW \u2014 generate SVG preview without touching the canvas\n// ============================================================\n\n/**\n * Generate a preview SVG string from parsed LixScript.\n */\nexport function previewLixScript(parsed) {\n const { shapes: defs, errors } = parsed\n if (errors.length > 0) return ''\n\n resolveShapeRefs(defs)\n\n // Build a shape map for resolving arrow references in preview\n const shapeMap = new Map()\n for (const def of defs) {\n if (def.type !== 'arrow' && def.type !== 'line') {\n shapeMap.set(def.id, def)\n }\n }\n\n // Resolve arrow/line endpoints to coordinates for preview\n function resolvePreviewPoint(pointDef) {\n if (!pointDef) return { x: 0, y: 0 }\n if (pointDef.x !== undefined && pointDef.y !== undefined) return pointDef\n\n if (pointDef.ref) {\n const target = shapeMap.get(pointDef.ref)\n if (!target) return { x: 0, y: 0 }\n\n const side = pointDef.side || 'center'\n const offset = pointDef.offset || 0\n const tx = target.x || 0\n const ty = target.y || 0\n const tw = target.width || 160\n const th = target.height || 60\n\n // For circle, x/y is top-left of bounding box in our DSL\n const cx = tx + tw / 2\n const cy = ty + th / 2\n\n switch (side) {\n case 'top': return { x: cx + offset, y: ty }\n case 'bottom': return { x: cx + offset, y: ty + th }\n case 'left': return { x: tx, y: cy + offset }\n case 'right': return { x: tx + tw, y: cy + offset }\n case 'center': return { x: cx + offset, y: cy }\n default: return { x: cx, y: cy }\n }\n }\n return { x: 0, y: 0 }\n }\n\n // Calculate bounds\n let minX = Infinity, minY = Infinity, maxX = -Infinity, maxY = -Infinity\n\n for (const def of defs) {\n if (def.type === 'arrow' || def.type === 'line') {\n const from = resolvePreviewPoint(def.from)\n const to = resolvePreviewPoint(def.to)\n minX = Math.min(minX, from.x, to.x)\n minY = Math.min(minY, from.y, to.y)\n maxX = Math.max(maxX, from.x, to.x)\n maxY = Math.max(maxY, from.y, to.y)\n } else if (def.type !== 'frame') {\n const x = def.x || 0\n const y = def.y || 0\n const w = def.width || 160\n const h = def.height || 60\n minX = Math.min(minX, x)\n minY = Math.min(minY, y)\n maxX = Math.max(maxX, x + w)\n maxY = Math.max(maxY, y + h)\n }\n }\n\n if (!isFinite(minX)) { minX = 0; minY = 0; maxX = 400; maxY = 300 }\n\n const pad = 40\n const vw = maxX - minX + pad * 2\n const vh = maxY - minY + pad * 2\n\n let svgContent = ''\n\n // Render each shape as simple SVG\n for (const def of defs) {\n const props = def.props || {}\n\n switch (def.type) {\n case 'rect':\n svgContent += `<rect x=\"${def.x || 0}\" y=\"${def.y || 0}\" width=\"${def.width || 160}\" height=\"${def.height || 60}\" stroke=\"${props.stroke || '#fff'}\" stroke-width=\"${props.strokeWidth || 2}\" fill=\"${props.fill || 'transparent'}\" rx=\"4\" />`\n if (props.label) {\n const cx = (def.x || 0) + (def.width || 160) / 2\n const cy = (def.y || 0) + (def.height || 60) / 2\n svgContent += `<text x=\"${cx}\" y=\"${cy}\" text-anchor=\"middle\" dominant-baseline=\"central\" fill=\"${props.labelColor || '#e0e0e0'}\" font-size=\"${props.labelFontSize || 14}\" font-family=\"sans-serif\">${escapeXml(props.label)}</text>`\n }\n break\n\n case 'circle':\n case 'ellipse': {\n const rx = (def.width || 80) / 2\n const ry = (def.height || 80) / 2\n const cx = (def.x || 0) + rx\n const cy = (def.y || 0) + ry\n svgContent += `<ellipse cx=\"${cx}\" cy=\"${cy}\" rx=\"${rx}\" ry=\"${ry}\" stroke=\"${props.stroke || '#fff'}\" stroke-width=\"${props.strokeWidth || 2}\" fill=\"${props.fill || 'transparent'}\" />`\n if (props.label) {\n svgContent += `<text x=\"${cx}\" y=\"${cy}\" text-anchor=\"middle\" dominant-baseline=\"central\" fill=\"${props.labelColor || '#e0e0e0'}\" font-size=\"${props.labelFontSize || 14}\" font-family=\"sans-serif\">${escapeXml(props.label)}</text>`\n }\n break\n }\n\n case 'text': {\n const content = props.content || props.text || 'Text'\n svgContent += `<text x=\"${def.x || 0}\" y=\"${def.y || 0}\" fill=\"${props.color || props.fill || '#fff'}\" font-size=\"${props.fontSize || 16}\" font-family=\"sans-serif\">${escapeXml(content)}</text>`\n break\n }\n\n case 'arrow': {\n const fromOrig = resolvePreviewPoint(def.from)\n const toOrig = resolvePreviewPoint(def.to)\n const stroke = props.stroke || '#fff'\n const sw = props.strokeWidth || 2\n const dash = props.style === 'dashed' ? ' stroke-dasharray=\"10,10\"' : props.style === 'dotted' ? ' stroke-dasharray=\"2,8\"' : ''\n const curve = props.curve || 'straight'\n const markerId = `ah-${def.id}`\n const headLen = 10 // arrowhead marker size\n\n // Pull back arrow endpoint so the tip lands at the shape edge, not inside it\n const to = shortenEndpoint(fromOrig, toOrig, headLen)\n const from = fromOrig\n\n // Per-arrow colored arrowhead marker \u2014 refX=0 so tip is at the shortened line end\n svgContent += `<defs><marker id=\"${markerId}\" markerWidth=\"10\" markerHeight=\"7\" refX=\"0\" refY=\"3.5\" orient=\"auto\"><polygon points=\"0 0, 10 3.5, 0 7\" fill=\"${stroke}\" /></marker></defs>`\n\n if (curve === 'curved') {\n // Compute a quadratic bezier control point perpendicular to the line\n const mx = (from.x + toOrig.x) / 2\n const my = (from.y + toOrig.y) / 2\n const dx = toOrig.x - from.x\n const dy = toOrig.y - from.y\n const dist = Math.sqrt(dx * dx + dy * dy) || 1\n const amt = props.curveAmount || Math.min(dist * 0.3, 80)\n // Perpendicular offset (always curve to the same side)\n const cpx = mx + (dy / dist) * amt\n const cpy = my - (dx / dist) * amt\n // Shorten the bezier endpoint\n const toShort = shortenEndpoint({ x: cpx, y: cpy }, toOrig, headLen)\n svgContent += `<path d=\"M${from.x},${from.y} Q${cpx},${cpy} ${toShort.x},${toShort.y}\" stroke=\"${stroke}\" stroke-width=\"${sw}\" fill=\"none\"${dash} marker-end=\"url(#${markerId})\" />`\n if (props.label) {\n // Label at the curve midpoint (t=0.5 on quadratic bezier)\n const lx = 0.25 * from.x + 0.5 * cpx + 0.25 * toOrig.x\n const ly = 0.25 * from.y + 0.5 * cpy + 0.25 * toOrig.y - 8\n svgContent += `<text x=\"${lx}\" y=\"${ly}\" text-anchor=\"middle\" fill=\"${props.labelColor || '#a0a0b0'}\" font-size=\"11\" font-family=\"sans-serif\">${escapeXml(props.label)}</text>`\n }\n } else if (curve === 'elbow') {\n // Simple elbow: go vertical then horizontal (or vice versa)\n const midY = from.y + (toOrig.y - from.y) / 2\n // Shorten the last segment endpoint\n const lastFrom = { x: toOrig.x, y: midY }\n const toShort = shortenEndpoint(lastFrom, toOrig, headLen)\n svgContent += `<path d=\"M${from.x},${from.y} L${from.x},${midY} L${toOrig.x},${midY} L${toShort.x},${toShort.y}\" stroke=\"${stroke}\" stroke-width=\"${sw}\" fill=\"none\"${dash} marker-end=\"url(#${markerId})\" />`\n if (props.label) {\n const lx = (from.x + toOrig.x) / 2\n const ly = midY - 8\n svgContent += `<text x=\"${lx}\" y=\"${ly}\" text-anchor=\"middle\" fill=\"${props.labelColor || '#a0a0b0'}\" font-size=\"11\" font-family=\"sans-serif\">${escapeXml(props.label)}</text>`\n }\n } else {\n svgContent += `<line x1=\"${from.x}\" y1=\"${from.y}\" x2=\"${to.x}\" y2=\"${to.y}\" stroke=\"${stroke}\" stroke-width=\"${sw}\"${dash} marker-end=\"url(#${markerId})\" />`\n if (props.label) {\n const lx = (from.x + toOrig.x) / 2\n const ly = (from.y + toOrig.y) / 2 - 10\n svgContent += `<text x=\"${lx}\" y=\"${ly}\" text-anchor=\"middle\" fill=\"${props.labelColor || '#a0a0b0'}\" font-size=\"11\" font-family=\"sans-serif\">${escapeXml(props.label)}</text>`\n }\n }\n break\n }\n\n case 'line': {\n const from = resolvePreviewPoint(def.from)\n const to = resolvePreviewPoint(def.to)\n const dash = props.style === 'dashed' ? ' stroke-dasharray=\"10,10\"' : props.style === 'dotted' ? ' stroke-dasharray=\"2,8\"' : ''\n svgContent += `<line x1=\"${from.x}\" y1=\"${from.y}\" x2=\"${to.x}\" y2=\"${to.y}\" stroke=\"${props.stroke || '#fff'}\" stroke-width=\"${props.strokeWidth || 2}\"${dash} />`\n break\n }\n\n case 'frame': {\n const frameName = props.name || def.id\n svgContent += `<rect x=\"${def.x || 0}\" y=\"${def.y || 0}\" width=\"${def.width || 600}\" height=\"${def.height || 400}\" stroke=\"${props.stroke || '#555'}\" stroke-width=\"1\" fill=\"transparent\" stroke-dasharray=\"8,4\" rx=\"8\" />`\n svgContent += `<text x=\"${(def.x || 0) + 10}\" y=\"${(def.y || 0) - 8}\" fill=\"#888\" font-size=\"12\" font-family=\"sans-serif\">${escapeXml(frameName)}</text>`\n break\n }\n }\n }\n\n return `<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"${minX - pad} ${minY - pad} ${vw} ${vh}\" width=\"100%\" height=\"100%\" style=\"background: transparent;\">\n ${svgContent}\n </svg>`\n}\n\n/**\n * Pull back an arrow endpoint so the arrowhead tip lands at the target edge,\n * rather than the line extending into the shape.\n */\nfunction shortenEndpoint(from, to, amount) {\n const dx = to.x - from.x\n const dy = to.y - from.y\n const dist = Math.sqrt(dx * dx + dy * dy)\n if (dist < amount * 2) return to // too short to shorten\n return {\n x: to.x - (dx / dist) * amount,\n y: to.y - (dy / dist) * amount,\n }\n}\n\nfunction escapeXml(str) {\n return String(str).replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/\"/g, '&quot;')\n}\n\n// ============================================================\n// STROKE STYLE HELPERS\n// ============================================================\n\nfunction resolveStrokeStyle(style) {\n if (!style) return ''\n switch (style) {\n case 'dashed': return '10,10'\n case 'dotted': return '2,8'\n case 'solid':\n default: return ''\n }\n}\n\n// ============================================================\n// WINDOW BRIDGE \u2014 expose to canvas engine\n// ============================================================\n\nexport function initLixScriptBridge() {\n window.__lixscriptParse = parseLixScript\n window.__lixscriptRender = renderLixScript\n window.__lixscriptPreview = (source) => {\n const parsed = parseLixScript(source)\n return previewLixScript(parsed)\n }\n window.__lixscriptExecute = (source) => {\n const parsed = parseLixScript(source)\n if (parsed.errors.length > 0) {\n return { success: false, errors: parsed.errors, shapesCreated: 0 }\n }\n return renderLixScript(parsed)\n }\n}\n", "import { parseLixScript, resolveShapeRefs } from '../core/LixScriptParser.js';\n\nconst MAX_SOURCE_LENGTH = 100_000;\n\nfunction options(def) {\n return {\n stroke: def.props.stroke || def.props.color || '#8b76d6',\n strokeWidth: Number(def.props.strokeWidth) || 2,\n fill: def.props.fill || 'transparent',\n fillStyle: def.props.fillStyle || 'solid',\n roughness: def.props.roughness === undefined ? 1.2 : Number(def.props.roughness),\n opacity: def.props.opacity === undefined ? 1 : Number(def.props.opacity),\n };\n}\n\nfunction bounds(def) {\n const width = Number(def.width) || (def.type === 'frame' ? 600 : def.type === 'rect' ? 160 : 80);\n const height = Number(def.height) || (def.type === 'frame' ? 400 : def.type === 'rect' ? 60 : 80);\n return { x: Number(def.x) || 0, y: Number(def.y) || 0, width, height };\n}\n\nfunction endpoint(point, definitions) {\n if (Number.isFinite(point?.x) && Number.isFinite(point?.y)) return { x: point.x, y: point.y };\n const target = definitions.get(point?.ref);\n if (!target) throw new Error(`Cannot resolve LixScript connection target \"${point?.ref || ''}\"`);\n const box = bounds(target);\n const offset = Number(point.offset) || 0;\n const side = point.side || 'center';\n if (side === 'top') return { x: box.x + box.width / 2 + offset, y: box.y };\n if (side === 'bottom') return { x: box.x + box.width / 2 + offset, y: box.y + box.height };\n if (side === 'left') return { x: box.x, y: box.y + box.height / 2 + offset };\n if (side === 'right') return { x: box.x + box.width, y: box.y + box.height / 2 + offset };\n return { x: box.x + box.width / 2 + offset, y: box.y + box.height / 2 };\n}\n\nfunction labelShape(def, shapeID, parentFrame) {\n if (!def.props.label) return null;\n const box = bounds(def);\n return {\n type: 'text', shapeID: `${shapeID}-label`, x: box.x + box.width / 2, y: box.y + box.height / 2,\n text: String(def.props.label), fontSize: Number(def.props.labelFontSize) || 14,\n color: def.props.labelColor || '#e8e3f3', parentFrame,\n };\n}\n\nexport function compileLixScript(source, { x = 0, y = 0 } = {}) {\n const input = String(source || '');\n if (!input.trim()) throw new Error('LixScript source is required');\n if (input.length > MAX_SOURCE_LENGTH) throw new Error('LixScript source exceeds 100 KB');\n const parsed = parseLixScript(input);\n if (parsed.errors.length) throw new Error(`LixScript parse failed: ${parsed.errors.map((entry) => `line ${entry.line}: ${entry.message}`).join('; ')}`);\n resolveShapeRefs(parsed.shapes);\n const prefix = `lix-${crypto.randomUUID().slice(0, 8)}`;\n const shapeId = (id) => `${prefix}-${id}`;\n const definitions = new Map(parsed.shapes.map((shape) => [shape.id, shape]));\n const frame = parsed.shapes.find((shape) => shape.type === 'frame');\n const frameId = frame ? shapeId(frame.id) : `${prefix}-frame`;\n const frameMembers = frame?.props.contains ? new Set(String(frame.props.contains).split(',').map((value) => value.trim()).filter(Boolean)) : null;\n const shapes = [];\n for (const def of parsed.shapes) {\n const box = bounds(def);\n const parentFrame = def === frame || (frameMembers && !frameMembers.has(def.id)) ? null : frameId;\n let shape;\n const id = shapeId(def.id);\n if (def.type === 'rect') shape = { type: 'rectangle', shapeID: id, x: box.x + x, y: box.y + y, width: box.width, height: box.height, rotation: Number(def.props.rotation) || 0, options: options(def), parentFrame };\n else if (def.type === 'circle' || def.type === 'ellipse') shape = { type: 'circle', shapeID: id, x: box.x + box.width / 2 + x, y: box.y + box.height / 2 + y, rx: box.width / 2, ry: box.height / 2, rotation: Number(def.props.rotation) || 0, options: options(def), parentFrame };\n else if (def.type === 'text') shape = { type: 'text', shapeID: id, x: box.x + x, y: box.y + y, text: String(def.props.content || def.props.text || 'Text'), fontSize: Number(def.props.fontSize) || 16, color: def.props.color || def.props.fill || '#e8e3f3', fontFamily: def.props.fontFamily || 'lixFont', parentFrame };\n else if (def.type === 'frame') shape = { type: 'frame', shapeID: id, x: box.x + x, y: box.y + y, width: box.width, height: box.height, frameName: String(def.props.frameName || def.props.name || def.id), fillStyle: def.props.fillStyle || 'transparent', fillColor: def.props.fillColor || def.props.fill || '#1e1e28', options: options(def) };\n else if (def.type === 'freehand') {\n const points = String(def.props.points || '').split(';').map((value) => value.split(',').map(Number)).filter((point) => point.length >= 2 && point.every(Number.isFinite)).map(([px, py, pressure = 0.5]) => [px + x, py + y, pressure]);\n shape = { type: 'freehandStroke', shapeID: id, points, options: options(def), parentFrame };\n } else if (def.type === 'line' || def.type === 'arrow') {\n const startPoint = endpoint(def.from, definitions), endPoint = endpoint(def.to, definitions);\n startPoint.x += x; startPoint.y += y; endPoint.x += x; endPoint.y += y;\n shape = def.type === 'line'\n ? { type: 'line', shapeID: id, startPoint, endPoint, isCurved: def.props.curve === true || def.props.curve === 'true', options: options(def), parentFrame }\n : { type: 'arrow', shapeID: id, startPoint, endPoint, arrowHeadStyle: def.props.head || 'triangle', arrowOutlineStyle: def.props.style || 'solid', arrowCurved: def.props.curve && def.props.curve !== 'straight', arrowCurveAmount: Number(def.props.curveAmount) || 0.2, options: options(def), parentFrame };\n } else throw new Error(`LixScript ${def.type} is not writable through MCP`);\n shapes.push(shape);\n const label = labelShape(def, id, parentFrame);\n if (label) { label.x += x; label.y += y; shapes.push(label); }\n }\n if (!frame && shapes.length) {\n const boxes = parsed.shapes.filter((def) => !['arrow', 'line'].includes(def.type)).map(bounds);\n const pointShapes = shapes.filter((shape) => shape.startPoint && shape.endPoint);\n const minX = boxes.length ? Math.min(...boxes.map((box) => box.x)) + x : Math.min(...pointShapes.flatMap((shape) => [shape.startPoint.x, shape.endPoint.x]));\n const minY = boxes.length ? Math.min(...boxes.map((box) => box.y)) + y : Math.min(...pointShapes.flatMap((shape) => [shape.startPoint.y, shape.endPoint.y]));\n const maxX = boxes.length ? Math.max(...boxes.map((box) => box.x + box.width)) + x : Math.max(...pointShapes.flatMap((shape) => [shape.startPoint.x, shape.endPoint.x]));\n const maxY = boxes.length ? Math.max(...boxes.map((box) => box.y + box.height)) + y : Math.max(...pointShapes.flatMap((shape) => [shape.startPoint.y, shape.endPoint.y]));\n shapes.unshift({ type: 'frame', shapeID: frameId, x: minX - 40, y: minY - 40, width: Math.max(80, maxX - minX + 80), height: Math.max(80, maxY - minY + 80), frameName: 'LixScript', fillStyle: 'transparent', fillColor: '#1e1e28' });\n }\n return { shapes, operations: shapes.map((shape) => ({ op: 'add', shape })), sourceShapeCount: parsed.shapes.length };\n}\n", "import { applyScenePatch, createEmptyScene, getSceneSummary, mergeTemplateScene, validateScene, MCP_LIMITS } from './scene.js';\nimport { MarketplaceTemplateProvider } from './templates.js';\nimport { renderSceneSvg } from './preview.js';\nimport { compileLixScript } from './lixscript.js';\n\nconst SERVER_NAME = 'lixsketch';\nconst SERVER_VERSION = '1.1.0';\nconst PROTOCOL_VERSION = '2025-11-25';\nconst SUPPORTED_PROTOCOL_VERSIONS = new Set([PROTOCOL_VERSION, '2025-06-18', '2024-11-05']);\n\nconst PATCH_OPERATION_SCHEMA = {\n oneOf: [\n { type: 'object', required: ['op', 'shape'], properties: { op: { const: 'add' }, shape: { type: 'object', description: 'A rectangle, circle, line, arrow, frame, freehandStroke, or text shape.' } } },\n { type: 'object', required: ['op', 'shapeID', 'changes'], properties: { op: { const: 'update' }, shapeID: { type: 'string' }, changes: { type: 'object' } } },\n { type: 'object', required: ['op'], properties: { op: { const: 'delete' }, shapeID: { type: 'string' }, shapeIDs: { type: 'array', items: { type: 'string' } } } },\n { type: 'object', required: ['op', 'shapeIDs', 'dx', 'dy'], properties: { op: { const: 'translate' }, shapeIDs: { type: 'array', items: { type: 'string' } }, dx: { type: 'number' }, dy: { type: 'number' } } },\n { type: 'object', required: ['op', 'name'], properties: { op: { const: 'rename_canvas' }, name: { type: 'string', maxLength: 72 } } },\n ],\n};\n\nexport const LIXSKETCH_MCP_TOOLS = Object.freeze([\n {\n name: 'canvas_get',\n title: 'Read LixSketch canvas',\n description: 'Return the canvas summary and optionally its editable scene shapes. Read this before mutation to obtain the current revision.',\n inputSchema: { type: 'object', properties: { includeShapes: { type: 'boolean', default: false }, shapeIDs: { type: 'array', maxItems: 500, items: { type: 'string' } } }, additionalProperties: false },\n annotations: { readOnlyHint: true, destructiveHint: false, idempotentHint: true },\n },\n {\n name: 'canvas_apply_patch',\n title: 'Apply atomic canvas patch',\n description: `Atomically add, update, translate, or delete shapes. Supports ${MCP_LIMITS.maxOperations} operations per call, optimistic revision checks, and dry runs.`,\n inputSchema: { type: 'object', required: ['operations'], properties: { expectedRevision: { type: 'integer', minimum: 0 }, dryRun: { type: 'boolean', default: false }, operations: { type: 'array', minItems: 1, maxItems: MCP_LIMITS.maxOperations, items: PATCH_OPERATION_SCHEMA } }, additionalProperties: false },\n annotations: { readOnlyHint: false, destructiveHint: true, idempotentHint: false },\n },\n {\n name: 'canvas_validate',\n title: 'Validate LixSketch canvas',\n description: 'Validate the current scene format, supported shapes, unique IDs, and package limits.',\n inputSchema: { type: 'object', properties: {}, additionalProperties: false },\n annotations: { readOnlyHint: true, destructiveHint: false, idempotentHint: true },\n },\n {\n name: 'canvas_preview',\n title: 'Render canvas preview',\n description: 'Render a lightweight SVG preview of the current scene for visual inspection before or after edits.',\n inputSchema: { type: 'object', properties: { background: { type: 'string', pattern: '^#[0-9a-fA-F]{3,8}$' }, padding: { type: 'number', minimum: 0, maximum: 200, default: 40 } }, additionalProperties: false },\n annotations: { readOnlyHint: true, destructiveHint: false, idempotentHint: true },\n },\n {\n name: 'canvas_new',\n title: 'Create blank LixSketch canvas',\n description: 'Replace the current scene with a blank canvas. Requires explicit confirmation.',\n inputSchema: { type: 'object', required: ['confirm'], properties: { name: { type: 'string', maxLength: 72 }, confirm: { const: true } }, additionalProperties: false },\n annotations: { readOnlyHint: false, destructiveHint: true, idempotentHint: false },\n },\n {\n name: 'lixscript_apply',\n title: 'Apply LixScript diagram',\n description: 'Compile LixScript into the same validated atomic scene patch used by structured canvas edits. Supports revisions and dry runs.',\n inputSchema: { type: 'object', required: ['source'], properties: { source: { type: 'string', maxLength: 100000 }, x: { type: 'number' }, y: { type: 'number' }, expectedRevision: { type: 'integer', minimum: 0 }, dryRun: { type: 'boolean', default: false } }, additionalProperties: false },\n annotations: { readOnlyHint: false, destructiveHint: false, idempotentHint: false },\n },\n {\n name: 'templates_search',\n title: 'Search LixSketch templates',\n description: 'Search published workspace and component templates in the LixSketch marketplace.',\n inputSchema: { type: 'object', properties: { query: { type: 'string', maxLength: 80 }, tag: { type: 'string', maxLength: 24 }, limit: { type: 'integer', minimum: 1, maximum: 24, default: 12 } }, additionalProperties: false },\n annotations: { readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: true },\n },\n {\n name: 'template_insert',\n title: 'Insert LixSketch template',\n description: 'Insert a published template into the current canvas, remapping every shape and relationship ID. The operation is atomic and supports a dry run.',\n inputSchema: { type: 'object', required: ['slug'], properties: { slug: { type: 'string', pattern: '^[a-z0-9-]{1,80}$' }, x: { type: 'number' }, y: { type: 'number' }, expectedRevision: { type: 'integer', minimum: 0 }, dryRun: { type: 'boolean', default: false } }, additionalProperties: false },\n annotations: { readOnlyHint: false, destructiveHint: false, idempotentHint: false, openWorldHint: true },\n },\n]);\n\nfunction toolResult(value, message) {\n return {\n content: [{ type: 'text', text: message || JSON.stringify(value, null, 2) }],\n structuredContent: value,\n };\n}\n\nfunction toolError(error) {\n const message = error instanceof Error ? error.message : String(error);\n return { isError: true, content: [{ type: 'text', text: message }], structuredContent: { error: message } };\n}\n\nexport class LixSketchMcpServer {\n constructor({ store, templateProvider = new MarketplaceTemplateProvider(), serverInfo = {} } = {}) {\n if (!store?.read || !store?.write) throw new Error('createLixSketchMcpServer requires a scene store with read() and write()');\n this.store = store;\n this.templateProvider = templateProvider;\n this.serverInfo = { name: SERVER_NAME, version: SERVER_VERSION, ...serverInfo };\n this.mutationChain = Promise.resolve();\n }\n\n listTools() {\n return LIXSKETCH_MCP_TOOLS;\n }\n\n async callTool(name, args = {}) {\n try {\n switch (name) {\n case 'canvas_get': {\n const scene = await this.store.read();\n let shapes;\n if (args.includeShapes) {\n const ids = new Set(args.shapeIDs || []);\n shapes = ids.size ? scene.shapes.filter((shape) => ids.has(shape.shapeID)) : scene.shapes;\n }\n return toolResult({ summary: getSceneSummary(scene), ...(shapes ? { shapes } : {}) });\n }\n case 'canvas_validate': {\n const scene = await this.store.read();\n const validation = validateScene(scene);\n return toolResult({ ...validation, summary: getSceneSummary(scene), limits: MCP_LIMITS });\n }\n case 'canvas_preview': {\n const scene = await this.store.read();\n const svg = renderSceneSvg(scene, args);\n return toolResult({ svg, dataUrl: `data:image/svg+xml;base64,${encodeBase64(svg)}`, summary: getSceneSummary(scene) }, svg);\n }\n case 'templates_search': {\n const templates = await this.templateProvider.search(args);\n return toolResult({ templates: templates.map(safeTemplateMetadata) });\n }\n case 'canvas_apply_patch':\n return await this.enqueueMutation(async () => {\n const scene = await this.store.read();\n const result = applyScenePatch(scene, args.operations, args);\n if (!args.dryRun) await this.store.write(result.scene);\n return toolResult({ revision: result.revision, dryRun: result.dryRun, changedShapeIDs: result.changedShapeIDs, summary: getSceneSummary(result.scene) }, args.dryRun ? 'Canvas patch is valid. No changes were saved.' : `Canvas patch saved at revision ${result.revision}.`);\n });\n case 'canvas_new':\n if (args.confirm !== true) throw new Error('canvas_new requires confirm=true');\n return await this.enqueueMutation(async () => {\n const current = await this.store.read();\n const scene = createEmptyScene(args.name);\n scene.mcpRevision = Number(current.mcpRevision || 0) + 1;\n await this.store.write(scene);\n return toolResult({ summary: getSceneSummary(scene) }, 'Blank canvas created.');\n });\n case 'lixscript_apply':\n return await this.enqueueMutation(async () => {\n const scene = await this.store.read();\n const compiled = compileLixScript(args.source, args);\n const result = applyScenePatch(scene, compiled.operations, args);\n if (!args.dryRun) await this.store.write(result.scene);\n return toolResult({ revision: result.revision, dryRun: result.dryRun, sourceShapeCount: compiled.sourceShapeCount, createdShapeIDs: result.changedShapeIDs, summary: getSceneSummary(result.scene) }, args.dryRun ? 'LixScript is valid. No changes were saved.' : `LixScript added ${result.changedShapeIDs.length} canvas elements.`);\n });\n case 'template_insert':\n return await this.enqueueMutation(async () => {\n const scene = await this.store.read();\n const revision = Number(scene.mcpRevision || 0);\n if (args.expectedRevision !== undefined && Number(args.expectedRevision) !== revision) throw new Error(`Revision conflict: expected ${args.expectedRevision}, current ${revision}`);\n const template = await this.templateProvider.load(args.slug);\n const result = mergeTemplateScene(scene, template.scene, args);\n if (!args.dryRun) await this.store.write(result.scene);\n return toolResult({ template: safeTemplateMetadata(template.metadata), revision: result.revision, dryRun: Boolean(args.dryRun), importedShapeIDs: result.importedShapeIDs, summary: getSceneSummary(result.scene) }, args.dryRun ? 'Template import is valid. No changes were saved.' : `Template inserted with ${result.importedShapeIDs.length} shapes.`);\n });\n default: throw new Error(`Unknown tool \"${name}\"`);\n }\n } catch (error) {\n return toolError(error);\n }\n }\n\n enqueueMutation(operation) {\n const pending = this.mutationChain.then(operation, operation);\n this.mutationChain = pending.catch(() => {});\n return pending;\n }\n\n async handleRequest(request) {\n const method = request?.method;\n if (method === 'initialize') {\n const requested = request.params?.protocolVersion;\n const protocolVersion = SUPPORTED_PROTOCOL_VERSIONS.has(requested) ? requested : PROTOCOL_VERSION;\n return { protocolVersion, capabilities: { tools: { listChanged: false }, resources: { subscribe: false, listChanged: false } }, serverInfo: this.serverInfo, instructions: 'Read canvas_get before mutations. Use expectedRevision and dryRun for safe edits. Prefer template_insert for reusable component packs.' };\n }\n if (method === 'ping') return {};\n if (method === 'tools/list') return { tools: this.listTools() };\n if (method === 'tools/call') return this.callTool(request.params?.name, request.params?.arguments || {});\n if (method === 'resources/list') return { resources: [{ uri: 'lixsketch://canvas', name: 'Current LixSketch canvas', description: 'The active editable .lixjson scene', mimeType: 'application/vnd.lixsketch+json' }, { uri: 'lixsketch://canvas/preview.svg', name: 'Current canvas preview', description: 'A lightweight SVG preview of the current scene', mimeType: 'image/svg+xml' }] };\n if (method === 'resources/read') {\n const scene = await this.store.read();\n if (request.params?.uri === 'lixsketch://canvas') return { contents: [{ uri: 'lixsketch://canvas', mimeType: 'application/vnd.lixsketch+json', text: JSON.stringify(scene) }] };\n if (request.params?.uri === 'lixsketch://canvas/preview.svg') return { contents: [{ uri: 'lixsketch://canvas/preview.svg', mimeType: 'image/svg+xml', text: renderSceneSvg(scene) }] };\n throw Object.assign(new Error('Resource not found'), { code: -32002 });\n }\n if (method?.startsWith('notifications/')) return undefined;\n throw Object.assign(new Error(`Method not found: ${method}`), { code: -32601 });\n }\n}\n\nfunction safeTemplateMetadata(template = {}) {\n return { id: template.id, slug: template.slug, title: template.title, description: template.description || '', tags: template.tags || [], publisher: template.publisher, views: template.views, forks: template.forks, clones: template.clones, publishedAt: template.publishedAt, updatedAt: template.updatedAt };\n}\n\nfunction encodeBase64(value) {\n if (typeof btoa === 'function') return btoa(unescape(encodeURIComponent(value)));\n return Buffer.from(value, 'utf8').toString('base64');\n}\n\nexport function createLixSketchMcpServer(options) {\n return new LixSketchMcpServer(options);\n}\n\nexport { PROTOCOL_VERSION as LIXSKETCH_MCP_PROTOCOL_VERSION };\n", "import { createEmptyScene, validateScene } from './scene.js';\n\nexport class MemorySceneStore {\n #scene;\n\n constructor(scene = createEmptyScene()) {\n const validation = validateScene(scene);\n if (!validation.valid) throw new Error(`Invalid initial scene: ${validation.errors.join('; ')}`);\n this.#scene = structuredClone(scene);\n }\n\n async read() {\n return structuredClone(this.#scene);\n }\n\n async write(scene) {\n const validation = validateScene(scene);\n if (!validation.valid) throw new Error(`Refusing to store invalid scene: ${validation.errors.join('; ')}`);\n this.#scene = structuredClone(scene);\n return this.read();\n }\n}\n\n", "import { validateScene } from './scene.js';\n\nfunction decodeBase64Url(value) {\n const base64 = String(value).replaceAll('-', '+').replaceAll('_', '/');\n const padded = base64 + '='.repeat((4 - base64.length % 4) % 4);\n const binary = atob(padded);\n return Uint8Array.from(binary, (character) => character.charCodeAt(0));\n}\n\nfunction encodeBase64Url(bytes) {\n let binary = '';\n for (const byte of bytes) binary += String.fromCharCode(byte);\n return btoa(binary).replaceAll('+', '-').replaceAll('/', '_').replace(/=+$/, '');\n}\n\nasync function importWorkspaceKey(keyValue, usages) {\n const bytes = decodeBase64Url(keyValue);\n if (bytes.byteLength !== 32) throw new Error('The workspace encryption key is not AES-256');\n return crypto.subtle.importKey('raw', bytes, { name: 'AES-GCM', length: 256 }, false, usages);\n}\n\nexport async function decryptRemoteScene(ciphertext, keyValue) {\n const combined = decodeBase64Url(ciphertext);\n if (combined.byteLength < 28) throw new Error('The encrypted workspace payload is invalid');\n const key = await importWorkspaceKey(keyValue, ['decrypt']);\n const plaintext = await crypto.subtle.decrypt({ name: 'AES-GCM', iv: combined.slice(0, 12) }, key, combined.slice(12));\n return JSON.parse(new TextDecoder().decode(plaintext));\n}\n\nexport async function encryptRemoteScene(scene, keyValue) {\n const key = await importWorkspaceKey(keyValue, ['encrypt']);\n const iv = crypto.getRandomValues(new Uint8Array(12));\n const plaintext = new TextEncoder().encode(JSON.stringify(scene));\n const ciphertext = new Uint8Array(await crypto.subtle.encrypt({ name: 'AES-GCM', iv }, key, plaintext));\n const combined = new Uint8Array(iv.byteLength + ciphertext.byteLength);\n combined.set(iv);\n combined.set(ciphertext, iv.byteLength);\n return encodeBase64Url(combined);\n}\n\nexport class RemoteSceneStore {\n constructor({ baseUrl = 'https://sketch.elixpo.com', workspaceId, token, encryptionKey, fetchImpl = globalThis.fetch } = {}) {\n if (!workspaceId) throw new Error('RemoteSceneStore requires workspaceId');\n if (!token) throw new Error('RemoteSceneStore requires an agent grant token');\n if (!encryptionKey) throw new Error('RemoteSceneStore requires the workspace encryption key');\n if (typeof fetchImpl !== 'function') throw new Error('RemoteSceneStore requires fetch');\n this.url = new URL(`/api/mcp/workspaces/${encodeURIComponent(workspaceId)}`, String(baseUrl).replace(/\\/$/, ''));\n this.workspaceId = workspaceId;\n this.token = token;\n this.encryptionKey = encryptionKey;\n this.fetch = fetchImpl;\n this.remoteRevision = null;\n }\n\n async read() {\n const response = await this.fetch(this.url, { headers: this.headers(), cache: 'no-store' });\n const body = await readJson(response);\n if (!response.ok) throw remoteError(response, body);\n const scene = await decryptRemoteScene(body.encryptedData, this.encryptionKey);\n const validation = validateScene(scene);\n if (!validation.valid) throw new Error(`Remote workspace is invalid: ${validation.errors.join('; ')}`);\n this.remoteRevision = Number(body.revision || 0);\n scene.mcpRevision = this.remoteRevision;\n return scene;\n }\n\n async write(scene) {\n const validation = validateScene(scene);\n if (!validation.valid) throw new Error(`Refusing to store invalid remote scene: ${validation.errors.join('; ')}`);\n if (!Number.isInteger(this.remoteRevision)) throw new Error('Read the remote workspace before writing it');\n const encryptedData = await encryptRemoteScene(scene, this.encryptionKey);\n const response = await this.fetch(this.url, {\n method: 'PUT',\n headers: { ...this.headers(), 'Content-Type': 'application/json' },\n body: JSON.stringify({ encryptedData, expectedRevision: this.remoteRevision, workspaceName: scene.name }),\n });\n const body = await readJson(response);\n if (!response.ok) throw remoteError(response, body);\n this.remoteRevision = Number(body.revision);\n return structuredClone({ ...scene, mcpRevision: this.remoteRevision });\n }\n\n headers() {\n return { Accept: 'application/json', Authorization: `Bearer ${this.token}` };\n }\n}\n\nasync function readJson(response) {\n return response.json().catch(() => ({}));\n}\n\nfunction remoteError(response, body) {\n const error = new Error(body.error === 'REVISION_CONFLICT'\n ? `Revision conflict: expected ${body.expectedRevision}, current ${body.currentRevision}`\n : body.error || `Remote workspace request failed (${response.status})`);\n error.status = response.status;\n error.details = body;\n return error;\n}\n"],
5
+ "mappings": "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",
6
+ "names": ["color", "shape", "bounds", "bounds", "options", "point", "options", "decodeBase64Url"]
7
7
  }