alanbox 0.1.1 → 0.1.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.
Files changed (82) hide show
  1. package/0boxer/AGENTS.md +25 -0
  2. package/0boxer/src/AGENTS.md +16 -0
  3. package/0boxer/src/cli.js +53 -0
  4. package/0boxer/src/commands/AGENTS.md +15 -0
  5. package/{0commondflowv1 → 0boxer}/src/commands/install.js +9 -0
  6. package/{0commondflowv1 → 1swarmer}/AGENTS.md +11 -12
  7. package/{0commondflowv1 → 1swarmer}/src/AGENTS.md +6 -5
  8. package/{0commondflowv1 → 1swarmer}/src/args.js +1 -1
  9. package/{0commondflowv1 → 1swarmer}/src/cli.js +5 -18
  10. package/{0commondflowv1 → 1swarmer}/src/commands/AGENTS.md +7 -8
  11. package/{0commondflowv1 → 1swarmer}/src/commands/doctor.js +2 -2
  12. package/{0commondflowv1 → 1swarmer}/src/core/AGENTS.md +2 -2
  13. package/{0commondflowv1 → 1swarmer}/src/core/prompt-templates.js +1 -1
  14. package/{0commondflowv1 → 1swarmer}/src/core/storage.js +1 -1
  15. package/{0commondflowv1 → 1swarmer}/src/prompt/AGENTS.md +1 -1
  16. package/{0commondflowv1 → 1swarmer}/src/prompt/default.md +1 -1
  17. package/{0commondflowv1 → 1swarmer}/src/prompt/synthesizer.md +1 -1
  18. package/{0commondflowv1 → 1swarmer}/src/prompt/verifier.md +1 -1
  19. package/{0commondflowv1 → 1swarmer}/src/runner/AGENTS.md +3 -3
  20. package/2designer/LICENSE +21 -0
  21. package/2designer/README.md +39 -0
  22. package/2designer/dist/cdp-engine-A5WTMTVF.js +10 -0
  23. package/2designer/dist/cdp-engine-A5WTMTVF.js.map +1 -0
  24. package/2designer/dist/cdp-engine-JK2XVDHK.js +314 -0
  25. package/2designer/dist/cdp-engine-JK2XVDHK.js.map +1 -0
  26. package/2designer/dist/chunk-JVF26NXD.js +313 -0
  27. package/2designer/dist/chunk-JVF26NXD.js.map +1 -0
  28. package/2designer/dist/chunk-NLYFLQ3C.js +74 -0
  29. package/2designer/dist/chunk-NLYFLQ3C.js.map +1 -0
  30. package/2designer/dist/chunk-NQ3ASZUE.js +185 -0
  31. package/2designer/dist/chunk-NQ3ASZUE.js.map +1 -0
  32. package/2designer/dist/chunk-SKEIVBOU.js +58 -0
  33. package/2designer/dist/chunk-SKEIVBOU.js.map +1 -0
  34. package/2designer/dist/chunk-UVKSRKXR.js +71 -0
  35. package/2designer/dist/chunk-UVKSRKXR.js.map +1 -0
  36. package/2designer/dist/cli.js +498 -0
  37. package/2designer/dist/cli.js.map +1 -0
  38. package/2designer/dist/index.d.ts +129 -0
  39. package/2designer/dist/index.js +230 -0
  40. package/2designer/dist/index.js.map +1 -0
  41. package/2designer/dist/playwright-engine-3YKJOUNU.js +8 -0
  42. package/2designer/dist/playwright-engine-3YKJOUNU.js.map +1 -0
  43. package/2designer/dist/playwright-engine-YBRDIUHF.js +186 -0
  44. package/2designer/dist/playwright-engine-YBRDIUHF.js.map +1 -0
  45. package/2designer/dist/tint-I3FTT23O.js +60 -0
  46. package/2designer/dist/tint-I3FTT23O.js.map +1 -0
  47. package/2designer/dist/tint-RUSSUAWA.js +7 -0
  48. package/2designer/dist/tint-RUSSUAWA.js.map +1 -0
  49. package/2designer/package.json +56 -0
  50. package/README.md +14 -9
  51. package/bin/alanbox.js +11 -0
  52. package/bin/designer.js +10 -0
  53. package/bin/swarmer.js +11 -0
  54. package/cli.js +153 -0
  55. package/hooks/hooks.json +1 -1
  56. package/package.json +24 -10
  57. package/plugin/AGENTS.md +2 -2
  58. package/plugin/plugin.json +7 -7
  59. package/shared/AGENTS.md +15 -0
  60. package/shared/package-args.js +68 -0
  61. package/skills/AGENTS.md +9 -5
  62. package/skills/aitool/SKILL.md +36 -0
  63. package/skills/desginer/SKILL.md +122 -0
  64. package/skills/swarmer/SKILL.md +109 -0
  65. package/bin/multirunagent.js +0 -15
  66. package/skills/aibox-swam/SKILL.md +0 -77
  67. package/skills/sub-codex-doctor/SKILL.md +0 -27
  68. package/skills/sub-codex-swarm/SKILL.md +0 -56
  69. /package/{0commondflowv1 → 1swarmer}/res/three-lens-review.js +0 -0
  70. /package/{0commondflowv1 → 1swarmer}/src/commands/info.js +0 -0
  71. /package/{0commondflowv1 → 1swarmer}/src/commands/swarm/auto.js +0 -0
  72. /package/{0commondflowv1 → 1swarmer}/src/commands/swarm/custom.js +0 -0
  73. /package/{0commondflowv1 → 1swarmer}/src/commands/swarm/index.js +0 -0
  74. /package/{0commondflowv1 → 1swarmer}/src/core/handoff.js +0 -0
  75. /package/{0commondflowv1 → 1swarmer}/src/core/prompt-builder.js +0 -0
  76. /package/{0commondflowv1 → 1swarmer}/src/core/swarm-executor.js +0 -0
  77. /package/{0commondflowv1 → 1swarmer}/src/core/workers.js +0 -0
  78. /package/{0commondflowv1 → 1swarmer}/src/core/workflow-planner.js +0 -0
  79. /package/{0commondflowv1 → 1swarmer}/src/core/workflow-storage.js +0 -0
  80. /package/{0commondflowv1 → 1swarmer}/src/prompt/reviewer.md +0 -0
  81. /package/{0commondflowv1 → 1swarmer}/src/runner/codex-runner.js +0 -0
  82. /package/{0commondflowv1 → 1swarmer}/src/runner/config.json +0 -0
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/engine/cdp/cdp-client.ts","../src/engine/cdp/cdp-engine.ts"],"sourcesContent":["import WebSocket from 'ws'\r\n\r\nexport interface CdpTarget {\r\n id: string\r\n title: string\r\n type: string\r\n url: string\r\n webSocketDebuggerUrl: string\r\n}\r\n\r\nexport async function listTargets(host: string, port: number): Promise<CdpTarget[]> {\r\n const res = await fetch(`http://${host}:${port}/json`)\r\n if (!res.ok) throw new Error(`CDP target list failed: ${res.status}`)\r\n return res.json() as Promise<CdpTarget[]>\r\n}\r\n\r\nexport class CdpClient {\r\n private ws: WebSocket\r\n private nextId = 1\r\n private pending = new Map<number, { resolve: (v: any) => void; reject: (e: Error) => void }>()\r\n private ready: Promise<void>\r\n\r\n private constructor(wsUrl: string) {\r\n this.ws = new WebSocket(wsUrl)\r\n this.ready = new Promise((resolve, reject) => {\r\n this.ws.once('open', resolve)\r\n this.ws.once('error', reject)\r\n })\r\n this.ws.on('message', (data: WebSocket.Data) => {\r\n const payload = JSON.parse(data.toString())\r\n if (payload.id != null) {\r\n const p = this.pending.get(payload.id)\r\n if (p) {\r\n this.pending.delete(payload.id)\r\n if (payload.error) {\r\n p.reject(new Error(`CDP: ${payload.error.message}`))\r\n } else {\r\n p.resolve(payload.result)\r\n }\r\n }\r\n }\r\n })\r\n this.ws.on('close', () => {\r\n for (const p of this.pending.values()) {\r\n p.reject(new Error('CDP connection closed'))\r\n }\r\n this.pending.clear()\r\n })\r\n }\r\n\r\n static async connect(target: CdpTarget): Promise<CdpClient> {\r\n const client = new CdpClient(target.webSocketDebuggerUrl)\r\n await client.ready\r\n await client.call('DOM.enable')\r\n await client.call('CSS.enable')\r\n await client.call('Page.enable')\r\n await client.call('Runtime.enable')\r\n return client\r\n }\r\n\r\n async call<T = any>(method: string, params?: Record<string, unknown>, timeout = 30000): Promise<T> {\r\n const id = this.nextId++\r\n return new Promise<T>((resolve, reject) => {\r\n const timer = setTimeout(() => {\r\n this.pending.delete(id)\r\n reject(new Error(`CDP call '${method}' timed out after ${timeout}ms`))\r\n }, timeout)\r\n this.pending.set(id, {\r\n resolve: (v) => { clearTimeout(timer); resolve(v) },\r\n reject: (e) => { clearTimeout(timer); reject(e) },\r\n })\r\n this.ws.send(JSON.stringify({ id, method, params }))\r\n })\r\n }\r\n\r\n close(): void {\r\n this.ws.close()\r\n }\r\n}\r\n\r\nexport async function connectToPage(\r\n host: string,\r\n port: number,\r\n urlFilter?: string,\r\n): Promise<{ client: CdpClient; target: CdpTarget }> {\r\n const targets = await listTargets(host, port)\r\n const pages = targets.filter(t => t.type === 'page')\r\n if (pages.length === 0) throw new Error('No page targets found')\r\n\r\n const target = urlFilter\r\n ? pages.find(t => t.url.includes(urlFilter)) ?? pages[0]\r\n : pages[0]\r\n\r\n const client = await CdpClient.connect(target)\r\n return { client, target }\r\n}\r\n","import type { RuntimeEngine, MeasureResult, ScreenshotOptions, OverlayParams } from '../types.js'\nimport {\n MEASURE_RETRY_INTERVAL_MS,\n MEASURE_WAIT_TIMEOUT_MS,\n RELEVANT_PROPS,\n REQUIRED_MEASURE_PROPS,\n} from '../constants.js'\nimport { CdpClient, connectToPage } from './cdp-client.js'\n\r\ninterface BoxModelQuad {\r\n quad: number[]\r\n}\r\n\r\nexport function buildClip(\r\n model: { content: BoxModelQuad; border?: BoxModelQuad },\r\n viewport: { width: number; height: number },\r\n padding = 0,\r\n): { x: number; y: number; width: number; height: number } {\r\n const q = model.border?.quad ?? model.content.quad\r\n const minX = Math.min(q[0], q[2], q[4], q[6])\r\n const maxX = Math.max(q[0], q[2], q[4], q[6])\r\n const minY = Math.min(q[1], q[3], q[5], q[7])\r\n const maxY = Math.max(q[1], q[3], q[5], q[7])\r\n\r\n const x = Math.max(0, minX - padding)\r\n const y = Math.max(0, minY - padding)\r\n const width = Math.min(viewport.width, maxX + padding) - x\r\n const height = Math.min(viewport.height, maxY + padding) - y\r\n\r\n return { x, y, width, height }\r\n}\r\n\r\nexport class CdpEngine implements RuntimeEngine {\r\n private constructor(\r\n private client: CdpClient,\r\n private pageUrl: string,\r\n ) {}\r\n\r\n static async create(host: string, port: number, urlFilter?: string): Promise<CdpEngine> {\r\n const { client, target } = await connectToPage(host, port, urlFilter)\r\n return new CdpEngine(client, target.url)\r\n }\r\n\r\n async screenshot(options?: ScreenshotOptions): Promise<Buffer> {\r\n if (options?.selector) {\r\n // Use JSON.stringify to safely escape the selector\r\n const safeSelector = JSON.stringify(options.selector)\r\n const { result } = await this.client.call<any>('Runtime.evaluate', {\r\n expression: `(() => {\r\n const el = document.querySelector(${safeSelector});\r\n if (!el) throw new Error('Element not found: ' + ${safeSelector});\r\n return JSON.stringify(el.getBoundingClientRect());\r\n })()`,\r\n returnByValue: true,\r\n })\r\n if (result.subtype === 'error') {\r\n throw new Error(result.description || `Element not found: ${options.selector}`)\r\n }\r\n const rect = JSON.parse(result.value)\r\n const viewport = await this.getViewport()\r\n const clip = {\r\n x: Math.max(0, rect.x),\r\n y: Math.max(0, rect.y),\r\n width: Math.min(viewport.width - rect.x, rect.width),\r\n height: Math.min(viewport.height - rect.y, rect.height),\r\n scale: 1,\r\n }\r\n const { data } = await this.client.call<{ data: string }>('Page.captureScreenshot', {\r\n format: 'png',\r\n clip,\r\n fromSurface: true,\r\n })\r\n return Buffer.from(data, 'base64')\r\n }\r\n\r\n const { data } = await this.client.call<{ data: string }>('Page.captureScreenshot', {\r\n format: 'png',\r\n fromSurface: true,\r\n })\r\n return Buffer.from(data, 'base64')\r\n }\r\n\r\n async measure(selector: string, depth = 1, frameSelector?: string): Promise<MeasureResult> {\n // All user inputs passed via JSON.stringify to prevent injection\n const safeSelector = JSON.stringify(selector)\n const safeFrameSelector = JSON.stringify(frameSelector)\n const safeProps = JSON.stringify(RELEVANT_PROPS)\n const safeRequiredProps = JSON.stringify(REQUIRED_MEASURE_PROPS)\n const safeDepth = Number.isFinite(depth) ? Math.max(0, depth) : 1\n\n const js = `\n (() => {\n function toBBox(rect, origin) {\n const originX = origin ? origin.x : 0;\n const originY = origin ? origin.y : 0;\n const originLeft = origin ? origin.left : 0;\n const originTop = origin ? origin.top : 0;\n return {\n x: +(rect.x - originX).toFixed(1),\n y: +(rect.y - originY).toFixed(1),\n width: +rect.width.toFixed(1),\n height: +rect.height.toFixed(1),\n top: +(rect.top - originTop).toFixed(1),\n right: +(rect.right - originLeft).toFixed(1),\n bottom: +(rect.bottom - originTop).toFixed(1),\n left: +(rect.left - originLeft).toFixed(1),\n };\n }\n\n function isValidBBox(bbox) {\n return Object.values(bbox).every(Number.isFinite);\n }\n\n function collectStyle(win, el) {\n const cs = win.getComputedStyle(el);\n const style = {};\n ${safeProps}.forEach(p => {\n style[p] = p === 'font' ? cs.font : cs.getPropertyValue(p);\n });\n return style;\n }\n\n function hasRequiredStyle(style) {\n return ${safeRequiredProps}.every(p => typeof style[p] === 'string' && style[p] !== '');\n }\n\n function collectChildren(parent, parentRect, currentDepth, maxDepth) {\n if (currentDepth >= maxDepth) return [];\n const result = [];\n for (const child of parent.children) {\n const cr = child.getBoundingClientRect();\n const node = {\r\n tag: child.tagName.toLowerCase(),\n className: (child.className || '').toString().substring(0, 120),\n bbox: toBBox(cr, parentRect),\n text: (child.textContent || '').substring(0, 80).trim() || undefined,\n };\n if (currentDepth + 1 < maxDepth && child.children.length > 0) {\n node.children = collectChildren(child, cr, currentDepth + 1, maxDepth);\r\n }\r\n result.push(node);\r\n }\r\n return result;\n }\n\n const sel = ${safeSelector};\n const frameSel = ${safeFrameSelector};\n let doc = document;\n let win = window;\n if (frameSel) {\n const frame = document.querySelector(frameSel);\n if (!frame || !frame.contentDocument || !frame.contentWindow) return JSON.stringify(null);\n doc = frame.contentDocument;\n win = frame.contentWindow;\n }\n\n const el = doc.querySelector(sel);\n if (!el) return JSON.stringify(null);\n const r = el.getBoundingClientRect();\n const bbox = toBBox(r);\n const style = collectStyle(win, el);\n if (!isValidBBox(bbox)) return JSON.stringify(null);\n if (!hasRequiredStyle(style)) return JSON.stringify(null);\n if (bbox.width <= 0 || bbox.height <= 0 || style.display === 'none' || style.visibility === 'hidden') {\n return JSON.stringify(null);\n }\n\n return JSON.stringify({\n bbox,\n computedStyle: style,\n children: ${safeDepth} > 0 ? collectChildren(el, r, 0, ${safeDepth}) : [],\n });\n })()\n `\n\n const deadline = Date.now() + MEASURE_WAIT_TIMEOUT_MS\n let lastError: Error | undefined\n while (Date.now() <= deadline) {\n try {\n const { result, exceptionDetails } = await this.client.call<any>('Runtime.evaluate', {\n expression: js,\n returnByValue: true,\n })\n if (exceptionDetails || result.subtype === 'error') {\n throw new Error(result.description || exceptionDetails?.text || 'measure failed')\n }\n\n const parsed = JSON.parse(result.value)\n if (parsed) {\n return frameSelector ? { selector, frameSelector, ...parsed } : { selector, ...parsed }\n }\n lastError = new Error(\n frameSelector\n ? `Element not ready or incomplete: ${selector} in frame ${frameSelector}`\n : `Element not ready or incomplete: ${selector}`,\n )\n } catch (error) {\n lastError = error instanceof Error ? error : new Error(String(error))\n }\n await new Promise(resolve => setTimeout(resolve, MEASURE_RETRY_INTERVAL_MS))\n }\n\n throw lastError ?? new Error('measure failed')\n }\n\r\n async evaluate<T = unknown>(expression: string): Promise<T> {\r\n const { result } = await this.client.call<any>('Runtime.evaluate', {\r\n expression,\r\n returnByValue: true,\r\n })\r\n return result.value as T\r\n }\r\n\r\n async injectOverlay(params: OverlayParams): Promise<void> {\r\n const { tintDesignImage } = await import('../../overlay/tint.js')\r\n const tintedBuf = await tintDesignImage(params.designImagePath)\r\n const base64 = tintedBuf.toString('base64')\r\n // Numeric params are safe, base64 is safe, no user strings interpolated\r\n const js = `\r\n (() => {\r\n let overlay = document.getElementById('__design_ruler_overlay__');\r\n if (!overlay) {\r\n overlay = document.createElement('img');\r\n overlay.id = '__design_ruler_overlay__';\r\n overlay.style.cssText = 'position:fixed;top:0;left:0;width:100vw;height:auto;pointer-events:none;z-index:999999;';\r\n document.body.appendChild(overlay);\r\n }\r\n overlay.src = 'data:image/png;base64,' + ${JSON.stringify(base64)};\r\n overlay.style.opacity = String(${Number(params.opacity)});\r\n overlay.style.transform = 'translate(' + ${Number(params.offsetX)} + 'px, ' + ${Number(params.offsetY)} + 'px) scale(' + ${Number(params.scale)} + ')';\r\n overlay.style.transformOrigin = 'top left';\r\n if (${Number(params.scrollY ?? 0)} > 0) {\r\n window.scrollTo(0, ${Number(params.scrollY ?? 0)});\r\n }\r\n return 'overlay injected';\r\n })()\r\n `\r\n await this.evaluate(js)\r\n }\r\n\r\n async captureOverlay(options?: import('../types.js').ScreenshotOptions): Promise<Buffer> {\r\n return this.screenshot(options)\r\n }\r\n\r\n async close(): Promise<void> {\r\n this.client.close()\r\n }\r\n\r\n private async getViewport(): Promise<{ width: number; height: number }> {\r\n return this.evaluate<{ width: number; height: number }>(\r\n 'JSON.parse(JSON.stringify({ width: window.innerWidth, height: window.innerHeight }))'\r\n )\r\n }\r\n}\r\n"],"mappings":"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","names":["data"]}
@@ -0,0 +1,74 @@
1
+ #!/usr/bin/env node
2
+
3
+
4
+ // src/engine/constants.ts
5
+ var RELEVANT_PROPS = [
6
+ "width",
7
+ "height",
8
+ "min-width",
9
+ "min-height",
10
+ "max-width",
11
+ "max-height",
12
+ "padding",
13
+ "padding-top",
14
+ "padding-right",
15
+ "padding-bottom",
16
+ "padding-left",
17
+ "margin",
18
+ "margin-top",
19
+ "margin-right",
20
+ "margin-bottom",
21
+ "margin-left",
22
+ "border",
23
+ "border-width",
24
+ "border-radius",
25
+ "border-color",
26
+ "border-style",
27
+ "font",
28
+ "font-size",
29
+ "font-weight",
30
+ "font-family",
31
+ "line-height",
32
+ "letter-spacing",
33
+ "text-align",
34
+ "color",
35
+ "background-color",
36
+ "background",
37
+ "gap",
38
+ "row-gap",
39
+ "column-gap",
40
+ "display",
41
+ "flex-direction",
42
+ "justify-content",
43
+ "align-items",
44
+ "position",
45
+ "top",
46
+ "right",
47
+ "bottom",
48
+ "left",
49
+ "opacity",
50
+ "overflow",
51
+ "visibility",
52
+ "z-index",
53
+ "box-sizing"
54
+ ];
55
+ var REQUIRED_MEASURE_PROPS = [
56
+ "font",
57
+ "color",
58
+ "background-color",
59
+ "border",
60
+ "padding",
61
+ "margin",
62
+ "display",
63
+ "visibility"
64
+ ];
65
+ var MEASURE_WAIT_TIMEOUT_MS = 5e3;
66
+ var MEASURE_RETRY_INTERVAL_MS = 100;
67
+
68
+ export {
69
+ RELEVANT_PROPS,
70
+ REQUIRED_MEASURE_PROPS,
71
+ MEASURE_WAIT_TIMEOUT_MS,
72
+ MEASURE_RETRY_INTERVAL_MS
73
+ };
74
+ //# sourceMappingURL=chunk-NLYFLQ3C.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/engine/constants.ts"],"sourcesContent":["export const RELEVANT_PROPS = [\n 'width', 'height', 'min-width', 'min-height', 'max-width', 'max-height',\n 'padding', 'padding-top', 'padding-right', 'padding-bottom', 'padding-left',\n 'margin', 'margin-top', 'margin-right', 'margin-bottom', 'margin-left',\n 'border', 'border-width', 'border-radius', 'border-color', 'border-style',\n 'font', 'font-size', 'font-weight', 'font-family', 'line-height', 'letter-spacing',\n 'text-align', 'color', 'background-color', 'background',\n 'gap', 'row-gap', 'column-gap',\n 'display', 'flex-direction', 'justify-content', 'align-items',\n 'position', 'top', 'right', 'bottom', 'left',\n 'opacity', 'overflow', 'visibility', 'z-index',\n 'box-sizing',\n]\n\nexport const REQUIRED_MEASURE_PROPS = [\n 'font',\n 'color',\n 'background-color',\n 'border',\n 'padding',\n 'margin',\n 'display',\n 'visibility',\n]\n\nexport const MEASURE_WAIT_TIMEOUT_MS = 5000\nexport const MEASURE_RETRY_INTERVAL_MS = 100\n"],"mappings":";;;;AAAO,IAAM,iBAAiB;AAAA,EAC5B;AAAA,EAAS;AAAA,EAAU;AAAA,EAAa;AAAA,EAAc;AAAA,EAAa;AAAA,EAC3D;AAAA,EAAW;AAAA,EAAe;AAAA,EAAiB;AAAA,EAAkB;AAAA,EAC7D;AAAA,EAAU;AAAA,EAAc;AAAA,EAAgB;AAAA,EAAiB;AAAA,EACzD;AAAA,EAAU;AAAA,EAAgB;AAAA,EAAiB;AAAA,EAAgB;AAAA,EAC3D;AAAA,EAAQ;AAAA,EAAa;AAAA,EAAe;AAAA,EAAe;AAAA,EAAe;AAAA,EAClE;AAAA,EAAc;AAAA,EAAS;AAAA,EAAoB;AAAA,EAC3C;AAAA,EAAO;AAAA,EAAW;AAAA,EAClB;AAAA,EAAW;AAAA,EAAkB;AAAA,EAAmB;AAAA,EAChD;AAAA,EAAY;AAAA,EAAO;AAAA,EAAS;AAAA,EAAU;AAAA,EACtC;AAAA,EAAW;AAAA,EAAY;AAAA,EAAc;AAAA,EACrC;AACF;AAEO,IAAM,yBAAyB;AAAA,EACpC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAEO,IAAM,0BAA0B;AAChC,IAAM,4BAA4B;","names":[]}
@@ -0,0 +1,185 @@
1
+ import {
2
+ MEASURE_RETRY_INTERVAL_MS,
3
+ MEASURE_WAIT_TIMEOUT_MS,
4
+ RELEVANT_PROPS,
5
+ REQUIRED_MEASURE_PROPS
6
+ } from "./chunk-UVKSRKXR.js";
7
+
8
+ // src/engine/playwright/playwright-engine.ts
9
+ var PlaywrightEngine = class _PlaywrightEngine {
10
+ browser;
11
+ page;
12
+ constructor(browser, page) {
13
+ this.browser = browser;
14
+ this.page = page;
15
+ }
16
+ static async create(url, options = {}) {
17
+ const { chromium } = await import("playwright");
18
+ const browser = await chromium.launch({
19
+ headless: options.headless ?? true
20
+ });
21
+ const context = await browser.newContext({
22
+ viewport: options.viewport ?? { width: 1920, height: 1080 },
23
+ deviceScaleFactor: options.deviceScaleFactor ?? 1
24
+ });
25
+ const page = await context.newPage();
26
+ await page.goto(url, {
27
+ waitUntil: options.waitUntil ?? "networkidle",
28
+ timeout: options.waitTimeout ?? 15e3
29
+ });
30
+ return new _PlaywrightEngine(browser, page);
31
+ }
32
+ async screenshot(options) {
33
+ if (options?.selector) {
34
+ const el = await this.page.waitForSelector(options.selector, {
35
+ timeout: 5e3,
36
+ state: "visible"
37
+ });
38
+ return el.screenshot({ type: "png" });
39
+ }
40
+ return this.page.screenshot({
41
+ type: "png",
42
+ fullPage: options?.fullPage ?? false
43
+ });
44
+ }
45
+ async measure(selector, depth = 1, frameSelector) {
46
+ const maxDepth = Number.isFinite(depth) ? Math.max(0, depth) : 1;
47
+ const handle = await this.page.waitForFunction(
48
+ ({
49
+ sel,
50
+ frameSel,
51
+ props,
52
+ requiredProps,
53
+ maxDepth: maxDepth2
54
+ }) => {
55
+ function toBBox(rect, origin) {
56
+ const originX = origin?.x ?? 0;
57
+ const originY = origin?.y ?? 0;
58
+ const originLeft = origin?.left ?? 0;
59
+ const originTop = origin?.top ?? 0;
60
+ return {
61
+ x: +(rect.x - originX).toFixed(1),
62
+ y: +(rect.y - originY).toFixed(1),
63
+ width: +rect.width.toFixed(1),
64
+ height: +rect.height.toFixed(1),
65
+ top: +(rect.top - originTop).toFixed(1),
66
+ right: +(rect.right - originLeft).toFixed(1),
67
+ bottom: +(rect.bottom - originTop).toFixed(1),
68
+ left: +(rect.left - originLeft).toFixed(1)
69
+ };
70
+ }
71
+ function isValidBBox(bbox2) {
72
+ return Object.values(bbox2).every(Number.isFinite);
73
+ }
74
+ function collectStyle(win2, el2) {
75
+ const cs = win2.getComputedStyle(el2);
76
+ const style2 = {};
77
+ props.forEach((p) => {
78
+ style2[p] = p === "font" ? cs.font : cs.getPropertyValue(p);
79
+ });
80
+ return style2;
81
+ }
82
+ function hasRequiredStyle(style2) {
83
+ return requiredProps.every((p) => typeof style2[p] === "string" && style2[p] !== "");
84
+ }
85
+ function collectChildren(parent, parentRect, currentDepth, maxDep) {
86
+ if (currentDepth >= maxDep) return [];
87
+ const result2 = [];
88
+ for (const child of parent.children) {
89
+ const cr = child.getBoundingClientRect();
90
+ const node = {
91
+ tag: child.tagName.toLowerCase(),
92
+ className: (child.className || "").toString().substring(0, 120),
93
+ bbox: toBBox(cr, parentRect),
94
+ text: (child.textContent || "").substring(0, 80).trim() || void 0
95
+ };
96
+ if (currentDepth + 1 < maxDep && child.children.length > 0) {
97
+ node.children = collectChildren(child, cr, currentDepth + 1, maxDep);
98
+ }
99
+ result2.push(node);
100
+ }
101
+ return result2;
102
+ }
103
+ let doc = document;
104
+ let win = window;
105
+ if (frameSel) {
106
+ const frame = document.querySelector(frameSel);
107
+ if (!frame || !frame.contentDocument || !frame.contentWindow) return null;
108
+ doc = frame.contentDocument;
109
+ win = frame.contentWindow;
110
+ }
111
+ const el = doc.querySelector(sel);
112
+ if (!el) return null;
113
+ const r = el.getBoundingClientRect();
114
+ const bbox = toBBox(r);
115
+ const style = collectStyle(win, el);
116
+ if (!isValidBBox(bbox)) return null;
117
+ if (!hasRequiredStyle(style)) return null;
118
+ if (bbox.width <= 0 || bbox.height <= 0 || style.display === "none" || style.visibility === "hidden") {
119
+ return null;
120
+ }
121
+ return {
122
+ bbox,
123
+ computedStyle: style,
124
+ children: maxDepth2 > 0 ? collectChildren(el, r, 0, maxDepth2) : []
125
+ };
126
+ },
127
+ {
128
+ sel: selector,
129
+ frameSel: frameSelector,
130
+ props: RELEVANT_PROPS,
131
+ requiredProps: REQUIRED_MEASURE_PROPS,
132
+ maxDepth
133
+ },
134
+ {
135
+ timeout: MEASURE_WAIT_TIMEOUT_MS,
136
+ polling: MEASURE_RETRY_INTERVAL_MS
137
+ }
138
+ );
139
+ const result = await handle.jsonValue();
140
+ return frameSelector ? { selector, frameSelector, ...result } : { selector, ...result };
141
+ }
142
+ async evaluate(expression) {
143
+ return this.page.evaluate(expression);
144
+ }
145
+ async injectOverlay(params) {
146
+ const { tintDesignImage } = await import("./tint-RUSSUAWA.js");
147
+ const tintedBuf = await tintDesignImage(params.designImagePath);
148
+ const base64 = tintedBuf.toString("base64");
149
+ await this.page.evaluate(
150
+ ({ b64, opacity, offsetX, offsetY, scale, scrollY }) => {
151
+ let overlay = document.getElementById("__design_ruler_overlay__");
152
+ if (!overlay) {
153
+ overlay = document.createElement("img");
154
+ overlay.id = "__design_ruler_overlay__";
155
+ overlay.style.cssText = "position:fixed;top:0;left:0;width:100vw;height:auto;pointer-events:none;z-index:999999;";
156
+ document.body.appendChild(overlay);
157
+ }
158
+ overlay.src = `data:image/png;base64,${b64}`;
159
+ overlay.style.opacity = String(opacity);
160
+ overlay.style.transform = `translate(${offsetX}px, ${offsetY}px) scale(${scale})`;
161
+ overlay.style.transformOrigin = "top left";
162
+ if (scrollY > 0) window.scrollTo(0, scrollY);
163
+ },
164
+ {
165
+ b64: base64,
166
+ opacity: params.opacity,
167
+ offsetX: params.offsetX,
168
+ offsetY: params.offsetY,
169
+ scale: params.scale,
170
+ scrollY: params.scrollY ?? 0
171
+ }
172
+ );
173
+ }
174
+ async captureOverlay(options) {
175
+ return this.screenshot(options);
176
+ }
177
+ async close() {
178
+ await this.browser.close();
179
+ }
180
+ };
181
+
182
+ export {
183
+ PlaywrightEngine
184
+ };
185
+ //# sourceMappingURL=chunk-NQ3ASZUE.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/engine/playwright/playwright-engine.ts"],"sourcesContent":["import type { RuntimeEngine, MeasureResult, ScreenshotOptions, OverlayParams } from '../types.js'\nimport {\n MEASURE_RETRY_INTERVAL_MS,\n MEASURE_WAIT_TIMEOUT_MS,\n RELEVANT_PROPS,\n REQUIRED_MEASURE_PROPS,\n} from '../constants.js'\n\r\nexport interface PlaywrightEngineOptions {\r\n headless?: boolean\r\n viewport?: { width: number; height: number }\r\n deviceScaleFactor?: number\r\n waitUntil?: 'load' | 'domcontentloaded' | 'networkidle' | 'commit'\r\n waitTimeout?: number\r\n}\r\n\r\nexport class PlaywrightEngine implements RuntimeEngine {\r\n private browser: any\r\n private page: any\r\n\r\n private constructor(browser: any, page: any) {\r\n this.browser = browser\r\n this.page = page\r\n }\r\n\r\n static async create(\r\n url: string,\r\n options: PlaywrightEngineOptions = {},\r\n ): Promise<PlaywrightEngine> {\r\n const { chromium } = await import('playwright')\r\n const browser = await chromium.launch({\r\n headless: options.headless ?? true,\r\n })\r\n const context = await browser.newContext({\r\n viewport: options.viewport ?? { width: 1920, height: 1080 },\r\n deviceScaleFactor: options.deviceScaleFactor ?? 1,\r\n })\r\n const page = await context.newPage()\r\n await page.goto(url, {\r\n waitUntil: options.waitUntil ?? 'networkidle',\r\n timeout: options.waitTimeout ?? 15000,\r\n })\r\n return new PlaywrightEngine(browser, page)\r\n }\r\n\r\n async screenshot(options?: ScreenshotOptions): Promise<Buffer> {\r\n if (options?.selector) {\r\n const el = await this.page.waitForSelector(options.selector, {\r\n timeout: 5000,\r\n state: 'visible',\r\n })\r\n return el.screenshot({ type: 'png' })\r\n }\r\n return this.page.screenshot({\r\n type: 'png',\r\n fullPage: options?.fullPage ?? false,\r\n })\r\n }\r\n\r\n async measure(selector: string, depth = 1, frameSelector?: string): Promise<MeasureResult> {\n const maxDepth = Number.isFinite(depth) ? Math.max(0, depth) : 1\n const handle = await this.page.waitForFunction(\n (\n {\n sel,\n frameSel,\n props,\n requiredProps,\n maxDepth,\n }: { sel: string; frameSel?: string; props: string[]; requiredProps: string[]; maxDepth: number },\n ) => {\n function toBBox(rect: DOMRect, origin?: DOMRect) {\n const originX = origin?.x ?? 0\n const originY = origin?.y ?? 0\n const originLeft = origin?.left ?? 0\n const originTop = origin?.top ?? 0\n return {\n x: +(rect.x - originX).toFixed(1),\n y: +(rect.y - originY).toFixed(1),\n width: +rect.width.toFixed(1),\n height: +rect.height.toFixed(1),\n top: +(rect.top - originTop).toFixed(1),\n right: +(rect.right - originLeft).toFixed(1),\n bottom: +(rect.bottom - originTop).toFixed(1),\n left: +(rect.left - originLeft).toFixed(1),\n }\n }\n\n function isValidBBox(bbox: Record<string, number>) {\n return Object.values(bbox).every(Number.isFinite)\n }\n\n function collectStyle(win: Window, el: Element) {\n const cs = win.getComputedStyle(el)\n const style: Record<string, string> = {}\n props.forEach(p => {\n style[p] = p === 'font' ? cs.font : cs.getPropertyValue(p)\n })\n return style\n }\n\n function hasRequiredStyle(style: Record<string, string>) {\n return requiredProps.every(p => typeof style[p] === 'string' && style[p] !== '')\n }\n\n function collectChildren(\n parent: Element,\n parentRect: DOMRect,\n currentDepth: number,\n maxDep: number,\n ): any[] {\n if (currentDepth >= maxDep) return []\n const result: any[] = []\n for (const child of parent.children) {\n const cr = child.getBoundingClientRect()\n const node: any = {\n tag: child.tagName.toLowerCase(),\n className: (child.className || '').toString().substring(0, 120),\n bbox: toBBox(cr, parentRect),\n text: (child.textContent || '').substring(0, 80).trim() || undefined,\n }\n if (currentDepth + 1 < maxDep && child.children.length > 0) {\n node.children = collectChildren(child, cr, currentDepth + 1, maxDep)\r\n }\r\n result.push(node)\r\n }\n return result\n }\n\n let doc: Document = document\n let win: Window = window\n if (frameSel) {\n const frame = document.querySelector(frameSel) as HTMLIFrameElement | null\n if (!frame || !frame.contentDocument || !frame.contentWindow) return null\n doc = frame.contentDocument\n win = frame.contentWindow\n }\n\n const el = doc.querySelector(sel)\n if (!el) return null\n const r = el.getBoundingClientRect()\n const bbox = toBBox(r)\n const style = collectStyle(win, el)\n if (!isValidBBox(bbox)) return null\n if (!hasRequiredStyle(style)) return null\n if (bbox.width <= 0 || bbox.height <= 0 || style.display === 'none' || style.visibility === 'hidden') {\n return null\n }\n\n return {\n bbox,\n computedStyle: style,\n children: maxDepth > 0 ? collectChildren(el, r, 0, maxDepth) : [],\n }\n },\n {\n sel: selector,\n frameSel: frameSelector,\n props: RELEVANT_PROPS,\n requiredProps: REQUIRED_MEASURE_PROPS,\n maxDepth,\n },\n {\n timeout: MEASURE_WAIT_TIMEOUT_MS,\n polling: MEASURE_RETRY_INTERVAL_MS,\n },\n )\n const result = await handle.jsonValue()\n return frameSelector ? { selector, frameSelector, ...result } : { selector, ...result }\n }\n\r\n async evaluate<T = unknown>(expression: string): Promise<T> {\r\n return this.page.evaluate(expression)\r\n }\r\n\r\n async injectOverlay(params: OverlayParams): Promise<void> {\r\n const { tintDesignImage } = await import('../../overlay/tint.js')\r\n const tintedBuf = await tintDesignImage(params.designImagePath)\r\n const base64 = tintedBuf.toString('base64')\r\n await this.page.evaluate(\r\n ({ b64, opacity, offsetX, offsetY, scale, scrollY }: any) => {\r\n let overlay = document.getElementById('__design_ruler_overlay__') as HTMLImageElement\r\n if (!overlay) {\r\n overlay = document.createElement('img')\r\n overlay.id = '__design_ruler_overlay__'\r\n overlay.style.cssText =\r\n 'position:fixed;top:0;left:0;width:100vw;height:auto;pointer-events:none;z-index:999999;'\r\n document.body.appendChild(overlay)\r\n }\r\n overlay.src = `data:image/png;base64,${b64}`\r\n overlay.style.opacity = String(opacity)\r\n overlay.style.transform = `translate(${offsetX}px, ${offsetY}px) scale(${scale})`\r\n overlay.style.transformOrigin = 'top left'\r\n if (scrollY > 0) window.scrollTo(0, scrollY)\r\n },\r\n {\r\n b64: base64,\r\n opacity: params.opacity,\r\n offsetX: params.offsetX,\r\n offsetY: params.offsetY,\r\n scale: params.scale,\r\n scrollY: params.scrollY ?? 0,\r\n },\r\n )\r\n }\r\n\r\n async captureOverlay(options?: import('../types.js').ScreenshotOptions): Promise<Buffer> {\r\n return this.screenshot(options)\r\n }\r\n\r\n async close(): Promise<void> {\r\n await this.browser.close()\r\n }\r\n}\r\n"],"mappings":"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","names":["maxDepth","bbox","win","el","style","result"]}
@@ -0,0 +1,58 @@
1
+ // src/overlay/tint.ts
2
+ import sharp from "sharp";
3
+ async function tintDesignImage(imagePath, mode = "auto") {
4
+ const { data, info } = await sharp(imagePath).ensureAlpha().raw().toBuffer({ resolveWithObject: true });
5
+ const pixels = new Uint8Array(data.buffer);
6
+ const resolvedMode = mode === "auto" ? detectMode(pixels) : mode;
7
+ if (resolvedMode === "magenta") {
8
+ return tintMagenta(pixels, info);
9
+ }
10
+ if (resolvedMode === "difference") {
11
+ return sharp(imagePath).ensureAlpha().png().toBuffer();
12
+ }
13
+ return tintGhost(pixels, info, 0.4);
14
+ }
15
+ function detectMode(pixels) {
16
+ let brightCount = 0;
17
+ const sampleSize = Math.min(pixels.length / 4, 1e3);
18
+ const step = Math.floor(pixels.length / 4 / sampleSize);
19
+ for (let i = 0; i < sampleSize; i++) {
20
+ const idx = i * step * 4;
21
+ const brightness = (pixels[idx] + pixels[idx + 1] + pixels[idx + 2]) / 3;
22
+ if (brightness > 220) brightCount++;
23
+ }
24
+ return brightCount / sampleSize > 0.5 ? "magenta" : "ghost";
25
+ }
26
+ var LIGHT_THRESHOLD = 230;
27
+ var MAGENTA = [220, 40, 160];
28
+ function tintMagenta(pixels, info) {
29
+ for (let i = 0; i < pixels.length; i += 4) {
30
+ const r = pixels[i], g = pixels[i + 1], b = pixels[i + 2];
31
+ const brightness = (r + g + b) / 3;
32
+ if (brightness > LIGHT_THRESHOLD) {
33
+ pixels[i + 3] = 0;
34
+ } else {
35
+ const darkness = 1 - brightness / 255;
36
+ pixels[i] = MAGENTA[0];
37
+ pixels[i + 1] = MAGENTA[1];
38
+ pixels[i + 2] = MAGENTA[2];
39
+ pixels[i + 3] = Math.round(darkness * 200);
40
+ }
41
+ }
42
+ return sharp(Buffer.from(pixels.buffer), {
43
+ raw: { width: info.width, height: info.height, channels: 4 }
44
+ }).png().toBuffer();
45
+ }
46
+ function tintGhost(pixels, info, opacity) {
47
+ for (let i = 0; i < pixels.length; i += 4) {
48
+ pixels[i + 3] = Math.round(pixels[i + 3] * opacity);
49
+ }
50
+ return sharp(Buffer.from(pixels.buffer), {
51
+ raw: { width: info.width, height: info.height, channels: 4 }
52
+ }).png().toBuffer();
53
+ }
54
+
55
+ export {
56
+ tintDesignImage
57
+ };
58
+ //# sourceMappingURL=chunk-SKEIVBOU.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/overlay/tint.ts"],"sourcesContent":["import sharp from 'sharp'\r\n\r\nexport type TintMode = 'magenta' | 'ghost' | 'difference'\r\n\r\n/**\r\n * Process a design image for overlay compositing.\r\n *\r\n * Modes:\r\n * - 'magenta': Tint non-white pixels magenta (best for white/light backgrounds)\r\n * - 'ghost': Reduce opacity uniformly (works on any background color)\r\n * - 'difference': No preprocessing — caller should use 'difference' blend mode\r\n *\r\n * Returns a PNG buffer with alpha channel.\r\n */\r\nexport async function tintDesignImage(\r\n imagePath: string,\r\n mode: TintMode = 'auto' as any,\r\n): Promise<Buffer> {\r\n const { data, info } = await sharp(imagePath)\r\n .ensureAlpha()\r\n .raw()\r\n .toBuffer({ resolveWithObject: true })\r\n\r\n const pixels = new Uint8Array(data.buffer)\r\n\r\n // Auto-detect: check if background is white/light\r\n const resolvedMode = mode === ('auto' as any) ? detectMode(pixels) : mode\r\n\r\n if (resolvedMode === 'magenta') {\r\n return tintMagenta(pixels, info)\r\n }\r\n\r\n if (resolvedMode === 'difference') {\r\n // Return as-is for difference blend\r\n return sharp(imagePath).ensureAlpha().png().toBuffer()\r\n }\r\n\r\n // ghost mode: uniform opacity reduction\r\n return tintGhost(pixels, info, 0.4)\r\n}\r\n\r\nfunction detectMode(pixels: Uint8Array): TintMode {\r\n // Sample corners + edges to detect background color\r\n // If most sampled pixels are bright (>220), use magenta mode\r\n // Otherwise use ghost mode\r\n let brightCount = 0\r\n const sampleSize = Math.min(pixels.length / 4, 1000)\r\n const step = Math.floor(pixels.length / 4 / sampleSize)\r\n\r\n for (let i = 0; i < sampleSize; i++) {\r\n const idx = i * step * 4\r\n const brightness = (pixels[idx] + pixels[idx + 1] + pixels[idx + 2]) / 3\r\n if (brightness > 220) brightCount++\r\n }\r\n\r\n return (brightCount / sampleSize) > 0.5 ? 'magenta' : 'ghost'\r\n}\r\n\r\nconst LIGHT_THRESHOLD = 230\r\nconst MAGENTA: [number, number, number] = [220, 40, 160]\r\n\r\nfunction tintMagenta(\r\n pixels: Uint8Array,\r\n info: { width: number; height: number },\r\n): Promise<Buffer> {\r\n for (let i = 0; i < pixels.length; i += 4) {\r\n const r = pixels[i], g = pixels[i + 1], b = pixels[i + 2]\r\n const brightness = (r + g + b) / 3\r\n\r\n if (brightness > LIGHT_THRESHOLD) {\r\n pixels[i + 3] = 0\r\n } else {\r\n const darkness = 1 - brightness / 255\r\n pixels[i] = MAGENTA[0]\r\n pixels[i + 1] = MAGENTA[1]\r\n pixels[i + 2] = MAGENTA[2]\r\n pixels[i + 3] = Math.round(darkness * 200)\r\n }\r\n }\r\n\r\n return sharp(Buffer.from(pixels.buffer), {\r\n raw: { width: info.width, height: info.height, channels: 4 },\r\n })\r\n .png()\r\n .toBuffer()\r\n}\r\n\r\nfunction tintGhost(\r\n pixels: Uint8Array,\r\n info: { width: number; height: number },\r\n opacity: number,\r\n): Promise<Buffer> {\r\n for (let i = 0; i < pixels.length; i += 4) {\r\n pixels[i + 3] = Math.round(pixels[i + 3] * opacity)\r\n }\r\n\r\n return sharp(Buffer.from(pixels.buffer), {\r\n raw: { width: info.width, height: info.height, channels: 4 },\r\n })\r\n .png()\r\n .toBuffer()\r\n}\r\n"],"mappings":";AAAA,OAAO,WAAW;AAclB,eAAsB,gBACpB,WACA,OAAiB,QACA;AACjB,QAAM,EAAE,MAAM,KAAK,IAAI,MAAM,MAAM,SAAS,EACzC,YAAY,EACZ,IAAI,EACJ,SAAS,EAAE,mBAAmB,KAAK,CAAC;AAEvC,QAAM,SAAS,IAAI,WAAW,KAAK,MAAM;AAGzC,QAAM,eAAe,SAAU,SAAiB,WAAW,MAAM,IAAI;AAErE,MAAI,iBAAiB,WAAW;AAC9B,WAAO,YAAY,QAAQ,IAAI;AAAA,EACjC;AAEA,MAAI,iBAAiB,cAAc;AAEjC,WAAO,MAAM,SAAS,EAAE,YAAY,EAAE,IAAI,EAAE,SAAS;AAAA,EACvD;AAGA,SAAO,UAAU,QAAQ,MAAM,GAAG;AACpC;AAEA,SAAS,WAAW,QAA8B;AAIhD,MAAI,cAAc;AAClB,QAAM,aAAa,KAAK,IAAI,OAAO,SAAS,GAAG,GAAI;AACnD,QAAM,OAAO,KAAK,MAAM,OAAO,SAAS,IAAI,UAAU;AAEtD,WAAS,IAAI,GAAG,IAAI,YAAY,KAAK;AACnC,UAAM,MAAM,IAAI,OAAO;AACvB,UAAM,cAAc,OAAO,GAAG,IAAI,OAAO,MAAM,CAAC,IAAI,OAAO,MAAM,CAAC,KAAK;AACvE,QAAI,aAAa,IAAK;AAAA,EACxB;AAEA,SAAQ,cAAc,aAAc,MAAM,YAAY;AACxD;AAEA,IAAM,kBAAkB;AACxB,IAAM,UAAoC,CAAC,KAAK,IAAI,GAAG;AAEvD,SAAS,YACP,QACA,MACiB;AACjB,WAAS,IAAI,GAAG,IAAI,OAAO,QAAQ,KAAK,GAAG;AACzC,UAAM,IAAI,OAAO,CAAC,GAAG,IAAI,OAAO,IAAI,CAAC,GAAG,IAAI,OAAO,IAAI,CAAC;AACxD,UAAM,cAAc,IAAI,IAAI,KAAK;AAEjC,QAAI,aAAa,iBAAiB;AAChC,aAAO,IAAI,CAAC,IAAI;AAAA,IAClB,OAAO;AACL,YAAM,WAAW,IAAI,aAAa;AAClC,aAAO,CAAC,IAAI,QAAQ,CAAC;AACrB,aAAO,IAAI,CAAC,IAAI,QAAQ,CAAC;AACzB,aAAO,IAAI,CAAC,IAAI,QAAQ,CAAC;AACzB,aAAO,IAAI,CAAC,IAAI,KAAK,MAAM,WAAW,GAAG;AAAA,IAC3C;AAAA,EACF;AAEA,SAAO,MAAM,OAAO,KAAK,OAAO,MAAM,GAAG;AAAA,IACvC,KAAK,EAAE,OAAO,KAAK,OAAO,QAAQ,KAAK,QAAQ,UAAU,EAAE;AAAA,EAC7D,CAAC,EACE,IAAI,EACJ,SAAS;AACd;AAEA,SAAS,UACP,QACA,MACA,SACiB;AACjB,WAAS,IAAI,GAAG,IAAI,OAAO,QAAQ,KAAK,GAAG;AACzC,WAAO,IAAI,CAAC,IAAI,KAAK,MAAM,OAAO,IAAI,CAAC,IAAI,OAAO;AAAA,EACpD;AAEA,SAAO,MAAM,OAAO,KAAK,OAAO,MAAM,GAAG;AAAA,IACvC,KAAK,EAAE,OAAO,KAAK,OAAO,QAAQ,KAAK,QAAQ,UAAU,EAAE;AAAA,EAC7D,CAAC,EACE,IAAI,EACJ,SAAS;AACd;","names":[]}
@@ -0,0 +1,71 @@
1
+ // src/engine/constants.ts
2
+ var RELEVANT_PROPS = [
3
+ "width",
4
+ "height",
5
+ "min-width",
6
+ "min-height",
7
+ "max-width",
8
+ "max-height",
9
+ "padding",
10
+ "padding-top",
11
+ "padding-right",
12
+ "padding-bottom",
13
+ "padding-left",
14
+ "margin",
15
+ "margin-top",
16
+ "margin-right",
17
+ "margin-bottom",
18
+ "margin-left",
19
+ "border",
20
+ "border-width",
21
+ "border-radius",
22
+ "border-color",
23
+ "border-style",
24
+ "font",
25
+ "font-size",
26
+ "font-weight",
27
+ "font-family",
28
+ "line-height",
29
+ "letter-spacing",
30
+ "text-align",
31
+ "color",
32
+ "background-color",
33
+ "background",
34
+ "gap",
35
+ "row-gap",
36
+ "column-gap",
37
+ "display",
38
+ "flex-direction",
39
+ "justify-content",
40
+ "align-items",
41
+ "position",
42
+ "top",
43
+ "right",
44
+ "bottom",
45
+ "left",
46
+ "opacity",
47
+ "overflow",
48
+ "visibility",
49
+ "z-index",
50
+ "box-sizing"
51
+ ];
52
+ var REQUIRED_MEASURE_PROPS = [
53
+ "font",
54
+ "color",
55
+ "background-color",
56
+ "border",
57
+ "padding",
58
+ "margin",
59
+ "display",
60
+ "visibility"
61
+ ];
62
+ var MEASURE_WAIT_TIMEOUT_MS = 5e3;
63
+ var MEASURE_RETRY_INTERVAL_MS = 100;
64
+
65
+ export {
66
+ RELEVANT_PROPS,
67
+ REQUIRED_MEASURE_PROPS,
68
+ MEASURE_WAIT_TIMEOUT_MS,
69
+ MEASURE_RETRY_INTERVAL_MS
70
+ };
71
+ //# sourceMappingURL=chunk-UVKSRKXR.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/engine/constants.ts"],"sourcesContent":["export const RELEVANT_PROPS = [\n 'width', 'height', 'min-width', 'min-height', 'max-width', 'max-height',\n 'padding', 'padding-top', 'padding-right', 'padding-bottom', 'padding-left',\n 'margin', 'margin-top', 'margin-right', 'margin-bottom', 'margin-left',\n 'border', 'border-width', 'border-radius', 'border-color', 'border-style',\n 'font', 'font-size', 'font-weight', 'font-family', 'line-height', 'letter-spacing',\n 'text-align', 'color', 'background-color', 'background',\n 'gap', 'row-gap', 'column-gap',\n 'display', 'flex-direction', 'justify-content', 'align-items',\n 'position', 'top', 'right', 'bottom', 'left',\n 'opacity', 'overflow', 'visibility', 'z-index',\n 'box-sizing',\n]\n\nexport const REQUIRED_MEASURE_PROPS = [\n 'font',\n 'color',\n 'background-color',\n 'border',\n 'padding',\n 'margin',\n 'display',\n 'visibility',\n]\n\nexport const MEASURE_WAIT_TIMEOUT_MS = 5000\nexport const MEASURE_RETRY_INTERVAL_MS = 100\n"],"mappings":";AAAO,IAAM,iBAAiB;AAAA,EAC5B;AAAA,EAAS;AAAA,EAAU;AAAA,EAAa;AAAA,EAAc;AAAA,EAAa;AAAA,EAC3D;AAAA,EAAW;AAAA,EAAe;AAAA,EAAiB;AAAA,EAAkB;AAAA,EAC7D;AAAA,EAAU;AAAA,EAAc;AAAA,EAAgB;AAAA,EAAiB;AAAA,EACzD;AAAA,EAAU;AAAA,EAAgB;AAAA,EAAiB;AAAA,EAAgB;AAAA,EAC3D;AAAA,EAAQ;AAAA,EAAa;AAAA,EAAe;AAAA,EAAe;AAAA,EAAe;AAAA,EAClE;AAAA,EAAc;AAAA,EAAS;AAAA,EAAoB;AAAA,EAC3C;AAAA,EAAO;AAAA,EAAW;AAAA,EAClB;AAAA,EAAW;AAAA,EAAkB;AAAA,EAAmB;AAAA,EAChD;AAAA,EAAY;AAAA,EAAO;AAAA,EAAS;AAAA,EAAU;AAAA,EACtC;AAAA,EAAW;AAAA,EAAY;AAAA,EAAc;AAAA,EACrC;AACF;AAEO,IAAM,yBAAyB;AAAA,EACpC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAEO,IAAM,0BAA0B;AAChC,IAAM,4BAA4B;","names":[]}