@llc3233149/core 0.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (457) hide show
  1. package/dist/canvaskit.d.ts +9 -0
  2. package/dist/canvaskit.d.ts.map +1 -0
  3. package/dist/canvaskit.js +55 -0
  4. package/dist/canvaskit.js.map +1 -0
  5. package/dist/clipboard.d.ts +32 -0
  6. package/dist/clipboard.d.ts.map +1 -0
  7. package/dist/clipboard.js +345 -0
  8. package/dist/clipboard.js.map +1 -0
  9. package/dist/color.d.ts +28 -0
  10. package/dist/color.d.ts.map +1 -0
  11. package/dist/color.js +67 -0
  12. package/dist/color.js.map +1 -0
  13. package/dist/constants.d.ts +159 -0
  14. package/dist/constants.d.ts.map +1 -0
  15. package/dist/constants.js +224 -0
  16. package/dist/constants.js.map +1 -0
  17. package/dist/copy.d.ts +20 -0
  18. package/dist/copy.d.ts.map +1 -0
  19. package/dist/copy.js +64 -0
  20. package/dist/copy.js.map +1 -0
  21. package/dist/fig-export-worker.d.ts +2 -0
  22. package/dist/fig-export-worker.d.ts.map +1 -0
  23. package/dist/fig-export-worker.js +17 -0
  24. package/dist/fig-export-worker.js.map +1 -0
  25. package/dist/fig-export.d.ts +13 -0
  26. package/dist/fig-export.d.ts.map +1 -0
  27. package/dist/fig-export.js +243 -0
  28. package/dist/fig-export.js.map +1 -0
  29. package/dist/figma-api.d.ts +268 -0
  30. package/dist/figma-api.d.ts.map +1 -0
  31. package/dist/figma-api.js +1074 -0
  32. package/dist/figma-api.js.map +1 -0
  33. package/dist/figma-rest-import.d.ts +122 -0
  34. package/dist/figma-rest-import.d.ts.map +1 -0
  35. package/dist/figma-rest-import.js +319 -0
  36. package/dist/figma-rest-import.js.map +1 -0
  37. package/dist/fonts.d.ts +24 -0
  38. package/dist/fonts.d.ts.map +1 -0
  39. package/dist/fonts.js +356 -0
  40. package/dist/fonts.js.map +1 -0
  41. package/dist/geometry.d.ts +14 -0
  42. package/dist/geometry.d.ts.map +1 -0
  43. package/dist/geometry.js +47 -0
  44. package/dist/geometry.js.map +1 -0
  45. package/dist/index.d.ts +38 -0
  46. package/dist/index.d.ts.map +1 -0
  47. package/dist/index.js +32 -0
  48. package/dist/index.js.map +1 -0
  49. package/dist/kiwi/codec.d.ts +292 -0
  50. package/dist/kiwi/codec.d.ts.map +1 -0
  51. package/dist/kiwi/codec.js +340 -0
  52. package/dist/kiwi/codec.js.map +1 -0
  53. package/dist/kiwi/fig-file.d.ts +4 -0
  54. package/dist/kiwi/fig-file.d.ts.map +1 -0
  55. package/dist/kiwi/fig-file.js +236 -0
  56. package/dist/kiwi/fig-file.js.map +1 -0
  57. package/dist/kiwi/fig-import.d.ts +4 -0
  58. package/dist/kiwi/fig-import.d.ts.map +1 -0
  59. package/dist/kiwi/fig-import.js +248 -0
  60. package/dist/kiwi/fig-import.js.map +1 -0
  61. package/dist/kiwi/fig-parse-worker.d.ts +7 -0
  62. package/dist/kiwi/fig-parse-worker.d.ts.map +1 -0
  63. package/dist/kiwi/fig-parse-worker.js +184 -0
  64. package/dist/kiwi/fig-parse-worker.js.map +1 -0
  65. package/dist/kiwi/instance-overrides.d.ts +66 -0
  66. package/dist/kiwi/instance-overrides.d.ts.map +1 -0
  67. package/dist/kiwi/instance-overrides.js +644 -0
  68. package/dist/kiwi/instance-overrides.js.map +1 -0
  69. package/dist/kiwi/kiwi-convert.d.ts +19 -0
  70. package/dist/kiwi/kiwi-convert.d.ts.map +1 -0
  71. package/dist/kiwi/kiwi-convert.js +678 -0
  72. package/dist/kiwi/kiwi-convert.js.map +1 -0
  73. package/dist/kiwi/kiwi-schema/bb.d.ts +25 -0
  74. package/dist/kiwi/kiwi-schema/bb.d.ts.map +1 -0
  75. package/dist/kiwi/kiwi-schema/bb.js +225 -0
  76. package/dist/kiwi/kiwi-schema/bb.js.map +1 -0
  77. package/dist/kiwi/kiwi-schema/binary.d.ts +5 -0
  78. package/dist/kiwi/kiwi-schema/binary.d.ts.map +1 -0
  79. package/dist/kiwi/kiwi-schema/binary.js +86 -0
  80. package/dist/kiwi/kiwi-schema/binary.js.map +1 -0
  81. package/dist/kiwi/kiwi-schema/index.d.ts +6 -0
  82. package/dist/kiwi/kiwi-schema/index.d.ts.map +1 -0
  83. package/dist/kiwi/kiwi-schema/index.js +5 -0
  84. package/dist/kiwi/kiwi-schema/index.js.map +1 -0
  85. package/dist/kiwi/kiwi-schema/js.d.ts +4 -0
  86. package/dist/kiwi/kiwi-schema/js.d.ts.map +1 -0
  87. package/dist/kiwi/kiwi-schema/js.js +282 -0
  88. package/dist/kiwi/kiwi-schema/js.js.map +1 -0
  89. package/dist/kiwi/kiwi-schema/parser.d.ts +5 -0
  90. package/dist/kiwi/kiwi-schema/parser.d.ts.map +1 -0
  91. package/dist/kiwi/kiwi-schema/parser.js +228 -0
  92. package/dist/kiwi/kiwi-schema/parser.js.map +1 -0
  93. package/dist/kiwi/kiwi-schema/schema.d.ts +22 -0
  94. package/dist/kiwi/kiwi-schema/schema.d.ts.map +1 -0
  95. package/dist/kiwi/kiwi-schema/schema.js +2 -0
  96. package/dist/kiwi/kiwi-schema/schema.js.map +1 -0
  97. package/dist/kiwi/kiwi-schema/util.d.ts +3 -0
  98. package/dist/kiwi/kiwi-schema/util.d.ts.map +1 -0
  99. package/dist/kiwi/kiwi-schema/util.js +10 -0
  100. package/dist/kiwi/kiwi-schema/util.js.map +1 -0
  101. package/dist/kiwi/protocol.d.ts +172 -0
  102. package/dist/kiwi/protocol.d.ts.map +1 -0
  103. package/dist/kiwi/protocol.js +214 -0
  104. package/dist/kiwi/protocol.js.map +1 -0
  105. package/dist/kiwi/schema.d.ts +3 -0
  106. package/dist/kiwi/schema.d.ts.map +1 -0
  107. package/dist/kiwi/schema.js +2285 -0
  108. package/dist/kiwi/schema.js.map +1 -0
  109. package/dist/kiwi-serialize.d.ts +17 -0
  110. package/dist/kiwi-serialize.d.ts.map +1 -0
  111. package/dist/kiwi-serialize.js +419 -0
  112. package/dist/kiwi-serialize.js.map +1 -0
  113. package/dist/layout.d.ts +9 -0
  114. package/dist/layout.d.ts.map +1 -0
  115. package/dist/layout.js +533 -0
  116. package/dist/layout.js.map +1 -0
  117. package/dist/profiler/draw-call-counter.d.ts +9 -0
  118. package/dist/profiler/draw-call-counter.d.ts.map +1 -0
  119. package/dist/profiler/draw-call-counter.js +37 -0
  120. package/dist/profiler/draw-call-counter.js.map +1 -0
  121. package/dist/profiler/frame-capture.d.ts +34 -0
  122. package/dist/profiler/frame-capture.d.ts.map +1 -0
  123. package/dist/profiler/frame-capture.js +90 -0
  124. package/dist/profiler/frame-capture.js.map +1 -0
  125. package/dist/profiler/frame-stats.d.ts +33 -0
  126. package/dist/profiler/frame-stats.d.ts.map +1 -0
  127. package/dist/profiler/frame-stats.js +103 -0
  128. package/dist/profiler/frame-stats.js.map +1 -0
  129. package/dist/profiler/gpu-timer.d.ts +15 -0
  130. package/dist/profiler/gpu-timer.d.ts.map +1 -0
  131. package/dist/profiler/gpu-timer.js +77 -0
  132. package/dist/profiler/gpu-timer.js.map +1 -0
  133. package/dist/profiler/hud-renderer.d.ts +22 -0
  134. package/dist/profiler/hud-renderer.d.ts.map +1 -0
  135. package/dist/profiler/hud-renderer.js +200 -0
  136. package/dist/profiler/hud-renderer.js.map +1 -0
  137. package/dist/profiler/index.d.ts +9 -0
  138. package/dist/profiler/index.d.ts.map +1 -0
  139. package/dist/profiler/index.js +8 -0
  140. package/dist/profiler/index.js.map +1 -0
  141. package/dist/profiler/phase-timer.d.ts +9 -0
  142. package/dist/profiler/phase-timer.d.ts.map +1 -0
  143. package/dist/profiler/phase-timer.js +51 -0
  144. package/dist/profiler/phase-timer.js.map +1 -0
  145. package/dist/profiler/render-profiler.d.ts +41 -0
  146. package/dist/profiler/render-profiler.d.ts.map +1 -0
  147. package/dist/profiler/render-profiler.js +142 -0
  148. package/dist/profiler/render-profiler.js.map +1 -0
  149. package/dist/render/components.d.ts +25 -0
  150. package/dist/render/components.d.ts.map +1 -0
  151. package/dist/render/components.js +55 -0
  152. package/dist/render/components.js.map +1 -0
  153. package/dist/render/emoji-icons.d.ts +5 -0
  154. package/dist/render/emoji-icons.d.ts.map +1 -0
  155. package/dist/render/emoji-icons.js +55 -0
  156. package/dist/render/emoji-icons.js.map +1 -0
  157. package/dist/render/export-code.d.ts +9 -0
  158. package/dist/render/export-code.d.ts.map +1 -0
  159. package/dist/render/export-code.js +335 -0
  160. package/dist/render/export-code.js.map +1 -0
  161. package/dist/render/export-jsx.d.ts +5 -0
  162. package/dist/render/export-jsx.d.ts.map +1 -0
  163. package/dist/render/export-jsx.js +621 -0
  164. package/dist/render/export-jsx.js.map +1 -0
  165. package/dist/render/index.d.ts +8 -0
  166. package/dist/render/index.d.ts.map +1 -0
  167. package/dist/render/index.js +8 -0
  168. package/dist/render/index.js.map +1 -0
  169. package/dist/render/jsx-runtime.d.ts +31 -0
  170. package/dist/render/jsx-runtime.d.ts.map +1 -0
  171. package/dist/render/jsx-runtime.js +13 -0
  172. package/dist/render/jsx-runtime.js.map +1 -0
  173. package/dist/render/mini-react.d.ts +14 -0
  174. package/dist/render/mini-react.d.ts.map +1 -0
  175. package/dist/render/mini-react.js +16 -0
  176. package/dist/render/mini-react.js.map +1 -0
  177. package/dist/render/render-jsx.d.ts +24 -0
  178. package/dist/render/render-jsx.d.ts.map +1 -0
  179. package/dist/render/render-jsx.js +51 -0
  180. package/dist/render/render-jsx.js.map +1 -0
  181. package/dist/render/renderer.d.ts +16 -0
  182. package/dist/render/renderer.d.ts.map +1 -0
  183. package/dist/render/renderer.js +437 -0
  184. package/dist/render/renderer.js.map +1 -0
  185. package/dist/render/tailwind.d.ts +20 -0
  186. package/dist/render/tailwind.d.ts.map +1 -0
  187. package/dist/render/tailwind.js +115 -0
  188. package/dist/render/tailwind.js.map +1 -0
  189. package/dist/render/tree.d.ts +72 -0
  190. package/dist/render/tree.d.ts.map +1 -0
  191. package/dist/render/tree.js +63 -0
  192. package/dist/render/tree.js.map +1 -0
  193. package/dist/render-image.d.ts +19 -0
  194. package/dist/render-image.d.ts.map +1 -0
  195. package/dist/render-image.js +84 -0
  196. package/dist/render-image.js.map +1 -0
  197. package/dist/renderer/effects.d.ts +9 -0
  198. package/dist/renderer/effects.d.ts.map +1 -0
  199. package/dist/renderer/effects.js +44 -0
  200. package/dist/renderer/effects.js.map +1 -0
  201. package/dist/renderer/fills.d.ts +9 -0
  202. package/dist/renderer/fills.d.ts.map +1 -0
  203. package/dist/renderer/fills.js +189 -0
  204. package/dist/renderer/fills.js.map +1 -0
  205. package/dist/renderer/index.d.ts +2 -0
  206. package/dist/renderer/index.d.ts.map +1 -0
  207. package/dist/renderer/index.js +2 -0
  208. package/dist/renderer/index.js.map +1 -0
  209. package/dist/renderer/label-cache.d.ts +43 -0
  210. package/dist/renderer/label-cache.d.ts.map +1 -0
  211. package/dist/renderer/label-cache.js +85 -0
  212. package/dist/renderer/label-cache.js.map +1 -0
  213. package/dist/renderer/labels.d.ts +6 -0
  214. package/dist/renderer/labels.d.ts.map +1 -0
  215. package/dist/renderer/labels.js +126 -0
  216. package/dist/renderer/labels.js.map +1 -0
  217. package/dist/renderer/lru-cache.d.ts +20 -0
  218. package/dist/renderer/lru-cache.d.ts.map +1 -0
  219. package/dist/renderer/lru-cache.js +65 -0
  220. package/dist/renderer/lru-cache.js.map +1 -0
  221. package/dist/renderer/overlays.d.ts +25 -0
  222. package/dist/renderer/overlays.d.ts.map +1 -0
  223. package/dist/renderer/overlays.js +783 -0
  224. package/dist/renderer/overlays.js.map +1 -0
  225. package/dist/renderer/renderer.d.ts +229 -0
  226. package/dist/renderer/renderer.d.ts.map +1 -0
  227. package/dist/renderer/renderer.js +909 -0
  228. package/dist/renderer/renderer.js.map +1 -0
  229. package/dist/renderer/rulers.d.ts +8 -0
  230. package/dist/renderer/rulers.d.ts.map +1 -0
  231. package/dist/renderer/rulers.js +147 -0
  232. package/dist/renderer/rulers.js.map +1 -0
  233. package/dist/renderer/scene.d.ts +11 -0
  234. package/dist/renderer/scene.d.ts.map +1 -0
  235. package/dist/renderer/scene.js +392 -0
  236. package/dist/renderer/scene.js.map +1 -0
  237. package/dist/renderer/shapes.d.ts +13 -0
  238. package/dist/renderer/shapes.d.ts.map +1 -0
  239. package/dist/renderer/shapes.js +160 -0
  240. package/dist/renderer/shapes.js.map +1 -0
  241. package/dist/renderer/strokes.d.ts +9 -0
  242. package/dist/renderer/strokes.d.ts.map +1 -0
  243. package/dist/renderer/strokes.js +180 -0
  244. package/dist/renderer/strokes.js.map +1 -0
  245. package/dist/rpc/commands.d.ts +202 -0
  246. package/dist/rpc/commands.d.ts.map +1 -0
  247. package/dist/rpc/commands.js +429 -0
  248. package/dist/rpc/commands.js.map +1 -0
  249. package/dist/rpc/index.d.ts +3 -0
  250. package/dist/rpc/index.d.ts.map +1 -0
  251. package/dist/rpc/index.js +2 -0
  252. package/dist/rpc/index.js.map +1 -0
  253. package/dist/scene-graph.d.ts +318 -0
  254. package/dist/scene-graph.d.ts.map +1 -0
  255. package/dist/scene-graph.js +803 -0
  256. package/dist/scene-graph.js.map +1 -0
  257. package/dist/snap.d.ts +16 -0
  258. package/dist/snap.d.ts.map +1 -0
  259. package/dist/snap.js +97 -0
  260. package/dist/snap.js.map +1 -0
  261. package/dist/style-runs.d.ts +20 -0
  262. package/dist/style-runs.d.ts.map +1 -0
  263. package/dist/style-runs.js +168 -0
  264. package/dist/style-runs.js.map +1 -0
  265. package/dist/svg-export/defs.d.ts +19 -0
  266. package/dist/svg-export/defs.d.ts.map +1 -0
  267. package/dist/svg-export/defs.js +191 -0
  268. package/dist/svg-export/defs.js.map +1 -0
  269. package/dist/svg-export/index.d.ts +8 -0
  270. package/dist/svg-export/index.d.ts.map +1 -0
  271. package/dist/svg-export/index.js +318 -0
  272. package/dist/svg-export/index.js.map +1 -0
  273. package/dist/svg-export/paths.d.ts +9 -0
  274. package/dist/svg-export/paths.d.ts.map +1 -0
  275. package/dist/svg-export/paths.js +189 -0
  276. package/dist/svg-export/paths.js.map +1 -0
  277. package/dist/svg-node.d.ts +8 -0
  278. package/dist/svg-node.d.ts.map +1 -0
  279. package/dist/svg-node.js +48 -0
  280. package/dist/svg-node.js.map +1 -0
  281. package/dist/text-editor.d.ts +57 -0
  282. package/dist/text-editor.d.ts.map +1 -0
  283. package/dist/text-editor.js +337 -0
  284. package/dist/text-editor.js.map +1 -0
  285. package/dist/tools/ai-adapter.d.ts +22 -0
  286. package/dist/tools/ai-adapter.d.ts.map +1 -0
  287. package/dist/tools/ai-adapter.js +121 -0
  288. package/dist/tools/ai-adapter.js.map +1 -0
  289. package/dist/tools/analyze.d.ts +22 -0
  290. package/dist/tools/analyze.d.ts.map +1 -0
  291. package/dist/tools/analyze.js +677 -0
  292. package/dist/tools/analyze.js.map +1 -0
  293. package/dist/tools/create.d.ts +8 -0
  294. package/dist/tools/create.d.ts.map +1 -0
  295. package/dist/tools/create.js +204 -0
  296. package/dist/tools/create.js.map +1 -0
  297. package/dist/tools/describe.d.ts +9 -0
  298. package/dist/tools/describe.d.ts.map +1 -0
  299. package/dist/tools/describe.js +295 -0
  300. package/dist/tools/describe.js.map +1 -0
  301. package/dist/tools/export-code.d.ts +2 -0
  302. package/dist/tools/export-code.d.ts.map +1 -0
  303. package/dist/tools/export-code.js +34 -0
  304. package/dist/tools/export-code.js.map +1 -0
  305. package/dist/tools/export-tailwind-config.d.ts +27 -0
  306. package/dist/tools/export-tailwind-config.d.ts.map +1 -0
  307. package/dist/tools/export-tailwind-config.js +215 -0
  308. package/dist/tools/export-tailwind-config.js.map +1 -0
  309. package/dist/tools/icons.d.ts +5 -0
  310. package/dist/tools/icons.d.ts.map +1 -0
  311. package/dist/tools/icons.js +192 -0
  312. package/dist/tools/icons.js.map +1 -0
  313. package/dist/tools/index.d.ts +7 -0
  314. package/dist/tools/index.d.ts.map +1 -0
  315. package/dist/tools/index.js +6 -0
  316. package/dist/tools/index.js.map +1 -0
  317. package/dist/tools/modify.d.ts +22 -0
  318. package/dist/tools/modify.d.ts.map +1 -0
  319. package/dist/tools/modify.js +653 -0
  320. package/dist/tools/modify.js.map +1 -0
  321. package/dist/tools/patterns.d.ts +2 -0
  322. package/dist/tools/patterns.d.ts.map +1 -0
  323. package/dist/tools/patterns.js +173 -0
  324. package/dist/tools/patterns.js.map +1 -0
  325. package/dist/tools/read.d.ts +17 -0
  326. package/dist/tools/read.d.ts.map +1 -0
  327. package/dist/tools/read.js +379 -0
  328. package/dist/tools/read.js.map +1 -0
  329. package/dist/tools/registry.d.ts +3 -0
  330. package/dist/tools/registry.d.ts.map +1 -0
  331. package/dist/tools/registry.js +124 -0
  332. package/dist/tools/registry.js.map +1 -0
  333. package/dist/tools/schema.d.ts +46 -0
  334. package/dist/tools/schema.d.ts.map +1 -0
  335. package/dist/tools/schema.js +17 -0
  336. package/dist/tools/schema.js.map +1 -0
  337. package/dist/tools/structure.d.ts +18 -0
  338. package/dist/tools/structure.d.ts.map +1 -0
  339. package/dist/tools/structure.js +345 -0
  340. package/dist/tools/structure.js.map +1 -0
  341. package/dist/tools/variables.d.ts +12 -0
  342. package/dist/tools/variables.d.ts.map +1 -0
  343. package/dist/tools/variables.js +190 -0
  344. package/dist/tools/variables.js.map +1 -0
  345. package/dist/tools/vector.d.ts +15 -0
  346. package/dist/tools/vector.d.ts.map +1 -0
  347. package/dist/tools/vector.js +312 -0
  348. package/dist/tools/vector.js.map +1 -0
  349. package/dist/types.d.ts +29 -0
  350. package/dist/types.d.ts.map +1 -0
  351. package/dist/types.js +2 -0
  352. package/dist/types.js.map +1 -0
  353. package/dist/undo.d.ts +33 -0
  354. package/dist/undo.d.ts.map +1 -0
  355. package/dist/undo.js +98 -0
  356. package/dist/undo.js.map +1 -0
  357. package/dist/vector.d.ts +14 -0
  358. package/dist/vector.d.ts.map +1 -0
  359. package/dist/vector.js +334 -0
  360. package/dist/vector.js.map +1 -0
  361. package/dist/xpath.d.ts +8 -0
  362. package/dist/xpath.d.ts.map +1 -0
  363. package/dist/xpath.js +199 -0
  364. package/dist/xpath.js.map +1 -0
  365. package/package.json +54 -0
  366. package/src/canvaskit.ts +66 -0
  367. package/src/clipboard.ts +444 -0
  368. package/src/color.ts +83 -0
  369. package/src/constants.ts +277 -0
  370. package/src/copy.ts +75 -0
  371. package/src/fig-export-worker.ts +28 -0
  372. package/src/fig-export.ts +321 -0
  373. package/src/figma-api.ts +1297 -0
  374. package/src/figma-rest-import.ts +443 -0
  375. package/src/fonts.ts +369 -0
  376. package/src/geometry.ts +73 -0
  377. package/src/global.d.ts +20 -0
  378. package/src/index.ts +247 -0
  379. package/src/kiwi/codec.ts +614 -0
  380. package/src/kiwi/fig-file.ts +248 -0
  381. package/src/kiwi/fig-import.ts +300 -0
  382. package/src/kiwi/fig-parse-worker.ts +213 -0
  383. package/src/kiwi/instance-overrides.ts +682 -0
  384. package/src/kiwi/kiwi-convert.ts +771 -0
  385. package/src/kiwi/kiwi-schema/bb.ts +244 -0
  386. package/src/kiwi/kiwi-schema/binary.ts +102 -0
  387. package/src/kiwi/kiwi-schema/index.ts +5 -0
  388. package/src/kiwi/kiwi-schema/js.ts +339 -0
  389. package/src/kiwi/kiwi-schema/parser.ts +287 -0
  390. package/src/kiwi/kiwi-schema/schema.ts +24 -0
  391. package/src/kiwi/kiwi-schema/util.ts +10 -0
  392. package/src/kiwi/protocol.ts +237 -0
  393. package/src/kiwi/schema.ts +2286 -0
  394. package/src/kiwi-serialize.ts +467 -0
  395. package/src/layout.ts +608 -0
  396. package/src/profiler/draw-call-counter.ts +43 -0
  397. package/src/profiler/frame-capture.ts +139 -0
  398. package/src/profiler/frame-stats.ts +122 -0
  399. package/src/profiler/gpu-timer.ts +93 -0
  400. package/src/profiler/hud-renderer.ts +242 -0
  401. package/src/profiler/index.ts +8 -0
  402. package/src/profiler/phase-timer.ts +62 -0
  403. package/src/profiler/render-profiler.ts +163 -0
  404. package/src/render/components.ts +69 -0
  405. package/src/render/emoji-icons.ts +60 -0
  406. package/src/render/export-code.ts +366 -0
  407. package/src/render/export-jsx.ts +633 -0
  408. package/src/render/index.ts +38 -0
  409. package/src/render/jsx-runtime.ts +36 -0
  410. package/src/render/mini-react.ts +30 -0
  411. package/src/render/render-jsx.ts +74 -0
  412. package/src/render/renderer.ts +508 -0
  413. package/src/render/tailwind.ts +114 -0
  414. package/src/render/tree.ts +137 -0
  415. package/src/render-image.ts +139 -0
  416. package/src/renderer/effects.ts +64 -0
  417. package/src/renderer/fills.ts +248 -0
  418. package/src/renderer/index.ts +1 -0
  419. package/src/renderer/label-cache.ts +114 -0
  420. package/src/renderer/labels.ts +168 -0
  421. package/src/renderer/lru-cache.ts +71 -0
  422. package/src/renderer/overlays.ts +1089 -0
  423. package/src/renderer/renderer.ts +1226 -0
  424. package/src/renderer/rulers.ts +230 -0
  425. package/src/renderer/scene.ts +554 -0
  426. package/src/renderer/shapes.ts +193 -0
  427. package/src/renderer/strokes.ts +221 -0
  428. package/src/rpc/commands.ts +667 -0
  429. package/src/rpc/index.ts +25 -0
  430. package/src/scene-graph.ts +1254 -0
  431. package/src/snap.ts +122 -0
  432. package/src/style-runs.ts +234 -0
  433. package/src/svg-export/defs.ts +255 -0
  434. package/src/svg-export/index.ts +427 -0
  435. package/src/svg-export/paths.ts +212 -0
  436. package/src/svg-node.ts +62 -0
  437. package/src/text-editor.ts +349 -0
  438. package/src/tools/ai-adapter.ts +144 -0
  439. package/src/tools/analyze.ts +786 -0
  440. package/src/tools/create.ts +206 -0
  441. package/src/tools/describe.ts +280 -0
  442. package/src/tools/export-code.ts +41 -0
  443. package/src/tools/export-tailwind-config.ts +266 -0
  444. package/src/tools/icons.ts +213 -0
  445. package/src/tools/index.ts +6 -0
  446. package/src/tools/modify.ts +651 -0
  447. package/src/tools/patterns.ts +189 -0
  448. package/src/tools/read.ts +401 -0
  449. package/src/tools/registry.ts +155 -0
  450. package/src/tools/schema.ts +65 -0
  451. package/src/tools/structure.ts +348 -0
  452. package/src/tools/variables.ts +193 -0
  453. package/src/tools/vector.ts +311 -0
  454. package/src/types.ts +32 -0
  455. package/src/undo.ts +126 -0
  456. package/src/vector.ts +413 -0
  457. package/src/xpath.ts +259 -0
