@field/cascade 0.11.0 → 0.13.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 (220) hide show
  1. package/AGENTS.md +8 -5
  2. package/ARCHITECTURE.md +5 -4
  3. package/CHANGELOG.md +245 -0
  4. package/README.md +1 -1
  5. package/dist/assets/AgentPanel-1JugFjE4.css +1 -0
  6. package/dist/assets/AgentPanel-BDL5MddA.js +5 -0
  7. package/dist/assets/{CodeEditor-4O7FQ__R.js → CodeEditor-C-xYG-Wn.js} +120 -120
  8. package/dist/assets/CodePanel-CtXd50m6.js +2 -0
  9. package/dist/assets/CookInfoPanel-B3NMhKJF.css +1 -0
  10. package/dist/assets/CookInfoPanel-DG4_TRsX.js +2 -0
  11. package/dist/assets/CustomNodeDialog-CHfZUs-r.js +1 -0
  12. package/dist/assets/DefinitionNode-CaRTXQ_b.js +1 -0
  13. package/dist/assets/DefinitionPanel-C3CxZY9r.js +1 -0
  14. package/dist/assets/DefinitionPanel-VNLnAiQD.css +1 -0
  15. package/dist/assets/OpenGraphDialog-BLdr6k_q.js +1 -0
  16. package/dist/assets/ProjectSettings-ZnvmIAir.js +2 -0
  17. package/dist/assets/{SettingsDialog-Bz8JxISH.js → SettingsDialog-CBX3Wa87.js} +1 -1
  18. package/dist/assets/TimelinePanel-CDeR0arY.css +1 -0
  19. package/dist/assets/TimelinePanel-CWgnFH1e.js +1 -0
  20. package/dist/assets/{VersionHistoryDialog-D5Z0nJ5-.js → VersionHistoryDialog-BOSoW1R-.js} +1 -1
  21. package/dist/assets/assert-BO2_erPD.js +1 -0
  22. package/dist/assets/assert-hvykGCnP.js +1 -0
  23. package/dist/assets/builder-BmBKcDix.js +1 -0
  24. package/dist/assets/camera-DFF7YA3F.js +1 -0
  25. package/dist/assets/checks-DAvyO9Gf.js +1 -0
  26. package/dist/assets/contactSheet-N1NcaWxw.js +2 -0
  27. package/dist/assets/{core-Yqi0Ni61.js → core-DB-MkGjj.js} +3 -4
  28. package/dist/assets/coreTypes-DtnDATZ7.js +1 -0
  29. package/dist/assets/{cssMode-CxUzc4vp.js → cssMode-DPVckSOc.js} +1 -1
  30. package/dist/assets/definitions-B227e7f_.js +1 -0
  31. package/dist/assets/definitions-D0WOUJd7.js +1 -0
  32. package/dist/assets/{editor.api-BNFb25CX.js → editor.api-Dkutg_Z1.js} +1 -1
  33. package/dist/assets/expressions-X-Z-GrgW.js +5 -0
  34. package/dist/assets/file-DAL6IfjV.js +1 -0
  35. package/dist/assets/filters-D3k1LRMa.js +1 -0
  36. package/dist/assets/{freemarker2-0ZDnWxeM.js → freemarker2-CLiLKk3B.js} +1 -1
  37. package/dist/assets/generators-BhDxRAFC.js +1 -0
  38. package/dist/assets/geo-BsMImJIJ.js +1 -0
  39. package/dist/assets/geo-C4YngDob.js +2 -0
  40. package/dist/assets/{handlebars-Cy18MoaD.js → handlebars-CcD3aMeL.js} +1 -1
  41. package/dist/assets/{html-B-2Dx7nq.js → html-DvZWGfqb.js} +1 -1
  42. package/dist/assets/{htmlMode-DUAc9B_d.js → htmlMode-DUD3VaoN.js} +1 -1
  43. package/dist/assets/image-0SfH-snh.js +1 -0
  44. package/dist/assets/image-Ck-RdGU4.js +2 -0
  45. package/dist/assets/index-BWnrmIB9.js +137 -0
  46. package/dist/assets/index-DIaxEONI.css +1 -0
  47. package/dist/assets/io-BGmt2g0D.js +1 -0
  48. package/dist/assets/{javascript-DeQsDqP5.js → javascript-Cap2ahgh.js} +1 -1
  49. package/dist/assets/{jsonMode-BiFwJVSk.js → jsonMode-B0uLjp9C.js} +1 -1
  50. package/dist/assets/{liquid-BLoHH68a.js → liquid-CnxwhfLn.js} +1 -1
  51. package/dist/assets/{lspLanguageFeatures-CNFgm1Kv.js → lspLanguageFeatures-Dn9hlKX6.js} +1 -1
  52. package/dist/assets/math-GeULS-sk.js +1 -0
  53. package/dist/assets/{mdx-CFXQVNfs.js → mdx-BV3jbrVa.js} +1 -1
  54. package/dist/assets/pop-KMF_qloi.js +1 -0
  55. package/dist/assets/preload-helper-Czpn1I53.js +1 -0
  56. package/dist/assets/{python-Cf7S7p2E.js → python-CGyFk4XK.js} +1 -1
  57. package/dist/assets/{razor-CMHBcG-g.js → razor-CQfzX3-N.js} +1 -1
  58. package/dist/assets/remap-5SjXQU-q.js +1 -0
  59. package/dist/assets/renderMarkdown-ork0Oir7.js +67 -0
  60. package/dist/assets/studioImages-CAyH-0Pl.js +1 -0
  61. package/dist/assets/text-ZpX7qNkx.js +2 -0
  62. package/dist/assets/time-P_OiBhcf.js +1 -0
  63. package/dist/assets/{tsMode-BEih0GDj.js → tsMode-BOeXzO9H.js} +1 -1
  64. package/dist/assets/{typescript-COEKYD_a.js → typescript-J1SnE_Tu.js} +1 -1
  65. package/dist/assets/{workers-BNhAhMNn.js → workers-CYwwTiVF.js} +1 -1
  66. package/dist/assets/{xml-CPiMpnPl.js → xml-DnPRNzK9.js} +1 -1
  67. package/dist/assets/{yaml-Bgp1ITLR.js → yaml-BmmYBNa9.js} +1 -1
  68. package/dist/cli/DefinitionNode-P7AA4TAU.js +15 -0
  69. package/dist/cli/{Graph-ZJJTRQTM.js → Graph-OB6EWSGL.js} +12 -12
  70. package/dist/cli/assert-GROGQNCQ.js +25 -0
  71. package/dist/cli/checks-3WB44XBL.js +189 -0
  72. package/dist/cli/{chunk-3JTJHF7V.js → chunk-2L34ERS2.js} +4 -4
  73. package/dist/cli/chunk-53LGFPWX.js +138 -0
  74. package/dist/cli/chunk-5ORUQ6ES.js +267 -0
  75. package/dist/cli/{chunk-YAT5Y25U.js → chunk-7QE2ZNSN.js} +3 -3
  76. package/dist/cli/{chunk-SGJAET2L.js → chunk-BPODRH52.js} +8 -4
  77. package/dist/cli/{chunk-XWDSKG7N.js → chunk-BZ63XQ3I.js} +2 -2
  78. package/dist/cli/{chunk-FCDXJ6EK.js → chunk-CTPLRSWF.js} +2 -13
  79. package/dist/cli/{chunk-WIH4TEIS.js → chunk-EZRWJ4G2.js} +1 -1
  80. package/dist/cli/{chunk-BIJO5OFS.js → chunk-FWMSGKEH.js} +1 -1
  81. package/dist/cli/{chunk-POMMNKZZ.js → chunk-G23A2BZZ.js} +38 -5
  82. package/dist/cli/{chunk-35D343DC.js → chunk-GRIN2DDP.js} +19 -1
  83. package/dist/cli/{chunk-WKURDVYP.js → chunk-JEW5MPGI.js} +28 -331
  84. package/dist/cli/chunk-JVOCK5W4.js +83 -0
  85. package/dist/cli/chunk-KBGUO27Q.js +15 -0
  86. package/dist/cli/{chunk-GFS6W3C5.js → chunk-L6B6FUQP.js} +54 -32
  87. package/dist/cli/chunk-LTXWBXOM.js +438 -0
  88. package/dist/cli/chunk-MI5JLQYA.js +220 -0
  89. package/dist/cli/{chunk-A4OAMOZH.js → chunk-NJFMDXHR.js} +13 -3
  90. package/dist/cli/{chunk-DUIUFVU2.js → chunk-OBZAP3GG.js} +49 -23
  91. package/dist/cli/chunk-QAGATJGE.js +336 -0
  92. package/dist/cli/{chunk-EUIAC3U3.js → chunk-QKL7CCRS.js} +966 -132
  93. package/dist/cli/{chunk-RLCAJBVR.js → chunk-TJW67QSI.js} +8 -7
  94. package/dist/cli/{chunk-RQZ4SX5R.js → chunk-W5PJ5RMP.js} +156 -84
  95. package/dist/cli/chunk-W7OUAT7J.js +122 -0
  96. package/dist/cli/chunk-WGKPJZDY.js +364 -0
  97. package/dist/cli/{chunk-D6BUOHUG.js → chunk-X4WKAOQP.js} +4 -4
  98. package/dist/cli/{chunk-VVGSLVSF.js → chunk-X566FWBV.js} +6 -1
  99. package/dist/cli/chunk-YH637PDL.js +317 -0
  100. package/dist/cli/chunk-ZSCUZE6I.js +112 -0
  101. package/dist/cli/{cliCommands-UQSFGEHF.js → cliCommands-XVFRD7CF.js} +23 -17
  102. package/dist/cli/{commands-Q23M26QM.js → commands-M2XLTPTZ.js} +129 -47
  103. package/dist/cli/contactSheet-2PQVRUFW.js +11 -0
  104. package/dist/cli/{definitions-HF2FTHYU.js → definitions-BPOPW52L.js} +7 -7
  105. package/dist/cli/{doctorCommand-B7BPQMN6.js → doctorCommand-RAEI7GVY.js} +36 -6
  106. package/dist/cli/{edit-JHCPTQFT.js → edit-S5KEQ5RA.js} +3 -3
  107. package/dist/cli/editorCommands-5BBG4S6V.js +41 -0
  108. package/dist/cli/{encode-HAUZTYPT.js → encode-ICPEPMH5.js} +2 -2
  109. package/dist/cli/file-3HTQHPYQ.js +41 -0
  110. package/dist/cli/filters-6ODFWYK4.js +379 -0
  111. package/dist/cli/generators-YU7GB4MD.js +210 -0
  112. package/dist/cli/{geo-4RNK3QVN.js → geo-6ZPGKZRU.js} +7 -7
  113. package/dist/cli/{graphCommands-6BMAKGQE.js → graphCommands-MULQ7VD2.js} +4 -4
  114. package/dist/cli/{graphFile-VPSQ6OF7.js → graphFile-CITF36ZM.js} +25 -19
  115. package/dist/cli/{headlessCanvas-5XLDZT7M.js → headlessCanvas-ENRHC7GS.js} +3 -2
  116. package/dist/cli/{helpCommand-3VRE3KVO.js → helpCommand-X2QDANM3.js} +9 -7
  117. package/dist/cli/image-TXELZZK5.js +55 -0
  118. package/dist/cli/index.js +14 -14
  119. package/dist/cli/{math-ZRMLKU2D.js → math-RSYRQ3C6.js} +5 -5
  120. package/dist/cli/{mcp-ZLEEMYGF.js → mcp-YRIGRLYQ.js} +4 -4
  121. package/dist/cli/{parity-KINARCP2.js → parity-3N3HTKWX.js} +42 -36
  122. package/dist/cli/{pop-USDFXB7H.js → pop-B7SIIYKN.js} +5 -5
  123. package/dist/cli/project-SJF5ZF3F.js +12 -0
  124. package/dist/cli/{projectDefinition-DMTZN2NE.js → projectDefinition-F3D7UIHJ.js} +8 -8
  125. package/dist/cli/{projectRuntime-Z5PJOH47.js → projectRuntime-NY4XMDFH.js} +19 -12
  126. package/dist/cli/registerStandardNodes-BXJCB6E4.js +744 -0
  127. package/dist/cli/{render-YURAPPUI.js → render-Y23W6MY6.js} +29 -22
  128. package/dist/cli/{runCommand-PI764LEG.js → runCommand-XOG7AVC5.js} +3 -3
  129. package/dist/cli/runner-DNJO5WO2.js +43 -0
  130. package/dist/cli/runtime/image.ts +27 -2
  131. package/dist/cli/runtime/io.ts +78 -0
  132. package/dist/cli/share-B7HTCOJX.js +166 -0
  133. package/dist/cli/stageCache-TY2BFZJR.js +15 -0
  134. package/dist/cli/{stageRunner-KUNIMQKJ.js → stageRunner-KY2EJP7X.js} +2 -2
  135. package/dist/cli/text-MB3EKR4H.js +126 -0
  136. package/dist/cli/{verbs-RCE3K4VQ.js → verbs-PI2JH5FI.js} +2 -2
  137. package/dist/cli/webBuild-2K4COCGY.js +44 -0
  138. package/dist/contracts/capabilities.d.ts +39 -1
  139. package/dist/contracts/color.d.ts +8 -0
  140. package/dist/contracts/color.js +23 -0
  141. package/dist/contracts/definition.d.ts +10 -0
  142. package/dist/contracts/schema.d.ts +1 -1
  143. package/dist/contracts/schema.js +1 -0
  144. package/dist/contracts/validate.js +11 -1
  145. package/dist/contracts/values.d.ts +24 -0
  146. package/dist/image.d.ts +15 -0
  147. package/dist/image.js +36 -2
  148. package/dist/index.html +8 -2
  149. package/dist/io.d.ts +29 -0
  150. package/dist/io.js +40 -0
  151. package/dist/player/app.js +11 -7
  152. package/dist/player/editor.js +3 -2
  153. package/dist/player/editorEngine.js +3 -2
  154. package/dist/player/embed.js +2 -0
  155. package/dist/player/types.d.ts +6 -0
  156. package/dist/runtime/builtins/assert/checks.d.ts +18 -0
  157. package/dist/runtime/builtins/assert/checks.js +207 -0
  158. package/dist/runtime/builtins/assert/definitions.d.ts +130 -0
  159. package/dist/runtime/builtins/assert/definitions.js +54 -0
  160. package/dist/runtime/builtins/assert/index.d.ts +152 -0
  161. package/dist/runtime/builtins/assert/index.js +36 -0
  162. package/dist/runtime/builtins/image/contactSheet.d.ts +3 -165
  163. package/dist/runtime/builtins/image/contactSheet.js +0 -49
  164. package/dist/runtime/builtins/image/definitions.d.ts +950 -0
  165. package/dist/runtime/builtins/image/definitions.js +343 -0
  166. package/dist/runtime/builtins/image/file.d.ts +8 -0
  167. package/dist/runtime/builtins/image/file.js +37 -0
  168. package/dist/runtime/builtins/image/filters.d.ts +8 -0
  169. package/dist/runtime/builtins/image/filters.js +394 -0
  170. package/dist/runtime/builtins/image/generators.d.ts +7 -0
  171. package/dist/runtime/builtins/image/generators.js +144 -0
  172. package/dist/runtime/builtins/image/index.d.ts +947 -4
  173. package/dist/runtime/builtins/image/index.js +41 -6
  174. package/dist/runtime/builtins/image/io.d.ts +100 -0
  175. package/dist/runtime/builtins/image/io.js +142 -0
  176. package/dist/runtime/builtins/image/planar.d.ts +55 -0
  177. package/dist/runtime/builtins/image/planar.js +274 -0
  178. package/dist/runtime/builtins/image/simplex.d.ts +22 -0
  179. package/dist/runtime/builtins/image/simplex.js +92 -0
  180. package/dist/runtime/builtins/image/text.d.ts +4 -0
  181. package/dist/runtime/builtins/image/text.js +141 -0
  182. package/dist/runtime/builtins/index.d.ts +3 -0
  183. package/dist/runtime/builtins/index.js +7 -0
  184. package/dist/runtime/definition/architecture.js +89 -0
  185. package/dist/runtime/gpu.d.ts +25 -0
  186. package/dist/runtime/gpu.js +40 -0
  187. package/dist/runtime/runtime.d.ts +2 -0
  188. package/dist/runtime/runtime.js +268 -44
  189. package/dist/runtime/types.d.ts +30 -0
  190. package/doc/CLI_REFERENCE.md +21 -3
  191. package/doc/EDITOR_EXPORT.md +26 -0
  192. package/doc/MCP.md +2 -1
  193. package/doc/NODE_REFERENCE.md +286 -14
  194. package/doc/PROJECT_AUTHORING.md +158 -4
  195. package/doc/WEB_PLAYER.md +9 -1
  196. package/package.json +4 -1
  197. package/dist/assets/CodePanel-BU-autmq.js +0 -2
  198. package/dist/assets/CustomNodeDialog-BRpDfOV5.js +0 -1
  199. package/dist/assets/OpenGraphDialog-BwbRlC0X.js +0 -1
  200. package/dist/assets/ProjectSettings-DLOXLxcA.js +0 -2
  201. package/dist/assets/definitions-GreEMXLV.js +0 -1
  202. package/dist/assets/geo-u0n_jOsD.js +0 -1
  203. package/dist/assets/image-cAa-Nu9O.js +0 -2062
  204. package/dist/assets/index-5ZtDAuy2.js +0 -220
  205. package/dist/assets/index-7vae6YFC.css +0 -1
  206. package/dist/assets/math-DioIQOPJ.js +0 -1
  207. package/dist/assets/pop-DC_TQG9t.js +0 -1
  208. package/dist/cli/chunk-36P5K3SD.js +0 -631
  209. package/dist/cli/chunk-4UDFYF5G.js +0 -132
  210. package/dist/cli/chunk-53NMBJAO.js +0 -35
  211. package/dist/cli/chunk-MIIEFUGG.js +0 -623
  212. package/dist/cli/chunk-QBBKRNGY.js +0 -90
  213. package/dist/cli/chunk-WPUDGEFY.js +0 -20
  214. package/dist/cli/editorCommands-UIF5YLUZ.js +0 -33
  215. package/dist/cli/project-K3QIPGBB.js +0 -12
  216. package/dist/cli/registerStandardNodes-S2VLMF6J.js +0 -3081
  217. package/dist/cli/runner-RA6UKEPD.js +0 -37
  218. package/dist/cli/webBuild-GT4PZT5D.js +0 -37
  219. package/dist/runtime/builtins/headless.d.ts +0 -19
  220. package/dist/runtime/builtins/headless.js +0 -25
