@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.
- package/AGENTS.md +8 -5
- package/ARCHITECTURE.md +5 -4
- package/CHANGELOG.md +245 -0
- package/README.md +1 -1
- package/dist/assets/AgentPanel-1JugFjE4.css +1 -0
- package/dist/assets/AgentPanel-BDL5MddA.js +5 -0
- package/dist/assets/{CodeEditor-4O7FQ__R.js → CodeEditor-C-xYG-Wn.js} +120 -120
- package/dist/assets/CodePanel-CtXd50m6.js +2 -0
- package/dist/assets/CookInfoPanel-B3NMhKJF.css +1 -0
- package/dist/assets/CookInfoPanel-DG4_TRsX.js +2 -0
- package/dist/assets/CustomNodeDialog-CHfZUs-r.js +1 -0
- package/dist/assets/DefinitionNode-CaRTXQ_b.js +1 -0
- package/dist/assets/DefinitionPanel-C3CxZY9r.js +1 -0
- package/dist/assets/DefinitionPanel-VNLnAiQD.css +1 -0
- package/dist/assets/OpenGraphDialog-BLdr6k_q.js +1 -0
- package/dist/assets/ProjectSettings-ZnvmIAir.js +2 -0
- package/dist/assets/{SettingsDialog-Bz8JxISH.js → SettingsDialog-CBX3Wa87.js} +1 -1
- package/dist/assets/TimelinePanel-CDeR0arY.css +1 -0
- package/dist/assets/TimelinePanel-CWgnFH1e.js +1 -0
- package/dist/assets/{VersionHistoryDialog-D5Z0nJ5-.js → VersionHistoryDialog-BOSoW1R-.js} +1 -1
- package/dist/assets/assert-BO2_erPD.js +1 -0
- package/dist/assets/assert-hvykGCnP.js +1 -0
- package/dist/assets/builder-BmBKcDix.js +1 -0
- package/dist/assets/camera-DFF7YA3F.js +1 -0
- package/dist/assets/checks-DAvyO9Gf.js +1 -0
- package/dist/assets/contactSheet-N1NcaWxw.js +2 -0
- package/dist/assets/{core-Yqi0Ni61.js → core-DB-MkGjj.js} +3 -4
- package/dist/assets/coreTypes-DtnDATZ7.js +1 -0
- package/dist/assets/{cssMode-CxUzc4vp.js → cssMode-DPVckSOc.js} +1 -1
- package/dist/assets/definitions-B227e7f_.js +1 -0
- package/dist/assets/definitions-D0WOUJd7.js +1 -0
- package/dist/assets/{editor.api-BNFb25CX.js → editor.api-Dkutg_Z1.js} +1 -1
- package/dist/assets/expressions-X-Z-GrgW.js +5 -0
- package/dist/assets/file-DAL6IfjV.js +1 -0
- package/dist/assets/filters-D3k1LRMa.js +1 -0
- package/dist/assets/{freemarker2-0ZDnWxeM.js → freemarker2-CLiLKk3B.js} +1 -1
- package/dist/assets/generators-BhDxRAFC.js +1 -0
- package/dist/assets/geo-BsMImJIJ.js +1 -0
- package/dist/assets/geo-C4YngDob.js +2 -0
- package/dist/assets/{handlebars-Cy18MoaD.js → handlebars-CcD3aMeL.js} +1 -1
- package/dist/assets/{html-B-2Dx7nq.js → html-DvZWGfqb.js} +1 -1
- package/dist/assets/{htmlMode-DUAc9B_d.js → htmlMode-DUD3VaoN.js} +1 -1
- package/dist/assets/image-0SfH-snh.js +1 -0
- package/dist/assets/image-Ck-RdGU4.js +2 -0
- package/dist/assets/index-BWnrmIB9.js +137 -0
- package/dist/assets/index-DIaxEONI.css +1 -0
- package/dist/assets/io-BGmt2g0D.js +1 -0
- package/dist/assets/{javascript-DeQsDqP5.js → javascript-Cap2ahgh.js} +1 -1
- package/dist/assets/{jsonMode-BiFwJVSk.js → jsonMode-B0uLjp9C.js} +1 -1
- package/dist/assets/{liquid-BLoHH68a.js → liquid-CnxwhfLn.js} +1 -1
- package/dist/assets/{lspLanguageFeatures-CNFgm1Kv.js → lspLanguageFeatures-Dn9hlKX6.js} +1 -1
- package/dist/assets/math-GeULS-sk.js +1 -0
- package/dist/assets/{mdx-CFXQVNfs.js → mdx-BV3jbrVa.js} +1 -1
- package/dist/assets/pop-KMF_qloi.js +1 -0
- package/dist/assets/preload-helper-Czpn1I53.js +1 -0
- package/dist/assets/{python-Cf7S7p2E.js → python-CGyFk4XK.js} +1 -1
- package/dist/assets/{razor-CMHBcG-g.js → razor-CQfzX3-N.js} +1 -1
- package/dist/assets/remap-5SjXQU-q.js +1 -0
- package/dist/assets/renderMarkdown-ork0Oir7.js +67 -0
- package/dist/assets/studioImages-CAyH-0Pl.js +1 -0
- package/dist/assets/text-ZpX7qNkx.js +2 -0
- package/dist/assets/time-P_OiBhcf.js +1 -0
- package/dist/assets/{tsMode-BEih0GDj.js → tsMode-BOeXzO9H.js} +1 -1
- package/dist/assets/{typescript-COEKYD_a.js → typescript-J1SnE_Tu.js} +1 -1
- package/dist/assets/{workers-BNhAhMNn.js → workers-CYwwTiVF.js} +1 -1
- package/dist/assets/{xml-CPiMpnPl.js → xml-DnPRNzK9.js} +1 -1
- package/dist/assets/{yaml-Bgp1ITLR.js → yaml-BmmYBNa9.js} +1 -1
- package/dist/cli/DefinitionNode-P7AA4TAU.js +15 -0
- package/dist/cli/{Graph-ZJJTRQTM.js → Graph-OB6EWSGL.js} +12 -12
- package/dist/cli/assert-GROGQNCQ.js +25 -0
- package/dist/cli/checks-3WB44XBL.js +189 -0
- package/dist/cli/{chunk-3JTJHF7V.js → chunk-2L34ERS2.js} +4 -4
- package/dist/cli/chunk-53LGFPWX.js +138 -0
- package/dist/cli/chunk-5ORUQ6ES.js +267 -0
- package/dist/cli/{chunk-YAT5Y25U.js → chunk-7QE2ZNSN.js} +3 -3
- package/dist/cli/{chunk-SGJAET2L.js → chunk-BPODRH52.js} +8 -4
- package/dist/cli/{chunk-XWDSKG7N.js → chunk-BZ63XQ3I.js} +2 -2
- package/dist/cli/{chunk-FCDXJ6EK.js → chunk-CTPLRSWF.js} +2 -13
- package/dist/cli/{chunk-WIH4TEIS.js → chunk-EZRWJ4G2.js} +1 -1
- package/dist/cli/{chunk-BIJO5OFS.js → chunk-FWMSGKEH.js} +1 -1
- package/dist/cli/{chunk-POMMNKZZ.js → chunk-G23A2BZZ.js} +38 -5
- package/dist/cli/{chunk-35D343DC.js → chunk-GRIN2DDP.js} +19 -1
- package/dist/cli/{chunk-WKURDVYP.js → chunk-JEW5MPGI.js} +28 -331
- package/dist/cli/chunk-JVOCK5W4.js +83 -0
- package/dist/cli/chunk-KBGUO27Q.js +15 -0
- package/dist/cli/{chunk-GFS6W3C5.js → chunk-L6B6FUQP.js} +54 -32
- package/dist/cli/chunk-LTXWBXOM.js +438 -0
- package/dist/cli/chunk-MI5JLQYA.js +220 -0
- package/dist/cli/{chunk-A4OAMOZH.js → chunk-NJFMDXHR.js} +13 -3
- package/dist/cli/{chunk-DUIUFVU2.js → chunk-OBZAP3GG.js} +49 -23
- package/dist/cli/chunk-QAGATJGE.js +336 -0
- package/dist/cli/{chunk-EUIAC3U3.js → chunk-QKL7CCRS.js} +966 -132
- package/dist/cli/{chunk-RLCAJBVR.js → chunk-TJW67QSI.js} +8 -7
- package/dist/cli/{chunk-RQZ4SX5R.js → chunk-W5PJ5RMP.js} +156 -84
- package/dist/cli/chunk-W7OUAT7J.js +122 -0
- package/dist/cli/chunk-WGKPJZDY.js +364 -0
- package/dist/cli/{chunk-D6BUOHUG.js → chunk-X4WKAOQP.js} +4 -4
- package/dist/cli/{chunk-VVGSLVSF.js → chunk-X566FWBV.js} +6 -1
- package/dist/cli/chunk-YH637PDL.js +317 -0
- package/dist/cli/chunk-ZSCUZE6I.js +112 -0
- package/dist/cli/{cliCommands-UQSFGEHF.js → cliCommands-XVFRD7CF.js} +23 -17
- package/dist/cli/{commands-Q23M26QM.js → commands-M2XLTPTZ.js} +129 -47
- package/dist/cli/contactSheet-2PQVRUFW.js +11 -0
- package/dist/cli/{definitions-HF2FTHYU.js → definitions-BPOPW52L.js} +7 -7
- package/dist/cli/{doctorCommand-B7BPQMN6.js → doctorCommand-RAEI7GVY.js} +36 -6
- package/dist/cli/{edit-JHCPTQFT.js → edit-S5KEQ5RA.js} +3 -3
- package/dist/cli/editorCommands-5BBG4S6V.js +41 -0
- package/dist/cli/{encode-HAUZTYPT.js → encode-ICPEPMH5.js} +2 -2
- package/dist/cli/file-3HTQHPYQ.js +41 -0
- package/dist/cli/filters-6ODFWYK4.js +379 -0
- package/dist/cli/generators-YU7GB4MD.js +210 -0
- package/dist/cli/{geo-4RNK3QVN.js → geo-6ZPGKZRU.js} +7 -7
- package/dist/cli/{graphCommands-6BMAKGQE.js → graphCommands-MULQ7VD2.js} +4 -4
- package/dist/cli/{graphFile-VPSQ6OF7.js → graphFile-CITF36ZM.js} +25 -19
- package/dist/cli/{headlessCanvas-5XLDZT7M.js → headlessCanvas-ENRHC7GS.js} +3 -2
- package/dist/cli/{helpCommand-3VRE3KVO.js → helpCommand-X2QDANM3.js} +9 -7
- package/dist/cli/image-TXELZZK5.js +55 -0
- package/dist/cli/index.js +14 -14
- package/dist/cli/{math-ZRMLKU2D.js → math-RSYRQ3C6.js} +5 -5
- package/dist/cli/{mcp-ZLEEMYGF.js → mcp-YRIGRLYQ.js} +4 -4
- package/dist/cli/{parity-KINARCP2.js → parity-3N3HTKWX.js} +42 -36
- package/dist/cli/{pop-USDFXB7H.js → pop-B7SIIYKN.js} +5 -5
- package/dist/cli/project-SJF5ZF3F.js +12 -0
- package/dist/cli/{projectDefinition-DMTZN2NE.js → projectDefinition-F3D7UIHJ.js} +8 -8
- package/dist/cli/{projectRuntime-Z5PJOH47.js → projectRuntime-NY4XMDFH.js} +19 -12
- package/dist/cli/registerStandardNodes-BXJCB6E4.js +744 -0
- package/dist/cli/{render-YURAPPUI.js → render-Y23W6MY6.js} +29 -22
- package/dist/cli/{runCommand-PI764LEG.js → runCommand-XOG7AVC5.js} +3 -3
- package/dist/cli/runner-DNJO5WO2.js +43 -0
- package/dist/cli/runtime/image.ts +27 -2
- package/dist/cli/runtime/io.ts +78 -0
- package/dist/cli/share-B7HTCOJX.js +166 -0
- package/dist/cli/stageCache-TY2BFZJR.js +15 -0
- package/dist/cli/{stageRunner-KUNIMQKJ.js → stageRunner-KY2EJP7X.js} +2 -2
- package/dist/cli/text-MB3EKR4H.js +126 -0
- package/dist/cli/{verbs-RCE3K4VQ.js → verbs-PI2JH5FI.js} +2 -2
- package/dist/cli/webBuild-2K4COCGY.js +44 -0
- package/dist/contracts/capabilities.d.ts +39 -1
- package/dist/contracts/color.d.ts +8 -0
- package/dist/contracts/color.js +23 -0
- package/dist/contracts/definition.d.ts +10 -0
- package/dist/contracts/schema.d.ts +1 -1
- package/dist/contracts/schema.js +1 -0
- package/dist/contracts/validate.js +11 -1
- package/dist/contracts/values.d.ts +24 -0
- package/dist/image.d.ts +15 -0
- package/dist/image.js +36 -2
- package/dist/index.html +8 -2
- package/dist/io.d.ts +29 -0
- package/dist/io.js +40 -0
- package/dist/player/app.js +11 -7
- package/dist/player/editor.js +3 -2
- package/dist/player/editorEngine.js +3 -2
- package/dist/player/embed.js +2 -0
- package/dist/player/types.d.ts +6 -0
- package/dist/runtime/builtins/assert/checks.d.ts +18 -0
- package/dist/runtime/builtins/assert/checks.js +207 -0
- package/dist/runtime/builtins/assert/definitions.d.ts +130 -0
- package/dist/runtime/builtins/assert/definitions.js +54 -0
- package/dist/runtime/builtins/assert/index.d.ts +152 -0
- package/dist/runtime/builtins/assert/index.js +36 -0
- package/dist/runtime/builtins/image/contactSheet.d.ts +3 -165
- package/dist/runtime/builtins/image/contactSheet.js +0 -49
- package/dist/runtime/builtins/image/definitions.d.ts +950 -0
- package/dist/runtime/builtins/image/definitions.js +343 -0
- package/dist/runtime/builtins/image/file.d.ts +8 -0
- package/dist/runtime/builtins/image/file.js +37 -0
- package/dist/runtime/builtins/image/filters.d.ts +8 -0
- package/dist/runtime/builtins/image/filters.js +394 -0
- package/dist/runtime/builtins/image/generators.d.ts +7 -0
- package/dist/runtime/builtins/image/generators.js +144 -0
- package/dist/runtime/builtins/image/index.d.ts +947 -4
- package/dist/runtime/builtins/image/index.js +41 -6
- package/dist/runtime/builtins/image/io.d.ts +100 -0
- package/dist/runtime/builtins/image/io.js +142 -0
- package/dist/runtime/builtins/image/planar.d.ts +55 -0
- package/dist/runtime/builtins/image/planar.js +274 -0
- package/dist/runtime/builtins/image/simplex.d.ts +22 -0
- package/dist/runtime/builtins/image/simplex.js +92 -0
- package/dist/runtime/builtins/image/text.d.ts +4 -0
- package/dist/runtime/builtins/image/text.js +141 -0
- package/dist/runtime/builtins/index.d.ts +3 -0
- package/dist/runtime/builtins/index.js +7 -0
- package/dist/runtime/definition/architecture.js +89 -0
- package/dist/runtime/gpu.d.ts +25 -0
- package/dist/runtime/gpu.js +40 -0
- package/dist/runtime/runtime.d.ts +2 -0
- package/dist/runtime/runtime.js +268 -44
- package/dist/runtime/types.d.ts +30 -0
- package/doc/CLI_REFERENCE.md +21 -3
- package/doc/EDITOR_EXPORT.md +26 -0
- package/doc/MCP.md +2 -1
- package/doc/NODE_REFERENCE.md +286 -14
- package/doc/PROJECT_AUTHORING.md +158 -4
- package/doc/WEB_PLAYER.md +9 -1
- package/package.json +4 -1
- package/dist/assets/CodePanel-BU-autmq.js +0 -2
- package/dist/assets/CustomNodeDialog-BRpDfOV5.js +0 -1
- package/dist/assets/OpenGraphDialog-BwbRlC0X.js +0 -1
- package/dist/assets/ProjectSettings-DLOXLxcA.js +0 -2
- package/dist/assets/definitions-GreEMXLV.js +0 -1
- package/dist/assets/geo-u0n_jOsD.js +0 -1
- package/dist/assets/image-cAa-Nu9O.js +0 -2062
- package/dist/assets/index-5ZtDAuy2.js +0 -220
- package/dist/assets/index-7vae6YFC.css +0 -1
- package/dist/assets/math-DioIQOPJ.js +0 -1
- package/dist/assets/pop-DC_TQG9t.js +0 -1
- package/dist/cli/chunk-36P5K3SD.js +0 -631
- package/dist/cli/chunk-4UDFYF5G.js +0 -132
- package/dist/cli/chunk-53NMBJAO.js +0 -35
- package/dist/cli/chunk-MIIEFUGG.js +0 -623
- package/dist/cli/chunk-QBBKRNGY.js +0 -90
- package/dist/cli/chunk-WPUDGEFY.js +0 -20
- package/dist/cli/editorCommands-UIF5YLUZ.js +0 -33
- package/dist/cli/project-K3QIPGBB.js +0 -12
- package/dist/cli/registerStandardNodes-S2VLMF6J.js +0 -3081
- package/dist/cli/runner-RA6UKEPD.js +0 -37
- package/dist/cli/webBuild-GT4PZT5D.js +0 -37
- package/dist/runtime/builtins/headless.d.ts +0 -19
- package/dist/runtime/builtins/headless.js +0 -25
package/doc/NODE_REFERENCE.md
CHANGED
|
@@ -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
|
|
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.
|
|
1014
|
-
|
|
1015
|
-
|
|
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
|
package/doc/PROJECT_AUTHORING.md
CHANGED
|
@@ -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.
|
|
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};
|