@@ -0,0 +1,803 @@
1
+ import { createNanoEvents } from 'nanoevents';
2
+ import { BLACK, DEFAULT_FONT_FAMILY, DEFAULT_STROKE_MITER_LIMIT } from './constants.js';
3
+ import { copyEffects, copyFills, copyStrokes, copyStyleRuns } from './copy.js';
4
+ let nextLocalID = 1;
5
+ export function generateId() {
6
+ return `0:${nextLocalID++}`;
7
+ }
8
+ function createDefaultNode(type, overrides = {}, id) {
9
+ return {
10
+ id: id ?? generateId(),
11
+ type,
12
+ name: type.charAt(0) + type.slice(1).toLowerCase(),
13
+ parentId: null,
14
+ childIds: [],
15
+ x: 0,
16
+ y: 0,
17
+ width: 100,
18
+ height: 100,
19
+ rotation: 0,
20
+ fills: [],
21
+ strokes: [],
22
+ effects: [],
23
+ opacity: 1,
24
+ cornerRadius: 0,
25
+ topLeftRadius: 0,
26
+ topRightRadius: 0,
27
+ bottomRightRadius: 0,
28
+ bottomLeftRadius: 0,
29
+ independentCorners: false,
30
+ cornerSmoothing: 0,
31
+ visible: true,
32
+ locked: false,
33
+ clipsContent: false,
34
+ text: '',
35
+ fontSize: 14,
36
+ fontFamily: DEFAULT_FONT_FAMILY,
37
+ fontWeight: 400,
38
+ italic: false,
39
+ textAlignHorizontal: 'LEFT',
40
+ lineHeight: null,
41
+ letterSpacing: 0,
42
+ layoutMode: 'NONE',
43
+ layoutWrap: 'NO_WRAP',
44
+ primaryAxisAlign: 'MIN',
45
+ counterAxisAlign: 'MIN',
46
+ primaryAxisSizing: 'FIXED',
47
+ counterAxisSizing: 'FIXED',
48
+ itemSpacing: 0,
49
+ counterAxisSpacing: 0,
50
+ paddingTop: 0,
51
+ paddingRight: 0,
52
+ paddingBottom: 0,
53
+ paddingLeft: 0,
54
+ blendMode: 'PASS_THROUGH',
55
+ layoutPositioning: 'AUTO',
56
+ layoutGrow: 0,
57
+ layoutAlignSelf: 'AUTO',
58
+ vectorNetwork: null,
59
+ fillGeometry: [],
60
+ strokeGeometry: [],
61
+ arcData: null,
62
+ textAlignVertical: 'TOP',
63
+ textAutoResize: 'NONE',
64
+ textCase: 'ORIGINAL',
65
+ textDecoration: 'NONE',
66
+ maxLines: null,
67
+ styleRuns: [],
68
+ horizontalConstraint: 'MIN',
69
+ verticalConstraint: 'MIN',
70
+ strokeCap: 'NONE',
71
+ strokeJoin: 'MITER',
72
+ dashPattern: [],
73
+ borderTopWeight: 0,
74
+ borderRightWeight: 0,
75
+ borderBottomWeight: 0,
76
+ borderLeftWeight: 0,
77
+ independentStrokeWeights: false,
78
+ strokeMiterLimit: DEFAULT_STROKE_MITER_LIMIT,
79
+ minWidth: null,
80
+ maxWidth: null,
81
+ minHeight: null,
82
+ maxHeight: null,
83
+ isMask: false,
84
+ maskType: 'ALPHA',
85
+ gridTemplateColumns: [],
86
+ gridTemplateRows: [],
87
+ gridColumnGap: 0,
88
+ gridRowGap: 0,
89
+ gridPosition: null,
90
+ counterAxisAlignContent: 'AUTO',
91
+ itemReverseZIndex: false,
92
+ strokesIncludedInLayout: false,
93
+ expanded: true,
94
+ textTruncation: 'DISABLED',
95
+ autoRename: true,
96
+ pointCount: 5,
97
+ starInnerRadius: 0.38,
98
+ componentId: null,
99
+ overrides: {},
100
+ boundVariables: {},
101
+ internalOnly: false,
102
+ flipX: false,
103
+ flipY: false,
104
+ textPicture: null,
105
+ ...overrides
106
+ };
107
+ }
108
+ const CONTAINER_TYPES = new Set([
109
+ 'CANVAS',
110
+ 'FRAME',
111
+ 'GROUP',
112
+ 'SECTION',
113
+ 'COMPONENT',
114
+ 'COMPONENT_SET',
115
+ 'INSTANCE'
116
+ ]);
117
+ export class SceneGraph {
118
+ nodes = new Map();
119
+ images = new Map();
120
+ variables = new Map();
121
+ variableCollections = new Map();
122
+ activeMode = new Map();
123
+ rootId;
124
+ emitter = createNanoEvents();
125
+ absPosCache = new Map();
126
+ instanceIndex = new Map();
127
+ nextLocalID = 1;
128
+ constructor() {
129
+ const root = createDefaultNode('FRAME', {
130
+ name: 'Document',
131
+ width: 0,
132
+ height: 0
133
+ }, this.generateId());
134
+ this.rootId = root.id;
135
+ this.nodes.set(root.id, root);
136
+ this.addPage('Page 1');
137
+ }
138
+ generateId() {
139
+ return `0:${this.nextLocalID++}`;
140
+ }
141
+ addPage(name) {
142
+ return this.createNode('CANVAS', this.rootId, { name, width: 0, height: 0 });
143
+ }
144
+ getPages(includeInternal = false) {
145
+ return this.getChildren(this.rootId).filter((n) => n.type === 'CANVAS' && (includeInternal || !n.internalOnly));
146
+ }
147
+ getAllNodes() {
148
+ return this.nodes.values();
149
+ }
150
+ getNode(id) {
151
+ return this.nodes.get(id);
152
+ }
153
+ // --- Variables ---
154
+ addVariable(variable) {
155
+ this.variables.set(variable.id, variable);
156
+ const collection = this.variableCollections.get(variable.collectionId);
157
+ if (collection && !collection.variableIds.includes(variable.id)) {
158
+ collection.variableIds.push(variable.id);
159
+ }
160
+ }
161
+ removeVariable(id) {
162
+ const variable = this.variables.get(id);
163
+ if (!variable)
164
+ return;
165
+ this.variables.delete(id);
166
+ const collection = this.variableCollections.get(variable.collectionId);
167
+ if (collection) {
168
+ collection.variableIds = collection.variableIds.filter((vid) => vid !== id);
169
+ }
170
+ for (const node of this.nodes.values()) {
171
+ for (const [field, varId] of Object.entries(node.boundVariables)) {
172
+ if (varId === id)
173
+ delete node.boundVariables[field];
174
+ }
175
+ }
176
+ }
177
+ addCollection(collection) {
178
+ this.variableCollections.set(collection.id, collection);
179
+ if (!this.activeMode.has(collection.id)) {
180
+ this.activeMode.set(collection.id, collection.defaultModeId);
181
+ }
182
+ }
183
+ createVariable(name, type, collectionId, value) {
184
+ const collection = this.variableCollections.get(collectionId);
185
+ if (!collection)
186
+ throw new Error(`Collection "${collectionId}" not found`);
187
+ const id = this.generateId();
188
+ let defaultValue;
189
+ if (value !== undefined) {
190
+ defaultValue = value;
191
+ }
192
+ else if (type === 'COLOR') {
193
+ defaultValue = { ...BLACK };
194
+ }
195
+ else if (type === 'FLOAT') {
196
+ defaultValue = 0;
197
+ }
198
+ else if (type === 'BOOLEAN') {
199
+ defaultValue = false;
200
+ }
201
+ else {
202
+ defaultValue = '';
203
+ }
204
+ const valuesByMode = {};
205
+ for (const mode of collection.modes) {
206
+ valuesByMode[mode.modeId] = structuredClone(defaultValue);
207
+ }
208
+ const variable = {
209
+ id,
210
+ name,
211
+ type,
212
+ collectionId,
213
+ valuesByMode,
214
+ description: '',
215
+ hiddenFromPublishing: false
216
+ };
217
+ this.addVariable(variable);
218
+ return variable;
219
+ }
220
+ createCollection(name) {
221
+ const id = this.generateId();
222
+ const modeId = this.generateId();
223
+ const collection = {
224
+ id,
225
+ name,
226
+ modes: [{ modeId, name: 'Mode 1' }],
227
+ defaultModeId: modeId,
228
+ variableIds: []
229
+ };
230
+ this.addCollection(collection);
231
+ return collection;
232
+ }
233
+ removeCollection(id) {
234
+ const collection = this.variableCollections.get(id);
235
+ if (collection) {
236
+ for (const varId of Array.from(collection.variableIds)) {
237
+ this.removeVariable(varId);
238
+ }
239
+ }
240
+ this.variableCollections.delete(id);
241
+ this.activeMode.delete(id);
242
+ }
243
+ getActiveModeId(collectionId) {
244
+ const mode = this.activeMode.get(collectionId);
245
+ if (mode)
246
+ return mode;
247
+ const collection = this.variableCollections.get(collectionId);
248
+ return collection?.defaultModeId ?? '';
249
+ }
250
+ setActiveMode(collectionId, modeId) {
251
+ this.activeMode.set(collectionId, modeId);
252
+ }
253
+ resolveVariable(variableId, modeId, visited) {
254
+ if (visited?.has(variableId))
255
+ return undefined;
256
+ const variable = this.variables.get(variableId);
257
+ if (!variable)
258
+ return undefined;
259
+ const resolvedModeId = modeId ?? this.getActiveModeId(variable.collectionId);
260
+ const value = variable.valuesByMode[resolvedModeId];
261
+ if (typeof value === 'object' && 'aliasId' in value) {
262
+ const seen = visited ?? new Set();
263
+ seen.add(variableId);
264
+ return this.resolveVariable(value.aliasId, undefined, seen);
265
+ }
266
+ return value;
267
+ }
268
+ resolveColorVariable(variableId) {
269
+ const value = this.resolveVariable(variableId);
270
+ if (value && typeof value === 'object' && 'r' in value)
271
+ return value;
272
+ return undefined;
273
+ }
274
+ resolveNumberVariable(variableId) {
275
+ const value = this.resolveVariable(variableId);
276
+ return typeof value === 'number' ? value : undefined;
277
+ }
278
+ getVariablesForCollection(collectionId) {
279
+ const collection = this.variableCollections.get(collectionId);
280
+ if (!collection)
281
+ return [];
282
+ return collection.variableIds
283
+ .map((id) => this.variables.get(id))
284
+ .filter((v) => v !== undefined);
285
+ }
286
+ getVariablesByType(type) {
287
+ return [...this.variables.values()].filter((v) => v.type === type);
288
+ }
289
+ bindVariable(nodeId, field, variableId) {
290
+ const node = this.nodes.get(nodeId);
291
+ if (node)
292
+ node.boundVariables[field] = variableId;
293
+ }
294
+ unbindVariable(nodeId, field) {
295
+ const node = this.nodes.get(nodeId);
296
+ if (node)
297
+ delete node.boundVariables[field];
298
+ }
299
+ getChildren(id) {
300
+ const node = this.nodes.get(id);
301
+ if (!node)
302
+ return [];
303
+ return node.childIds
304
+ .map((cid) => this.nodes.get(cid))
305
+ .filter((n) => n !== undefined);
306
+ }
307
+ isContainer(id) {
308
+ const node = this.nodes.get(id);
309
+ return node ? CONTAINER_TYPES.has(node.type) : false;
310
+ }
311
+ isDescendant(childId, ancestorId) {
312
+ let current = this.nodes.get(childId);
313
+ while (current) {
314
+ if (current.id === ancestorId)
315
+ return true;
316
+ current = current.parentId ? this.nodes.get(current.parentId) : undefined;
317
+ }
318
+ return false;
319
+ }
320
+ clearAbsPosCache() {
321
+ this.absPosCache.clear();
322
+ }
323
+ getAbsolutePosition(id) {
324
+ const cached = this.absPosCache.get(id);
325
+ if (cached)
326
+ return cached;
327
+ let ax = 0;
328
+ let ay = 0;
329
+ let current = this.nodes.get(id);
330
+ while (current && current.id !== this.rootId && current.type !== 'CANVAS') {
331
+ ax += current.x;
332
+ ay += current.y;
333
+ current = current.parentId ? this.nodes.get(current.parentId) : undefined;
334
+ }
335
+ const result = { x: ax, y: ay };
336
+ this.absPosCache.set(id, result);
337
+ return result;
338
+ }
339
+ getAbsoluteBounds(id) {
340
+ const pos = this.getAbsolutePosition(id);
341
+ const node = this.nodes.get(id);
342
+ return {
343
+ x: pos.x,
344
+ y: pos.y,
345
+ width: node?.width ?? 0,
346
+ height: node?.height ?? 0
347
+ };
348
+ }
349
+ createNode(type, parentId, overrides = {}) {
350
+ // Figma API compat: map `characters` → `text`
351
+ if ('characters' in overrides && overrides.characters != null && !('text' in overrides)) {
352
+ overrides.text = overrides.characters;
353
+ }
354
+ const node = createDefaultNode(type, overrides, this.generateId());
355
+ node.parentId = parentId;
356
+ this.nodes.set(node.id, node);
357
+ const parent = this.nodes.get(parentId);
358
+ if (parent) {
359
+ parent.childIds.push(node.id);
360
+ }
361
+ if (node.type === 'INSTANCE' && node.componentId) {
362
+ let set = this.instanceIndex.get(node.componentId);
363
+ if (!set) {
364
+ set = new Set();
365
+ this.instanceIndex.set(node.componentId, set);
366
+ }
367
+ set.add(node.id);
368
+ }
369
+ this.emitter.emit('node:created', node);
370
+ return node;
371
+ }
372
+ static POS_AFFECTING_PROPS = new Set([
373
+ 'x', 'y', 'width', 'height', 'rotation', 'parentId',
374
+ 'layoutMode', 'layoutAlign', 'layoutGrow',
375
+ 'primaryAxisSizingMode', 'counterAxisSizingMode',
376
+ ]);
377
+ updateNode(id, changes) {
378
+ const node = this.nodes.get(id);
379
+ if (!node)
380
+ return;
381
+ for (const key of Object.keys(changes)) {
382
+ if (SceneGraph.POS_AFFECTING_PROPS.has(key)) {
383
+ this.absPosCache.clear();
384
+ break;
385
+ }
386
+ }
387
+ if (node.type === 'INSTANCE' && 'componentId' in changes && changes.componentId !== node.componentId) {
388
+ if (node.componentId)
389
+ this.instanceIndex.get(node.componentId)?.delete(id);
390
+ if (changes.componentId) {
391
+ let set = this.instanceIndex.get(changes.componentId);
392
+ if (!set) {
393
+ set = new Set();
394
+ this.instanceIndex.set(changes.componentId, set);
395
+ }
396
+ set.add(id);
397
+ }
398
+ }
399
+ Object.assign(node, changes);
400
+ this.emitter.emit('node:updated', id, changes);
401
+ }
402
+ reparentNode(nodeId, newParentId) {
403
+ const node = this.nodes.get(nodeId);
404
+ if (!node || nodeId === this.rootId)
405
+ return;
406
+ if (this.isDescendant(newParentId, nodeId))
407
+ return;
408
+ const oldParent = node.parentId ? this.nodes.get(node.parentId) : undefined;
409
+ const newParent = this.nodes.get(newParentId);
410
+ if (!newParent)
411
+ return;
412
+ if (node.parentId === newParentId)
413
+ return;
414
+ const oldParentId = node.parentId;
415
+ this.absPosCache.clear();
416
+ // Convert absolute position
417
+ const absPos = this.getAbsolutePosition(nodeId);
418
+ const newParentNode = this.nodes.get(newParentId);
419
+ const newParentAbs = newParentId === this.rootId || newParentNode?.type === 'CANVAS'
420
+ ? { x: 0, y: 0 }
421
+ : this.getAbsolutePosition(newParentId);
422
+ // Remove from old parent
423
+ if (oldParent) {
424
+ oldParent.childIds = oldParent.childIds.filter((cid) => cid !== nodeId);
425
+ }
426
+ // Add to new parent
427
+ node.parentId = newParentId;
428
+ newParent.childIds.push(nodeId);
429
+ // Adjust position so node stays in same visual place
430
+ node.x = absPos.x - newParentAbs.x;
431
+ node.y = absPos.y - newParentAbs.y;
432
+ this.emitter.emit('node:reparented', nodeId, oldParentId, newParentId);
433
+ }
434
+ reorderChild(nodeId, parentId, insertIndex) {
435
+ const node = this.nodes.get(nodeId);
436
+ if (!node)
437
+ return;
438
+ const oldParent = node.parentId ? this.nodes.get(node.parentId) : undefined;
439
+ const newParent = this.nodes.get(parentId);
440
+ if (!newParent)
441
+ return;
442
+ // Capture original index before removal for same-parent off-by-one correction
443
+ const oldIndex = oldParent === newParent ? oldParent.childIds.indexOf(nodeId) : -1;
444
+ // Remove from old parent
445
+ if (oldParent) {
446
+ oldParent.childIds = oldParent.childIds.filter((cid) => cid !== nodeId);
447
+ }
448
+ // If same parent and target is after the removed position, adjust down by 1
449
+ let idx = insertIndex;
450
+ if (oldParent === newParent && oldIndex !== -1 && idx > oldIndex) {
451
+ idx--;
452
+ }
453
+ node.parentId = parentId;
454
+ idx = Math.min(idx, newParent.childIds.length);
455
+ newParent.childIds.splice(idx, 0, nodeId);
456
+ this.emitter.emit('node:reordered', nodeId, parentId, idx);
457
+ }
458
+ deleteNode(id) {
459
+ const node = this.nodes.get(id);
460
+ if (!node || id === this.rootId)
461
+ return;
462
+ if (node.parentId) {
463
+ const parent = this.nodes.get(node.parentId);
464
+ if (parent) {
465
+ parent.childIds = parent.childIds.filter((cid) => cid !== id);
466
+ }
467
+ }
468
+ for (const childId of Array.from(node.childIds)) {
469
+ this.deleteNode(childId);
470
+ }
471
+ if (node.type === 'INSTANCE' && node.componentId) {
472
+ this.instanceIndex.get(node.componentId)?.delete(id);
473
+ }
474
+ this.nodes.delete(id);
475
+ this.emitter.emit('node:deleted', id);
476
+ }
477
+ hitTest(px, py, scopeId) {
478
+ const scope = scopeId ?? this.rootId;
479
+ return this.hitTestChildren(px, py, scope, 0, 0, false);
480
+ }
481
+ hitTestDeep(px, py, scopeId) {
482
+ const scope = scopeId ?? this.rootId;
483
+ return this.hitTestChildren(px, py, scope, 0, 0, true);
484
+ }
485
+ static OPAQUE_CONTAINER_TYPES = new Set(['COMPONENT', 'INSTANCE']);
486
+ static hasVisibleFillOrStroke(node) {
487
+ return (node.fills.some((f) => f.visible) ||
488
+ node.strokes.some((s) => s.visible));
489
+ }
490
+ static containsPoint(px, py, ax, ay, node) {
491
+ return px >= ax && px <= ax + node.width && py >= ay && py <= ay + node.height;
492
+ }
493
+ hitTestOpaqueContainer(px, py, child, childId, ax, ay, deep) {
494
+ if (!SceneGraph.containsPoint(px, py, ax, ay, child))
495
+ return null;
496
+ const childHit = this.hitTestChildren(px, py, childId, ax, ay, deep);
497
+ if (childHit)
498
+ return child;
499
+ if (SceneGraph.hasVisibleFillOrStroke(child))
500
+ return child;
501
+ return null;
502
+ }
503
+ hitTestTransparentContainer(px, py, child, childId, ax, ay, deep) {
504
+ const deepHit = this.hitTestChildren(px, py, childId, ax, ay, deep);
505
+ if (deepHit)
506
+ return deepHit;
507
+ if (child.type === 'GROUP')
508
+ return null;
509
+ if (SceneGraph.containsPoint(px, py, ax, ay, child) && SceneGraph.hasVisibleFillOrStroke(child))
510
+ return child;
511
+ return null;
512
+ }
513
+ hitTestChildren(px, py, parentId, offsetX, offsetY, deep = false) {
514
+ const parent = this.nodes.get(parentId);
515
+ if (!parent)
516
+ return null;
517
+ if (parent.clipsContent) {
518
+ if (!SceneGraph.containsPoint(px, py, offsetX, offsetY, parent))
519
+ return null;
520
+ }
521
+ for (let i = parent.childIds.length - 1; i >= 0; i--) {
522
+ const childId = parent.childIds[i];
523
+ const child = this.nodes.get(childId);
524
+ if (!child || !child.visible)
525
+ continue;
526
+ const ax = offsetX + child.x;
527
+ const ay = offsetY + child.y;
528
+ if (CONTAINER_TYPES.has(child.type)) {
529
+ if (SceneGraph.OPAQUE_CONTAINER_TYPES.has(child.type) && !deep) {
530
+ const hit = this.hitTestOpaqueContainer(px, py, child, childId, ax, ay, deep);
531
+ if (hit)
532
+ return hit;
533
+ continue;
534
+ }
535
+ const hit = this.hitTestTransparentContainer(px, py, child, childId, ax, ay, deep);
536
+ if (hit)
537
+ return hit;
538
+ continue;
539
+ }
540
+ if (SceneGraph.containsPoint(px, py, ax, ay, child))
541
+ return child;
542
+ }
543
+ return null;
544
+ }
545
+ hitTestFrame(px, py, excludeIds, scopeId) {
546
+ return this.hitTestFrameChildren(px, py, scopeId ?? this.rootId, 0, 0, excludeIds);
547
+ }
548
+ hitTestFrameChildren(px, py, parentId, offsetX, offsetY, excludeIds) {
549
+ const parent = this.nodes.get(parentId);
550
+ if (!parent)
551
+ return null;
552
+ // Deepest matching frame wins
553
+ let best = null;
554
+ for (const childId of parent.childIds) {
555
+ if (excludeIds.has(childId))
556
+ continue;
557
+ const child = this.nodes.get(childId);
558
+ if (!child || !child.visible)
559
+ continue;
560
+ const ax = offsetX + child.x;
561
+ const ay = offsetY + child.y;
562
+ if (!CONTAINER_TYPES.has(child.type))
563
+ continue;
564
+ if (px < ax || px > ax + child.width || py < ay || py > ay + child.height)
565
+ continue;
566
+ best = child;
567
+ const deeper = this.hitTestFrameChildren(px, py, childId, ax, ay, excludeIds);
568
+ if (deeper)
569
+ best = deeper;
570
+ }
571
+ return best;
572
+ }
573
+ cloneTree(sourceId, parentId, overrides = {}) {
574
+ const src = this.nodes.get(sourceId);
575
+ if (!src)
576
+ return null;
577
+ const { id: _srcId, parentId: _srcParent, childIds: _srcChildren, ...rest } = src;
578
+ const clone = this.createNode(src.type, parentId, { ...rest, ...overrides });
579
+ for (const childId of src.childIds) {
580
+ this.cloneTree(childId, clone.id);
581
+ }
582
+ return clone;
583
+ }
584
+ static INSTANCE_SYNC_PROPS = [
585
+ 'width',
586
+ 'height',
587
+ 'fills',
588
+ 'strokes',
589
+ 'effects',
590
+ 'opacity',
591
+ 'cornerRadius',
592
+ 'topLeftRadius',
593
+ 'topRightRadius',
594
+ 'bottomRightRadius',
595
+ 'bottomLeftRadius',
596
+ 'independentCorners',
597
+ 'layoutMode',
598
+ 'layoutWrap',
599
+ 'primaryAxisAlign',
600
+ 'counterAxisAlign',
601
+ 'primaryAxisSizing',
602
+ 'counterAxisSizing',
603
+ 'itemSpacing',
604
+ 'counterAxisSpacing',
605
+ 'paddingTop',
606
+ 'paddingRight',
607
+ 'paddingBottom',
608
+ 'paddingLeft',
609
+ 'gridTemplateColumns',
610
+ 'gridTemplateRows',
611
+ 'gridColumnGap',
612
+ 'gridRowGap',
613
+ 'gridPosition',
614
+ 'clipsContent',
615
+ 'independentStrokeWeights',
616
+ 'borderTopWeight',
617
+ 'borderRightWeight',
618
+ 'borderBottomWeight',
619
+ 'borderLeftWeight'
620
+ ];
621
+ static copyProp(target, source, key) {
622
+ const val = source[key];
623
+ if (key === 'fills') {
624
+ ;
625
+ target[key] = copyFills(val);
626
+ }
627
+ else if (key === 'strokes') {
628
+ ;
629
+ target[key] = copyStrokes(val);
630
+ }
631
+ else if (key === 'effects') {
632
+ ;
633
+ target[key] = copyEffects(val);
634
+ }
635
+ else if (key === 'styleRuns') {
636
+ ;
637
+ target[key] = copyStyleRuns(val);
638
+ }
639
+ else {
640
+ ;
641
+ target[key] = Array.isArray(val) ? structuredClone(val) : val;
642
+ }
643
+ }
644
+ createInstance(componentId, parentId, overrides = {}) {
645
+ const component = this.nodes.get(componentId);
646
+ if (component?.type !== 'COMPONENT')
647
+ return null;
648
+ const props = { name: component.name, componentId };
649
+ for (const key of SceneGraph.INSTANCE_SYNC_PROPS) {
650
+ SceneGraph.copyProp(props, component, key);
651
+ }
652
+ const instance = this.createNode('INSTANCE', parentId, { ...props, ...overrides });
653
+ this.cloneChildrenWithMapping(component.id, instance.id);
654
+ return instance;
655
+ }
656
+ populateInstanceChildren(instanceId, componentId) {
657
+ const instance = this.nodes.get(instanceId);
658
+ const component = this.nodes.get(componentId);
659
+ if (!instance || !component || instance.type !== 'INSTANCE')
660
+ return;
661
+ this.cloneChildrenWithMapping(componentId, instanceId);
662
+ }
663
+ cloneChildrenWithMapping(sourceParentId, destParentId) {
664
+ const sourceParent = this.nodes.get(sourceParentId);
665
+ if (!sourceParent)
666
+ return;
667
+ for (const childId of sourceParent.childIds) {
668
+ const src = this.nodes.get(childId);
669
+ if (!src)
670
+ continue;
671
+ const { id: _, parentId: _p, childIds: _c, ...rest } = src;
672
+ const clone = this.createNode(src.type, destParentId, {
673
+ ...rest,
674
+ componentId: childId
675
+ });
676
+ if (src.childIds.length > 0) {
677
+ this.cloneChildrenWithMapping(childId, clone.id);
678
+ }
679
+ }
680
+ }
681
+ syncInstances(componentId) {
682
+ const component = this.nodes.get(componentId);
683
+ if (component?.type !== 'COMPONENT')
684
+ return;
685
+ for (const instance of this.getInstances(componentId)) {
686
+ // Sync instance-level props (unless overridden)
687
+ for (const key of SceneGraph.INSTANCE_SYNC_PROPS) {
688
+ if (key in instance.overrides)
689
+ continue;
690
+ SceneGraph.copyProp(instance, component, key);
691
+ }
692
+ // Sync children: match by componentId
693
+ this.syncChildren(component.id, instance.id, instance.overrides);
694
+ }
695
+ }
696
+ syncChildren(compParentId, instParentId, overrides) {
697
+ const compParent = this.nodes.get(compParentId);
698
+ const instParent = this.nodes.get(instParentId);
699
+ if (!compParent || !instParent)
700
+ return;
701
+ const instChildMap = new Map();
702
+ for (const childId of instParent.childIds) {
703
+ const child = this.nodes.get(childId);
704
+ if (child?.componentId)
705
+ instChildMap.set(child.componentId, child);
706
+ }
707
+ // Add new children from component that don't exist in instance
708
+ for (const compChildId of compParent.childIds) {
709
+ if (!instChildMap.has(compChildId)) {
710
+ const src = this.nodes.get(compChildId);
711
+ if (!src)
712
+ continue;
713
+ const { id: _, parentId: _p, childIds: _c, ...rest } = src;
714
+ const clone = this.createNode(src.type, instParentId, {
715
+ ...rest,
716
+ componentId: compChildId
717
+ });
718
+ if (src.childIds.length > 0) {
719
+ this.cloneChildrenWithMapping(compChildId, clone.id);
720
+ }
721
+ instChildMap.set(compChildId, clone);
722
+ }
723
+ }
724
+ // Sync existing children
725
+ for (const compChildId of compParent.childIds) {
726
+ const compChild = this.nodes.get(compChildId);
727
+ const instChild = instChildMap.get(compChildId);
728
+ if (!compChild || !instChild)
729
+ continue;
730
+ for (const key of SceneGraph.INSTANCE_SYNC_PROPS) {
731
+ const overrideKey = `${instChild.id}:${key}`;
732
+ if (overrideKey in overrides)
733
+ continue;
734
+ SceneGraph.copyProp(instChild, compChild, key);
735
+ }
736
+ for (const key of ['name', 'text', 'fontSize', 'fontWeight', 'fontFamily']) {
737
+ const overrideKey = `${instChild.id}:${key}`;
738
+ if (overrideKey in overrides)
739
+ continue;
740
+ SceneGraph.copyProp(instChild, compChild, key);
741
+ }
742
+ if (compChild.childIds.length > 0) {
743
+ this.syncChildren(compChildId, instChild.id, overrides);
744
+ }
745
+ }
746
+ // Reorder instance children to match component order
747
+ const compChildOrder = compParent.childIds;
748
+ instParent.childIds.sort((a, b) => {
749
+ const nodeA = this.nodes.get(a);
750
+ const nodeB = this.nodes.get(b);
751
+ const idxA = nodeA?.componentId ? compChildOrder.indexOf(nodeA.componentId) : -1;
752
+ const idxB = nodeB?.componentId ? compChildOrder.indexOf(nodeB.componentId) : -1;
753
+ return idxA - idxB;
754
+ });
755
+ }
756
+ detachInstance(instanceId) {
757
+ const node = this.nodes.get(instanceId);
758
+ if (node?.type !== 'INSTANCE')
759
+ return;
760
+ if (node.componentId) {
761
+ this.instanceIndex.get(node.componentId)?.delete(instanceId);
762
+ }
763
+ node.type = 'FRAME';
764
+ node.componentId = null;
765
+ node.overrides = {};
766
+ }
767
+ getMainComponent(instanceId) {
768
+ const node = this.nodes.get(instanceId);
769
+ if (!node?.componentId)
770
+ return undefined;
771
+ return this.nodes.get(node.componentId);
772
+ }
773
+ getInstances(componentId) {
774
+ const ids = this.instanceIndex.get(componentId);
775
+ if (!ids)
776
+ return [];
777
+ const instances = [];
778
+ for (const id of ids) {
779
+ const node = this.nodes.get(id);
780
+ if (node)
781
+ instances.push(node);
782
+ }
783
+ return instances;
784
+ }
785
+ flattenTree(parentId, depth = 0) {
786
+ const id = parentId ?? this.rootId;
787
+ const parent = this.nodes.get(id);
788
+ if (!parent)
789
+ return [];
790
+ const result = [];
791
+ for (const childId of parent.childIds) {
792
+ const child = this.nodes.get(childId);
793
+ if (!child)
794
+ continue;
795
+ result.push({ node: child, depth });
796
+ if (child.childIds.length > 0) {
797
+ result.push(...this.flattenTree(childId, depth + 1));
798
+ }
799
+ }
800
+ return result;
801
+ }
802
+ }
803
+ //# sourceMappingURL=scene-graph.js.map