@@ -589,6 +589,104 @@ Runs on `portable`.
589
589
  | --- | --- | --- | --- |
590
590
  | `geometry` | `geometry` | | |
591
591
 
592
+ ### `cascade.image.Blur`
593
+
594
+ Blur — Box (three passes, fast) or true Gaussian blur.
595
+
596
+ Runs on `portable`.
597
+
598
+ **Inputs**
599
+
600
+ | name | type | default | range |
601
+ | --- | --- | --- | --- |
602
+ | `image` | `image` | | |
603
+
604
+ **Props**
605
+
606
+ | name | type | default | range |
607
+ | --- | --- | --- | --- |
608
+ | `method` | `string` | `"box"` | |
609
+ | `radius` | `float` | `5` | 0…100 |
610
+ | `wrapEdges` | `bool` | `false` | |
611
+
612
+ **Outputs**
613
+
614
+ | name | type | default | range |
615
+ | --- | --- | --- | --- |
616
+ | `image` | `image` | | |
617
+
618
+ ### `cascade.image.Checkers`
619
+
620
+ Checkers — A checkerboard.
621
+
622
+ Runs on `portable`.
623
+
624
+ **Props**
625
+
626
+ | name | type | default | range |
627
+ | --- | --- | --- | --- |
628
+ | `color1` | `color` | `[1,1,1,1]` | |
629
+ | `color2` | `color` | `[0,0,0,1]` | |
630
+ | `mode` | `string` | `"size"` | |
631
+ | `size` | `float` | `32` | 1…512 |
632
+ | `divisions` | `int` | `16` | 1…512 |
633
+ | `centered` | `bool` | `false` | |
634
+ | `resolution` | `vec2i` | `[512,512]` | 1…4096 |
635
+
636
+ **Outputs**
637
+
638
+ | name | type | default | range |
639
+ | --- | --- | --- | --- |
640
+ | `image` | `image` | | |
641
+
642
+ ### `cascade.image.Color`
643
+
644
+ Color — A solid colour.
645
+
646
+ Runs on `portable`.
647
+
648
+ **Props**
649
+
650
+ | name | type | default | range |
651
+ | --- | --- | --- | --- |
652
+ | `color` | `color` | `[1,1,1,1]` | |
653
+ | `resolution` | `vec2i` | `[512,512]` | 1…4096 |
654
+
655
+ **Outputs**
656
+
657
+ | name | type | default | range |
658
+ | --- | --- | --- | --- |
659
+ | `image` | `image` | | |
660
+
661
+ ### `cascade.image.Composite`
662
+
663
+ Composite — Blend image2 over image1.
664
+
665
+ Runs on `portable`.
666
+
667
+ **Inputs**
668
+
669
+ | name | type | default | range |
670
+ | --- | --- | --- | --- |
671
+ | `image1` | `image` | | |
672
+ | `image2` | `image` | | |
673
+
674
+ **Props**
675
+
676
+ | name | type | default | range |
677
+ | --- | --- | --- | --- |
678
+ | `blendMode` | `string` | `"multiply"` | |
679
+ | `opacity` | `float` | `1` | 0…1 |
680
+ | `outputResolution` | `string` | `"input1"` | |
681
+ | `customResolution` | `vec2i` | `[512,512]` | 1…4096 |
682
+ | `fitMode` | `string` | `"fill"` | |
683
+
684
+ **Outputs**
685
+
686
+ | name | type | default | range |
687
+ | --- | --- | --- | --- |
688
+ | `image` | `image` | | |
689
+
592
690
  ### `cascade.image.ContactSheet`
