openfig-core 0.3.3 → 0.3.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -0
- package/dist/index.cjs +811 -2
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +242 -20
- package/dist/index.d.ts +242 -20
- package/dist/index.js +793 -1
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/parser.ts","../src/utils.ts","../src/encoder.ts","../src/schema.ts","../src/template.ts"],"sourcesContent":["/**\n * Isomorphic .fig binary parser.\n *\n * .fig files are ZIP archives containing:\n * - canvas.fig (binary: prelude + version + kiwi-encoded chunks)\n * - meta.json (optional)\n * - thumbnail.png (optional)\n * - images/ (optional)\n *\n * Parsing flow:\n * 1. Unzip → extract canvas.fig\n * 2. Read 8-byte prelude + 4-byte version\n * 3. Chunk 0: deflateRaw → kiwi binary schema\n * 4. Chunk 1: zstd or deflateRaw → kiwi message (nodeChanges[])\n * 5. Build node maps\n */\n\nimport { unzipSync, inflateSync } from \"fflate\";\nimport { decodeBinarySchema, compileSchema } from \"kiwi-schema\";\nimport { decompress as zstdDecompress } from \"fzstd\";\nimport type { FigDocument, FigNode } from \"./types.js\";\nimport { nodeId } from \"./utils.js\";\n\n/**\n * Parse raw canvas.fig binary data (the blob inside the ZIP).\n * Use this if you extract the ZIP yourself.\n */\nexport function parseFigBinary(data: Uint8Array): FigDocument {\n const view = new DataView(data.buffer, data.byteOffset, data.byteLength);\n\n // Read 8-byte prelude + 4-byte version\n const prelude = String.fromCharCode(...data.subarray(0, 8));\n if (!prelude.startsWith(\"fig-\")) {\n throw new Error(`Unknown prelude: ${prelude}`);\n }\n const version = view.getUint32(8, true);\n\n // Read length-prefixed chunks\n const chunks: Uint8Array[] = [];\n let off = 12;\n while (off < data.byteLength) {\n const len = view.getUint32(off, true);\n off += 4;\n chunks.push(data.subarray(off, off + len));\n off += len;\n }\n\n if (chunks.length < 2) {\n throw new Error(\"Expected at least 2 chunks in .fig binary\");\n }\n\n // Chunk 0: kiwi schema (deflateRaw compressed)\n const schemaData = inflateSync(chunks[0]);\n const schema = decodeBinarySchema(schemaData);\n const compiled = compileSchema(schema);\n\n // Chunk 1: message (zstd or deflateRaw — auto-detect by magic bytes)\n let msgData: Uint8Array;\n const c1 = chunks[1];\n if (c1[0] === 0x28 && c1[1] === 0xb5 && c1[2] === 0x2f && c1[3] === 0xfd) {\n msgData = zstdDecompress(c1);\n } else {\n msgData = inflateSync(c1);\n }\n const message = compiled.decodeMessage(msgData);\n\n // Build maps\n const nodes: FigNode[] = message.nodeChanges;\n const nodeMap = new Map<string, FigNode>();\n const childrenMap = new Map<string, FigNode[]>();\n\n for (const node of nodes) {\n const id = nodeId(node);\n if (id) nodeMap.set(id, node);\n }\n\n for (const node of nodes) {\n if (!node.parentIndex?.guid) continue;\n const pid = `${node.parentIndex.guid.sessionID}:${node.parentIndex.guid.localID}`;\n if (!childrenMap.has(pid)) childrenMap.set(pid, []);\n childrenMap.get(pid)!.push(node);\n }\n\n return {\n header: { prelude: prelude.trim(), version },\n nodes,\n nodeMap,\n childrenMap,\n schema,\n compiledSchema: compiled,\n rawChunks: chunks,\n message,\n images: new Map(),\n };\n}\n\n/**\n * Parse a complete .fig file (ZIP archive).\n * Extracts canvas.fig, meta.json, thumbnail.png, and images/*.\n */\nexport function parseFig(data: Uint8Array): FigDocument {\n // Check ZIP header\n if (data[0] !== 0x50 || data[1] !== 0x4b) {\n throw new Error(\"Not a valid .fig file (missing ZIP header)\");\n }\n\n const unzipped = unzipSync(data);\n\n // Find and parse canvas.fig\n const canvasKey = Object.keys(unzipped).find((k) => k.endsWith(\"canvas.fig\"));\n if (!canvasKey) {\n throw new Error(\"No canvas.fig found in .fig archive\");\n }\n const doc = parseFigBinary(unzipped[canvasKey]);\n\n // Extract meta.json\n const metaKey = Object.keys(unzipped).find((k) => k.endsWith(\"meta.json\"));\n if (metaKey) {\n try {\n doc.meta = JSON.parse(new TextDecoder().decode(unzipped[metaKey]));\n } catch { /* ignore malformed meta */ }\n }\n\n // Extract thumbnail\n const thumbKey = Object.keys(unzipped).find((k) => k.endsWith(\"thumbnail.png\"));\n if (thumbKey) {\n doc.thumbnail = unzipped[thumbKey];\n }\n\n // Extract images\n for (const key of Object.keys(unzipped)) {\n if (key.includes(\"images/\") && key !== \"images/\") {\n const filename = key.split(\"/\").pop()!;\n doc.images.set(filename, unzipped[key]);\n }\n }\n\n return doc;\n}\n","import type { FigNode } from \"./types.js\";\n\n/**\n * Returns the string ID for a node (\"sessionID:localID\"), or null if no guid.\n */\nexport function nodeId(node: FigNode): string | null {\n if (!node?.guid) return null;\n return `${node.guid.sessionID}:${node.guid.localID}`;\n}\n","/**\n * .fig file encoder — the write side of the roundtrip.\n *\n * Encodes a FigDocument back to .fig binary format.\n * Zstd compression of chunk 1 (message) is NOT included — the caller\n * provides pre-compressed bytes. This keeps openfig-core isomorphic\n * (no WASM dependency).\n *\n * Encoding flow:\n * 1. compiledSchema.encodeMessage(message) → kiwi binary\n * 2. encodeBinarySchema(schema) + deflateSync → compressed chunk 0\n * 3. Caller zstd-compresses the message → compressed chunk 1\n * 4. assembleCanvasFig() builds the binary\n * 5. createFigZip() packages into ZIP\n */\n\nimport { deflateSync, zipSync } from \"fflate\";\nimport { encodeBinarySchema } from \"kiwi-schema\";\nimport type { FigDocument } from \"./types.js\";\n\nexport interface EncodedFigParts {\n /** deflateRaw-compressed kiwi schema (ready for chunk 0) */\n schemaCompressed: Uint8Array;\n /** Raw kiwi-encoded message — caller MUST zstd-compress this for chunk 1 */\n messageRaw: Uint8Array;\n /** Original prelude string (e.g., \"fig-kiwi\") */\n prelude: string;\n /** Original version number */\n version: number;\n /** Passthrough chunks (rawChunks[2+]) — included as-is */\n passThrough: Uint8Array[];\n}\n\nexport interface AssembleCanvasFigInput {\n prelude: string;\n version: number;\n schemaCompressed: Uint8Array;\n messageCompressed: Uint8Array;\n passThrough?: Uint8Array[];\n}\n\nexport interface CreateFigZipInput {\n canvasFig: Uint8Array;\n meta?: Record<string, any>;\n thumbnail?: Uint8Array;\n images?: Map<string, Uint8Array>;\n}\n\n/**\n * Encode a FigDocument into parts ready for assembly.\n * The message is returned as raw kiwi bytes — caller must zstd-compress it.\n */\nexport function encodeFigParts(doc: FigDocument): EncodedFigParts {\n if (!doc.compiledSchema || !doc.message) {\n throw new Error(\"FigDocument missing compiledSchema or message — cannot encode\");\n }\n if (!doc.schema) {\n throw new Error(\"FigDocument missing schema — cannot encode\");\n }\n\n // Encode kiwi message\n const messageRaw = new Uint8Array(doc.compiledSchema.encodeMessage(doc.message));\n\n // Encode + deflateRaw-compress kiwi schema\n const schemaRaw = encodeBinarySchema(doc.schema);\n const schemaCompressed = deflateSync(new Uint8Array(schemaRaw));\n\n // Passthrough chunks 2+\n const passThrough = doc.rawChunks.slice(2);\n\n return {\n schemaCompressed,\n messageRaw,\n prelude: doc.header.prelude,\n version: doc.header.version,\n passThrough,\n };\n}\n\n/**\n * Assemble a canvas.fig binary from pre-compressed chunks.\n *\n * Format: [prelude 8B][version uint32 LE][len uint32 LE][chunk0][len][chunk1][len][chunk2+]...\n */\nexport function assembleCanvasFig(input: AssembleCanvasFigInput): Uint8Array {\n const { prelude, version, schemaCompressed, messageCompressed, passThrough = [] } = input;\n\n const chunks = [schemaCompressed, messageCompressed, ...passThrough];\n\n // Calculate total size: 8 (prelude) + 4 (version) + sum(4 + chunk.length)\n const headerSize = 8 + 4;\n const totalSize = chunks.reduce((sz, c) => sz + 4 + c.byteLength, headerSize);\n\n const buf = new Uint8Array(totalSize);\n const view = new DataView(buf.buffer);\n\n // Write prelude (8 bytes, padded with spaces if shorter)\n let off = 0;\n const enc = new TextEncoder();\n const preludeBytes = enc.encode(prelude);\n buf.set(preludeBytes, 0);\n // Pad to 8 bytes if needed\n for (let i = preludeBytes.length; i < 8; i++) {\n buf[i] = 0x20; // space\n }\n off = 8;\n\n // Write version (uint32 LE)\n view.setUint32(off, version, true);\n off += 4;\n\n // Write length-prefixed chunks\n for (const chunk of chunks) {\n view.setUint32(off, chunk.byteLength, true);\n off += 4;\n buf.set(chunk, off);\n off += chunk.byteLength;\n }\n\n return buf;\n}\n\n/**\n * Create a .fig/.deck ZIP archive from canvas.fig + optional metadata.\n * Uses store mode (no compression) via fflate.\n */\nexport function createFigZip(input: CreateFigZipInput): Uint8Array {\n const opts: Record<string, [Uint8Array, { level: 0 }]> = {};\n\n opts[\"canvas.fig\"] = [input.canvasFig, { level: 0 }];\n\n if (input.meta) {\n opts[\"meta.json\"] = [new TextEncoder().encode(JSON.stringify(input.meta)), { level: 0 }];\n }\n\n if (input.thumbnail) {\n opts[\"thumbnail.png\"] = [input.thumbnail, { level: 0 }];\n }\n\n if (input.images) {\n for (const [name, data] of input.images) {\n opts[`images/${name}`] = [data, { level: 0 }];\n }\n }\n\n return zipSync(opts);\n}\n","/** Pre-built empty .fig template — generated by src/utilities/generateTemplate.ts */\n/** @deprecated-backup Figma-derived blob (kept for rollback only):\n * UEsDBBQAAAAAALu8cFyLpHS2wWcAAMFnAAAKAAAAY2FudmFzLmZpZ2ZpZy1raXdpZQAAAJJlAAC0fQuY...\n */\nexport const emptyFigTemplate = \"UEsDBBQAAAAAADoOcVxRM0UEL2YAAC9mAAAKAAAAY2FudmFzLmZpZ2ZpZy1raXdpZQAAAJJlAAC0fQuYZFdV7j6nqrq6p+eVyTskIbzfGMLb17Wqu7q7Zrq7iqrqnkyu17a6q2a6mO6upqp6MpPr1RARMQSEABEBY4wYQoyIiIgYERERERERERURIyIiIiIiIuL9/7X23mefqprI993vzvdN136dtd9rr7X2Wmvfk11q9/vNU+3Gud22MZcfrZSX1+qNQq1h8G+5Mltam1koLM+X6ohGK/VSLYjHUrq0PItwpl6eXy4sIpStN04slhDISWCtXiKsiQTyWv1YubpWKy1WCvwyv1xplOdOrNUXKiuLs2sr1flaYZbfT9rg2mxlmfEpF6+V5mql+gKS9tVnSsulNSRXF9aet1KqnUDidJhYK1UXmbh/tjw3h98DM4vl0nJjrVhD7TOFOtt2MGjb0cpKDf0osWWH6o1aqbDkx+OwjWuPLygvN0q1wkyjvIpOLpb9UCHvSK00U1leLs2gs2NaeOH4bNfWi9y4rpWXZ2qlJbS3sIhc+w1KXCwzg3Y1VupJrZfYvtXwaakmXbi0uHLDDWuFarVWWQUMX/SywtlOHzN4PaeZdUaFjQ2sBCShi7NrlWVpiZHI8Vq5wY+i5W6rXd1s9rFSYjSs0JA6UGipsirB6Hhnp9XZOVXb22KZ5cryDaVahWUqs5JPCLrUvguZBGpmKzMr7CKzZwrLqwVZWvO1ykqV62quVlhiuWyxUlksFZbXKlWMeqNcWeYSW8V4VGpcX5wkrqbFsoCdLC0ulqt1WTcYuQb6LYtyX600v7JYqK1VK4sn5gXINKrCgM1yhH25/Y3S9WzSAczsDBMO1k8sFStc4IfKy6hsWVKxJMozxzhUF9QXCtXS2vFyY2HNfnvETpg08MIZTllxsTJzjFN8vDw7LxvjYsBaYk8vWSrNlgucs4Xy/MIi/jP7sjoAaGcvt8E1DHZtscBKrzheqC+U1xqoGbGHrRZq5UJR2n9lwwauksDaDMYDsatdEbstHy4LF4FrCvV6uY4JXQPkygrzHjG6wEuLshqR+UgPiK2pKZBHLVVmV6TWR2v5eWQg9hiN1SrHEXks9m61slwXqNKIx8nQzFSWkKzQH88RXKsWGtzkT5DsYNCfKAmL5WKtINvpSRKfK0vNT9bMwokSR/0pxdqKYIqnLhWWC/PoHvZweXkeKd/WqBWW63OV2hIi184s1ddq5Rk/d0/DZuQCJ5Drjta5T55eWiqWZrlQsJsalcYJGfRnYB9gH8+Vi1L2mUHvdJNKF591vFSson4En32sdMIt6ue48BoaIwvjuYXl8pIsb9RSwsdhx79d+ibNQOw7iuVlDIDr+HfWN5u77eOdwWajfXagm+zq+vNWCjXZZsl+iLDMliqCw2IMhqx4oF1uNh+drRznksuO2xq5aqFWWFwE/gbaWsKo6UqdSCcvluaYmi8tz6/NFrAIC1L5JOPAgyuyMxmxzd8n4coiMBf3JMajWrqhIstnP0ZitjSHjS1DP1OqE0UcwMovLTL/oEMha3VMrUA75JOWVhYb5aokHsYaWAEWLC9XZYFfsFC6vqA44MjMQmm1JsELq8S3mnxRBd3WIPcpW3ZJdXGF1V9aqGE9u25epjE3FpfXV5aW0Ja1oyvLbvteIWjgYfVqqYRlVlwp2o0quwxHDlZmpaZL5KriVnuntQRcyeZgZ641FjAT81zIOJRrS3LQRrOF2rESQce2k9wMGSJA4LcizjHO4ExlseJjOUEr8s1EHRhcQoIy8cVsBSiJU6SfuOhUgm721StzDWw87eT0QqEGdGFjcsDi1NGVeqB0/QzGSXt+cEFm+1Adx5VH3YelFs7C4gqGqlIvN1jFkWqzs2NXL6oD3mCfee7L0aZNZed9En9lPHBm2CSsVOJ4joZPSxZ9FhtMepbDuXW0zLFYBXriMZUHyuFscBSWK2U9PsrboI/qG82tts4ICJxaqTEjkzFXlnMLa1ha0NC1nCmdPNnesL2YKuMQqIG8KWBT8ZvZWqWaRCNgoBJPOxz3xcUVNjouAhekkzKKjoS8OrG0VGoI4suhd2WZTNfY/PwilgubTyQwI0f1RAXLEqiCLTQrVRyfrHaxclwCaHNDG13HsgKJUKjy+2wSw66szQjGyRHobHuj22sOOt0dfOMOcWKJmj16I6LYY6Vkycbpz+qDc6QOMn52ZysYdCUfCqvsV7zYbpKMaPQ620pGSCVozNpCya63aHlve73dW9npDEC1ZGoFGdtq+frSotCq6CZIK5aMZ7o7/UEvWVd5rDeBh3wdjKUCEXycTGymPgMikOMwB4iza/pFzkak9ER90Ouebhe2Oqc4Eh6YAcLW4zDCOWqDsRaeae5iR7v+yAzLgDksHVukgoFkJzIaLT1vpbzIs0jpa7uSiTiVTs15tO2TJkIaIp9QCWtP49oI4tdxhQfxp3ObB/FncKMH8WdyqwfxZwlNXa7NhLUfLAExkPJbAx7Rzh5iEtDtTGPxhE06HJZawi4gMmAasoOkIzp0R7sdDvMSSFEZ5WJptSRY0I1iXOx2t9rNncpu2y3P7MqyIhvMCT4j/STDvVLkcStr43rBQRmuUJnJhW6vc1N3Z9DcwucWuQcLxSH4+OgKKL+5snQ3+Xq13Rt0gCmYVuGJGnxaxCqvkNaIl7p7/fbMXq/f7WFwcbIVgL6lcK1SB2IoS/nSiRIxhW7XGIS7VFXFhgf3sjKDDcbFgMNKjmTg3TKHY2KJh4JQwlgv4Nc4334xSHSKKILYbt8qkFS3t9Tp9dgSv5ndQR/pokLNOOaW54UYi2eb/U3FgzHYDeljsm0iwZW6y3JVIbPM0WqJv1F9lT9xdZZsWGapypWVLZ3d7fYGwxs0A8IZpxS5I92FxiWAbJZmRC7B44N4sXmuuzeY73VaCiQ7ssuTdsa6hTPJN9XmYNDuYc0QCZSrsv1w7AiCimR+9wbdWrvfuYntcyMlzZEBSvBS0iKhw3p7Oxt2Ocaz5TpJZkF64NGUDo0EH9bbtu+Yylq9YrF1A+ym9BarTdcOOF9QT8szctQ3SiCZLRGcdWAwmIO2H8mRI1RmyR6AwErNjdP2VHN9WsBxcQNGV2kMnP3gcNz5KqAy8pXFe6OjbHEp6T17IOgHM909NKxnv5v4FnBwYaXBZZoNQOUE1NG9/qBz8hyi54VSLcyAUl4tKR+b0Xix1DiuNE+Wcz6z2dlquX7YyoxCjDxEt1T4AddAo4cGkE9OsPhxOXCkZXVdH3JOKGtcL98A6r4C5ChDn0pQbrG8VAWPiRhz/KxUu/0Olw2OQZ4LtnWFIiZ0RblxKXa8xyMFjQGXXpDdaH81Oxx0uzACaMOjEqHIDnACqtXlM+066YlU8jQiCqrJkiClwtGZWawI/ZElxxKwobmVKoj/0prwtmu1leVGWRifCezf2TJJQVla+fAzIH6V/1SKRyki8RyRyoAEXsIlESAXh0hDhJEos8fNoBeHUQy4SlpqCnPoiXylXG60VIFYCzyBzLWENSODrxZI+7JbmmG5opzGhGWasIwalwAkWSp7mAUdL5Tz8hoYPPfZPkRXKypNmEZYx2RB1sV+H1fh0gGtwi3CgxqF/GNVDlMswh1dHtrDK5RJbJCNBPVhB8sA32C5yCfRnArVYmXF52oVz6JlgiR3vmWDND3JckGKP8omquCuU8DySYqDNZkkKaipJMFD2kcRUgrSdJLiIO1PkhQShskleEgHtaGYRO4yC+xQKtHBO5xKVZAXpNI81CNSUxrohWGag3lRmKggLw6TPMRLgITLM1jsMj+Xgt6G+FHXtUjowJ9VQIEnKZeXmn0SxTLjByEhnFkplmc4zwTtIhF4qSAae44pgy+4XX1WluVSKTn9NpU2oWePj+frVStAmZzH8qQkySVM2aI+YZ+GnCRDd8d0OrFxnKho/1DiAnhT4fE3et2trdlOT7HSt3RMYYSVhJdvifWIDdotIMQByZbS9VWc2IqfSUaQFFT2Y34FB1wU9yEIRWUI50201QU9J0HwEVugk6Jsz0yZ6BT+xOv4k2niT1ZJKXx8lpnnmFlDEkonCTey9CZLC6T6oLuLDzYE6kkT7VqMz6K+wGqzZ+KMLyMBpn12wsTBB5ml5qDXOWuiie1rr2WF29c+jXC2r72OudtPY2J2+2lMzG0/jYkT1WYPx0F5p9XGd/GpvU7LtIJWTONUERYLmWeaW3ttgt0Tdutq0CEY1uXmdttEmZPN7c7WOZSP+sLZ4UMAGfQ3ep3dAWIZlkWbO018srfd7nU25jqn9npKSFlhhsE6tfQQZEDuCkGqSX9a321uyJkYfAuhEOggf5pEkDZZ/n8MgDl7NqQgAPNCzKNfA5OCuhaWIvgarBtOfaB494kwyEIlY5e6SFwtgZ8WoofJPkZOBLcNciSS4dauTgTw3XmfahY4FWVYLBfA8pZ9xpHvSpWxCXTv19vbANXZON7unNrkSZ8UguxaeU1bpAwWp7NxHjgzIAnrO+jxZhf1ybYBbsC5Ypu1DLHAAhCZmzGerLFLXYM8WLmqxcUlHKyU2c3bIxIrv9WurD/fS0eyEIx6aa1hxEud5QyLlnHMA3u6IvGwfFTq6ToqNuFhdG4CSYq90ojBH8qpOdduDmQR/m1UhWRBsMF1Ve2+zlQ8U62rWBQz5iaRM2gvNSYgbiQzk6/UZkVkVJirMX9qdlnPtOWVJRFmgveiYH8/iBCO14FZ/T1IpoyHEyQn/D1cKAgfeAEQmdwfgKuWc6au8YtqqyKaupjYjidI/bjIti+dqR/n72VYwCJ9nJmRG4Ur6kpIP2wBkn38XmkJzKsqtWW272pOOH4fDqKBa+Oa2YbITh4xt1hgPx65NF/jzD6qjv2I30eDsWT9j5kD34Pfxy7o7+MWtN7HNzT+hOfp7xOr+vskMsv4ffLiXJHxp1Sq8vvUWkN+v62q319bPbbMcXraInAyfq/DL9v59FpjkfFn4JfxZxaKtVX8PqtQXGX82fhlu5+DKy7Cee4qGoTfby8uHuf8fAd+We478cty31U4tsB+fPfMUREC/I+ZOUEW3zNTlXhhZqXGckXQT4zP4MTg7+ycwqcomu2Zwy/lJ/P4pdxkAdWyvjJ+Cf/ogvYHtc2zPYsLlaNcN2AxhOhbLoM6w2/laPXZzyEaO1p9DuE872j1udfit3a0ei255Pri0SV+18DlEcuvkMfH7yopRu4a/LId1y8dW2L6ieVFoXVvWF45xnr+J3YK2/W93DH4/V+rGHD8fl+13mD6Gn6Z/v21YzXGm7XqAn/XaytFzvtGHRwKflsNbUe7sSxs6UlME+fv1CoEu/jdXNX8zqr2+/mrx2S9nF6tNTi+W/hlO7frdZxOxuzgl/EuftnvXfyyvy/AL+VMPfxSvtTH77PxO8Avx2kPv8/F75l6HeeaMTfil/DO4pfwzuGX8G7CL+H9b/wS3g/gl/D+D34J7wfxS3g/hF/Cuzmq168jwBdGM6vSwlsYIMgfZoAwX8QAgf4IA4T6YgYI9kcZINyXMEDAP8YAId+KgDT1pQwQ8m0MEPLLGCDklzNAyD/OACG/ggFCfiUDhHw7A4T8KgYI+dUISJtfwwAh38EAIf8EA4T8WgYI+ScZIOTXMUDIr2eAkN/AACH/FAOEfCcCTyfkn2aAkO9igJB/hgFCvpsBQv5ZBgj5jQwQ8s8xQMj3MEDIb2KAkO9F4BmE/GYGCPk+Bgj55xkg5PsZIORfYICQ38IAIf8iA4T8VgYI+ZcYIOS3IfBMQv5lBgj57QwQ8q8wQMjvYICQf5UBQn4nA4T8awwQ8rsYIORfZ4CQH0DgWYT8GwwQ8rsZIOTfZICQ38MAIf8WA4T8XgYI+bcZIOT3MUDIv8MAIb8fgWcT8u8yQMgfYICQf48BQv4gA4T8+wwQ8ocYIOQ/YICQP8wAIf8hA4T8EQSeQ8h/xAAhf5QBQv5jBgj5YwwQ8p8wQMgfZ4CQ/5QBQv4EA4T8ZwwQ8p8jICjqLxgg5E8yQMh/yQAhf4oBQv4rBgj50wwQ8l8zQMgPMkDIf8MAIX8mGhYJgvwckFR4lokcGRqTUF9q7u6SEIzik73uNknXQRd/4+JWd91E0fq5QbtvMpGKJEFDQ29hk/EdUq2gUVvNQVPK5k1mtdNqd00cuzL9p6/0tlio2uwP2vXuXm8DIOJ+D5SrULgRgtRlYIVIgsBBKPZC6/kQTZlocsCGg17ubzZb3Rv7bPMmSDKIYTZBP4Mib7UHzc4WifI2+tsnIQLK/AzENG0IIkmeD9rbIsnWrPyZzjqYfjRjCgw1x0Wrteo7Jt73/7fKDWGj0LcpM7XeI8wdqotMmX3SGBM/VibpsGVRwKvEXVLqA3I+mTOdfmcdAxeZLH7s1eZBk+uDw+mbrWgCsHf6J7u9bbNr8h2ZsTsiMymhxibYkB02HUlTzR0kgpvTaUXKYU0B6QzKHlObNxfIZ8mN3RGzT1M2u3tbLZmopeYOP4/MJb0u6Ftloqb7/ASB/SdHpvQNkTmwmww7sKM52N7uPr9DgraKuwmMcT46dEYW0msjcwT3CKc6O2AdWfPxTmuwiZZdmEpdUCo9by6yQ2UZu8eGXN7F0nQbebgMGCM70aUDjssCVmwR13zAO9PmMp+ERXx5X5YtV2mZnN0Vfcs5TZmH7aq02/FSm+YxNqWB5S2E+Rsjc+UZe5sh0sNtig7vicxVm/6GJJV+tbCP1zS3BhR7ozGP2Ol2+grs7sg8stWmxIqr4VGSIZLSTfPoZV8KTCyvsRuWgscdF7Qs9EZxdsUFsSPTDeXVqOgmWI4vEAxAKC/3+2kRQSrVgUu6ArmBU39LpMoqlBP2awm7aBaow8S50+1z5oyJTiJ1sbPjphP7jimznVNtrJsM+GPPtN2C9c+YZc9yuFB0DKAswTjThFpWo3mKggcGhcMGGnKIT26atPYLNzabItfo9YmPfExqKs9yNcbCj1cwjZBdtxtN7sB70aAtNLZv7s5F+7fk/gO3VpR3oNLJk82trXXIjdmuvjkT7dvuOLmx794F+pWdwOw6Vp9CfHsU5U5tndvd7OOQjSZa/sa3jyM2yq9DlHL6BXtd4uV3RdFhjoQfzXujaGoT89kDqNPF7lmUeWsUTQ/89QnY0J4VVuTMAZvebvlWHdzqnuJilSKN7owbj8rJk/32AIeFmYoOcYYBS+G/LYqOtCARONNucfr65o256MJZTUjG2Y6R7W2U6m2c9BbYNdVb4LlUb3PDvZ0Y7W3+PL2dHO3t1LfQ233DvZ0e7u3+haANJp5Yx21Bq2+eDzmPHn9WKJTZ2Maq7J1qD8z7sWi74KDLO8vtG7GkgEKTnoDby0FW7qvFHklA9pMuQZaGQ8CFMx1gtC1UhN1hm3wMOytvckRsHGwTT3qxFObgRsGm2GfMO8FtwYAfmyxjhf4GdzNOMWzsbq8dahTgODvZ6fUHftRYFxoUxifmObUmntrobkNg0upbUiGRjyFT9pfIBnWTc42g/lHgzdYZe5BOjB4aeUlSLROM8AewDYNDaSrQt4hjykExmqBQfNUkeOxKAwJxOLuIMwKDLslLzR4m2M5D2GgVWuo6x5eMLLcHN3ZR3PYWQ7eNubkJ0lPdAOfDKdwwwKWbsnDRUGA1KzLEqX5js8fZFbKNhUwccWX1TSuK6ue217tbtg19iaBxKK5hV1OftcQQP5JIkKN9DqMLQgOz78A6ijCOrSiTVb0H9dpNXey1m6d3OexaXdQNgYtu6nx7x2oP2Bali+Defg6La56EKYbk3I4cn6ih1Tl5srKzda6GuQSyltIZW215e3tvwIES+kThxmm4iFgMHB/tnx3bOgvsfNmFPvZ9ucWdH0dY+b0OMj4a+YwSks6h3iaj3F44MyQM2uDj6IAUq7VBtsU81pDr2gQ0YGGYOO+kxPIpi38M32JnDzAm3b1dlPlEZDK6xFpgE0zWTmkLHAKITR51GAlEPwXE4aJY9kh5MMLlQggq9kLpVHV6wp0/21V4nnw5btmG2f+uhFt7/z0sduC84ECDQh36/ECgVbCLUwOzq+NwnmLH2+u7QBHnL9DYbG8/RK+IcxZJ0ffOnR8GC5HFeegSM91ttJiXB+cv1tw50+xb4jPOuDLhahhdN3Ii1Jo7pMyZm5wXWNJ6XpTObmztcazshcxWc12w45k2MVBld/QCZ0OvwP0VzvAXSkXGuEFVqaqZhZaz3rCPlIYqUmd3t92q7Nb2dqhqS0IrVoSPPnw1MhGO6sX2zikh9+NdvWIBpvsqSIRem9RDqwIVJZvEi6D/pgbItnGMCnP1NYKX0fkKRk9CytIU22VeeZMr2qm1uXHJ2uDWSAi3Ijnh8k5xD0qJPX6atQ3RkUZCbsywoHocu5g1dirVD2XH0ZiMb0z2v21MzjYG6GRidBzywy2aTLWougV8K2xFnN3sgAfqnavs9mX88f3XgeXSqRyzb6ChNpVjunPKkrF2GICeQTKjtn6jW8CA77TMN8fOR3vLXj3GuR1l+KOTnfZWi9ML6gSZQbMzGxioQWEw10NlpGcGAOHIa/Qzl+x1nWxgMnv/A+QKWlsZRZ6arIOoncS/Ihm5/OEpDEYw4xIDxgPJWZ9Mlr7n+DvkeNSLW7/mKSiNbAaZE1Ymkp/bwhHq9JBw+8zt4NTNoUEwU6qqgmuMi6L5ZWsKkKG9wEpR1T9Ax4FhByKq9sjax5MDRtwQ8FgZxvkxx8ji9D6OjAj0oCivWj59DyzJOZ2GttCInX6x2wMpe74Cuf7eOi8f10HGs3KLkib6G4g1E2Yn3+nb477dwoRtz0K7C6pAWHxJL9Ln6W0x6JUwz52q0kl05/PYKxLW3r8kxnEEOpCkAvEeWtLGRqIsaQoihrY9hwOqJ7anrvDwuDol3gxImz7kh2AtrGgrt6XonPRPo1u3vUYxuce+HTwGiFdF1FpTfm/n5BYZXmoVhSAnO/0VlyVjOKXN9oh+iXIwRykOQY1299a3Ov1NWzGb2+g22s1te9pIa1BJPFwJ8D2QPIbDHbQ4/dHthOgiqMrJ+o1oKbGJFiZFB6SeakKanBoPd/W6bwmy3PdbGkJmZAg06u1hwbiD0q4ANMgfnF8ElOFi2Al+Fd2BVVTc2uv5oyd1kS03pbjxFGWx9i4uKW0pr8hhvMZ7RO1nm+01n6FzBmXhFIQKtwvlF5XacejsayHIQ9QcRJXV1SAskxiEXS96jXJlqiVM/ETB/BeZqCtsJtgBHAGtzh7lgNlExpcLZXwT/V2Q3S1yYrhNvhHrCtLJYhurpSUCVGw3hWFFXGC4EuHXPv3YxqbP2sB+Jyk7IIc79vLBXjJUb4jNIQpPzN2xOUyFBUm9MzYXCNowd8XmyHoy/q+LzYVCayjvjE5dhNb7yJWSV3PdvNiLN/vgy3ZaWN+qFnLSXBbKtS7pt7HG8+aqja3OLjYnbXPQ10sTMdjlKfnYFYm09GG99kmro+Crvbq/297Y22r2CjunRET5cJdAbTcH8pp1nLdblg19xMYmkBoOso0ClDgsBzllHgno9kibxfFo2dJHJXWGAB893BQ77o9JNceJLUeaZDMeN6YlNuvx/V3IV2zkCWMaYbOeKBpv5P2wrDo4HHte+GftIkxgFxHVj5VoDhCPfEU5OT+8Jw4WcZwsXeA2XVCgkcIFlXMLaiJcUHm/oCb7p9s3Xk92nQHKJPYlOnrlnZO8XJCKv9dErT0/GTHOiUGXGbPtM50NK9H0Ok5ewyFQAJY0SDetfgSYTH5YcwKDwFpi5via3NFEQ5WAiJKm3I8xEH1mjAC2mbB4FL/IOOHs8UKIt8TQFQMWxEw5LRVt6GRi9ABNN6cWFzGc6M8y5pTjMqr95krCplOivnDOJnibMrXYQihvG1CEcPIUWAayA17NM+w1FVGh66EKn1S688YYwwA89tUvRVMaVohqlTRanFQiaCc5vWPKSAMo78BQJkkOIcTLTdyuyBhammq5sApVEGEuTGJWFdWPi/5JzF+vxwoTFFEAVB1odysGyJhOEg+0BElMZ029Ni+6QtBZqALsWvXpa6u8fYtnlk6Iiq5CANmFiyKc+vH+PihhqIzhANdrFjbxGQb6aP7m7RXk5c+c4rGvul5g58+cwtUbEfd7sCsQq+wNKG8T6hxEliXz+xSGIJ5HibkuriHUiANkBHSngfIhSCms97tbe4O2lUyB5hDU6nr3QGz2vQCknSKiaXxQ7GzsrUMBrLm9u0WtNLPfdml13jYJXNzc2nIJxoJyxhUWjxdOiG52oudv4gOy+J+jAnYDCi3Y/Tt723XFjX1KMi2GwC0ZkL2IZRW1TpzaE/JaY3l3JEzaSxTz7WYqgOTOMoXmzrIAojvVEqjueJsH+Uepnm2qQ1lAHE4yq+K0zI2B3fWkkEeh0DKU+Qmlbe2g3NK35ms0kKgcE/reWsFmSrDpE52YLHRgoGKnRmei1TNR7O31NysgaXAXZHfheAJDCtrdFtjOwbiDxnayaM+BA8HUyiJJlmjmZK/9gj0QzFwCEPue0rMv7m93uyCzRfERskAZtaFPc6coAw8/Ao/Gw+loh8X5ZSBkzRIP+hwYGYCL24AsMw0zws2X7+wHMR1O/CNcm8hzgVsDrUyIRKwUOgb9aIOZfvsUxdygFLHELHvASQm4A50wS16nWQLHULBAiioPP4FlUaJQiG8SZsNqxYIAA24Sqx9FM0I5qnnb8YUS0OdCGc4YKnMwwWE2dXOd0TKWCW3ebY5Y6xd6G74VoJYwXI5OoeAmiMYdGBj0PFmTUUIbTOxpfLvX67DxrY4QBe7uy0btrWKmurWHG1Rb265EsByFsaTAGR+o/NIWrLW3mrg82dQPsuEH2/bqHJ/Y/cLPOv1ZsJKW1Vza2xp0WHu7N0eG3DGPMb4QqRIFTKG0ibaGtKAgY8p7dSoBOo1ENbrg6Sh62Vb53uuDZ92hl/PH4QS/gRFCoOmcL1kj3cASZMpXWtppiXwbPcW4S1BEcCJQD28ugPDZus/G2AYYIRGyJNkQg1iAoj3d3bJrO9E4xi2M4CSA8mVVXOIO5KXy7CyUw9F+f5+aJOl9qjM36fLaivyHJboDLc6iasdHRZiVC0WXqm2p47qLTaUVfyGFJREK4H4RvfXfU3DiLFFLi0VYwwraAn4qOEsuqAGqW4ugVsViniwRxWHsC9ED3tmxGIXcP+5hzmnpR1j0StiKXiNnxhZ7YzEYNi576zYaVSUWZTlYIPksUETXJ1l5BelzYbpdo7ExOUSxUp/yCHyfuFRwitXTEhMpTnp97Z9DaG2usFQWbdkDErV6owclctxVfkjMbnxbDkNqStMaGhWpXvAFokkdJBzRhGph1tq+XagJ1uDnIo2FsqWLK/xYtE8vCR1EXKrtsr25jEcS3UuszQshdbnEQcqtLC3bpCt8kRloAxPEw8JCLvFKXwwuFzAw0EaeLZEnviosPZR3tf8IXSVR/vCwsE27ZnR54EQRWuSrWLNJ7gzkUacgtawKSS623XYzzNDzQblYXtQBwaZYAD0p5Gps7SGFI6BlbKVqRzCb1qfOjVak5KqZPAEXEWqhDptCdRMDczVZ/9XystCQqA2zLJT7otj052ChKGanEFuoM4Ex8KE/AwUtZ8XwDfR2Q5I8nQyRa5v3zZnRj/GZvczT4fg6CDb92nwT23nkAwpYYidFI3buQKmpb27G5WFSFujRVQm4Mhn87mtxpE2BqAiN4Y07myDaM9nk66V2k8pTPMOJXOsk0UzW2vt6dB5ZBB973mcsBEgCtX9UYnMaZYOuDYEA0lSp5MUZCJS7oH81CkGLnKaK3XjQEY2TPAWt65LnOmdxlIFIVZiQhIkMWC9GJ0FfKeU+DatgldYtQd5lGdbuVstJ+EhoUI5lxW1B2QWVsUPmjymOh3SOQIgw7sWI9nPwoe0tDrs0WhQScP5nKV/HZ6gvoVd4x3/akgK85j+tinlZkFxQR5BziVw9LqpdlaVWB9dG7EB20MEZPwC/UO53n/MsaPQCNBiJnlSCqe4PWLjdKpDjz2xA1OQiWWY4dD85C6PNebGoOw5zvVKxojRuJKZiQgBhz63RRLsiTqbgDKsh6fC+QXdFYlq1CH8YOFzsPpyYK88vFeQ0yJMrsuKMwmJ1garTNOly7hTEP4b1AGMvE21pz7qK2xNvmylqVC4W2yOZN6uguZKPinAqoKcw8CpvvGSnp0rrMEJLTz59XQbSUYzZyi5UJ9sQPZ5tuPEl5UMKlxY/SnJm/DhnsXPP2NoBIlfcu+km8NI93pPXSN7j6kzqwSWQxmQJ2Ag8PPgJc0l2vgC2077RFYAWVIQJH4h6Jq5qoA2Bqya5k0Q/bEVQOMiPqZ+0vQXeN3fiNj0sY7eNDJ6XzOB8BoNTFilTpO61LKWg3tGQCzNt+lMSGm8sOO11ZmOvx8s1W8XdGOQbm30gf5Dne/2tc/qdkKMxpNW22WfAmGAY7OaDEgkIm1a7BHMtyEVk0lSDh3qqVpXVjU1GlASpT6lKiMpW4FalqmJ8qnpg8IBd2FSosfBuK74/665w+asqas/cFV9gtERjQBOfZe8K5eIW92xBVAs8W868fUBl+NWk59j7pxx/Nem5vj2iYhJB/Tu9wN4NzJBGWLdmzM1hohuc2zLRT1qm4DeFE7LqDH0oSJv/Cnjjp9mgtqDd6QPjbSmNGEEvvtO3DKFN+RmkuBsG/vobPeR9TcHKPv1ADPV4ieKGKejBbwYqFj8veAkqLeCVksuyH88MMXLvibvPh1SxvgfciZ0KLpVzJKyJ+URs/gxC6TNL3e4OpCaLsMkTpgfpn8TVS717Ej5YhLNxjXwrOrDc3dH9bIf5l6g/PIa/BJT7w6yEWf14DB39zs4m9FOoHKsDJhzHnS45GDfJuNtl+CGT5De5ZCvX8Rn3+gy5iEgy3uwyKNpJku8b0x5IobQZyP81qz7VQiKLUFHlQ3YhME0Lupw/CHLksETah4M0ezuC1D8MUkXYhLSPBLJCUZXuw44i+q3xLUykjWjle2XFORUJzM1fU4fORh0NKWpWcr8D7JqLvujmaOi+8eWxuQnQJDW9r/53+EF4J/gDYUayJn9Qk8fdDL4ihuazXmamV/orYDc6/uLxjVQP28BhMj77M+5u0ardf9wSFJb+UBLhpRlbSOb+T4fvBj+BYZy5Dj39Mwes7fn4acyQqmQPkSjfSKBwpGfbJ/vmk9noVkoKkmSMb998PBu9VO/oNbGOW5C+eUMu+hurziZj897IvCCJKobhrFGnK1CBwxXj/4FypihP6OWM+hwp7XC6eAjc6u4wIasPril/PN1goDir0Iwr9Wx0GwT8uJAu9NrFvXUL6Jf8zaZeu94eR1/zSmXuxvTVcfR1wfiOZOy6iHZh132wSJIOAq3fircTCuW1GRDpWHZbXcqG/xCyFQadH4rI/FOoNnmxCyvkMg4OVVTg2SGSs0uGkrTgUZ/qNBqmzKXDaVr0GFUNht38PNFcMyZZP2j4HO/Z58nmESOJWniF6eJy6xLzSBfWrFVGA0XOy8yj0ila7Higxzowj09imv29HCGhhc+YJ7iwZv0vAccVdH9knugimvd9dpl5nea3RObvREfdmTZD+tXdWeRVBbgSiuJ/KJWL6To7gCg+LHGzqL3bIrhI5FmEfmBThqVeGJbS85jjFRa5JSwCREbrCCT/cJhcB9mJXXtDu9dF1ovCrLRB+VmY5Y1munVxE2z1xnzqLpF+ABZ8Yb9p8P2DMOYL0vxRfHME4z4cpoGSzQAmb1LU45YPokSidXyleS/si3aAa05VIZHEgAqkyPyRS17EACH+x7HTwhcdZA7SPdnt5llV286ZvwIhfD4tor55URz9jJOGJVT3p3ldPUTYvyFj/kaUb0hA6w1Johzz+xFzcBDDSBzExFDubZlBl3J16nA1rCF1HxaM0R/ACEszoA+byvlw5NXEzfvQCYhfRdXbfDBnPpasRr17uS+KXiRNK3ZanaTan5C0wKXSd5vX0mZrodmCabC9gnpjPKJP/aOZvmrtWMLX0rwvCeySJmxQt8y3U6VasGReQ5r8HYzITdNtkXlbJrmyn7RBLfadof7DlI9o5nfZK9dp/mrS/witn/b7iGZ+TwuNdd6ppqIDQVQLFLbBPqKlh/mrSbPuagO3M1hYqO3eDHPLfXtbh+JHUgn63ZyAIOa+I2N+IyBcKr6nF44k6qfzwGShZP+iMK5FFnCtCLLKGr9MwSApiGuRZU1Sn0yPNFcFUS3wPE2hH71HQynCRTSz5uNypAzMP+M6wvuOeyytp1xMP6iDG9hKiLLHJlHNv0E/SEo8LkzQMv+zLeQf7Cni6Ek2rDlrozfC1w0laUFcw25tzbe7223qEr0/jp4eJmiZU1pzWOoZ6SQtt5k+V0heJs1/fSadWz/d2S1jP0bABYIIcKxyh7atwHxgfmroi8ZmZ+O0WP4NzE8PQxO24gpzV8YvYad2Ad2pOPpdcOwboGmAHhrd3cX2SRwtqTXzSjDhSYEal8VQiduTEsXuAELAMVBeNVxmHKBXJ4WSnA7JCqqCKnXymuEyDTgYTBe5Q8SH4FWItbzJqiCOn4hwEwYRVYFaMdAfQhHzhrx5EwUjI1fft8TQOcXYo9sLQtkh7adtmnbCJ99lk9lzn/gzNlG66lPvtqlYj+C+sFu57+9JqvI78U2pqnzyvUFVPvHNYVU+9T6bqpyTJuOUCcfq5+PEcjCw7r3GXDkuXVdzFTSwxbizhtpKGtHM50s8IfpOh3EtsiVJ1WaLpzCKbIdxLUIye8g53YI5K4nOzdxRc07imjsHsYFEE2IxqeCPNMsRhknGRzVD9XursL9WEDp+VeinastAKICEAvriV1W4JgmTpX4KWvto0mc1K2y4Zs2Zv7NZdG9nPwXPSO9Dn7PwtFkyhUj9+1SqLgIkfz4AI/ChY3sSg/MFWzxwUFczL6O+/sZpq/B9g/UqZH5ck8VLXcP8tsZsm5OZe18M1WfB2dghv4PLybMu8v7UFyk3dqvmTyFuppIlhD3U72Y7US80nEAlRXdkToEvqdES+t6s+WWJAefubYO8QMLbXfa86An8SpCvKe9wBQq4PQbybplfDcr4xHe6YugNSZRfCwrZpHeFddupvT9r/tw3MEn7Cy3KnrglpItu0XwyyUoWnsv8S8kM3BMum5/PCngo+3VvTLjH+yHng2MfnBpgHYpdtcv6RCwIW2bTXxe/lKhN1cbEpstn3JZkJOIKd8C9LEpACZF5XwyvE0maEBffC/8TSdJsog73+ggXI87F2ffB5jopJbdhPZjIiPoCGv0rYHhTzgqvhxlmkkT/hNNw8eDbanXf3hrDOlMuDQIPgTfAz0PQRki1Qe2iPQ+EJZeIlhx2/40wJ+jBuymlhP6DxEFdqRIZPnhPUIHaSdSxLwcFtWYnd5w0NdBs65u35KIHo654TNLCLvW+THqCyFfIZfi7c+bfI1V0EHbv03H0IRtPaUM8GEd/4UaMMi8a7n0uNl9O0qBOwJR/SVKSW/MvxzB4SH+tVNm/pr7XtK8maaFGQd98Po7+M8krtm8CsTBS4q9oyTLm1v9Lsfmv5GOZya/E5l+pwaZJjnPImddkm/72DTxSJvrneDu5hIOmfia6OZMUCS4Tb8mY38lA5jXkWn+/+WeK2nbbZJ686em/eSGxEF3WZg+ze3vWMuFjjAE/GMH05LzZrg+fic1HY95yDZkofiAyX4qeb60CPxSZf4AlcspS8MOR+QLVcgBUZVv/iOFstcVqdJFKUdSBuT1nfhjjZpPFvMG8Omd+Sa7c5DKifaNA+0gO+uvSccuGCRP/OsdeWuTc9zTI66FeB5cIsOA5R9rXvCgLvVO5M9LG5cwvuG/1wluwxofyWF/QuxmItSdrgwSuA81bjsSn8+YnofDG+z9aYDrHfi/PmlfGSbL1r5yHXEsT7WTATALaXc798m1Z8yqbP9OEfUgLiB0bGDmvyED4pTnlnd29gdeYenHO/JTNIEEI/SCM6Z02ZYHyMN0gt2bNz0L4pReVdeDy01bi+nMYPyIAjJFtBrQltZh8jiKfs+BoME4/JeYlOfNim1Y6Iyv2RbnoR22KkwXD8HpPaYBX5KIfCxvPZeufXnl5zrwygxWjNioYtr/PyOrAUeTOdHAzOCJjSdaDK5XzK5qDD3Tlw8I9Cx3YoLjQOZL8q5q81AYx3Jppb8E29q6seV3W40/gdDLnWDknO6Jqyib9CxTF0vmwW8IYdnCkqhALhb4SQ2ps7ZVeHJvbIV+UG7BWG2SPRY0YzM8q9w+5LM693rJY5E+bH6E0EvwP7D8EPlcxrsbUhBJ2PP8RW5kBUqTCN0ya/wzSaBl0a4w7eU2C5xReZSd35D+mGdaF4p2T5tfDhHqbEkqus2nzgUyrQ2HltnXISNn/P+B2miKXGhQdEf28jQZXQV+AYpx8pbIZan7KQHwkCz2nNEChxT6aNf+U/qTaBCvSMh/LApHitg1oYLbDzcoF+A0df8jiStBklYsPyKbuyJn/0IMPGRwUl/HanHlh3BQP2XKVB+coSUzp7GLC+ibkyKGRRC08Qw814gQoVCa+YDRVi5e2cWOJswk/NKxIYpq9pFIjVGXdn4RxLcKDWsitFGfymNFULX5CW+JVQ98dR09JJ2k5rIiU5/DvNE9Np2ixdZ1dXhn1ISWMvi2Ia4kNGEZwzfVPQ9bqRq8/kqiFgd8EdncO4xEZSuBcVAucWR92lf948+jhNC16PWSTLWxf8RHP4bvWPHkoSQt+v7Oc2CcBTfxuqoOWqaQiJvsY+8vSKVpssWn1Rz8Zw1OWOiKQ+AORuTaJauGWJvh2JuLBN4tAIvFC8G5ccWZ0WhJKNRi/G3mXAWTwvji61S9ru9ZeHkGknXI9+/1whKZCrbqoH+tausuW8/ZC90Rao/iM70M33Yolf9EWHPZHuw7PHOpcSdJUOPjL0ICB3o5Q+9jCbl9Ow+mIQvGn0Z/H8C4yco+UltfmcJW2kzZFeFcMB2Q8bIZtOt4WwyGZzXAqRYFm6O+6vPF2GG+PQY+MlAgsJ94Zw6mZuzMiomzB8Ri7T8K6h3ttDp29dxfRH1kLjjmpjE+mWF7PJP9lAoA344RwHgCfiqAGAGH8qVMYzPfm4JDsTBdMgZyo1U24t+Id499EbClpAK6kYhskCKgPyPrZwVb0D/aGkzpLffOpOPpHkZRTdi9L9s6c+SdMCBq6WcH9J40JMae0L/X2u5H5Eegp9AcJA/wSyKxxcCkNl8NtLe4lNpfaQNeS9I4J3K1iHWCe1etEQPO8Ju53cPZATuFuDKvNnTZOWQj14qY86ka59kJjaZH75848zHkoaK9ht5u78uYXJVYYwDZxHSIp+LXJm78NPly0inJvxRnhZH1QuBDvW5H5vDdElobCZuFt3l6ZSHNvW+6AeVjeDi7c51GKU4TRrriqeW0W1h6BXTAz++ZzE9E7w1Qcy7AW/jWfBATa3eK1lqznCSzpsClyLw7uYcL8uk9vYD3sWF2yTyWgN0A99c0XJ6K/pr0+ssX113Dbf0OoZgz+oHnWvCEL1WlRirO+4V6HaymoulgrmldnzMus6FlsH2jGgZX+bptWp2ngIfOgH7vEfqCPu5DoNzOtsfYQH47NezLwUTbG3uEjsfktQh9jtvDR2LzXfaWWGE462ze70ecy694640OxeR86AS6H91WQvtyZ1QZb5AYxH7w9yakZOr4QK+5/d7fJIPu9hw3x8vGRzNA3SH7RJBQ5cS0PTKbYtXQWR3rLEsgvhGlGV6+DPNNyS8YqTODy3sPpg7YzP5LleQRNb73a4nS9K2/+PsZkAKLDXUx+d9b8rk12hDWT35eFis52B4RRcGd2d978XlprBg37YIwtqRzK7Rnz++q62xks3Zs3fwIlOG58h4rVz8XH4w3i8ZreBSYHyv15YG+atyJVabRp8xdxq7uBe0leuwaw78ubvwTsUa1J0O+Z6EElSwtCLAtxCv0IHbbPSItliUuzH8ibfwS/lfIS/aIIGsguzbqFfnFk/g2IQUlvjKka2eu1uwzFq0A+pxyX8M7WsZ5DjnbeH5mvIOtkE9YUw85OWugAiE+VUibfcbAh35DU5BOvV/p7mW1aZlBJcx77XNI+jJXsPl9KPCn8K8AncMs7cxhfIsdbYeEZNCUh5TJg/dbt8do3D+axm50WK7gEsHpBdMRdRODr4Y4slkeSq4hCYNwcmwdQxVaXdGI37ZflCxCUZ4DQh6zHXxubPxYExGjKt8qXI/MxMj60Q5cuuo/Qxy8npvoVimis7pAuja+Oz0zIqX8LOppSuPna2AwqYP5wlizFEvgsTacA5a2Z6DZcX7skqJsnzmOmzYuzCTNs5QxgKgjhWGcwQ41cvSR/CQSXNhWxN2FsfXk/dZDtvUoySmfFRhBiskz0MvF2ydHkGRz4t4GZ/v0ypKptZs+Ft0iSb2Naj+lnHfobdoLzpcj8AiaBIsJUFpr6d3pupJypvwTkIN2PgL8XEySgm8notyWFn2Jhcgq07H2T5m8zzQ70MAeNTbGkf+ek+ZK2MoBgt3uqMnMfkFQqpYyFgx3t1Zw/jUazwZ6chDZChpwb5gB0lnDFf0LPqcV2GyhUsYBydUQCH9dmqN50yoXGn47PSdbsX2OR05uRrHTsuknzZ/JJ4Bv+VpypMp2cMNE/gjKXyq5sc1XhJWM+Jal2faHpkJKicz+KJSOO1nSZUASFqatAuMftw8sJXSxeafYeiHzwjSTI2qbdF+/RstsQCUubpkGswLPfOn2KQK00C8d46nkEY/fejPlZesoboh0+kjFvZHINJJ1X12DGxzPmQ7gSpZk5zvPgwHi9NT4HGbLtNUylr5/KgPRIf5LKfzBjfs7np3I+nTE/lW0KxmyL4wVV7BXVURVJ0BXda7DSWEQODEf5vTYj/o1me02chYT1MWhiBGnYkqUtkaOqpmgeSswbXT2oyEBL6i1Z83M21clKlMObNH+QWR+nkn0XEHE2zBnSnH5jxrwyu7m3ztXhyFdu089nMJE4zLC6QCWTQZWKvpAx7w9UnwnhgxPmo9xash5w1GLOzIcmzBcdwZKs1n8R2s6SBtMQgW13hWPyehufmTAvFXMD3p57fumA+XoGHIew6eoP7ysT5j9AyWB2drtkrizX9d5J8+84ESj9XhDmGkzppPlGRq9DpP23YtCzDljCuL8fUqnMcMWqdjxpvsntDf8TvCHO0hGFHJT/5cv7i4tD5mbfekvsHTAv9EkBz/zTMKFUUa5KOT84ian15byQFgdnFtdsLiNUR/x81rwZ0nh7laFCX4jZ8+bHsskVSeL27+V5cDk4VRbbp5ob54YuTe6S9yQ8vovzoiBL/DrRGUJ1efHeK2oQgeeHlHNPWPxwJdhYDvQWmMMqGPEtvb6HWUiILK0XWKu7HnXAhVLPnjJ6TgDPQ29DRA375m6gygSXW/6cgt1MW0P2EBJvMqljKcY1Q3Cu0nQsOFLVYmKm2z3dwZ0chSvqLOvIukQWcGqI9AA+Chinuh48akH7zel3sYbhPKBml5fBYu1snHMIIUvucNf5+c1hLex0b8TyAPejSRO6/WwMdh2C0zU2iasZnllQWLGGRz4hfdjuA4ytcyBJxRsUEqZ9QrrgfhyYVs/ZFT0QJKULH8QCOg1eHmIrLXrIJ6QLHu43z3gUeAHwCIUGLn4kHOvEQHwaJ6PdJ4k6rjqIgB+vs4mT4XdlTEav8yX6AA27tIbrU4VyNvVEqiy8ZUuqJzOkindmsMZlntTgY5JiCWipmSk7e9S8a5l94uCIa2o67EQaFh9246u16od51r6qM67WsCSeSlarXoINOoIHWs7/kKaWDjr4kE9nptiHZOAvdsYtQ0YiMT16U6dcHFZg0F28Az4gcdjqUptng9RcUlbFaY6jgCMxVzydkd/CkcqRPwn8AGxg1Qyn+t2NjnP5rUn7TnW7UCsquAUtBunT4jK4DlHZhig4n1XfovudsWQLysBNCn4g2sQSTyfzqharO0ksdltwfKdlD6WTtexh20q51L8gaKMkHIEySPEcRBx9ZTMjc6E60q21W3uQPy3JAYhkKPolqwhqFebiYI6C0cfcleasfal71jPCq+uefIpJTCUSAW8ISDKIfD+YfognMKVCMH5I/FhT4E+svFS3TvilIP2r4oAAucUV+n5YVCmYPq5aIvhDSRXuQAbgitKwG84pYIEs9to2sizGtkFTrQt4mG5tQ1QJAkrbite8Poj2ceOD8+nTx5F6JMiMfKvnN61uI9iJFdT7QlCqjj7SyUAavqhonQOjS6cu6ARyxPIDaXDBUMd+sWbVcGEZxNj0IZo0cBELa7eRfOfWjq5gbKraGH0MY5lqFBsSfKulaPwPQ2Vtihia8wF425IRMjhpyye0LakSriliWDMDPXDYM6ARqnmoWx3D+EkdktSXWthMLZRgDL88z0cqjA3znQq80yphPlUBM3wJ019Oxob5YEXWhvlmhbx6D1P/qljhwzaTBtH5Ip7kOfY8eKfXh9OTJgSNg+enxMMhTYJETZwHu1faPhMBs40n+Ycd/bpyQ4UCM7uUy2Rffgy3EIAu+lsA8JDJRy4xARn4gABrlGpaXB6W0PVtNYnbX4h1+STHcEHnRS/tHzhaGKXu8UaHJuqesBFHJemzDiHZr176haQSMwYx/HUnoPOQCkGJAS8o4bp4iQQTAL8LITR762iz4fuFrrVMqoi/YYc1uPrP4fuC8HJTwiNmgu+qeM3dvjuAJ7ZKC3iTTU44PN83BMf5fP2SXexMkw59RVCMaF5Ay0hEYpL+VZxuUPLpKZ8kSV9Hr0Ctb7Q3YcnNm2+bfnN2qG9OPcBPl+KtaHgAXKWF/kjxPsYwSn8AByxojQ7IhH0yzdgHHfTVx3hODGgzcKchTxjj4UY1lh4DJ1UnHHwHnso4t2Bahe34BtbheVoRIDauia9hZLWnmP30NypCGJpKvjsrTdcXbGM87lYcM3kQM7gBTzUZbgzCJpNrtFV8E9Vr1Kn588gYZqDF+5C8HWKvNuAaNpJ3a7xuTTxB0Q35MxKgENF0mosAQ8thaBWpy036YLQKVjzUIeAHiUCNtyXw/+IF30cm5AKKUmU6dNlHr2Ich2oBT9GqI5t5Wp2rtzGbGC+pS5rMyrINwTGCFGN0zafm6sfK1bXEXdSExPlan03IS4J4zJnki6CsRd4lhQW9+LzxynBsr/CY7oXQb62hDihRPBscKOAoZxtPpK0DcPmYNgYIH7gB9k1U7VUanqX4PPhEU3OwGdbPND6h9Y5VTsKpN8aRNW3tA79E6SP0FVlswlRmuORDL0kO9XJxpWG8GjCGci2QDHlbPePRnuGbv8RRsZS4Iwt/IakU8+yALhj2VBP58zVwGBMniXS2ov5NnM8b53gmO+xmJpdyM+OcDU6kU5XJgAOdMNE/WZxO9vzH1GoZDliEdlV/OpawmXYOePZ7dzgH7LM04vBIfSPCI0y6zwfTZaT2kUKHkkKB98SRYodHio0Hd0ERr1XyBWxU6IfwiE20X/r0C2261OhTL7KpWoFPvlge8IZbHj7Hysd2xAXGJTqU4mAn5R3o0tDj0WWhj6PLU+6Prkh5PHpY2j/RlSk/QFdJTJpBNxus/urEgdDDQ19G14x4K3pk2p3Ro+mfEW58sOrW4FoUz6euidu7xyycQOcs/fdYUHxr8BsPd7wACx9AZTAM4cJ4XH0RD6Ja5zwK4PFDzoqeMOqs6InXr1Ur/hnvJwFrJbEn1yre+edTlir6Bjpf/abTX4TpkOipY9I5At9m0wMQ19okYcnk46elUvjZdS4FuJIH3tOtZ0o4OyEW5UfPSCfxq2dWC3jcvlEr40Fo6wHsWUmSegB7tnuhPHwj9jkOa6SUBBL89LoAP4VFHJIa0RnwmIqlrZvtpIxcPVssi8LiSEOv+dPV3olqU3kOszo9VfM6QYoWv8rTKInWYxrW3YA1WsACzMJWQ13Z4AJRAjFSxJggR5J1ywazAgFKmGkNzXRN97iaxpVzPRh9+VkceY8FeB8ADuU+NBhqsYmyHeUqaVhvsbCGi6QBUjVKcszbs3i+N60KLzazCcS3AeKYEtY7kVpkJd6JvBTavCOHxoatoAhBbFIohHlHFuSUGKXYWKosCUYa9Cp7IlT7O/FB8lhhuqz13TO3KL7D1Oei8KMrcuKlJ2t0zB4YmdCxgybqhqi8MKIFkYB6D0CN5J9/MrUoh9J7zhUPQ0aYYHGEM6JbkVT2fl9ZkJ+uTDSdP4DRTZcDJeZk7DK470WJYCa5n+VGA2qFvNTJwhU5dHxVjxyczjaeC9mQ2Iez8KgooEkzanG4YGPYP9lh27jqIIC9QVBUzpLcJQ+SHq+gvSH+JNOkdDw7Vj038TcMR6j6tt2oru7419hTAK3yLsER2Ak5a4Gf0t4p7KMVnmSDEobiv5u62+sdPKGkdubOv1bKhUTgWQZDGrrFxN3F2HIml5BHabnPec5SPLoChq+M8xzesfQU14zM6LGJq5ex/i2AL12v7Jb7FNYH8LtK3/hWxpZcHQ2/7AYvCGmYuL2CCF/H3T0SKtdZluUi4GGHPFmVu9jPBaso3/5FrLVwzPJ6IwH9Pcu+fSlrJsNWToW6Z9CEN1/Omn1paTYE9kFz9Uu+sAb3LBLm4xPUQZEI/EDIKtIYXcltdZv+Va5s+mYx55goy6s6F+UrfVwNctVQdceVIT+p3fZf2a5nggR3EZjGAp8h9hpbaAwq+DQm0nN3fsKp6SDvWPHhUuFWme8OTFEEJZYN0z2UorpJdm9wyTUg+nhAnM66q5sxdQ714gtBL9KFQm7rs/4Q+Bw6kpo7RQVTxYq8/y17RT2xqfNxPkYEWn6mtGY9g2csac194OUOOTyEL14aJ7hbxDdswXJXeD4nqA13rKmlR2kqRRU2Oh1B+VlVR/kghk29ORfhccz0kgQiFlUBArVJ30QnRX25u2W+gm6KJpor/zVsGHW0yLdpOrREsTlfBWLW13NswjewX4aqs2IK+jkvzRXg045DJS735FKovFxdkRukOt5rEhenePcjqQHuhLG4WHGEg1z4Uxzhgg9Eqc33KWOzecJLMWh17mo5aSC1eOVk17lkSec8Et7ygi5AQiNF8SIR1ocqVQQjhfuNZJxG2uQqzTotXk5FeuIccXFLzlCPmfWfv7A9bEKfqfA/C9nJ2nytssI1FankQZSfKXKrQDCyNls5Ln4OxXu+yE6IxvHMPP7oG6jw2V2YWQCvI16gC8D2dTiLptM7RdyNFfLiqGklTLf+GtOWVBC6gLXXs3BF5KTee6H1fRjrZwklkAsdOGvY3qlLkrV5cueZqCh2brJqpTjD5JkEG81ZF5JDxlPWNbp3mGrqJQohGvoqgN+hs+Bx7WBlJBFsIJeh5FqZF/eoZRStmCeszN31+PWlq0fIHG9XZgdg1IgLOaCbwWrxkCTrpe6LPQOaTPBwB+Fx1Po8dS62w/roLlW1r8BrWJWGrFvXt+Uiu2v5QJltLY65hvp84TEHFbWTvAIFZQH6NHDzCv/+cv+YMjs0FzTATYN3LFdVXF6VlVlbKcq7MzPCD2aOFlZxu2XLZKnJzpE9WldHmiIeep74xq6eaCxI4uQ8qaKpuiTvqx8viwRo+liFTjUppqnBFyeFNMVCnRKHg5AE0k+ujNuhpULtmJ3bw77NahOJJ7LK80cLS6BsapxXMwvXunh5OHikGAuB0dhHIWEQkahLABOtXp5dAsSgcBXJPrkUeEDW9y/EuGLICgvklDrudJmhJRboWfwIPVYAjxglip2jHuPIuzpXxE40yONAZYOJNzNbzp3yAY8bGj7Apy45LT4BG63v4RpXpdt3gbPCqev85js/YfJkqzWOAytbTD7ANQClS7qeV/A2kosA41sRIIheDJEMmTw8SqtkbcM+cWYjL7ygGe4dyhweAB9tgnVW6xWy9a2Je3NmqpVOug/NTSfJ8zQDcz9ajteMdkCWUzXNVca37voYCz5ckKROiMlH8NBQji+QzVGNju2vnLTunyYDQjXpGAiU4TZFzHWPtXH9csDscLnhifwAupQ4dWUpt51ynmZVQXloNOCRVt3Wm8WG6m005PpquFis2UazwdOMGS0cV3A0W4Y0jiXxnoQLJw/UhLZEcU5JQcwWPn4r5suZxL8jxzfiAjf9ovWltzAkxBK7p5yHrMdcnB81/T+vjX9igpoy8adGX2BDBGZzxIQIajujzgQm5EJmATZ4SKK2iG+bE2bZJ5aFBub1p2fdoBwDhdUPg1wALaE3XbgQs6MBWjgZl+QqTKgLX4W9HImfMMbTw6h7hsAfRNjxlHOGQFkv6WPQ8bFODvg8TNpnQ/78tmZTozZr+x7CIcS0Ns+LYqai/dhBvaYW8PZ5eDrcgQBxACUiyfbVRubyoQJ+TZ5J9Lp5dXbFsLMJOAFr70D3Knga+4iYz5Os5XQ8MvWM9qNUhhE8R9syB9NpSvY9MGEOpdPN23LmwnSSu4S5SFaZne4XZ83hod7ojWHS2wukPA2h8WafLsyLfVLxXGFbJB/wvSiJ7qoR+pAs+ejg4vWzE9GlPpqszrfnosvSLfVi2Yel071w9sqR8qrcflUgtNVhTES3YoP0WC/P0/WSM1cnKfKBnF8PT5RPxX/xO3PmGp+kSvcP5MwjxKyO72vSP9ZjEkDp68aXZM3jRvLcSfmEBGw4wI/3skltAPk96/Nb35EIe5H4/58DpvZex/EaS/KOVhwkeXfzQZredWWDFH+jhfcAUj0nGepuNRUxWL90CS5JexvBpaClIodU7wLRVcbiS+uDxeSOlU44J+o44o8tg9hKCFk5Z64vVq7HM17CBFTropgDMo76WLgpYGewJhwWFnabhBr9/qDRYV3vwbnhX7kHjWLdYlv5GjWskh0JOjf1sD31tkgx0zTe4Wa5ArXChu0+c1UPSt5rVeUQScjYV/CtfSA9xHsedqZSPbE2u8Lzz/E81heiPLgL0NY3YruVOD/3ScVzPhFK+M4+LqvEjPkADr2hr4HAIMXB8TMEQNPzqdLuNWZgMzGDUOLj4LfgTNz65Xdv8+c2nU8UvHjPl1jVeiI/1vm4U5gM08ikOKvnfU71wWkCp5fafqnB8YFs/IFRb+YHsWyt0xGIBtwIUrqLpVy39+wy0uKdJD3OxAKhF5R40o6IGwcSyK61MHULW5cd2+XcmC5PpEt6tdIhAG5gJ1fRHOqIU7Sgmuv08eZf+o92qbpumy1CO8Zn/eOOVt3dGqdml+BunvJE+KOn8sFTscAToHhRWckA6MwHyf515GL3LGocgqiQ1BUMrB8hKRfFdygjA6WSyIFEWq39AHX4HBY9ernJSJ/feNNR9jc4UOdcSTwiI2TrjWAKAA3UgY3GfQhHbNghIv+x1RH71gGMc9Lk+ms/w9uubZguimEYPCbnfJ04t9yhpqeH5ZuEzqNqqAgn4ZhvuwtOAR51gY30BixNKcgqHXP8881GaxQdHqq0WMmOawQz/18a4k/mocbISS77ZvTkl4M6K1SIHDhqhmSnYfh+DrtYjbaEGncRoFQoMPOtTn05QV6hgPESzBL0pIeVd/gyRW7EKYyV/yao3OnZyKveQlnSzNWdiHya3I6C0Mt2tcAjOGSkyTOfiWXv+R7CE7eXYD4dGeUeV8hDXUwr+yzYuh2YNLoIfCYOralZrik1IbJPpbJNkG0taEk5v4a6gEXo2UfzObCiXt6beg4m78WJyczY5z8spzBcrWteGg5aNw58Vp+L+DJOKHnf2yo5wVlxColYtOM2n1N+9Ds4/Sh7Pvway+D5YIEe8nvRxXXf6MPtePDMlaqI9zG9QiiftN9gXdKdAS7pcecqC2bCp0C4JSn59Jxawi5TXobeBg55fY8SejMa5JsrS2UooOjrSqlPsaXExovP27kBo2+4UzQL5ZWuf9VGHtBT1ldc5mMHq58vN+LyXItbdHY+P49FNZpsTdu+AklHCD6rWNnDz+Dd5HAduq2g15Z8aDKNrPEIn3ZN35jAdI1v0ZiGJi2yQP27AF8D+59qpJwhuMNNziho2Tlo4kjN1sRH4IPx6puv5qJ8YEVrVbX1WSh9gMVSHPEqufxEDu3czkF3A5JOJSUKGJgtsJ9eew+LhyQC/AZBfudvl1wxuCyvwtU5tOxFSgoxtRP/ustH2HX0ButQxFaEUqLkXoTwhpqQPhaRwumTGNDdzreF9A52xj4INFuA5FOEklDOaeCKSMSquGSClhZpabldoiRfZJBiqTsHgRzp3gCsfzlIn0PCTS7et5GnrsLvaanWc7jjKSkFRl2cjtaivP7Jfhg5Mrbf9p2wk0BqpHeUuc6RiBFi56PAX+BKsTE+Bgma3/5wzTLZXadIgCs1H02p+Z4Vce8D9qNTBdIeeLIhF03rokrcmn0iF8H1dpo6gK1BLjogxCJbe1BWqStj8S32/qFU+jhhliDLw6liQ1oqbgc9dqQN6hgpF13gDC91L+GWKRcdCYzIzTcgFBBhlF+m38zBPKe5c5y69hjgizdBOc7RLkf3VmQuCTC1w/i43sxFl8r7BbqQv5gzl6WwpvlSzlzuZ64gB3Adbb/iJH0rVHYC7A4uf9Ov4hdNgLd/aGLoU7noKnEYOEwcPJiLroYFK1UkOBUPl6qs6zZBwNeMgzxE4Xw6Fz2imd6lN0MsI+zDCH3wmVz0qMD/nHUtJ+jVO5drmUdrkRESo4/1+CQnNUo7C2hBmpDGAbfwjfRhVxLJcN8S45309B5/MV5LJ/lC5FU6i1UgE3fvZPREtHTs9n3JhHlKIMqSPlmzbbdbaWarKx2aUd2dc9xlwgPJ1ZpQS6JsYx1nOKIzmxhmO0iWtOIgyJs1yYsDcfgWljzE5K7M5amuQDcrePcq/MZVkZHy/Fj0nif8uQ9tKw/FPRmm1GgdKAB3IXgV5Hl7bXgbSe4hU8w5XsLEsQ2136per9NqY14kNGBSUhCC927tg30QguyKHlHsXIiYV+N2NzG47wdnCB0JqC2VPTCBI3VZgluy9I2+za3MtegcWLWlSXrsExUgan0gvQbJg5Atqn2EVQh22SkjWf0oYuEsKoLBGDCq1VyCoj8RUw0IUlTQkeqpZ/k4z4IrUNMjpx6oPuGQTZpgH9PVR3C9ThRu/x8KMp0Rw2ABzDZJVEe0wlAFt+P2oca0CjzM2YmtcFck68J/YZ9SS5XdSaDcBVE474LD0yaDswDfFnvdZmsDrYRyQ1rbPj0RrwMIGUTzBsynPEYpyvh348re84S+PUxWxTNz5wQVG3AZJIvd3t1amRfXmzs7VQxkyZAnC3ZBSupt4dHz84k4DvRZb3ZPxHXbHcmmzNIiCEUNmUi2t4vfOhHh9ciHQge3TZhrCCG1s18+AUeBo7vx9gnzZFnNcKwfTTBUBOXqzrSriZFgl6RHcV59ixnoP8n9HNC1zZlycRml7zH7XNzaXkly0UyL4y25aNwvwUS2P/RO5UGtuNo8B90nooBDfIQ72cDEHHdMRIeDgfLb87UT5gKK1xKT/SNaLxY9djwdoeDtjD6HbWdjC2QErh6EbIelrBQk+hUkdBFWLW5HcP6K4RkeWeDpBhnIvRPRJZIEm9ok6dJ1tyTha3UiugyUiy7bur6F7m5N8+ZyqadIz3qbKmdMun6F5AWvWMIn2cMgkhXfuE44P22u9E9iyfIkw0OkfRXYxcE5+m0pqwLcIscvMg+nE4l1ug1PWKj2KYH14Xz0CLQOI2mxmbj/P2vuwwELNkYtChM7OgB7FPdKwqgfovx+jANmPN36OD354XhGPOAl9E3ePF76meyte3AwjnjLfmvWPAmzNNI2lXjYmR9CxMM5XkM0HoO2RSqspW0F5v6JKEvdZjggTFUdKHdaNxT/t7Ire5GsOuO3qrqW7tk39yXuS9xmHMd9udXVPVXTS7Vd1aMzWdoJY8fRqMN0DPMoeRAfQggi4mP+gCASgoQ8hCAiIU8iIkGCSAh5CCGIBBGRkN/vW85SVW3iS3fdc88999xzvrN93/f7feIrurEx+9QL1FBvS0dts1IJMRY9LDoXGmC/TNemwWn1tw2jut3BR6p/gBjeWPpmKfFJqNt5CkIpL2xWmtBvcCqnLqULeBrx57CD1yot9fLL0qYnZXaxmRl5wNO38fucLgCYBASXVxAQPYjNS2gAbb9AOmA83tjwIVttjkxiumhymkGDWKPBkbxRgYV+YwOzDoKSc65LqpksvrxV10qOpDb4uFTxzUbRJIpX0G9W6XIZvnY4ra+7y11xHKYUCecesppSSa28qtCtBBpHKec36MVUYaeFX0gvwDmJEV0AIF+KDQgYJ0NAAVlSynHNXY+mYDknUsLiOS+JB1UjdattZqCYVuqJO91bPo4SmQuB6WkN6s0hzr+/ZBvxLH6xnTgeBDJlRNsd/uE7gdXEL7p/sYYhM4OB0yFm9zHEPgXUByDJcG/PuDfvXkNT7oMlaB7x0wGAgiPNgt7cP5JI/6slBKhd9a84EBwdL/D2dDbI2K67vr5dQ3NqA9bTBmxkDdhMG7DlDTFtHzwz4YO3jX/w9kkfuuN/fejO8KG7wmHpOfXgAenFFp6/tEalvr41OGHAfQAeBWSkAyu+pG8A7HneqcY06Q/YqjxrDqDFOxgGynTaM/dDMFO1JEafxhtj0rvwW/Zgc8HteCb3W9B0OC9sg8EsSXm/QeYWcVPXhA8bsNtwt6uXf2yQrCVB1ibPfgyTOA16VtV6sfvpzVUYqrGYJLk+wBK+GQMOhu9oFHudSElwGX7jk0axL7sRHFL1/ovNYr86Geg1HKcPgEHH2jA4HhT7CRsM7oNrbXauXSKguuKdokMvILNweFyRua/W6XFikVHuvBD1ZciSXAnxAEb++hAzJgUzXKzD/9CztICjwuACwk9zTafXacYZxKumsMow2I63UCJ1gPTmWZudeGq5XOXPXaivhOlfX+z3F8R/dPfy3FEdxHt6qMXq2rDLnHtdpjm6Y+sIx9FYU/0ezrQxuTz3Q6G+FGeCMFNCWWcCT8+biGGlfwtXUmURDlBT9dQ2X7a3cSwMGFQXXTk7qkiJN++pzXkOFymQohOi0NEvV0xuI3IALyKhv30Nw05+hcByTKqq0Z+xHCxT4xSc51WPWHNLZmrKw0EoS1bDHwwXwX1Ad5Y4ioU3GfokHMorwUgY4w9Wy5zbTO2edsFD/gs/RhAbNSfFRVGP7XJkTZyP5KRrquWhhqen/jeiS97jGUvoJ87pDnSkBCdYSRHA5pssgNH1EjeOLi/hWqEsSwN7s/BopqQw9FFNrO5mahLcFU5jx7KZALLwIxDUOOklXc3ijAOvOvdpzDD8SKqGXZroGYil+QB9uxXU/2uA1knIU5brrgf5G62ucAfPq/FnyGdC4WC++R9heLiZwGawrSocXU00usaWGYerg0HgszvUYfR8XilJHc5WFY8pSBMEGZCEMQ0nh1PnHqcSPrNEEoRprksC5VCCKkiI2yfDMg3i5jB0jfo5eP65HnwEc2Mhxcetippu1keYbdIqOfQhYjiSqSFm8E5EEFsbV2Mo9/BeciRi+wayIGBlgXgWEh/ZK9jKr4aeHH5Nt21gYAPMuKaI3ymWQhSUzPi6J+ClbO265Uq40s2IXQCmTii8uDorKN43OjNz8/PwRg/X2+zadz3bIyx6R7bZ2Znjq3elmOndOUJ6zxiEeu8kDP++CRj+/eNA7QMCVoaZgxaFC1y6424nxy8RGht3MmK1yfYgNS8gAUNMeWMger9vgqNDf7rJy5+2jb1K9KeQaPklZX4GecgGYlgpDOUZ3wQ2qWVddyt6miCimhv5Od0ECLnq5LJ0UslGO7YqovVLvc1Gx/pWhSHO0eic8FcUN+EVovHKAF5ZmeictI6Yu/AJxRdcUvM3FF9u2U6hYb/iF7HRPt8yr0/aASm3WfwHo3jksznIRT/HIDk4QI/cNnfqyW0woG0TKnmUr0seDoUS7RISdxpKCmXrx5dKErxJ3PY/J9vCKK3VTSlJk4uXoE9Qdk9LALlnVX+acGWutRYFTYt6GeqB+B4nYgqeYo7UY7X8N2Yo2buchk8tHX0AkMQPS61r4dy8Nvw9cqMJDwdly4RudheOjWMvtbpC9VX8jJoJww5EcqjXJtaVSy4dDZVULU48lYSeQLj9IitBzRni4LcyWpxh+IJ916CnycYiHqMwEQ/WllZkrOk5r2IToY30qiBPVwj+CIPfptIscet6BKszFsysSq/Qu8klVZK0Qw0PcZ4gCI0XawKOoH7gSk4zTngrGzMHI76Ortgyn3MisK+KX6BGkbELXVj9wcg3vApVVuQ4wP5GiQ0A1Jprs2VxYljt68R5pi/LmcKAgJA1Ej/b92C/4BEnMPEZhAC4l96saroH6APr9uXyOFsdB109+HTJ1FbvkqOt0SU7W7NL989Wl4xs011ysc10HcS2LeAXts/3AWngrx04fhmVxE7m2dVl6m7MtUJ/ksIf9gr+ct8a/+7H1nONC9FijytQh2kXdjg5X9ThF18M5M+alHEJfs2WIlW4unRJoReX4eyGf5dTXK4Qu/iVlCQRyW8NllT8r2KtrsYAYDnXPIo/13bm+fR1ZbvNal5v2KcbxDJ/46owhJgQ3mzUU982u/4tWEDx79ZBucRsty20Wc/bceLEvzsG0kAH+TGHmHAnP+4wsU34f1e7wxtH2h32zN1YrVmJe6QK9z4m/+5b6c0O9YPvH/TXVgXE9EBvid/zoK3TDy2W7Tl+18OOxnykvQbPYhZWBlxmm/U3+Ak2SkPvvA5+axtisD4OjhABTs3DDVrLOpqQgnRlQHPtFo2VrprHFueOKixxwfVxi9xTSGyT4gmXO/NbOFyuqMutvvOKQFw6y5PI4hyPHnra7dgGrrc8zwLm7GvnraePQmR7OPtqOV04ZuivHpBfq7OEdh1LQYM7otxfqTQvQWivgeFRXITk+Ws7PZL49KUO13f6s2usEoXBW+wWIyRkr2tP3Gbtegf/Q6xYz4PYXbAWh3Cm51vvkm0GPs7eczfIZ9jb+OcF34vfoVb3Dc0g9dAQKrS2CFkZ+rUC9OfsAtyzOXjJXTM7J6JdM4XYFMeR1aTuv5NnGp7GPTGbtxnEoOUdru+c9hwzyi6jqVCuGQR452CltxzqtQu15gDHP0izSOVeipW+dR/pFqxW+9Hf7b6mH+AXcLyz/TTpQpsILuJ/fefFUhNvrEvYPtrslxqLw2X8b0VdzlaDRkf8dODOznwLi3321iKG36Nr8sSSYmQpnhzWfEtfcndAJiSZV8KvR1WwtHrb1Q8ev3Znc9m34pR0lXXJ1R0MQUu7bm5ppYtJlm+8cX5OPM9uClPazRhHYGKY5eyifkH61O0+7O5M6S+PhIntfkw2AZr5AKYcuDr65YN4ks39sE1bj7jqdNWkeJ0zPUmF5IITPvj/9ILz/ppfcPo/7hdcBURUecHF4PEgtyfCEnCSi4l23XfiUvNdjt94NvueiPm6tdX3FU+LX+tLI7FgoCbYPD3L4GgvkEyvEhQbI1Q7WIjTW772+nFblBW09tAobpHRYUcbMeph/U0Cv0B9sHpUll4wJSmBHZum0pkUJYY8y0fLWSG/s8cq2WNVCSg2FogmenYJz9ewH0AkStPMFEeacHoNwaLifjdnoUjoBca10bA6h/2NZizPneP2VHJX6tkbojq/nqjzgxa/4kc6IGicG04o33R0To2V5Rj6NwNV0xvokCzbCNfDWzxCjN4PPiueGDU+v0Z55PBPAxJ5dpeELGCReMWMPpFU4LeoQIjJYGq/ENRHrMZg8kGeTWPBRzAN7OzCE5EcvypHKs0crWojESCSB8UgXdWYa8XbaS0g1NKK76AVAxcC6xRtzbWQ2bgukpPwEGhnoKSHSkMA2gE5gAcvm1pwLJwiLnq9XOFWpd5fFsiQdnyDa/ugPC72mZL3W4M0iqy5LJJIA3OZYYnxU6gM1AV37tnnnz4j+lYyMUIIsDuQQYBVUyx7IyZuCRxkx3ofLyugMtMtA3e0/WWgwgW4ntVF+wxxbhA+HedMEKpAfykRMOQKygu9ctYCjWHwLnmtt7C2kwdBdF2iJRMX/9OVKqaRxA8h+uD+v24LU+JTJ1/4JyifBZnsAT7su7HeiAqjWOzBjqsfbm1RzfJHPagIynsYFPG+DURQKVkUC1XrPoPH3s8yxsgiI+3eXustKjOjU0/J2gyzZEp4MbEkO/9LtT6E/PohR6IMO0aeyiJVsXGuURWbUGFI5+r50DVH9HGOJbhTmVVYdHcsxtzKFNxWdo6T3YW1jal0Ax+vScoz55X7yNwTqIvHcIYpPHs0CZWsB7+kHE4oH2Mou3eaVPMv9Bdz84Gr9kV971+DNZDI+meKn7bEMw9K3+IfeOopiVf8T6xaYsMp/gWhFSkqPoUEmYstTrdwbTxffAaNgybFuCmfw6ZhgKMvmkULaGEsh08WXzaLafpMFF81KzOhScMhF75akxQmCfR3CwRz0IiM33b1SKoraWjkylgBxRuCYhYbGVjChDm2MuzC/oU1FrMLeCuP94TTuCpcxmPJUGwIT6Lu9HVbMuXY52RFntK50Vgoqrb61nxdnsorht4x79fi72T5ilgP9BFClTJwBUMZQYEn7mlJS/4NPSZpOmPCsQRmYYz3LEeDSSFDk24ocPMF2hAW4XBhbTadIvNnhE83VrMW253lim+olCnBJf2pGudNhJz6hk/JBP2NnzLcmQlpfLx+6jxcSZ7Ac2cZrhHqtXPWTcPn6dolZMq8Zd+dM6RpqUHOxySoJhIUVOnfUIYmFw5iF5eCf1PTk/Z7Mh7YGLUNGAFDh0JxFXs/7dxG1rkkMUuuD/Gr4YYav3panVdjfRwRRwORg+pOsCl1yDskJ+NyWNIpIBbSzMQ5dofGjSPBNRZYTnhPSuDevFMmZfKRfpbOq/3nNOY6R3vG15aFRUOoh/GIbzHES85IB/vcFOCNqZCpr+mY/xooU+DkpB7XwnI5CkUdSfTDguDU4IZtjoFSwBQxqvnqUyV0QpiV5dhVTXNQXclML2JCVywrTMCQanRHQEE/Bu3g80SOBuNeDwEn/LdrGsWkOELc75dJnk9gYxSvO9rhg5G95CCrAGDFuCnB4EdyLMzW5MYS7bXQz/kBoj65FDt8AIooRQX2zZDbWb0drk5nSMXpCnGUo2prZzQCptCKSDxVvlM+KHvVZvFyqwJ+HitdIi4KZbhGQGcVgudodQPRXCGdsrlDLeB+26pMJWUi5aVWpQ55ZFlJ3GAOQn2HlODh1auwBmuKNBtiJvqFfq98a5pZP17z+m9rGnlS0uCkaU9ofZ0eSuqs9+Bp32KgBzzoCZ67+HmLzv4s+xXPI3tsl9qC7CTwj9c4t9iExCwoBeL8kzPWXsJeKqeRTXsWtoVWBTO8M2RiOy1Y++idyxgv1Grj1dgZS81ebWG90+JfbwHLlsfzx0kwRvsPnSUG+xi3P7IviNZpRHVN5Ue4QtgiaDlBYo25fHm9A32XMoEliTFz3dwPHbxjFko5oixBAWZehvSJIBPgMEkEnT381OJ1VY9LSYrDDSKszYxFMuJ/CdtTwL8LHNJdcskigP8SLq1OTjBi2+CEDDnnFVzsMAyh52hVALtiviOHaSjytw3tCS699lM39rzyCB1A+G4eIxLcHET8QS38ax/FpgBZRh929Is58yp7QoyqiXkYbasQYqFLcPTUrzACvYyxoJtkSMRxyR3YK4hvw0i0rAUHuqMZA/WFxQ6hR3U+8Zc9LV9u8wQWFBCYd01hgP4YyzZuPnZSN9Wq4+wg7pu9jlhhxp5PLJGpYyDwBMre5o4+IPvSZ01UVHMucpjJn8tdlDex2aSPkjogsSCi1bBLgdMrPs/DrLyBMWwgLvbuVJJfRKmuBVqcU4S48458C1OLRsTw4JHaQOBeGyiPSTHEGKPJD1TpUltqo3HYh41dE5RTU67WB/CAE7UnMZCeuAJw7mophFRTmoyi5Yhb10vZ7TfmweYGVRScNbXcZkiYJcvt+kpX1QetkA78Nwaw3EX6dEgvO+k7Z9L0UMFt0HDjq0QNguxKXuefGgwYO7KPjU+LU25MT95GV47kziIMezC5ylF1T7y12ieSNL5nb7hlJo14a1+8BaqxpLj96Y1QMxjZYioaBqWJYuGCE7D+rLXhENsFzely2RMrnCeGt13kKdInF7NBwAwTbl9ytN9nIAToC6EZFrWR5rzUb5Sr2H5L0mWWtIQhJQmXe0K/HT9eb11htwYLJ3COw/dZ+pWzfEO3v9o7yQM96wxtPJKSL7sKuiKIAVgx1W0GSVez7dUOZG/hWIMOiWVea0lQS7PBrrNL+IqulpZ2/bK4DpdAqsWevSEkpr1wo4owjBSLQRJvOtknE1AKJYaFcWEYZZumABH89AW3JGMG3wrrebx3azoKY2/flg2amH57np4UdEe444PwoLe9PKztfsjTaF3N7txpd+C+ykgLox122G53y8V5gflp8l2ZeIxJzxG7DblYTJLv9mTtobHH7rH7jLiRStO9uaClz6XZ7ssqNUEq78/LkQmDtkBYjzTDA3kGSnoMFiI5HozTDH6lYvjQyB3vuoeziSkkP6JSXtJkU+Yzdqp4+x1WP401KPGfVeGtUc+h0MJkn9ykl6uHWHWPWuwuR0PogspQaTGL9tzJnurZBqyNePu3s9i61amzB3m0qJw9SG1Q9ewhXtXOHhLdkDsfxSC7OHKLZSgGLtQ4F+I3Nin2LlbkNvy8NdYRGEDo5CK6aqobk+i5RQ3xwdTy0heOLoS67MMYiK5h2f8FiQAAACi1L/0kuOUDABQGAQEEAwEAAAIABAEFRG9jdW1lbnQABgEIfwAAAAwAAAB/GgAdAB8BAAEAAQIAAwAAYQAEAgVQYWdlIDETfzJ7irDhDwJiSW50ZXJuYWwgT25seSBDYW52YXMABgCOAQEAAAoADwYarANhSgjRGcCO6KsKrFQ/gOVgFSfxPOi9UEsDBBQAAAAAADoOcVwnchZnJAAAACQAAAAJAAAAbWV0YS5qc29ueyJmaWxlX25hbWUiOiJVbnRpdGxlZCIsInZlcnNpb24iOjB9UEsDBBQAAAAAADoOcVy0YmhTQwAAAEMAAAANAAAAdGh1bWJuYWlsLnBuZ4lQTkcNChoKAAAADUlIRFIAAAABAAAAAQgGAAAAHxXEiQAAAApJREFUeJxiYAAAAAIAAeIhvDMAAAAASUVORK5CYIJQSwECFAAUAAAAAAA6DnFcUTNFBC9mAAAvZgAACgAAAAAAAAAAAAAAAAAAAAAAY2FudmFzLmZpZ1BLAQIUABQAAAAAADoOcVwnchZnJAAAACQAAAAJAAAAAAAAAAAAAAAAAFdmAABtZXRhLmpzb25QSwECFAAUAAAAAAA6DnFctGJoU0MAAABDAAAADQAAAAAAAAAAAAAAAACiZgAAdGh1bWJuYWlsLnBuZ1BLBQYAAAAAAwADAKoAAAAQZwAAAAA=\";\n","/**\n * Creates an empty FigDocument by parsing a pre-built template.\n * The template was created from a valid .fig file with user content\n * marked as REMOVED — proven to open in Figma.\n */\n\nimport { parseFig } from \"./parser.js\";\nimport { emptyFigTemplate } from \"./schema.js\";\nimport type { FigDocument } from \"./types.js\";\n\nfunction b64decode(b64: string): Uint8Array {\n const bin = atob(b64);\n const bytes = new Uint8Array(bin.length);\n for (let i = 0; i < bin.length; i++) bytes[i] = bin.charCodeAt(i);\n return bytes;\n}\n\nexport function createEmptyFigDoc(): FigDocument {\n const bytes = b64decode(emptyFigTemplate);\n return parseFig(bytes);\n}\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../src/parser.ts","../src/utils.ts","../src/encoder.ts","../src/schema.ts","../src/template.ts","../src/gradient.ts","../src/vector.ts","../src/color.ts","../src/svgPath.ts"],"sourcesContent":["/**\n * Isomorphic .fig binary parser.\n *\n * .fig files are ZIP archives containing:\n * - canvas.fig (binary: prelude + version + kiwi-encoded chunks)\n * - meta.json (optional)\n * - thumbnail.png (optional)\n * - images/ (optional)\n *\n * Parsing flow:\n * 1. Unzip → extract canvas.fig\n * 2. Read 8-byte prelude + 4-byte version\n * 3. Chunk 0: deflateRaw → kiwi binary schema\n * 4. Chunk 1: zstd or deflateRaw → kiwi message (nodeChanges[])\n * 5. Build node maps\n */\n\nimport { unzipSync, inflateSync } from \"fflate\";\nimport { decodeBinarySchema, compileSchema } from \"kiwi-schema\";\nimport { decompress as zstdDecompress } from \"fzstd\";\nimport type { FigDocument, FigNode } from \"./types.js\";\nimport { nodeId } from \"./utils.js\";\n\n/**\n * Parse raw canvas.fig binary data (the blob inside the ZIP).\n * Use this if you extract the ZIP yourself.\n */\nexport function parseFigBinary(data: Uint8Array): FigDocument {\n const view = new DataView(data.buffer, data.byteOffset, data.byteLength);\n\n // Read 8-byte prelude + 4-byte version\n const prelude = String.fromCharCode(...data.subarray(0, 8));\n if (!prelude.startsWith(\"fig-\")) {\n throw new Error(`Unknown prelude: ${prelude}`);\n }\n const version = view.getUint32(8, true);\n\n // Read length-prefixed chunks\n const chunks: Uint8Array[] = [];\n let off = 12;\n while (off < data.byteLength) {\n const len = view.getUint32(off, true);\n off += 4;\n chunks.push(data.subarray(off, off + len));\n off += len;\n }\n\n if (chunks.length < 2) {\n throw new Error(\"Expected at least 2 chunks in .fig binary\");\n }\n\n // Chunk 0: kiwi schema (deflateRaw compressed)\n const schemaData = inflateSync(chunks[0]);\n const schema = decodeBinarySchema(schemaData);\n const compiled = compileSchema(schema);\n\n // Chunk 1: message (zstd or deflateRaw — auto-detect by magic bytes)\n let msgData: Uint8Array;\n const c1 = chunks[1];\n if (c1[0] === 0x28 && c1[1] === 0xb5 && c1[2] === 0x2f && c1[3] === 0xfd) {\n msgData = zstdDecompress(c1);\n } else {\n msgData = inflateSync(c1);\n }\n const message = compiled.decodeMessage(msgData);\n\n // Build maps\n const nodes: FigNode[] = message.nodeChanges;\n const nodeMap = new Map<string, FigNode>();\n const childrenMap = new Map<string, FigNode[]>();\n\n for (const node of nodes) {\n const id = nodeId(node);\n if (id) nodeMap.set(id, node);\n }\n\n for (const node of nodes) {\n if (!node.parentIndex?.guid) continue;\n const pid = `${node.parentIndex.guid.sessionID}:${node.parentIndex.guid.localID}`;\n if (!childrenMap.has(pid)) childrenMap.set(pid, []);\n childrenMap.get(pid)!.push(node);\n }\n\n return {\n header: { prelude: prelude.trim(), version },\n nodes,\n nodeMap,\n childrenMap,\n schema,\n compiledSchema: compiled,\n rawChunks: chunks,\n message,\n images: new Map(),\n };\n}\n\n/**\n * Parse a complete .fig file (ZIP archive).\n * Extracts canvas.fig, meta.json, thumbnail.png, and images/*.\n */\nexport function parseFig(data: Uint8Array): FigDocument {\n // Check ZIP header\n if (data[0] !== 0x50 || data[1] !== 0x4b) {\n throw new Error(\"Not a valid .fig file (missing ZIP header)\");\n }\n\n const unzipped = unzipSync(data);\n\n // Find and parse canvas.fig\n const canvasKey = Object.keys(unzipped).find((k) => k.endsWith(\"canvas.fig\"));\n if (!canvasKey) {\n throw new Error(\"No canvas.fig found in .fig archive\");\n }\n const doc = parseFigBinary(unzipped[canvasKey]);\n\n // Extract meta.json\n const metaKey = Object.keys(unzipped).find((k) => k.endsWith(\"meta.json\"));\n if (metaKey) {\n try {\n doc.meta = JSON.parse(new TextDecoder().decode(unzipped[metaKey]));\n } catch { /* ignore malformed meta */ }\n }\n\n // Extract thumbnail\n const thumbKey = Object.keys(unzipped).find((k) => k.endsWith(\"thumbnail.png\"));\n if (thumbKey) {\n doc.thumbnail = unzipped[thumbKey];\n }\n\n // Extract images\n for (const key of Object.keys(unzipped)) {\n if (key.includes(\"images/\") && key !== \"images/\") {\n const filename = key.split(\"/\").pop()!;\n doc.images.set(filename, unzipped[key]);\n }\n }\n\n return doc;\n}\n","import type { FigNode } from \"./types.js\";\n\n/**\n * Returns the string ID for a node (\"sessionID:localID\"), or null if no guid.\n */\nexport function nodeId(node: FigNode): string | null {\n if (!node?.guid) return null;\n return `${node.guid.sessionID}:${node.guid.localID}`;\n}\n","/**\n * .fig file encoder — the write side of the roundtrip.\n *\n * Encodes a FigDocument back to .fig binary format.\n * Zstd compression of chunk 1 (message) is NOT included — the caller\n * provides pre-compressed bytes. This keeps openfig-core isomorphic\n * (no WASM dependency).\n *\n * Encoding flow:\n * 1. compiledSchema.encodeMessage(message) → kiwi binary\n * 2. encodeBinarySchema(schema) + deflateSync → compressed chunk 0\n * 3. Caller zstd-compresses the message → compressed chunk 1\n * 4. assembleCanvasFig() builds the binary\n * 5. createFigZip() packages into ZIP\n */\n\nimport { deflateSync, zipSync } from \"fflate\";\nimport { encodeBinarySchema } from \"kiwi-schema\";\nimport type { FigDocument } from \"./types.js\";\n\nexport interface EncodedFigParts {\n /** deflateRaw-compressed kiwi schema (ready for chunk 0) */\n schemaCompressed: Uint8Array;\n /** Raw kiwi-encoded message — caller MUST zstd-compress this for chunk 1 */\n messageRaw: Uint8Array;\n /** Original prelude string (e.g., \"fig-kiwi\") */\n prelude: string;\n /** Original version number */\n version: number;\n /** Passthrough chunks (rawChunks[2+]) — included as-is */\n passThrough: Uint8Array[];\n}\n\nexport interface AssembleCanvasFigInput {\n prelude: string;\n version: number;\n schemaCompressed: Uint8Array;\n messageCompressed: Uint8Array;\n passThrough?: Uint8Array[];\n}\n\nexport interface CreateFigZipInput {\n canvasFig: Uint8Array;\n meta?: Record<string, any>;\n thumbnail?: Uint8Array;\n images?: Map<string, Uint8Array>;\n}\n\n/**\n * Encode a FigDocument into parts ready for assembly.\n * The message is returned as raw kiwi bytes — caller must zstd-compress it.\n */\nexport function encodeFigParts(doc: FigDocument): EncodedFigParts {\n if (!doc.compiledSchema || !doc.message) {\n throw new Error(\"FigDocument missing compiledSchema or message — cannot encode\");\n }\n if (!doc.schema) {\n throw new Error(\"FigDocument missing schema — cannot encode\");\n }\n\n // Encode kiwi message\n const messageRaw = new Uint8Array(doc.compiledSchema.encodeMessage(doc.message));\n\n // Encode + deflateRaw-compress kiwi schema\n const schemaRaw = encodeBinarySchema(doc.schema);\n const schemaCompressed = deflateSync(new Uint8Array(schemaRaw));\n\n // Passthrough chunks 2+\n const passThrough = doc.rawChunks.slice(2);\n\n return {\n schemaCompressed,\n messageRaw,\n prelude: doc.header.prelude,\n version: doc.header.version,\n passThrough,\n };\n}\n\n/**\n * Assemble a canvas.fig binary from pre-compressed chunks.\n *\n * Format: [prelude 8B][version uint32 LE][len uint32 LE][chunk0][len][chunk1][len][chunk2+]...\n */\nexport function assembleCanvasFig(input: AssembleCanvasFigInput): Uint8Array {\n const { prelude, version, schemaCompressed, messageCompressed, passThrough = [] } = input;\n\n const chunks = [schemaCompressed, messageCompressed, ...passThrough];\n\n // Calculate total size: 8 (prelude) + 4 (version) + sum(4 + chunk.length)\n const headerSize = 8 + 4;\n const totalSize = chunks.reduce((sz, c) => sz + 4 + c.byteLength, headerSize);\n\n const buf = new Uint8Array(totalSize);\n const view = new DataView(buf.buffer);\n\n // Write prelude (8 bytes, padded with spaces if shorter)\n let off = 0;\n const enc = new TextEncoder();\n const preludeBytes = enc.encode(prelude);\n buf.set(preludeBytes, 0);\n // Pad to 8 bytes if needed\n for (let i = preludeBytes.length; i < 8; i++) {\n buf[i] = 0x20; // space\n }\n off = 8;\n\n // Write version (uint32 LE)\n view.setUint32(off, version, true);\n off += 4;\n\n // Write length-prefixed chunks\n for (const chunk of chunks) {\n view.setUint32(off, chunk.byteLength, true);\n off += 4;\n buf.set(chunk, off);\n off += chunk.byteLength;\n }\n\n return buf;\n}\n\n/**\n * Create a .fig/.deck ZIP archive from canvas.fig + optional metadata.\n * Uses store mode (no compression) via fflate.\n */\nexport function createFigZip(input: CreateFigZipInput): Uint8Array {\n const opts: Record<string, [Uint8Array, { level: 0 }]> = {};\n\n opts[\"canvas.fig\"] = [input.canvasFig, { level: 0 }];\n\n if (input.meta) {\n opts[\"meta.json\"] = [new TextEncoder().encode(JSON.stringify(input.meta)), { level: 0 }];\n }\n\n if (input.thumbnail) {\n opts[\"thumbnail.png\"] = [input.thumbnail, { level: 0 }];\n }\n\n if (input.images) {\n for (const [name, data] of input.images) {\n opts[`images/${name}`] = [data, { level: 0 }];\n }\n }\n\n return zipSync(opts);\n}\n","/** Pre-built empty .fig template — generated by src/utilities/generateTemplate.ts */\n/** @deprecated-backup Figma-derived blob (kept for rollback only):\n * UEsDBBQAAAAAALu8cFyLpHS2wWcAAMFnAAAKAAAAY2FudmFzLmZpZ2ZpZy1raXdpZQAAAJJlAAC0fQuY...\n */\nexport const emptyFigTemplate = \"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\";\n","/**\n * Creates an empty FigDocument by parsing a pre-built template.\n * The template was created from a valid .fig file with user content\n * marked as REMOVED — proven to open in Figma.\n */\n\nimport { parseFig } from \"./parser.js\";\nimport { emptyFigTemplate } from \"./schema.js\";\nimport type { FigDocument } from \"./types.js\";\n\nfunction b64decode(b64: string): Uint8Array {\n const bin = atob(b64);\n const bytes = new Uint8Array(bin.length);\n for (let i = 0; i < bin.length; i++) bytes[i] = bin.charCodeAt(i);\n return bytes;\n}\n\nexport function createEmptyFigDoc(): FigDocument {\n const bytes = b64decode(emptyFigTemplate);\n return parseFig(bytes);\n}\n","import type { FigGradientStop, FigPaint, FigTransform } from \"./types.js\";\n\nexport type GradientKind = \"linear\" | \"radial\";\n\nexport interface GradientFillLike {\n type: GradientKind;\n transform: FigTransform;\n}\n\nexport interface RenderableGradientFill extends GradientFillLike {\n opacity: number;\n stops: FigGradientStop[];\n}\n\nexport interface GradientPoint {\n x: number;\n y: number;\n}\n\nexport interface ResolvedLinearGradientGeometry {\n type: \"linear\";\n start: GradientPoint;\n end: GradientPoint;\n}\n\nexport interface ResolvedRadialGradientGeometry {\n type: \"radial\";\n center: GradientPoint;\n radiusX: number;\n radiusY: number;\n angle: number;\n}\n\nexport type ResolvedGradientGeometry =\n | ResolvedLinearGradientGeometry\n | ResolvedRadialGradientGeometry;\n\nconst IDENTITY_TRANSFORM: FigTransform = {\n m00: 1,\n m01: 0,\n m02: 0,\n m10: 0,\n m11: 1,\n m12: 0,\n};\n\nfunction cloneTransform(transform?: FigTransform): FigTransform {\n if (!transform) return { ...IDENTITY_TRANSFORM };\n return {\n m00: transform.m00,\n m01: transform.m01,\n m02: transform.m02,\n m10: transform.m10,\n m11: transform.m11,\n m12: transform.m12,\n };\n}\n\nfunction isRenderableGradientPaint(\n paint: FigPaint | null | undefined,\n): paint is FigPaint & { type: \"GRADIENT_LINEAR\" | \"GRADIENT_RADIAL\"; stops: FigGradientStop[] } {\n return !!paint &&\n paint.visible !== false &&\n (paint.type === \"GRADIENT_LINEAR\" || paint.type === \"GRADIENT_RADIAL\") &&\n Array.isArray(paint.stops) &&\n paint.stops.length > 0;\n}\n\nexport function extractRenderableGradientFill(\n paints: FigPaint[] | null | undefined,\n): RenderableGradientFill | null {\n const paint = paints?.find((entry) => isRenderableGradientPaint(entry));\n if (!paint) return null;\n\n return {\n type: paint.type === \"GRADIENT_LINEAR\" ? \"linear\" : \"radial\",\n opacity: paint.opacity ?? 1,\n transform: cloneTransform(paint.transform),\n stops: [...paint.stops]\n .sort((a, b) => a.position - b.position)\n .map((stop) => ({\n position: stop.position,\n color: { ...stop.color },\n colorVar: stop.colorVar,\n })),\n };\n}\n\nexport function resolveGradientGeometry(\n fill: GradientFillLike,\n width: number,\n height: number,\n): ResolvedGradientGeometry | null {\n if (width <= 0 || height <= 0) return null;\n\n const transform = fill.transform ?? IDENTITY_TRANSFORM;\n const { m00, m01, m02, m10, m11, m12 } = transform;\n const det = m00 * m11 - m10 * m01;\n if (Math.abs(det) < 1e-12) return null;\n\n // Figma stores paint.transform as node-space -> gradient-space.\n // Consumers usually need the inverse: gradient-space -> node-space.\n const ia = m11 / det;\n const ic = -m01 / det;\n const ie = (m01 * m12 - m11 * m02) / det;\n const ib = -m10 / det;\n const iid = m00 / det;\n const iif = (m10 * m02 - m00 * m12) / det;\n\n const point = (gx: number, gy: number): GradientPoint => ({\n x: (ia * gx + ic * gy + ie) * width,\n y: (ib * gx + iid * gy + iif) * height,\n });\n\n if (fill.type === \"linear\") {\n return {\n type: \"linear\",\n start: point(0, 0.5),\n end: point(1, 0.5),\n };\n }\n\n const center = point(0.5, 0.5);\n const xAxisPoint = point(1, 0.5);\n const yAxisPoint = point(0.5, 1);\n\n return {\n type: \"radial\",\n center,\n radiusX: Math.hypot(xAxisPoint.x - center.x, xAxisPoint.y - center.y),\n radiusY: Math.hypot(yAxisPoint.x - center.x, yAxisPoint.y - center.y),\n angle: Math.atan2(xAxisPoint.y - center.y, xAxisPoint.x - center.x),\n };\n}\n","import type { FigDocument, FigNode, FigPaint } from \"./types.js\";\n\nconst CMD_CLOSE = 0;\nconst CMD_MOVE_TO = 1;\nconst CMD_LINE_TO = 2;\nconst CMD_CUBIC_TO = 4;\nconst SEGMENT_LINE = 0;\nconst SEGMENT_CUBIC = 4;\nconst DEFAULT_HANDLE_MIRRORING = 4;\n\ntype GeometryRef = {\n commandsBlob?: number;\n windingRule?: string;\n styleID?: number;\n};\n\ntype StyleOverride = {\n styleID?: number;\n fillPaints?: FigPaint[];\n};\n\nexport interface ResolvedGeometryPath {\n blobIndex: number;\n commandsBlob: Uint8Array;\n svgPath: string;\n windingRule?: string;\n styleID: number;\n paints?: FigPaint[];\n}\n\nexport interface ResolvedVectorNodePaths {\n fill: ResolvedGeometryPath[];\n stroke: ResolvedGeometryPath[];\n}\n\nexport type VectorPathCommand =\n | { type: \"M\"; x: number; y: number }\n | { type: \"L\"; x: number; y: number }\n | { type: \"C\"; c1x: number; c1y: number; c2x: number; c2y: number; x: number; y: number }\n | { type: \"Z\" };\n\nfunction quadraticToCubic(\n x0: number,\n y0: number,\n qx: number,\n qy: number,\n x: number,\n y: number,\n): Extract<VectorPathCommand, { type: \"C\" }> {\n return {\n type: \"C\",\n c1x: x0 + (2 / 3) * (qx - x0),\n c1y: y0 + (2 / 3) * (qy - y0),\n c2x: x + (2 / 3) * (qx - x),\n c2y: y + (2 / 3) * (qy - y),\n x,\n y,\n };\n}\n\nexport interface VectorGeometryInput {\n svgPath?: string;\n commands?: readonly VectorPathCommand[];\n windingRule?: string;\n styleID?: number;\n}\n\nexport interface VectorStyleOverride {\n styleID: number;\n fillPaints?: FigPaint[];\n [key: string]: any;\n}\n\nexport interface AppendVectorPayloadInput {\n width: number;\n height: number;\n normalizedWidth?: number;\n normalizedHeight?: number;\n fillPaths?: readonly VectorGeometryInput[];\n /**\n * Stroke geometry is expected to already be expanded into outline paths.\n * This helper does not expand SVG strokes into strokeGeometry.\n */\n strokePaths?: readonly VectorGeometryInput[];\n styleOverrideTable?: readonly VectorStyleOverride[];\n}\n\nexport interface AuthoredVectorPayload {\n fillGeometry: GeometryRef[];\n strokeGeometry: GeometryRef[];\n vectorData: {\n vectorNetworkBlob: number;\n normalizedSize: { x: number; y: number };\n styleOverrideTable?: VectorStyleOverride[];\n };\n}\n\nexport function roundPathNumber(n: number, decimals = 2): number {\n const factor = 10 ** decimals;\n return Math.round(n * factor) / factor;\n}\n\nexport function getBlobBytes(doc: FigDocument, blobIndex: number | null | undefined): Uint8Array | null {\n if (blobIndex == null || blobIndex < 0) return null;\n\n const blob = doc.message?.blobs?.[blobIndex];\n if (!blob) return null;\n\n if (blob instanceof Uint8Array) return blob;\n if (blob.bytes instanceof Uint8Array) return blob.bytes;\n if (Array.isArray(blob.bytes)) return Uint8Array.from(blob.bytes);\n\n if (blob.bytes && typeof blob.bytes === \"object\") {\n const values = Object.values(blob.bytes);\n if (values.every((value) => typeof value === \"number\")) {\n return Uint8Array.from(values as number[]);\n }\n }\n\n return null;\n}\n\nexport function geometryBlobToSVGPath(blob: Uint8Array): string {\n if (!blob.length) return \"\";\n\n const view = new DataView(blob.buffer, blob.byteOffset, blob.byteLength);\n let offset = 0;\n const parts: string[] = [];\n\n const canRead = (byteLength: number) => offset + byteLength <= blob.length;\n\n while (offset < blob.length) {\n const cmd = blob[offset++];\n\n switch (cmd) {\n case CMD_CLOSE:\n parts.push(\"Z\");\n break;\n\n case CMD_MOVE_TO: {\n if (!canRead(8)) return parts.join(\"\");\n const x = roundPathNumber(view.getFloat32(offset, true));\n const y = roundPathNumber(view.getFloat32(offset + 4, true));\n offset += 8;\n parts.push(`M${x} ${y}`);\n break;\n }\n\n case CMD_LINE_TO: {\n if (!canRead(8)) return parts.join(\"\");\n const x = roundPathNumber(view.getFloat32(offset, true));\n const y = roundPathNumber(view.getFloat32(offset + 4, true));\n offset += 8;\n parts.push(`L${x} ${y}`);\n break;\n }\n\n case CMD_CUBIC_TO: {\n if (!canRead(24)) return parts.join(\"\");\n const x1 = roundPathNumber(view.getFloat32(offset, true));\n const y1 = roundPathNumber(view.getFloat32(offset + 4, true));\n const x2 = roundPathNumber(view.getFloat32(offset + 8, true));\n const y2 = roundPathNumber(view.getFloat32(offset + 12, true));\n const x = roundPathNumber(view.getFloat32(offset + 16, true));\n const y = roundPathNumber(view.getFloat32(offset + 20, true));\n offset += 24;\n parts.push(`C${x1} ${y1} ${x2} ${y2} ${x} ${y}`);\n break;\n }\n\n default:\n return parts.join(\"\");\n }\n }\n\n return parts.join(\"\");\n}\n\nexport function parseSVGPathData(svgPath: string): VectorPathCommand[] {\n const tokens: Array<string | number> = [];\n const re = /([MmLlCcSsQqTtHhVvZz])|([+-]?(?:\\d+\\.?\\d*|\\.\\d+)(?:[eE][+-]?\\d+)?)/g;\n let match: RegExpExecArray | null;\n while ((match = re.exec(svgPath)) !== null) {\n if (match[1]) tokens.push(match[1]);\n else tokens.push(Number.parseFloat(match[2]));\n }\n\n const commands: VectorPathCommand[] = [];\n let i = 0;\n let cx = 0;\n let cy = 0;\n let startX = 0;\n let startY = 0;\n let prevC2x = 0;\n let prevC2y = 0;\n let prevQuadraticX = 0;\n let prevQuadraticY = 0;\n let cmd = \"\";\n const num = () => {\n const value = tokens[i++];\n if (typeof value !== \"number\" || Number.isNaN(value)) {\n throw new Error(`Invalid SVG path data near token index ${i - 1}`);\n }\n return value;\n };\n\n while (i < tokens.length) {\n if (typeof tokens[i] === \"string\") cmd = tokens[i++] as string;\n switch (cmd) {\n case \"M\":\n cx = num(); cy = num(); startX = cx; startY = cy;\n commands.push({ type: \"M\", x: cx, y: cy });\n prevC2x = cx;\n prevC2y = cy;\n prevQuadraticX = cx;\n prevQuadraticY = cy;\n cmd = \"L\";\n break;\n case \"m\":\n cx += num(); cy += num(); startX = cx; startY = cy;\n commands.push({ type: \"M\", x: cx, y: cy });\n prevC2x = cx;\n prevC2y = cy;\n prevQuadraticX = cx;\n prevQuadraticY = cy;\n cmd = \"l\";\n break;\n case \"L\":\n cx = num(); cy = num();\n commands.push({ type: \"L\", x: cx, y: cy });\n prevC2x = cx;\n prevC2y = cy;\n prevQuadraticX = cx;\n prevQuadraticY = cy;\n break;\n case \"l\":\n cx += num(); cy += num();\n commands.push({ type: \"L\", x: cx, y: cy });\n prevC2x = cx;\n prevC2y = cy;\n prevQuadraticX = cx;\n prevQuadraticY = cy;\n break;\n case \"H\":\n cx = num();\n commands.push({ type: \"L\", x: cx, y: cy });\n prevC2x = cx;\n prevC2y = cy;\n prevQuadraticX = cx;\n prevQuadraticY = cy;\n break;\n case \"h\":\n cx += num();\n commands.push({ type: \"L\", x: cx, y: cy });\n prevC2x = cx;\n prevC2y = cy;\n prevQuadraticX = cx;\n prevQuadraticY = cy;\n break;\n case \"V\":\n cy = num();\n commands.push({ type: \"L\", x: cx, y: cy });\n prevC2x = cx;\n prevC2y = cy;\n prevQuadraticX = cx;\n prevQuadraticY = cy;\n break;\n case \"v\":\n cy += num();\n commands.push({ type: \"L\", x: cx, y: cy });\n prevC2x = cx;\n prevC2y = cy;\n prevQuadraticX = cx;\n prevQuadraticY = cy;\n break;\n case \"C\": {\n const c1x = num();\n const c1y = num();\n const c2x = num();\n const c2y = num();\n cx = num();\n cy = num();\n prevC2x = c2x;\n prevC2y = c2y;\n prevQuadraticX = cx;\n prevQuadraticY = cy;\n commands.push({ type: \"C\", c1x, c1y, c2x, c2y, x: cx, y: cy });\n break;\n }\n case \"c\": {\n const c1x = cx + num();\n const c1y = cy + num();\n const c2x = cx + num();\n const c2y = cy + num();\n cx += num();\n cy += num();\n prevC2x = c2x;\n prevC2y = c2y;\n prevQuadraticX = cx;\n prevQuadraticY = cy;\n commands.push({ type: \"C\", c1x, c1y, c2x, c2y, x: cx, y: cy });\n break;\n }\n case \"S\": {\n const c1x = 2 * cx - prevC2x;\n const c1y = 2 * cy - prevC2y;\n const c2x = num();\n const c2y = num();\n cx = num();\n cy = num();\n prevC2x = c2x;\n prevC2y = c2y;\n prevQuadraticX = cx;\n prevQuadraticY = cy;\n commands.push({ type: \"C\", c1x, c1y, c2x, c2y, x: cx, y: cy });\n break;\n }\n case \"s\": {\n const c1x = 2 * cx - prevC2x;\n const c1y = 2 * cy - prevC2y;\n const c2x = cx + num();\n const c2y = cy + num();\n cx += num();\n cy += num();\n prevC2x = c2x;\n prevC2y = c2y;\n prevQuadraticX = cx;\n prevQuadraticY = cy;\n commands.push({ type: \"C\", c1x, c1y, c2x, c2y, x: cx, y: cy });\n break;\n }\n case \"Q\": {\n const qx = num();\n const qy = num();\n const x = num();\n const y = num();\n const cubic = quadraticToCubic(cx, cy, qx, qy, x, y);\n commands.push(cubic);\n prevQuadraticX = qx;\n prevQuadraticY = qy;\n prevC2x = cubic.c2x;\n prevC2y = cubic.c2y;\n cx = x;\n cy = y;\n break;\n }\n case \"q\": {\n const qx = cx + num();\n const qy = cy + num();\n const x = cx + num();\n const y = cy + num();\n const cubic = quadraticToCubic(cx, cy, qx, qy, x, y);\n commands.push(cubic);\n prevQuadraticX = qx;\n prevQuadraticY = qy;\n prevC2x = cubic.c2x;\n prevC2y = cubic.c2y;\n cx = x;\n cy = y;\n break;\n }\n case \"T\": {\n const qx = 2 * cx - prevQuadraticX;\n const qy = 2 * cy - prevQuadraticY;\n const x = num();\n const y = num();\n const cubic = quadraticToCubic(cx, cy, qx, qy, x, y);\n commands.push(cubic);\n prevQuadraticX = qx;\n prevQuadraticY = qy;\n prevC2x = cubic.c2x;\n prevC2y = cubic.c2y;\n cx = x;\n cy = y;\n break;\n }\n case \"t\": {\n const qx = 2 * cx - prevQuadraticX;\n const qy = 2 * cy - prevQuadraticY;\n const x = cx + num();\n const y = cy + num();\n const cubic = quadraticToCubic(cx, cy, qx, qy, x, y);\n commands.push(cubic);\n prevQuadraticX = qx;\n prevQuadraticY = qy;\n prevC2x = cubic.c2x;\n prevC2y = cubic.c2y;\n cx = x;\n cy = y;\n break;\n }\n case \"Z\":\n case \"z\":\n commands.push({ type: \"Z\" });\n cx = startX;\n cy = startY;\n prevC2x = cx;\n prevC2y = cy;\n prevQuadraticX = cx;\n prevQuadraticY = cy;\n break;\n case \"\":\n i++;\n break;\n default:\n throw new Error(`Unsupported SVG path command: ${cmd}`);\n }\n }\n\n return commands;\n}\n\nexport function encodeCommandsBlob(\n commands: readonly VectorPathCommand[],\n scaleX = 1,\n scaleY = 1,\n): Uint8Array {\n let byteLength = 0;\n for (const command of commands) {\n byteLength += 1;\n if (command.type === \"M\" || command.type === \"L\") byteLength += 8;\n else if (command.type === \"C\") byteLength += 24;\n }\n\n const buffer = new ArrayBuffer(byteLength);\n const view = new DataView(buffer);\n let offset = 0;\n\n for (const command of commands) {\n switch (command.type) {\n case \"M\":\n view.setUint8(offset++, CMD_MOVE_TO);\n view.setFloat32(offset, command.x * scaleX, true); offset += 4;\n view.setFloat32(offset, command.y * scaleY, true); offset += 4;\n break;\n case \"L\":\n view.setUint8(offset++, CMD_LINE_TO);\n view.setFloat32(offset, command.x * scaleX, true); offset += 4;\n view.setFloat32(offset, command.y * scaleY, true); offset += 4;\n break;\n case \"C\":\n view.setUint8(offset++, CMD_CUBIC_TO);\n view.setFloat32(offset, command.c1x * scaleX, true); offset += 4;\n view.setFloat32(offset, command.c1y * scaleY, true); offset += 4;\n view.setFloat32(offset, command.c2x * scaleX, true); offset += 4;\n view.setFloat32(offset, command.c2y * scaleY, true); offset += 4;\n view.setFloat32(offset, command.x * scaleX, true); offset += 4;\n view.setFloat32(offset, command.y * scaleY, true); offset += 4;\n break;\n case \"Z\":\n view.setUint8(offset++, CMD_CLOSE);\n break;\n }\n }\n\n return new Uint8Array(buffer, 0, offset);\n}\n\nexport function encodeVectorNetworkBlob(pathCommandsList: readonly (readonly VectorPathCommand[])[]): Uint8Array {\n const vertices: Array<{ x: number; y: number }> = [];\n const segments: Array<{ s: number; tsx: number; tsy: number; e: number; tex: number; tey: number; t: number }> = [];\n const regions: number[][] = [];\n\n for (const pathCommands of pathCommandsList) {\n let regionSegments: number[] = [];\n let firstVertex = -1;\n let prevVertex = -1;\n let prevX = 0;\n let prevY = 0;\n\n for (const command of pathCommands) {\n if (command.type === \"M\") {\n // Each sub-path (M...Z sequence) becomes its own region so Figma\n // strokes compound paths correctly (e.g. counter holes in letters).\n if (regionSegments.length > 0) {\n regions.push(regionSegments);\n regionSegments = [];\n }\n const vertexIndex = vertices.length;\n vertices.push({ x: command.x, y: command.y });\n firstVertex = vertexIndex;\n prevVertex = vertexIndex;\n prevX = command.x;\n prevY = command.y;\n } else if (command.type === \"L\") {\n const vertexIndex = vertices.length;\n vertices.push({ x: command.x, y: command.y });\n if (prevVertex >= 0) {\n regionSegments.push(segments.length);\n segments.push({ s: prevVertex, tsx: 0, tsy: 0, e: vertexIndex, tex: 0, tey: 0, t: SEGMENT_LINE });\n }\n prevVertex = vertexIndex;\n prevX = command.x;\n prevY = command.y;\n } else if (command.type === \"C\") {\n const vertexIndex = vertices.length;\n vertices.push({ x: command.x, y: command.y });\n if (prevVertex >= 0) {\n regionSegments.push(segments.length);\n segments.push({\n s: prevVertex,\n tsx: command.c1x - prevX,\n tsy: command.c1y - prevY,\n e: vertexIndex,\n tex: command.c2x - command.x,\n tey: command.c2y - command.y,\n t: SEGMENT_CUBIC,\n });\n }\n prevVertex = vertexIndex;\n prevX = command.x;\n prevY = command.y;\n } else if (command.type === \"Z\") {\n if (prevVertex >= 0 && prevVertex !== firstVertex) {\n const lastPos = vertices[prevVertex];\n const firstPos = vertices[firstVertex];\n const dx = lastPos.x - firstPos.x;\n const dy = lastPos.y - firstPos.y;\n if (dx * dx + dy * dy < 1e-4) {\n // Path already returned to start — merge the duplicate end vertex\n // into firstVertex so Figma sees one vertex with correct incoming\n // and outgoing bezier tangent handles for miter join computation.\n // Without this, a zero-length closing LINE segment would give Figma\n // a degenerate tangent, producing wrong miter angles (visible as\n // notches at sharp corners like the \"g\" terminal).\n const lastSeg = segments[segments.length - 1];\n if (lastSeg && lastSeg.e === prevVertex) {\n lastSeg.e = firstVertex;\n vertices.pop();\n }\n } else {\n regionSegments.push(segments.length);\n segments.push({ s: prevVertex, tsx: 0, tsy: 0, e: firstVertex, tex: 0, tey: 0, t: SEGMENT_LINE });\n }\n }\n if (firstVertex >= 0) {\n prevVertex = firstVertex;\n prevX = vertices[firstVertex].x;\n prevY = vertices[firstVertex].y;\n }\n }\n }\n\n regions.push(regionSegments);\n }\n\n let regionsByteLength = 0;\n for (const region of regions) regionsByteLength += 4 + 4 + (region.length * 4) + 4;\n const totalByteLength = 16 + (vertices.length * 12) + (segments.length * 28) + regionsByteLength;\n\n const buffer = new ArrayBuffer(totalByteLength);\n const view = new DataView(buffer);\n let offset = 0;\n\n view.setUint32(offset, vertices.length, true); offset += 4;\n view.setUint32(offset, segments.length, true); offset += 4;\n view.setUint32(offset, regions.length, true); offset += 4;\n view.setUint32(offset, 1, true); offset += 4;\n\n for (const vertex of vertices) {\n view.setFloat32(offset, vertex.x, true); offset += 4;\n view.setFloat32(offset, vertex.y, true); offset += 4;\n view.setUint32(offset, DEFAULT_HANDLE_MIRRORING, true); offset += 4;\n }\n\n for (const segment of segments) {\n view.setUint32(offset, segment.s, true); offset += 4;\n view.setFloat32(offset, segment.tsx, true); offset += 4;\n view.setFloat32(offset, segment.tsy, true); offset += 4;\n view.setUint32(offset, segment.e, true); offset += 4;\n view.setFloat32(offset, segment.tex, true); offset += 4;\n view.setFloat32(offset, segment.tey, true); offset += 4;\n view.setUint32(offset, segment.t, true); offset += 4;\n }\n\n for (const region of regions) {\n view.setUint32(offset, 1, true); offset += 4;\n view.setUint32(offset, region.length, true); offset += 4;\n for (const segmentIndex of region) {\n view.setUint32(offset, segmentIndex, true); offset += 4;\n }\n view.setUint32(offset, 1, true); offset += 4;\n }\n\n return new Uint8Array(buffer, 0, offset);\n}\n\nfunction cloneStyleOverrides(styleOverrideTable: readonly VectorStyleOverride[] | undefined): VectorStyleOverride[] | undefined {\n if (!styleOverrideTable?.length) return undefined;\n return JSON.parse(JSON.stringify(styleOverrideTable));\n}\n\nfunction toCommands(input: VectorGeometryInput): VectorPathCommand[] {\n if (Array.isArray(input.commands) && input.commands.length > 0) {\n return input.commands.map((command) => ({ ...command }));\n }\n if (input.svgPath) return parseSVGPathData(input.svgPath);\n throw new Error(\"Vector geometry input requires either svgPath or commands\");\n}\n\nexport function appendVectorPayloadToDocument(\n doc: FigDocument,\n input: AppendVectorPayloadInput,\n): AuthoredVectorPayload {\n const blobs: any[] = doc.message?.blobs ?? (doc.message.blobs = []);\n const normalizedWidth = input.normalizedWidth ?? input.width;\n const normalizedHeight = input.normalizedHeight ?? input.height;\n const scaleX = normalizedWidth === 0 ? 1 : input.width / normalizedWidth;\n const scaleY = normalizedHeight === 0 ? 1 : input.height / normalizedHeight;\n\n const fillPaths = (input.fillPaths ?? []).map(toCommands);\n const strokePaths = (input.strokePaths ?? []).map(toCommands);\n if (fillPaths.length === 0 && strokePaths.length === 0) {\n throw new Error(\"Vector payload requires at least one fill or stroke path\");\n }\n\n const fillGeometry: GeometryRef[] = [];\n for (let i = 0; i < fillPaths.length; i++) {\n const bytes = encodeCommandsBlob(fillPaths[i], scaleX, scaleY);\n blobs.push({ bytes });\n const path = input.fillPaths?.[i];\n fillGeometry.push({\n windingRule: path?.windingRule ?? \"NONZERO\",\n commandsBlob: blobs.length - 1,\n styleID: path?.styleID ?? 0,\n });\n }\n\n const strokeGeometry: GeometryRef[] = [];\n for (let i = 0; i < strokePaths.length; i++) {\n const bytes = encodeCommandsBlob(strokePaths[i], scaleX, scaleY);\n blobs.push({ bytes });\n const path = input.strokePaths?.[i];\n strokeGeometry.push({\n windingRule: path?.windingRule ?? \"NONZERO\",\n commandsBlob: blobs.length - 1,\n styleID: path?.styleID ?? 0,\n });\n }\n\n const vectorNetworkBlob = encodeVectorNetworkBlob([...fillPaths, ...strokePaths]);\n blobs.push({ bytes: vectorNetworkBlob });\n\n return {\n fillGeometry,\n strokeGeometry,\n vectorData: {\n vectorNetworkBlob: blobs.length - 1,\n normalizedSize: { x: normalizedWidth, y: normalizedHeight },\n ...(cloneStyleOverrides(input.styleOverrideTable)?.length\n ? { styleOverrideTable: cloneStyleOverrides(input.styleOverrideTable) }\n : {}),\n },\n };\n}\n\nfunction getStyleOverrideTable(node: FigNode): StyleOverride[] {\n const table = node.vectorData?.styleOverrideTable;\n return Array.isArray(table) ? table : [];\n}\n\nfunction resolveFillPaints(node: FigNode, styleID: number): FigPaint[] | undefined {\n if (!styleID) return node.fillPaints;\n const override = getStyleOverrideTable(node).find((entry) => entry?.styleID === styleID);\n if (!override || !(\"fillPaints\" in override)) return node.fillPaints;\n return override.fillPaints;\n}\n\nfunction resolveGeometry(\n doc: FigDocument,\n node: FigNode,\n geometry: GeometryRef[] | undefined,\n kind: \"fill\" | \"stroke\",\n): ResolvedGeometryPath[] {\n if (!Array.isArray(geometry) || geometry.length === 0) return [];\n\n const resolved: Array<ResolvedGeometryPath | null> = geometry.map((entry) => {\n if (typeof entry?.commandsBlob !== \"number\") return null;\n const bytes = getBlobBytes(doc, entry.commandsBlob);\n if (!bytes) return null;\n const svgPath = geometryBlobToSVGPath(bytes);\n if (!svgPath) return null;\n\n const path: ResolvedGeometryPath = {\n blobIndex: entry.commandsBlob,\n commandsBlob: bytes,\n svgPath,\n windingRule: entry.windingRule,\n styleID: entry.styleID || 0,\n paints: kind === \"fill\" ? resolveFillPaints(node, entry.styleID || 0) : node.strokePaints,\n };\n\n return path;\n });\n\n return resolved.filter((entry): entry is ResolvedGeometryPath => entry !== null);\n}\n\nexport function resolveVectorNodePaths(doc: FigDocument, node: FigNode): ResolvedVectorNodePaths {\n return {\n fill: resolveGeometry(doc, node, node.fillGeometry as GeometryRef[] | undefined, \"fill\"),\n stroke: resolveGeometry(doc, node, node.strokeGeometry as GeometryRef[] | undefined, \"stroke\"),\n };\n}\n","/**\n * CSS / hex color ↔ Figma normalized RGBA color helpers.\n *\n * All functions are isomorphic (no DOM required).\n * For named CSS colors (e.g. \"coral\"), pass an optional `resolveNamed`\n * callback that uses the browser's computed-style machinery.\n */\n\nimport type { FigColor, FigPaint } from \"./types.js\";\n\nexport function hexToFigColor(hex: string): FigColor {\n if (!hex || hex === \"transparent\") return { r: 0, g: 0, b: 0, a: 0 };\n const h = hex.replace(\"#\", \"\");\n const r = parseInt(h.substring(0, 2), 16) / 255;\n const g = parseInt(h.substring(2, 4), 16) / 255;\n const b = parseInt(h.substring(4, 6), 16) / 255;\n const a = h.length >= 8 ? parseInt(h.substring(6, 8), 16) / 255 : 1;\n return { r, g, b, a };\n}\n\nexport function parseCssRgbColor(value: string): FigColor | null {\n const match = value.trim().match(/^rgba?\\((.+)\\)$/i);\n if (!match) return null;\n const parts = match[1].split(\",\").map((part) => part.trim());\n if (parts.length < 3) return null;\n const r = Number.parseFloat(parts[0]);\n const g = Number.parseFloat(parts[1]);\n const b = Number.parseFloat(parts[2]);\n const a = parts.length >= 4 ? Number.parseFloat(parts[3]) : 1;\n if ([r, g, b, a].some((n) => Number.isNaN(n))) return null;\n return { r: r / 255, g: g / 255, b: b / 255, a };\n}\n\nexport function cssColorToFigColor(\n value: string,\n resolveNamed?: (name: string) => FigColor | null,\n): FigColor {\n const trimmed = value.trim();\n if (trimmed === \"transparent\" || trimmed === \"none\") return { r: 0, g: 0, b: 0, a: 0 };\n if (trimmed.startsWith(\"#\")) return hexToFigColor(trimmed);\n const rgba = parseCssRgbColor(trimmed);\n if (rgba) return rgba;\n\n if (resolveNamed) {\n const resolved = resolveNamed(trimmed);\n if (resolved) return resolved;\n }\n\n throw new Error(`Unsupported CSS color: ${value}`);\n}\n\nexport function makeSolidPaint(\n fill: string,\n resolveNamed?: (name: string) => FigColor | null,\n): FigPaint {\n const color = cssColorToFigColor(fill, resolveNamed);\n return {\n type: \"SOLID\",\n color: { r: color.r, g: color.g, b: color.b, a: 1 },\n opacity: color.a,\n visible: true,\n blendMode: \"NORMAL\",\n };\n}\n","/**\n * SVG path serialization, transformation, and stroke/cap enum mapping.\n */\n\nimport { parseSVGPathData } from \"./vector.js\";\nimport type { VectorPathCommand } from \"./vector.js\";\n\nexport function serializeSvgPathData(commands: readonly VectorPathCommand[]): string {\n return commands\n .map((command) => {\n switch (command.type) {\n case \"M\":\n return `M${command.x} ${command.y}`;\n case \"L\":\n return `L${command.x} ${command.y}`;\n case \"C\":\n return `C${command.c1x} ${command.c1y} ${command.c2x} ${command.c2y} ${command.x} ${command.y}`;\n case \"Z\":\n return \"Z\";\n }\n })\n .join(\" \");\n}\n\nexport function transformSvgPathData(\n svgPath: string,\n {\n scaleX = 1,\n scaleY = 1,\n translateX = 0,\n translateY = 0,\n }: { scaleX?: number; scaleY?: number; translateX?: number; translateY?: number },\n): string {\n const commands = parseSVGPathData(svgPath).map((command) => {\n switch (command.type) {\n case \"M\":\n case \"L\":\n return {\n ...command,\n x: command.x * scaleX + translateX,\n y: command.y * scaleY + translateY,\n };\n case \"C\":\n return {\n ...command,\n c1x: command.c1x * scaleX + translateX,\n c1y: command.c1y * scaleY + translateY,\n c2x: command.c2x * scaleX + translateX,\n c2y: command.c2y * scaleY + translateY,\n x: command.x * scaleX + translateX,\n y: command.y * scaleY + translateY,\n };\n case \"Z\":\n return command;\n }\n });\n\n return serializeSvgPathData(commands);\n}\n\nexport function mapStrokeJoin(value: string | undefined): string {\n switch ((value || \"\").toLowerCase()) {\n case \"round\":\n return \"ROUND\";\n case \"bevel\":\n return \"BEVEL\";\n default:\n return \"MITER\";\n }\n}\n\nexport function mapStrokeCap(value: string | undefined): string {\n switch ((value || \"\").toLowerCase()) {\n case \"round\":\n return \"ROUND\";\n case \"square\":\n return \"SQUARE\";\n default:\n return \"NONE\";\n }\n}\n"],"mappings":"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","names":[]}
|