593
691
 
594
692
  Contact Sheet — Lay images out as one labelled grid.
@@ -622,6 +720,190 @@ Runs on `portable`.
622
720
  | `image` | `image` | | |
623
721
  | `asset` | `asset` | | |
624
722
 
723
+ ### `cascade.image.Image`
724
+
725
+ File — An image file from the project, or an image input, optionally resized.
726
+
727
+ Runs on `portable`.
728
+
729
+ **Inputs**
730
+
731
+ | name | type | default | range |
732
+ | --- | --- | --- | --- |
733
+ | `image` | `image` | | |
734
+
735
+ **Props**
736
+
737
+ | name | type | default | range |
738
+ | --- | --- | --- | --- |
739
+ | `file` | `string` | `""` | |
740
+ | `resolutionMode` | `string` | `"original"` | |
741
+ | `maxResolution` | `vec2i` | `[2048,2048]` | 1…4096 |
742
+ | `fixedResolution` | `vec2i` | `[512,512]` | 1…4096 |
743
+
744
+ **Outputs**
745
+
746
+ | name | type | default | range |
747
+ | --- | --- | --- | --- |
748
+ | `image` | `image` | | |
749
+
750
+ ### `cascade.image.Noise`
751
+
752
+ Noise — Fractal simplex noise, grey.
753
+
754
+ Runs on `portable`.
755
+
756
+ **Props**
757
+
758
+ | name | type | default | range |
759
+ | --- | --- | --- | --- |
760
+ | `seed` | `int` | `0` | 0…10000 |
761
+ | `scale` | `float` | `0.01` | 0.001…1 |
762
+ | `iterations` | `int` | `4` | 1…8 |
763
+ | `resolution` | `vec2i` | `[512,512]` | 1…4096 |
764
+
765
+ **Outputs**
766
+
767
+ | name | type | default | range |
768
+ | --- | --- | --- | --- |
769
+ | `image` | `image` | | |
770
+
771
+ ### `cascade.image.NormalMap`
772
+
773
+ Normal Map — A normal map from the red (or grey) channel as height.
774
+
775
+ Runs on `portable`.
776
+
777
+ **Inputs**
778
+
779
+ | name | type | default | range |
780
+ | --- | --- | --- | --- |
781
+ | `image` | `image` | | |
782
+
783
+ **Props**
784
+
785
+ | name | type | default | range |
786
+ | --- | --- | --- | --- |
787
+ | `scale` | `float` | `1` | 0…10 |
788
+ | `flipX` | `bool` | `false` | |
789
+ | `flipY` | `bool` | `false` | |
790
+
791
+ **Outputs**
792
+
793
+ | name | type | default | range |
794
+ | --- | --- | --- | --- |
795
+ | `image` | `image` | | |
796
+
797
+ ### `cascade.image.Ramp`
798
+
799
+ Ramp — A colour ramp: horizontal, vertical, radial or concentric.
800
+
801
+ Runs on `portable`.
802
+
803
+ **Props**
804
+
805
+ | name | type | default | range |
806
+ | --- | --- | --- | --- |
807
+ | `type` | `string` | `"horizontal"` | |
808
+ | `points` | `array` | `[{"position":0,"color":{"r":0,"g":0,"b":0},"interpolation":"linear"},{"position":1,"color":{"r":1,"g":1,"b":1},"interpolation":"linear"}]` | |
809
+ | `resolution` | `vec2i` | `[512,512]` | 1…4096 |
810
+
811
+ **Outputs**
812
+
813
+ | name | type | default | range |
814
+ | --- | --- | --- | --- |
815
+ | `image` | `image` | | |
816
+
817
+ ### `cascade.image.Resize`
818
+
819
+ Resize — Scale an image, or resize it to a fixed size, bilinear.
820
+
821
+ Runs on `portable`.
822
+
823
+ **Inputs**
824
+
825
+ | name | type | default | range |
826
+ | --- | --- | --- | --- |
827
+ | `image` | `image` | | |
828
+
829
+ **Props**
830
+
831
+ | name | type | default | range |
832
+ | --- | --- | --- | --- |
833
+ | `mode` | `string` | `"scale"` | |
834
+ | `scale` | `float` | `1` | 0.1…10 |
835
+ | `width` | `int` | `512` | 1…4096 |
836
+ | `height` | `int` | `512` | 1…4096 |
837
+
838
+ **Outputs**
839
+
840
+ | name | type | default | range |
841
+ | --- | --- | --- | --- |
842
+ | `image` | `image` | | |
843
+
844
+ ### `cascade.image.Text`
845
+
846
+ Text — Text drawn with a CSS font family, or a font file from the project.
847
+
848
+ Runs on `portable`.
849
+
850
+ **Props**
851
+
852
+ | name | type | default | range |
853
+ | --- | --- | --- | --- |
854
+ | `text` | `string` | `"Hello, World!"` | |
855
+ | `font` | `string` | `"Inter, system-ui, sans-serif"` | |
856
+ | `fontSize` | `float` | `48` | 1…500 |
857
+ | `fontWeight` | `string` | `"normal"` | |
858
+ | `fontStyle` | `string` | `"normal"` | |
859
+ | `alignH` | `string` | `"center"` | |
860
+ | `alignV` | `string` | `"middle"` | |
861
+ | `color` | `color` | `[1,1,1,1]` | |
862
+ | `backgroundColor` | `color` | `[0,0,0,0]` | |
863
+ | `resolution` | `vec2i` | `[512,512]` | 1…4096 |
864
+ | `offset` | `vec2` | `[0,0]` | -2048…2048 |
865
+ | `rotation` | `float` | `0` | -180…180 |
866
+ | `letterSpacing` | `float` | `0` | -50…100 |
867
+ | `lineHeight` | `float` | `1.2` | 0.5…3 |
868
+ | `opacity` | `float` | `1` | 0…1 |
869
+
870
+ **Outputs**
871
+
872
+ | name | type | default | range |
873
+ | --- | --- | --- | --- |
874
+ | `image` | `image` | | |
875
+
876
+ ### `cascade.image.Transform`
877
+
878
+ Transform — Rotate, translate and scale an image about a pivot.
879
+
880
+ Runs on `portable`.
881
+
882
+ **Inputs**
883
+
884
+ | name | type | default | range |
885
+ | --- | --- | --- | --- |
886
+ | `image` | `image` | | |
887
+
888
+ **Props**
889
+
890
+ | name | type | default | range |
891
+ | --- | --- | --- | --- |
892
+ | `translate` | `vec2` | `[0,0]` | -2048…2048 |
893
+ | `rotation` | `float` | `0` | -180…180 |
894
+ | `scale` | `vec2` | `[1,1]` | 0.01…10 |
895
+ | `uniformScale` | `bool` | `true` | |
896
+ | `pivot` | `string` | `"center"` | |
897
+ | `customPivot` | `vec2` | `[0.5,0.5]` | 0…1 |
898
+ | `filter` | `string` | `"bilinear"` | |
899
+ | `wrap` | `string` | `"clamp"` | |
900
+
901
+ **Outputs**
902
+
903
+ | name | type | default | range |
904
+ | --- | --- | --- | --- |
905
+ | `image` | `image` | | |
906
+
625
907
  ### `cascade.math.Binary`
626
908
 
627
909
  Binary Math — Two values, one operation. Component-wise, and a scalar broadcasts against a vector.
@@ -1006,13 +1288,13 @@ Runs on `portable`.
1006
1288
  | --- | --- | --- | --- |
1007
1289
  | `scene` | `scene` | | |
1008
1290
 
1009
- ## Assertions, headless only
1291
+ ## Assertions
1010
1292
 
1011
1293
  `cascade.assert.*` fail a `cascade run` (non-zero exit, the message in
1012
1294
  `run --json`'s `error.message`) when their check does not hold, and pass
1013
- their input through. The CLI registers them; Studio does not yet, and shows
1014
- them as unresolved. An image wired only into assertions still counts as the
1015
- graph's final image for `run --out`.
1295
+ their input through. In Studio a failed assertion is the node's error. An image
1296
+ wired only into assertions still counts as the graph's final image for
1297
+ `run --out`.
1016
1298
 
1017
1299
  ### `cascade.assert.Equals`
1018
1300
 
@@ -1133,16 +1415,6 @@ under `src/nodes/<library>/nodes/`.
1133
1415
  ### Geometry — `cascade.geo.*`
1134
1416
 
1135
1417
  **Geometry.** `cascade.geo.Rectangle` (A closed four-point polygon, counter-clockwise from bottom-left.), `cascade.geo.Circle` (A closed circle, as one cubic Bezier chain or as a polygon of divisions segments.), `cascade.geo.Transform` (Translate, rotate and scale geometry about a pivot.), `cascade.geo.Merge` (Concatenate geometries, taking the union of their attributes.), `cascade.geo.CopyToPoints` (Instance one geometry onto every point of another.), `cascade.geo.SvgExport` (Write geometry as an SVG document, one group element per group.), `cascade.geo.Render` (Draw a scene through a camera, as a raster.), `cascade.geo.FromRects` (Convert rects into geometry, one closed polygon each, keeping the tag.)
1136
-
1137
- ### Image — `cascade.image.*`
1138
-
1139
- **Create.** `Image` (Load images from files), `Color` (Create a solid color canvas), `Checkers` (Generate a checkerboard pattern), `Noise` (Generate procedural noise patterns), `Ramp` (Generate color ramps), `Text` (Render text with customizable font and style)
1140
-
1141
- **Filter.** `Blur` (Gaussian blur), `NormalMap` (Compute normal map from height map)
1142
-
1143
- **Transform.** `Transform` (2D rotation, translation, and scaling), `Resize` (Scale or resize an image)
1144
-
1145
- **Composite.** `Composite` (Blend two images together)
1146
1418
  ## A project's own nodes
1147
1419
 
1148
1420
  Not listed here, because they belong to the project rather than to Cascade. Ask
@@ -61,6 +61,40 @@ difference. Use a deliberate local package override
61
61
  for framework development rather than committing a machine-specific
62
62
  `file:../../Dev/cascade` dependency to a shared project.
63
63
 
64
+ ### Pin the core
65
+
66
+ A sketch pins one published Cascade, exactly, rather than linking the live
67
+ checkout, so a change on Cascade main cannot move its pixels until it opts in:
68
+
69
+ ```json
70
+ "devDependencies": {
71
+ "cascade": "npm:@field/cascade@0.11.0",
72
+ "@field/cascade-kit": "file:../../Dev/cascade/packages/kit"
73
+ }
74
+ ```
75
+
76
+ Keep the dependency name `cascade`: imports stay `cascade/io`,
77
+ `cascade/stage` and so on, which is what Studio's compiler resolves. Only the
78
+ core is pinned; the kit is not on npm and stays a `file:` dependency. Commit
79
+ the lockfile, since it holds the core's own dependencies (a newer
80
+ `@napi-rs/canvas` shifts antialiasing by a few levels). To move from a link:
81
+
82
+ ```bash
83
+ npm install --save-dev --save-exact cascade@npm:@field/cascade@0.11.0
84
+ ```
85
+
86
+ If `node_modules/cascade` is still a link afterwards, or npm fails with
87
+ `Cannot destructure property 'package' of 'node.target'`, the kit link is the
88
+ cause: its target sits inside the checkout, whose own package is
89
+ `@field/cascade`, so npm reuses the checkout. Move `node_modules` and
90
+ `package-lock.json` aside, install with the kit removed from `package.json`,
91
+ then add it back with `npm install --save-dev ../../Dev/cascade/packages/kit`.
92
+
93
+ To bump: change the version, `npm install`, `npx cascade check <graph>`, and
94
+ render a frame to compare. A sketch that needs something only on main (for
95
+ example `cascade share` before it ships) keeps the `file:` link and says why in
96
+ its README until the next release.
97
+
64
98
  `index.cascade` is the default graph name. A project may contain several `.cascade` files; pass one explicitly when there is no unambiguous default:
65
99
 
66
100
  ```bash
@@ -162,6 +196,65 @@ The initiating node ID is captured as `api.sourceNodeId`; `setParam` uses the sa
162
196
  }
163
197
  ```
164
198
 
199
+ ### Reading another project's data
200
+
201
+ File reads stay inside the project: a `..` path or a symlink out of it is
202
+ refused. To read another folder, declare it as a read-only root:
203
+
204
+ ```json
205
+ {
206
+ "reads": ["../other-sketch/data"]
207
+ }
208
+ ```
209
+
210
+ Each entry is a folder relative to the project (absolute and `~` paths are
211
+ refused). The `files` capability's `read`, `list` and `stat`, `cascade/io`'s
212
+ loaders and Studio's media route may then resolve into it, whether the path
213
+ reaches it with `..` (`../other-sketch/data/points.csv`) or through a symlink in
214
+ the project (`data -> ../other-sketch/data`). What counts is where the file
215
+ really is, so a symlink inside the read root that points elsewhere is still
216
+ refused. Writes into a read root are always refused. The declaration is the
217
+ project's, in `cascade.json`, never the graph's; Studio's Project Settings
218
+ cannot change it.
219
+
220
+ ### Named exports and a keyed cache
221
+
222
+ A node with the `files` capability (`runsOn: 'server'`) writes under the name
223
+ it gives, never renamed by a content hash, but only into `.cascade-cache/`. To
224
+ write a stably named export, such as a ladder's chosen variant, declare the
225
+ folder:
226
+
227
+ ```json
228
+ {
229
+ "writes": ["renders"]
230
+ }
231
+ ```
232
+
233
+ ```ts
234
+ await context.capabilities.files.write('renders/cloud-final.png', bytes, { signal: context.signal });
235
+ ```
236
+
237
+ Each entry is a folder inside the project; `..`, absolute paths, the project
238
+ root, `nodes`, `.git` and `.cascade` are refused, and a symlink out of a write
239
+ folder is refused like any other. `cascade/io`'s `write` and `saveImage` keep
240
+ content-hashed names in `.cascade-cache/`: they are intermediates between
241
+ nodes, and the hash is what stops a fixed name handing on the wrong pixels.
242
+
243
+ For a cache a node must find again on the next run, by a key it derives from
244
+ everything the bytes depend on, use `files.cache`:
245
+
246
+ ```ts
247
+ const { files } = context.capabilities;
248
+ const key = `stage/${hashOf(inputs, props)}`;
249
+ const hit = await files.cache.get(key, { signal: context.signal }); // Uint8Array | null
250
+ if (!hit) await files.cache.put(key, computed, { signal: context.signal });
251
+ ```
252
+
253
+ Entries live in `.cascade-cache/keyed/<key>`; keys are letters, digits, `.`,
254
+ `_` and `-` in `/`-separated parts, each starting with a letter or digit.
255
+ Writes are atomic, so parallel render workers can share one cache. The cache
256
+ rule above still holds: it may only memoize work from wired inputs and props.
257
+
165
258
  Read settings without giving nodes write access:
166
259
 
167
260
  ```ts
@@ -207,9 +300,9 @@ Clean graph design is clean code design:
207
300
  - **One responsibility per node**, named for what it does (`layout_rings`, not `main`).
208
301
  - **Data flows through typed ports**, never through module-level state or files one node writes and another reads behind the graph's back.
209
302
  - **What varies is a parameter**; seeds, counts and colours are on the node, not constants in the code.
210
- - **Shared helpers go in `lib/` or the kit** (`KIT.md`); the node is the unit you compose and reuse.
303
+ - **Shared helpers go in `lib/` or the kit** (`KIT.md`); the node is the unit you compose and reuse. A helper only this node uses may stay in its file: function declarations and immutable `const`s (`const TAU = Math.PI * 2`, `const PALETTE = [...] as const`, `const lerp = (a, b, t) => …`) pass `cascade check`. Anything that can change between cooks (`let`, `new Map()`, a bare array or object, a regex, a call) is module state and is refused (`architecture/module-state`).
211
304
 
212
- Split a node when it does two of load, generate, style, render and export, or when its `execute` grows past about 150 lines.
305
+ Split a node when it does two of load, generate, style, render and export, or when its `execute` grows past about 150 lines. `cascade check` warns on both (`shape/long-execute`, `shape/mixed-jobs`); the warnings are advice and never fail the check. Drawing with noise and colour is one job's worth of calls, so it only flags a module doing four of the five, or loading and exporting in the same node.
213
306
 
214
307
  ## Add a custom node
215
308
 
@@ -423,8 +516,8 @@ export async function execute(context: NodeExecutionContext<typeof definition>)
423
516
  | | Browser (Studio, exported editor) | Headless (CLI, MCP) |
424
517
  | --- | --- | --- |
425
518
  | `createCanvas`, `surface` | the realm's `OffscreenCanvas` | Skia's, from `@napi-rs/canvas` |
426
- | `decodeImage`, `readImage` | `createImageBitmap` | Skia's decoder |
427
- | `writeImage` | an in-memory generated asset | `.cascade-cache/<name>.<hash>.png` |
519
+ | `decodeImage`, `readImage` | `createImageBitmap` | the pixels from memory while the run holds them, else Skia's decoder |
520
+ | `writeImage` | an in-memory generated asset | `.cascade-cache/<name>.<hash>.png`, pixels held in memory and the file written behind |
428
521
  | `registerFont` | `FontFace` added to the page's or worker's font set | Skia's `GlobalFonts` |
429
522
  | `readBytes` | shipped files only (`editor.assets`, literal asset props, frozen files) | any project file |
430
523
 
@@ -445,6 +538,38 @@ export async function execute(context: NodeExecutionContext<typeof definition>)
445
538
  its output in an editor, freeze it (`cascade freeze <graph> <node> --fields
446
539
  path,size,channels,depth,space` ships the image file with the snapshot).
447
540
 
541
+ #### How an image travels between nodes
542
+
543
+ An `image` port carries an `ImageRef` (a path plus size, channels, depth and
544
+ space), never the pixels, so a value stays cheap to snapshot, hash, trace and
545
+ send to Python. What sits behind the path is the host's business, and the
546
+ headless host keeps it in memory:
547
+
548
+ - `writeImage` (and `saveImage` in `cascade/io`) hands the canvas to the host
549
+ as `ImagePixels` (8-bit RGBA, sRGB, unpremultiplied, top row first: what
550
+ `getImageData` returns and what a PNG decodes to) through the optional
551
+ `assets.keepImage`. Under `cascade run`/`render` the host holds those pixels,
552
+ names the file by their hash, and writes a lossless PNG at zlib level 1
553
+ behind the run, off the main thread.
554
+ - `readImage` (and `loadBitmap`/`loadImage`) asks `assets.imagePixels` first
555
+ and gets a canvas holding the pixels: no file read and no decode. The next
556
+ node sees the same numbers a PNG round trip would give it.
557
+ - Anything that reads the path as a file gets a whole file: a Python stage
558
+ call, `assets.read`, a run's end, `freeze`, `lock` and `ladder` all wait for
559
+ the write behind, and so does every `runsOn: 'server'` node before it
560
+ starts, since it may read an input with `node:fs`. A run's saved outputs
561
+ (`--out`, `run --frames`, `render`) are encoded from the pixels at full
562
+ compression, never copied from the level-1 intermediate.
563
+ - Hosts without `keepImage` (an exported editor, the web player, and Studio
564
+ for project nodes) encode and store as before, so a node written against
565
+ `readImage`/`writeImage` works unchanged in each. Studio gives `keepImage`
566
+ to the built-in image library only: its images stay in the page under
567
+ `.cascade-studio/…` paths, which `readImage`, `assets.read` and the Viewer
568
+ all resolve, but which name no file a server stage could open.
569
+
570
+ On field-logo (12 canvas nodes at 1024²) this took a frame from 1,791 ms to
571
+ about 860 ms; most of what remains is the nodes' own pixel loops.
572
+
448
573
  ### GPU nodes today
449
574
 
450
575
  A definition-v1 node may declare `capabilities: ['gpu']`. Studio and the optional
@@ -453,6 +578,26 @@ a cache scoped to each node instance for pipelines, samplers, and other
453
578
  resources that outlive one cook. The host clears cached resources on host
454
579
  disposal or device loss and requests a fresh device on a later cook.
455
580
 
581
+ The device is asked for with every limit the adapter allows, not WebGPU's
582
+ defaults: on an M3 Max that is 4 GiB per storage binding (default 128 MiB),
583
+ 1,024 invocations per workgroup (256), 32 KiB of workgroup storage (16 KiB) and
584
+ 10 storage buffers per stage (8). Read what you got from
585
+ `context.capabilities.gpu.limits` and size buffers and workgroups from it. A
586
+ node that cannot run below some limit declares it, and a smaller GPU then fails
587
+ before the cook with a sentence naming the limit:
588
+
589
+ ```ts
590
+ export const definition = {
591
+ apiVersion: 1,
592
+ runsOn: 'portable',
593
+ capabilities: ['gpu'],
594
+ gpuLimits: { maxStorageBufferBindingSize: 512 * 2 ** 20 },
595
+ // ...
596
+ } as const;
597
+ ```
598
+
599
+ `max*` limits are floors; `min*Alignment` limits are ceilings.
600
+
456
601
  Use `runsOn: 'portable'` for shared WebGPU code without browser APIs. Render into
457
602
  a texture and use `readTexture` from `cascade/gpu` for explicit RGBA8 pixels,
458
603
  then encode through the image/IO host. See [headless GPU rendering](HEADLESS_GPU.md)
@@ -684,6 +829,15 @@ in `cascade run --json` under `stages`, and in the run trace.
684
829
  keeps running its old code in a live Studio. Its bytecode cache is keyed by
685
830
  the code hash, because Python accepts a `.pyc` whose source kept its size
686
831
  within the same second.
832
+ - `workers` (headless runs only) is how many warm workers `cascade run` keeps
833
+ for the project, and so how many independent nodes it cooks at once: sibling
834
+ stage calls in one frame (the morph's four renders) run side by side. Default
835
+ 2–4, one per four cores and per 8 GB of memory; `CASCADE_STAGE_WORKERS`
836
+ overrides it, and `cascade render` workers keep one each. A second worker
837
+ starts only when a call finds the first busy. Nodes still start in the
838
+ graph's order, so the run trace lists them the same way every run; a stage
839
+ that writes a fixed path shared with another node is the one thing this can
840
+ break, and `"workers": 1` turns it off.
687
841
  - `cache` controls Cascade's own result cache. A stored result is served only
688
842
  while every file it names still has the bytes it had, so a stage that writes
689
843
  a fixed path and was re-run with other inputs misses rather than serving the
package/doc/WEB_PLAYER.md CHANGED
@@ -54,6 +54,12 @@ player.play();
54
54
  await player.dispose();
55
55
  ```
56
56
 
57
+ For a neutral preview page, `chrome: false` hides the player's dark frame, Play
58
+ button and frame field, leaving the output alone on a transparent page; the
59
+ controller still plays, seeks and reports errors. The plain-iframe form is
60
+ `player.html?chrome=0`. The other options have URL forms too: `frame`, `fps`,
61
+ `autoplay=1`, `outputNode` with `outputPort`.
62
+
57
63
  The generic `mountPlayer` export from `cascade/player` accepts the same options
58
64
  plus `url`, pointing to a built `player.html`. Each mount creates an iframe, so
59
65
  two sketches can use the same node IDs and cache filenames without sharing data.
@@ -70,7 +76,9 @@ serialized and playback coalesces requests instead of building a catch-up queue.
70
76
 
71
77
  - `play()`, `pause()`, `seek(frame)`.
72
78
  - `setInput(nodeId, name, value)` and `setProp(nodeId, name, value)`, which await
73
- the resulting cook.
79
+ the resulting cook. Every cook re-runs only the nodes whose inputs or props
80
+ changed and everything downstream of them; an unchanged upstream node keeps
81
+ its outputs (`run({ reuse: "strict" })`).
74
82
  - `selectOutput(nodeId, port)` and `getOutput(nodeId, port)`.
75
83
  - `downloadOutput()`, returning the selected output as a `Blob`.
76
84
  - `resize(width, height)` for the display, without changing authored resolution.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@field/cascade",
3
- "version": "0.11.0",
3
+ "version": "0.13.0",
4
4
  "description": "Visual programming for generative art",
5
5
  "license": "MIT",
6
6
  "author": "FIELD.IO <marcus@field.io>",
@@ -147,6 +147,8 @@
147
147
  "check": "svelte-check --tsconfig ./tsconfig.json",
148
148
  "verify": "node scripts/verify.mjs",
149
149
  "verify:fast": "node scripts/verify.mjs --fast",
150
+ "verify:push": "node scripts/verify.mjs --push",
151
+ "prepare": "node scripts/install-hooks.mjs",
150
152
  "check:architecture": "vitest run tests/architecture-",
151
153
  "check:bundle": "node scripts/bundle-budget.mjs",
152
154
  "check:node-reference": "tsx scripts/build-node-reference.mjs --check",
@@ -183,6 +185,7 @@
183
185
  "svelte": "^5.0.0",
184
186
  "svelte-check": "^4.7.6",
185
187
  "tsx": "^4.23.12",
188
+ "typescript7": "npm:typescript@^7.0.2",
186
189
  "vite": "^8.2.2",
187
190
  "vitest": "^4.1.11"
188
191
  },
@@ -1,2 +0,0 @@
1
- const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/CodeEditor-4O7FQ__R.js","assets/legacy-CTEeXeqF.js","assets/nodeTypeUtils-BDJsc2Ks.js","assets/index-5ZtDAuy2.js","assets/index-client-DqYmKstU.js","assets/index-7vae6YFC.css","assets/editor.api-BNFb25CX.js","assets/editor-1FQrmyyI.css","assets/CodeEditor-DR7u0q7p.css"])))=>i.map(i=>d[i]);
2
- import{Dt as e,G as t,M as n,Ot as r,Q as i,U as a,V as o,W as s,Z as c,ct as l,dt as u,et as d,ht as f,i as p,it as m,jt as h,l as g,nt as _,ot as v,pt as y,r as b,rt as x,st as S,vt as C,yt as w,z as T}from"./legacy-CTEeXeqF.js";import{P as E,et as D}from"./index-5ZtDAuy2.js";var O=t(`<div class="loading svelte-1pkj8m">Loading editor...</div>`),k=t(`<div class="error svelte-1pkj8m">Loading...</div>`),A=t(`<div class="error svelte-1pkj8m"> </div>`),j=t(`<div class="panel-wrapper svelte-1pkj8m"><!></div>`);function M(t,M){r(M,!1);let N=()=>w(D,`$sharedContextStore`,P),[P,F]=C(),I=u(null);b(async()=>{let e=await E(()=>import(`./CodeEditor-4O7FQ__R.js`).then(e=>e.t),__vite__mapDeps([0,1,2,3,4,5,6,7,8]));y(I,e.default)});let L=p(M,`panelParams`,8),R=p(M,`panelApi`,8),z=p(M,`graph`,12,void 0),B=p(M,`onRecordHistory`,12,void 0),V=u(null),H=L()?.nodeId;function U(){R()?.close&&R().close()}_(()=>N(),()=>{N()&&(z(N().graph),B(N().onRecordHistory))}),_(()=>c(z()),()=>{z()&&H?y(V,z().getNode(H)||null):y(V,null)}),_(()=>(c(R()),i(V)),()=>{R()?.setTitle&&i(V)&&R().setTitle(`Code: ${i(V).id}`)}),x(),g();var W=j(),G=v(W),K=e=>{var t=s(),r=S(t);{let e=f(()=>(c(z()),d(()=>z().packageManager||null)));n(r,()=>i(I),(t,n)=>{n(t,{get node(){return i(V)},get graph(){return z()},get packageManager(){return i(e)},onClose:U,showCloseButton:!1,get onRecordHistory(){return B()}})})}a(e,t)},q=e=>{var t=O();a(e,t)},J=e=>{var t=k();a(e,t)},Y=e=>{var t=A(),n=l(t);m(()=>o(n,`Node not found: ${H??``}`)),a(e,t)};T(G,e=>{i(V)&&z()&&i(I)?e(K):i(I)?z()?e(Y,-1):e(J,2):e(q,1)}),h(W),a(t,W),e(),F()}export{M as default};
@@ -1 +0,0 @@
1
- import{At as e,Dt as t,G as n,I as r,L as i,O as ee,Ot as a,Q as o,U as s,V as c,W as l,X as u,Z as d,_ as te,at as f,b as p,ct as m,d as h,dt as g,et as _,f as ne,i as v,it as y,jt as b,l as x,lt as S,nt as C,ot as w,p as re,pt as T,rt as E,s as ie,st as D,t as O,u as ae,v as k,z as A}from"./legacy-CTEeXeqF.js";import{H as j,U as M}from"./index-5ZtDAuy2.js";var N=n(`<span class="auto-badge svelte-1c1mvak">auto</span>`),P=n(`<span class="radio-path svelte-1c1mvak"> </span>`),F=n(`<input type="text" class="custom-base-input svelte-1c1mvak" placeholder="e.g., cascade.mylib.MyBaseNode" autocomplete="off"/>`),I=n(`<label><input type="radio" name="baseClass" class="svelte-1c1mvak"/> <div class="radio-content svelte-1c1mvak"><div class="radio-header svelte-1c1mvak"><span class="radio-label svelte-1c1mvak"> </span> <!></div> <!></div></label>`),oe=n(`<div class="dialog-overlay svelte-1c1mvak"><div class="dialog svelte-1c1mvak" role="dialog" aria-modal="true" aria-labelledby="custom-node-title"><div class="dialog-header svelte-1c1mvak"><h2 id="custom-node-title" class="svelte-1c1mvak">Create Custom Node</h2> <button class="close-button svelte-1c1mvak" aria-label="Close"><!></button></div> <form class="svelte-1c1mvak"><div class="form-group svelte-1c1mvak"><label for="node-name" class="svelte-1c1mvak">Node Name</label> <input id="node-name" type="text" placeholder="e.g., ParticleField" autocomplete="off" class="svelte-1c1mvak"/> <span class="hint svelte-1c1mvak">The display name for your node</span></div> <div class="form-group svelte-1c1mvak"><label for="module-path" class="svelte-1c1mvak">Module Path</label> <input id="module-path" type="text" placeholder="e.g., project.particle-field" autocomplete="off" class="svelte-1c1mvak"/> <span class="hint svelte-1c1mvak">Unique identifier for the node module <!></span></div> <div class="form-group svelte-1c1mvak"><span class="field-label svelte-1c1mvak">Base Class</span> <div class="base-class-options svelte-1c1mvak"></div></div> <div class="dialog-footer svelte-1c1mvak"><button type="button" class="cancel-button svelte-1c1mvak">Cancel</button> <button type="submit" class="create-button svelte-1c1mvak"><!> Create Node</button></div></form></div></div>`);function L(n,L){a(L,!1);let R=g(),se=[],z=v(L,`open`,12,!1),B=O(),V=g(``),H=g(``),U=g(`cascade.Node`),W=g(``),G=g(!0),K=[{id:`cascade.Node`,label:`Node`,description:`Base class for all nodes - use for general purpose computation`,template:`node`},{id:`cascade.image.ImageNodeBase`,label:`ImageNodeBase`,description:`Image processing base class with canvas/image utilities`,template:`image`},{id:`custom`,label:`Other`,description:`Specify a custom base class path`,template:`node`}];function ce(){T(G,!1)}function le(){let e=`local.${o(V).toLowerCase().replace(/[^a-z0-9]/g,``)}`;(o(H)===e||o(H)===``)&&T(G,!0)}function q(){if(!o(V).trim()||o(U)===`custom`&&!o(W).trim())return;let e=K.find(e=>e.id===o(U));B(`create`,{name:o(V).trim(),modulePath:o(H)||`local.${o(V).toLowerCase().replace(/[^a-z0-9]/g,``)}`,baseClass:o(R),template:e?.template||`node`}),Y()}function J(){Y(),B(`close`)}function Y(){T(V,``),T(H,``),T(U,`cascade.Node`),T(W,``),T(G,!0),z(!1)}function X(e){e.key===`Escape`?J():e.key===`Enter`&&!e.shiftKey&&(e.preventDefault(),q())}let Z=g();C(()=>(o(U),o(W)),()=>{T(R,o(U)===`custom`?o(W):o(U))}),C(()=>(o(G),o(V)),()=>{if(o(G)&&o(V)){let e=o(V).toLowerCase().replace(/[^a-z0-9]/g,``);T(H,`local.${e}`)}}),C(()=>(d(z()),o(Z)),()=>{z()&&o(Z)&&setTimeout(()=>o(Z)?.focus(),50)}),E(),x();var Q=l();u(`keydown`,f,X);var $=D(Q),ue=t=>{var n=oe(),a=w(n),l=w(a),d=S(w(l),2),f=w(d);M(f,{size:18}),b(d),b(l);var g=S(l,2),v=w(g),x=S(w(v),2);p(x),re(x,e=>T(Z,e),()=>o(Z)),e(2),b(v);var C=S(v,2),E=S(w(C),2);p(E);var D=S(E,2),O=S(w(D)),R=e=>{var t=N();s(e,t)};A(O,e=>{o(G)&&e(R)}),b(D),b(C);var z=S(C,2),B=S(w(z),2);r(B,5,()=>K,i,(e,t)=>{var n=I();let r;var i=w(n);p(i);var a,l=S(i,2),d=w(l),f=w(d),h=m(f,!0),g=S(f,2),v=e=>{var n=P(),r=m(n,!0);y(()=>c(r,(o(t),_(()=>o(t).id)))),s(e,n)};A(g,e=>{o(t),_(()=>o(t).id!==`custom`)&&e(v)}),b(d);var x=S(d,2),C=e=>{var t=F();p(t),k(t,()=>o(W),e=>T(W,e)),u(`click`,t,ne(function(e){ie.call(this,L,e)})),s(e,t)};A(x,e=>{o(t),o(U),_(()=>o(t).id===`custom`&&o(U)===`custom`)&&e(C)}),b(l),b(n),y(()=>{r=ee(n,1,`radio-option svelte-1c1mvak`,null,r,{selected:o(U)===o(t).id}),a!==(a=(o(t),_(()=>o(t).id)))&&(i.value=(i.__value=a)??``),c(h,(o(t),_(()=>o(t).label)))}),te(se,[],i,()=>(o(t),_(()=>o(t).id),o(U)),e=>T(U,e)),s(e,n)}),b(B),b(z);var Y=S(z,2),X=w(Y),Q=S(X,2),$=w(Q);j($,{name:`Zap`,size:14}),e(),b(Q),b(Y),b(g),b(a),b(n),y(e=>Q.disabled=e,[()=>(o(V),o(U),o(W),_(()=>!o(V).trim()||o(U)===`custom`&&!o(W).trim()))]),u(`click`,d,J),k(x,()=>o(V),e=>T(V,e)),u(`input`,x,le),k(E,()=>o(H),e=>T(H,e)),u(`input`,E,ce),u(`click`,X,J),u(`submit`,g,ae(q)),u(`click`,n,h(J)),s(t,n)};A($,e=>{z()&&e(ue)}),s(n,Q),t()}export{L as default};
@@ -1 +0,0 @@
1
- import{Dt as e,G as t,I as n,O as r,Ot as i,Q as a,U as o,V as s,W as c,X as l,Z as u,at as d,ct as f,d as p,dt as m,et as h,i as g,it as _,jt as v,l as y,lt as b,nt as x,ot as S,pt as C,rt as w,st as T,t as E,x as D,z as O}from"./legacy-CTEeXeqF.js";import{U as k}from"./index-5ZtDAuy2.js";var A=t(`<p class="root svelte-1j8ra8p"> </p>`),j=t(`<p class="note svelte-1j8ra8p">Loading…</p>`),M=t(`<p class="note error svelte-1j8ra8p"> </p>`),N=t(`<p class="note svelte-1j8ra8p">No <code>.cascade</code> files at the project root.</p>`),P=t(`<span class="tag svelte-1j8ra8p">open</span>`),F=t(`<li><button><span class="name"> </span> <!></button></li>`),I=t(`<ul class="graphs svelte-1j8ra8p"></ul>`),L=t(`<div class="dialog-overlay svelte-1j8ra8p"><div class="dialog svelte-1j8ra8p" role="dialog" aria-modal="true" aria-labelledby="open-graph-title"><div class="dialog-header svelte-1j8ra8p"><h2 id="open-graph-title" class="svelte-1j8ra8p">Open graph</h2> <button class="close-button svelte-1j8ra8p" aria-label="Close"><!></button></div> <!> <div class="body svelte-1j8ra8p"><!></div> <div class="dialog-footer svelte-1j8ra8p"><button class="secondary svelte-1j8ra8p">Open from this computer…</button></div></div></div>`);function R(t,R){i(R,!1);let z=g(R,`open`,8,!1),B=g(R,`current`,8,null),V=E(),H=m([]),U=m(``),W=m(!1),G=m(null);async function K(){C(W,!0),C(G,null);try{let e=await fetch(`/api/graph`);if(!e.ok)throw Error(await e.text());let t=await e.json();C(H,Array.isArray(t.graphs)?t.graphs:[]),C(U,typeof t.root==`string`?t.root:``)}catch(e){C(G,e instanceof Error?e.message:String(e)),C(H,[])}finally{C(W,!1)}}function q(e){V(`choose`,{filename:e})}function J(){V(`close`)}function Y(e){e.key===`Escape`&&J()}x(()=>u(z()),()=>{z()&&K()}),w(),y();var X=c();l(`keydown`,d,Y);var Z=T(X),Q=e=>{var t=L(),i=S(t),c=S(i),u=b(S(c),2),d=S(u);k(d,{size:16}),v(u),v(c);var m=b(c,2),g=e=>{var t=A(),n=f(t,!0);_(()=>{D(t,`title`,a(U)),s(n,a(U))}),o(e,t)};O(m,e=>{a(U)&&e(g)});var y=b(m,2),x=S(y),C=e=>{var t=j();o(e,t)},w=e=>{var t=M(),n=f(t);_(()=>s(n,`No project on this server — ${a(G)??``}`)),o(e,t)},T=e=>{var t=N();o(e,t)},E=e=>{var t=I();n(t,5,()=>a(H),e=>e,(e,t)=>{var n=F(),i=S(n);let c;var u=S(i),d=f(u,!0),p=b(u,2),m=e=>{var t=P();o(e,t)};O(p,e=>{a(t)===B()&&e(m)}),v(i),v(n),_(()=>{c=r(i,1,`graph svelte-1j8ra8p`,null,c,{current:a(t)===B()}),s(d,a(t))}),l(`click`,i,()=>q(a(t))),o(e,n)}),v(t),o(e,t)};O(x,e=>{a(W)?e(C):a(G)?e(w,1):(a(H),h(()=>a(H).length===0)?e(T,2):e(E,-1))}),v(y);var R=b(y,2),z=f(R);v(i),v(t),l(`click`,u,J),l(`click`,z,()=>V(`local`)),l(`click`,t,p(J)),o(e,t)};O(Z,e=>{z()&&e(Q)}),o(t,X),e()}export{R as default};
@@ -1,2 +0,0 @@
1
- import{At as e,C as t,Dt as n,G as r,I as i,L as a,O as o,Ot as s,Q as c,U as l,V as u,W as d,X as f,Z as p,_t as m,a as h,at as g,b as _,ct as v,d as ee,dt as y,et as b,i as te,it as x,jt as S,l as C,lt as w,nt as T,o as E,ot as D,pt as O,rt as ne,st as re,t as k,v as A,z as j}from"./legacy-CTEeXeqF.js";import{$ as M,G as ie,K as ae,U as oe,W as se,Z as ce,b as N,x as P}from"./index-5ZtDAuy2.js";var F=new Set([`$$slots`,`$$events`,`$$legacy`]);function le(e,t){let n=h(t,F),r=[[`path`,{d:`M10 11v6`}],[`path`,{d:`M14 11v6`}],[`path`,{d:`M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6`}],[`path`,{d:`M3 6h18`}],[`path`,{d:`M8 6V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2`}]];M(e,E({name:`trash-2`},()=>n,{get iconNode(){return r}}))}var ue=r(`<span> </span>`),de=r(`<div class="credentials-status svelte-9d4ggp"><!> <small class="svelte-9d4ggp">Add missing values to <code>~/.cascade/credentials.yaml</code> or the file named by <code>CASCADE_CREDENTIALS</code>. Values are never shown here.</small></div>`),fe=r(`<div class="empty-state svelte-9d4ggp"><!> <p class="svelte-9d4ggp">No project packages configured</p> <button class="add-button svelte-9d4ggp"><!> Add Package</button></div>`),pe=r(`<div class="package-item svelte-9d4ggp"><div class="package-info svelte-9d4ggp"><span class="package-alias svelte-9d4ggp"> </span> <span class="package-path svelte-9d4ggp"> </span></div> <button class="remove-button svelte-9d4ggp" aria-label="Remove package"><!></button></div>`),me=r(`<button class="add-button secondary svelte-9d4ggp"><!> Add Package</button>`),he=r(`<div class="packages-list svelte-9d4ggp"></div> <!>`,1),ge=r(`<div class="error-message svelte-9d4ggp"><!> </div>`),_e=r(`<div class="add-form svelte-9d4ggp"><div class="form-row svelte-9d4ggp"><label for="package-path" class="svelte-9d4ggp">Path</label> <div class="input-with-button svelte-9d4ggp"><input id="package-path" type="text" placeholder="./src or ../shared-lib" class="svelte-9d4ggp"/> <button class="browse-button svelte-9d4ggp" title="Browse folder"><!></button></div></div> <div class="form-row svelte-9d4ggp"><label for="package-alias" class="svelte-9d4ggp">Alias</label> <input id="package-alias" type="text" placeholder="myproject" class="svelte-9d4ggp"/></div> <!> <div class="form-actions svelte-9d4ggp"><button class="cancel-button svelte-9d4ggp">Cancel</button> <button class="confirm-button svelte-9d4ggp">Add Package</button></div></div>`),ve=r(`<div class="modal-overlay svelte-9d4ggp"><div class="modal svelte-9d4ggp" role="dialog" aria-modal="true" aria-labelledby="modal-title"><div class="modal-header svelte-9d4ggp"><h2 id="modal-title" class="svelte-9d4ggp"><!> Project Settings</h2> <button class="close-button svelte-9d4ggp" aria-label="Close"><!></button></div> <div class="modal-body svelte-9d4ggp"><section class="section svelte-9d4ggp"><h3 class="svelte-9d4ggp">Graph Metadata <small class="svelte-9d4ggp">(current .cascade file)</small></h3> <div class="form-row svelte-9d4ggp"><label for="graph-name" class="svelte-9d4ggp">Name</label><input id="graph-name" class="svelte-9d4ggp"/></div> <div class="form-row svelte-9d4ggp"><label for="graph-description" class="svelte-9d4ggp">Description</label><input id="graph-description" class="svelte-9d4ggp"/></div> <div class="form-row svelte-9d4ggp"><label for="graph-author" class="svelte-9d4ggp">Author</label><input id="graph-author" class="svelte-9d4ggp"/></div> <div class="form-row svelte-9d4ggp"><label for="graph-created" class="svelte-9d4ggp">Created</label><input id="graph-created" readonly="" class="svelte-9d4ggp"/></div></section> <section class="section svelte-9d4ggp"><h3 class="svelte-9d4ggp">Project Manifest <small class="svelte-9d4ggp">(cascade.json, shared by every graph)</small></h3> <div class="form-row svelte-9d4ggp"><label for="project-name" class="svelte-9d4ggp">Project name</label><input id="project-name" class="svelte-9d4ggp"/></div> <div class="form-row svelte-9d4ggp"><label for="commands-json" class="svelte-9d4ggp">Allowed commands</label><textarea id="commands-json" rows="4" class="svelte-9d4ggp"></textarea></div> <div class="form-row svelte-9d4ggp"><label for="settings-json" class="svelte-9d4ggp">Node settings</label><textarea id="settings-json" rows="5" class="svelte-9d4ggp"></textarea></div> <div class="form-row svelte-9d4ggp"><label for="credentials-list" class="svelte-9d4ggp">Required credentials</label><textarea id="credentials-list" rows="3" placeholder="one credential name per line" class="svelte-9d4ggp"></textarea></div> <!></section> <section class="section svelte-9d4ggp"><h3 class="svelte-9d4ggp">Project Packages</h3> <p class="section-description svelte-9d4ggp">Add local folders as packages. Each package gets an alias that you can use to import modules. <br/> Example: <code class="svelte-9d4ggp">myproject.filters.Blur</code> for file <code class="svelte-9d4ggp">./src/filters/Blur.ts</code></p> <!> <!></section> <section class="section svelte-9d4ggp"><h3 class="svelte-9d4ggp">Project Info</h3> <div class="info-grid svelte-9d4ggp"><div class="info-item svelte-9d4ggp"><span class="info-label svelte-9d4ggp">Embedded Modules</span> <span class="info-value svelte-9d4ggp"> </span></div> <div class="info-item svelte-9d4ggp"><span class="info-label svelte-9d4ggp">External Modules</span> <span class="info-value svelte-9d4ggp"> </span></div></div></section></div> <div class="modal-footer svelte-9d4ggp"><button class="cancel-button svelte-9d4ggp">Cancel</button> <button class="save-button svelte-9d4ggp">Save Changes</button></div></div></div>`);function I(r,h){s(h,!1);let E=te(h,`open`,12,!1),M=te(h,`graph`,12,void 0),F=k(),I=y([]),L=y(``),R=y(``),z=y(!1),B=y(``),V=y(``),H=y(``),U=y(``),W=y(``),G=y(`{}`),K=y(`{}`),q=y(``),J=y([]),Y=y(!1),X=y(!1);function Z(){E(!1),F(`close`)}async function ye(){O(B,``);let e,t;try{if(e=JSON.parse(c(G)||`{}`),t=JSON.parse(c(K)||`{}`),c(X)){let n=await P({name:c(W).trim(),commands:e,settings:t,credentials:c(q).split(/\r?\n|,/).map(e=>e.trim()).filter(Boolean)});O(J,n.requiredCredentials)}}catch(e){O(B,e instanceof Error?e.message:String(e));return}M()&&(M(M().project.name=c(V).trim(),!0),M(M().project.description=c(H).trim(),!0),M(M().project.author=c(U).trim(),!0),M(M().project.packages=[...c(I)],!0),c(I).forEach(e=>{M().moduleResolver.addProjectPackage(e)})),F(`save`,{packages:[...c(I)],graphName:c(V).trim(),projectName:c(W).trim(),missingCredentials:c(J).filter(e=>!e.set).map(e=>e.name)}),Z()}function be(){if(O(B,``),!c(L).trim()){O(B,`Path is required`);return}if(!c(R).trim()){O(B,`Alias is required`);return}if(!/^[a-zA-Z][a-zA-Z0-9_]*$/.test(c(R))){O(B,`Alias must start with a letter and contain only letters, numbers, and underscores`);return}if(c(I).some(e=>e.alias===c(R))){O(B,`Alias "${c(R)}" already exists`);return}O(I,[...c(I),{path:c(L).trim(),alias:c(R).trim()}]),O(L,``),O(R,``),O(z,!1)}function xe(e){O(I,c(I).filter((t,n)=>n!==e))}function Q(e){e.key===`Escape`&&(c(z)?O(z,!1):Z())}function $(e){let t=e.replace(/\\/g,`/`).split(`/`).filter(Boolean);return(t[t.length-1]||`mypackage`).replace(/[^a-zA-Z0-9]/g,``).toLowerCase()||`mypackage`}T(()=>(p(E()),p(M())),()=>{E()&&M()&&(O(I,[...M().project.packages]),O(z,!1),O(B,``),O(L,``),O(R,``))}),T(()=>p(E()),()=>{E()||O(Y,!1)}),T(()=>(p(E()),p(M()),c(Y),N),()=>{E()&&M()&&!c(Y)&&(O(Y,!0),O(V,M().project.name??``),O(H,M().project.description??``),O(U,M().project.author??``),N().then(e=>{O(X,!0),O(W,e.manifest.name),O(G,JSON.stringify(e.manifest.commands,null,2)),O(K,JSON.stringify(e.manifest.settings,null,2)),O(q,e.manifest.credentials.join(`
2
- `)),O(J,e.requiredCredentials)}).catch(()=>{O(X,!1)}))}),T(()=>(c(L),c(R)),()=>{c(L)&&!c(R)&&O(R,$(c(L)))}),ne(),C();var Se=d();f(`keydown`,g,Q);var Ce=re(Se),we=n=>{var r=ve(),s=D(r),d=D(s),h=D(d),g=D(h);ie(g,{size:20}),e(),S(h);var y=w(h,2),te=D(y);oe(te,{size:20}),S(y),S(d);var C=w(d,2),T=D(C),E=w(D(T),2),ne=w(D(E));_(ne),S(E);var k=w(E,2),N=w(D(k));_(N),S(k);var P=w(k,2),F=w(D(P));_(F),S(P);var Y=w(P,2),X=w(D(Y));_(X),S(Y),S(T);var Q=w(T,2),$=w(D(Q),2),Se=w(D($));_(Se),S($);var Ce=w($,2),we=w(D(Ce));m(we),S(Ce);var Te=w(Ce,2),Ee=w(D(Te));m(Ee),S(Te);var De=w(Te,2),Oe=w(D(De));m(Oe),S(De);var ke=w(De,2),Ae=t=>{var n=de(),r=D(n);i(r,1,()=>c(J),a,(e,t)=>{var n=ue();let r;var i=v(n);x(()=>{r=o(n,1,`svelte-9d4ggp`,null,r,{set:c(t).set}),u(i,`${c(t),b(()=>c(t).name)??``}: ${c(t),b(()=>c(t).set?`set`:`not set`)??``}`)}),l(e,n)}),e(2),S(n),l(t,n)};j(ke,e=>{c(J),b(()=>c(J).length)&&e(Ae)}),S(Q);var je=w(Q,2),Me=w(D(je),4),Ne=t=>{var n=fe(),r=D(n);ae(r,{size:32});var i=w(r,4),a=D(i);se(a,{size:16}),e(),S(i),S(n),f(`click`,i,()=>O(z,!0)),l(t,n)},Pe=t=>{var n=he(),r=re(n);i(r,5,()=>c(I),a,(e,t,n)=>{var r=pe(),i=D(r),a=D(i),o=v(a,!0),s=w(a,2),d=v(s,!0);S(i);var p=w(i,2);le(D(p),{size:16}),S(p),S(r),x(()=>{u(o,(c(t),b(()=>c(t).alias))),u(d,(c(t),b(()=>c(t).path)))}),f(`click`,p,()=>xe(n)),l(e,r)}),S(r);var o=w(r,2),s=t=>{var n=me(),r=D(n);se(r,{size:16}),e(),S(n),f(`click`,n,()=>O(z,!0)),l(t,n)};j(o,e=>{c(z)||e(s)}),l(t,n)};j(Me,e=>{c(I),c(z),b(()=>c(I).length===0&&!c(z))?e(Ne):e(Pe,-1)});var Fe=w(Me,2),Ie=e=>{var t=_e(),n=D(t),r=w(D(n),2),i=D(r);_(i);var a=w(i,2),o=D(a);ae(o,{size:16}),S(a),S(r),S(n);var s=w(n,2),d=w(D(s),2);_(d),S(s);var p=w(s,2),m=e=>{var t=ge(),n=D(t);ce(n,{size:14});var r=w(n);S(t),x(()=>u(r,` ${c(B)??``}`)),l(e,t)};j(p,e=>{c(B)&&e(m)});var h=w(p,2),g=D(h),v=w(g,2);S(h),S(t),A(i,()=>c(L),e=>O(L,e)),A(d,()=>c(R),e=>O(R,e)),f(`click`,g,()=>O(z,!1)),f(`click`,v,be),l(e,t)};j(Fe,e=>{c(z)&&e(Ie)}),S(je);var Le=w(je,2),Re=w(D(Le),2),ze=D(Re),Be=w(D(ze),2),Ve=v(Be,!0);S(ze);var He=w(ze,2),Ue=w(D(He),2),We=v(Ue,!0);S(He),S(Re),S(Le),S(C);var Ge=w(C,2),Ke=D(Ge),qe=w(Ke,2);S(Ge),S(s),S(r),x((e,n)=>{t(X,(p(M()),b(()=>M()?.created??``))),u(Ve,e),u(We,n)},[()=>(p(M()),b(()=>M()?Object.keys(M().moduleResolver.exportConfig().embeddedModules).length:0)),()=>(p(M()),b(()=>M()?Object.keys(M().moduleResolver.exportConfig().externalModules).length:0))]),f(`click`,y,Z),A(ne,()=>c(V),e=>O(V,e)),A(N,()=>c(H),e=>O(H,e)),A(F,()=>c(U),e=>O(U,e)),A(Se,()=>c(W),e=>O(W,e)),A(we,()=>c(G),e=>O(G,e)),A(Ee,()=>c(K),e=>O(K,e)),A(Oe,()=>c(q),e=>O(q,e)),f(`click`,Ke,Z),f(`click`,qe,ye),f(`click`,r,ee(Z)),l(n,r)};j(Ce,e=>{E()&&e(we)}),l(r,Se),n()}export{I as default};
@@ -1 +0,0 @@
1
- import{N as e,_ as t,d as n,f as r,g as i,h as a,l as o,u as s}from"./index-5ZtDAuy2.js";e([a,o,s,n,t,i,r]);
@@ -1 +0,0 @@
1
- import{M as e,N as t,c as n,w as r}from"./index-5ZtDAuy2.js";t(n,{assets:e});export{r as geoLibrary};