@field/cascade 0.2.22

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 (319) hide show
  1. package/AGENTS.md +168 -0
  2. package/ARCHITECTURE.md +137 -0
  3. package/DESIGN.md +161 -0
  4. package/LICENSE +21 -0
  5. package/README.md +229 -0
  6. package/dist/assets/CodeEditor-DR7u0q7p.css +1 -0
  7. package/dist/assets/CodeEditor-DoaNEUaM.js +641 -0
  8. package/dist/assets/CodePanel-B0_2XJ-t.js +2 -0
  9. package/dist/assets/CodePanel-IT1secyI.css +1 -0
  10. package/dist/assets/CustomNodeDialog-026lzecD.js +1 -0
  11. package/dist/assets/CustomNodeDialog-JGYnWY6m.css +1 -0
  12. package/dist/assets/ExportDialog-DOq0flMV.css +1 -0
  13. package/dist/assets/ExportDialog-DWN4nhXI.js +358 -0
  14. package/dist/assets/ProjectSettings-BzT164Yx.js +2 -0
  15. package/dist/assets/ProjectSettings-DdO9xoQz.css +1 -0
  16. package/dist/assets/SettingsDialog-CeK7ytpY.css +1 -0
  17. package/dist/assets/SettingsDialog-DmHb1V0r.js +1 -0
  18. package/dist/assets/VersionHistoryDialog-CWNmHQ-P.css +1 -0
  19. package/dist/assets/VersionHistoryDialog-hH6VsXLX.js +3 -0
  20. package/dist/assets/abap-08VXUWAP.js +1 -0
  21. package/dist/assets/apex-BWPQTe0t.js +1 -0
  22. package/dist/assets/azcli-Bc_sGQ0U.js +1 -0
  23. package/dist/assets/bat-i0X4ZdIN.js +1 -0
  24. package/dist/assets/bicep-B5-_aFwp.js +2 -0
  25. package/dist/assets/cameligo-DMUM7wLl.js +1 -0
  26. package/dist/assets/cascade.jpg +0 -0
  27. package/dist/assets/clojure-Cm7r79vr.js +1 -0
  28. package/dist/assets/codicon-Brq4_Ui5.ttf +0 -0
  29. package/dist/assets/coffee-Ba7i2nA0.js +1 -0
  30. package/dist/assets/core-Bji4aZUU.js +965 -0
  31. package/dist/assets/cpp-C7h46wYY.js +1 -0
  32. package/dist/assets/csharp-BKxtCVv1.js +1 -0
  33. package/dist/assets/csp-bTuwJoIa.js +1 -0
  34. package/dist/assets/css-DIMkf-bt.js +3 -0
  35. package/dist/assets/css.worker-B3ciXF_0.js +93 -0
  36. package/dist/assets/cssMode-B6Z_Q1Kh.js +1 -0
  37. package/dist/assets/cypher-CVaqCwHa.js +1 -0
  38. package/dist/assets/dart-onAF5SnQ.js +1 -0
  39. package/dist/assets/dockerfile-DZFCIeNp.js +1 -0
  40. package/dist/assets/ecl-D05T4iGw.js +1 -0
  41. package/dist/assets/editor-1FQrmyyI.css +1 -0
  42. package/dist/assets/editor.api-jMoW_43X.js +847 -0
  43. package/dist/assets/editor.worker-q-txB4vs.js +30 -0
  44. package/dist/assets/elixir-6RTg0lbw.js +1 -0
  45. package/dist/assets/flow9-C5_-GSwl.js +1 -0
  46. package/dist/assets/freemarker2-DvvPV6m5.js +3 -0
  47. package/dist/assets/fsharp-C8Ef5oNN.js +1 -0
  48. package/dist/assets/geo-CXmCtzMM.js +2 -0
  49. package/dist/assets/go-C-y9NEjX.js +1 -0
  50. package/dist/assets/graphql-fmXr3nnJ.js +1 -0
  51. package/dist/assets/handlebars-B8rfuSIa.js +1 -0
  52. package/dist/assets/hcl-CpzslTdj.js +1 -0
  53. package/dist/assets/html-DyHm6JCp.js +1 -0
  54. package/dist/assets/html.worker-C93Ht9o9.js +506 -0
  55. package/dist/assets/htmlMode-E9XLWE5u.js +1 -0
  56. package/dist/assets/image-BUcQC7PG.js +2076 -0
  57. package/dist/assets/index-BXYXSdgh.js +224 -0
  58. package/dist/assets/index-CrNke7SW.css +1 -0
  59. package/dist/assets/index-client-DN_FvjN8.js +1 -0
  60. package/dist/assets/ini-sBoK_t0W.js +1 -0
  61. package/dist/assets/java-BEtHBSE6.js +1 -0
  62. package/dist/assets/javascript-C_bM5PCN.js +1 -0
  63. package/dist/assets/json.worker-B2V3pomh.js +62 -0
  64. package/dist/assets/jsonMode-BdyVS7G4.js +7 -0
  65. package/dist/assets/julia-Bri6UV-V.js +1 -0
  66. package/dist/assets/kotlin-BOotOW0E.js +1 -0
  67. package/dist/assets/legacy-DIu3XRwl.js +2 -0
  68. package/dist/assets/less-B9JPFI3C.js +2 -0
  69. package/dist/assets/lexon-CfSJPG6W.js +1 -0
  70. package/dist/assets/liquid-CDkn3spA.js +1 -0
  71. package/dist/assets/lspLanguageFeatures-AB5DMAsr.js +4 -0
  72. package/dist/assets/lua-CsQS60Ue.js +1 -0
  73. package/dist/assets/m3-D-oSqn_W.js +1 -0
  74. package/dist/assets/markdown-Cimd5fb3.js +1 -0
  75. package/dist/assets/mdx-BvH_NjDN.js +1 -0
  76. package/dist/assets/mips-CIPQ_RoX.js +1 -0
  77. package/dist/assets/msdax-DauUninz.js +1 -0
  78. package/dist/assets/mysql-SOo6toE5.js +1 -0
  79. package/dist/assets/nodeTypeUtils-CweA3NHd.js +1 -0
  80. package/dist/assets/objective-c-FvmIjYaQ.js +1 -0
  81. package/dist/assets/pascal-DrH0SRf2.js +1 -0
  82. package/dist/assets/pascaligo-D-ptJ9y-.js +1 -0
  83. package/dist/assets/perl-oz_6vUea.js +1 -0
  84. package/dist/assets/pgsql-DTj74zXo.js +1 -0
  85. package/dist/assets/php-nr791fC2.js +1 -0
  86. package/dist/assets/pla-CopQ2nXW.js +1 -0
  87. package/dist/assets/postiats-43DmfD33.js +1 -0
  88. package/dist/assets/powerquery-D3hlyOfw.js +1 -0
  89. package/dist/assets/powershell-DmHpPYUd.js +1 -0
  90. package/dist/assets/projectSettingsApi-C1WvIwfP.js +1 -0
  91. package/dist/assets/protobuf-C531GsRP.js +2 -0
  92. package/dist/assets/pug-Z5eAx3Zn.js +1 -0
  93. package/dist/assets/python-B7uii4fi.js +1 -0
  94. package/dist/assets/qsharp-DkqhCAOL.js +1 -0
  95. package/dist/assets/quill-DjZ69wL_.js +121 -0
  96. package/dist/assets/r-BwWrilGY.js +1 -0
  97. package/dist/assets/razor-Z48fWdJc.js +1 -0
  98. package/dist/assets/redis-ClamHrr6.js +1 -0
  99. package/dist/assets/redshift-DT7zqm-g.js +1 -0
  100. package/dist/assets/restructuredtext-BYgofb2h.js +1 -0
  101. package/dist/assets/ruby-DezsRK8O.js +1 -0
  102. package/dist/assets/rust-DdL9SqIa.js +1 -0
  103. package/dist/assets/sb-CcwsVR0C.js +1 -0
  104. package/dist/assets/scala-DHpiXF5c.js +1 -0
  105. package/dist/assets/scheme-BeGwcela.js +1 -0
  106. package/dist/assets/scss-gp-XZpBa.js +3 -0
  107. package/dist/assets/shell-CC2rA5mh.js +1 -0
  108. package/dist/assets/solidity-BEEn4gHE.js +1 -0
  109. package/dist/assets/sophia-CRfGWb83.js +1 -0
  110. package/dist/assets/sparql-D_Lu-MrJ.js +1 -0
  111. package/dist/assets/sql-NEE52Syq.js +1 -0
  112. package/dist/assets/st-DbInun42.js +1 -0
  113. package/dist/assets/swift-Bxkupp3x.js +1 -0
  114. package/dist/assets/systemverilog-Bz4Y3fRF.js +1 -0
  115. package/dist/assets/tcl-DISqw1ZD.js +1 -0
  116. package/dist/assets/ts.worker-D7T1-Ig5.js +67738 -0
  117. package/dist/assets/tsMode-BDgacVG4.js +11 -0
  118. package/dist/assets/twig-De2hgUGE.js +1 -0
  119. package/dist/assets/typescript-Derb6Oqa.js +1 -0
  120. package/dist/assets/typespec-B8J7ngcE.js +1 -0
  121. package/dist/assets/vb-DV3o63ZY.js +1 -0
  122. package/dist/assets/wgsl-DpFanUEy.js +298 -0
  123. package/dist/assets/workers-BtoMX_pm.js +1 -0
  124. package/dist/assets/xml-B1CaFSrG.js +1 -0
  125. package/dist/assets/yaml-HmIeA0KH.js +1 -0
  126. package/dist/cli/index.js +11377 -0
  127. package/dist/cli/index.js.map +7 -0
  128. package/dist/cli/runtime/io.ts +445 -0
  129. package/dist/cli/runtime/net.ts +19 -0
  130. package/dist/cli/runtime/shell.ts +46 -0
  131. package/dist/cli/runtime/stage.ts +132 -0
  132. package/dist/contracts/capabilities.d.ts +109 -0
  133. package/dist/contracts/capabilities.d.ts.map +1 -0
  134. package/dist/contracts/capabilities.js +11 -0
  135. package/dist/contracts/capabilities.js.map +1 -0
  136. package/dist/contracts/color.d.ts +67 -0
  137. package/dist/contracts/color.d.ts.map +1 -0
  138. package/dist/contracts/color.js +83 -0
  139. package/dist/contracts/color.js.map +1 -0
  140. package/dist/contracts/definition.d.ts +118 -0
  141. package/dist/contracts/definition.d.ts.map +1 -0
  142. package/dist/contracts/definition.js +2 -0
  143. package/dist/contracts/definition.js.map +1 -0
  144. package/dist/contracts/document.d.ts +50 -0
  145. package/dist/contracts/document.d.ts.map +1 -0
  146. package/dist/contracts/document.js +2 -0
  147. package/dist/contracts/document.js.map +1 -0
  148. package/dist/contracts/geometry.d.ts +301 -0
  149. package/dist/contracts/geometry.d.ts.map +1 -0
  150. package/dist/contracts/geometry.js +604 -0
  151. package/dist/contracts/geometry.js.map +1 -0
  152. package/dist/contracts/index.d.ts +8 -0
  153. package/dist/contracts/index.d.ts.map +1 -0
  154. package/dist/contracts/index.js +8 -0
  155. package/dist/contracts/index.js.map +1 -0
  156. package/dist/contracts/schema.d.ts +6 -0
  157. package/dist/contracts/schema.d.ts.map +1 -0
  158. package/dist/contracts/schema.js +85 -0
  159. package/dist/contracts/schema.js.map +1 -0
  160. package/dist/contracts/validate.d.ts +13 -0
  161. package/dist/contracts/validate.d.ts.map +1 -0
  162. package/dist/contracts/validate.js +202 -0
  163. package/dist/contracts/validate.js.map +1 -0
  164. package/dist/contracts/values.d.ts +100 -0
  165. package/dist/contracts/values.d.ts.map +1 -0
  166. package/dist/contracts/values.js +59 -0
  167. package/dist/contracts/values.js.map +1 -0
  168. package/dist/graphs/default-orig.cascade +128 -0
  169. package/dist/graphs/default.cascade +21 -0
  170. package/dist/index.html +19 -0
  171. package/dist/runtime/browser.d.ts +3 -0
  172. package/dist/runtime/browser.d.ts.map +1 -0
  173. package/dist/runtime/browser.js +12 -0
  174. package/dist/runtime/browser.js.map +1 -0
  175. package/dist/runtime/builtins/core/index.d.ts +9 -0
  176. package/dist/runtime/builtins/core/index.d.ts.map +1 -0
  177. package/dist/runtime/builtins/core/index.js +21 -0
  178. package/dist/runtime/builtins/core/index.js.map +1 -0
  179. package/dist/runtime/builtins/core/random.d.ts +66 -0
  180. package/dist/runtime/builtins/core/random.d.ts.map +1 -0
  181. package/dist/runtime/builtins/core/random.js +46 -0
  182. package/dist/runtime/builtins/core/random.js.map +1 -0
  183. package/dist/runtime/builtins/core/remap.d.ts +105 -0
  184. package/dist/runtime/builtins/core/remap.d.ts.map +1 -0
  185. package/dist/runtime/builtins/core/remap.js +43 -0
  186. package/dist/runtime/builtins/core/remap.js.map +1 -0
  187. package/dist/runtime/builtins/core/routing.d.ts +117 -0
  188. package/dist/runtime/builtins/core/routing.d.ts.map +1 -0
  189. package/dist/runtime/builtins/core/routing.js +114 -0
  190. package/dist/runtime/builtins/core/routing.js.map +1 -0
  191. package/dist/runtime/builtins/core/structural.d.ts +86 -0
  192. package/dist/runtime/builtins/core/structural.d.ts.map +1 -0
  193. package/dist/runtime/builtins/core/structural.js +63 -0
  194. package/dist/runtime/builtins/core/structural.js.map +1 -0
  195. package/dist/runtime/builtins/geo/copyToPoints.d.ts +58 -0
  196. package/dist/runtime/builtins/geo/copyToPoints.d.ts.map +1 -0
  197. package/dist/runtime/builtins/geo/copyToPoints.js +35 -0
  198. package/dist/runtime/builtins/geo/copyToPoints.js.map +1 -0
  199. package/dist/runtime/builtins/geo/definitions.d.ts +526 -0
  200. package/dist/runtime/builtins/geo/definitions.d.ts.map +1 -0
  201. package/dist/runtime/builtins/geo/definitions.js +182 -0
  202. package/dist/runtime/builtins/geo/definitions.js.map +1 -0
  203. package/dist/runtime/builtins/geo/generators.d.ts +94 -0
  204. package/dist/runtime/builtins/geo/generators.d.ts.map +1 -0
  205. package/dist/runtime/builtins/geo/generators.js +41 -0
  206. package/dist/runtime/builtins/geo/generators.js.map +1 -0
  207. package/dist/runtime/builtins/geo/index.d.ts +23 -0
  208. package/dist/runtime/builtins/geo/index.d.ts.map +1 -0
  209. package/dist/runtime/builtins/geo/index.js +35 -0
  210. package/dist/runtime/builtins/geo/index.js.map +1 -0
  211. package/dist/runtime/builtins/geo/merge.d.ts +40 -0
  212. package/dist/runtime/builtins/geo/merge.d.ts.map +1 -0
  213. package/dist/runtime/builtins/geo/merge.js +24 -0
  214. package/dist/runtime/builtins/geo/merge.js.map +1 -0
  215. package/dist/runtime/builtins/geo/namespace.d.ts +15 -0
  216. package/dist/runtime/builtins/geo/namespace.d.ts.map +1 -0
  217. package/dist/runtime/builtins/geo/namespace.js +17 -0
  218. package/dist/runtime/builtins/geo/namespace.js.map +1 -0
  219. package/dist/runtime/builtins/geo/svgExport.d.ts +130 -0
  220. package/dist/runtime/builtins/geo/svgExport.d.ts.map +1 -0
  221. package/dist/runtime/builtins/geo/svgExport.js +50 -0
  222. package/dist/runtime/builtins/geo/svgExport.js.map +1 -0
  223. package/dist/runtime/builtins/geo/transform.d.ts +60 -0
  224. package/dist/runtime/builtins/geo/transform.d.ts.map +1 -0
  225. package/dist/runtime/builtins/geo/transform.js +32 -0
  226. package/dist/runtime/builtins/geo/transform.js.map +1 -0
  227. package/dist/runtime/builtins/index.d.ts +9 -0
  228. package/dist/runtime/builtins/index.d.ts.map +1 -0
  229. package/dist/runtime/builtins/index.js +16 -0
  230. package/dist/runtime/builtins/index.js.map +1 -0
  231. package/dist/runtime/definition/architecture.d.ts +8 -0
  232. package/dist/runtime/definition/architecture.d.ts.map +1 -0
  233. package/dist/runtime/definition/architecture.js +112 -0
  234. package/dist/runtime/definition/architecture.js.map +1 -0
  235. package/dist/runtime/definition/extract.d.ts +12 -0
  236. package/dist/runtime/definition/extract.d.ts.map +1 -0
  237. package/dist/runtime/definition/extract.js +151 -0
  238. package/dist/runtime/definition/extract.js.map +1 -0
  239. package/dist/runtime/error.d.ts +8 -0
  240. package/dist/runtime/error.d.ts.map +1 -0
  241. package/dist/runtime/error.js +11 -0
  242. package/dist/runtime/error.js.map +1 -0
  243. package/dist/runtime/geometry/attributes.d.ts +65 -0
  244. package/dist/runtime/geometry/attributes.d.ts.map +1 -0
  245. package/dist/runtime/geometry/attributes.js +201 -0
  246. package/dist/runtime/geometry/attributes.js.map +1 -0
  247. package/dist/runtime/geometry/builder.d.ts +57 -0
  248. package/dist/runtime/geometry/builder.d.ts.map +1 -0
  249. package/dist/runtime/geometry/builder.js +153 -0
  250. package/dist/runtime/geometry/builder.js.map +1 -0
  251. package/dist/runtime/geometry/copy.d.ts +36 -0
  252. package/dist/runtime/geometry/copy.d.ts.map +1 -0
  253. package/dist/runtime/geometry/copy.js +68 -0
  254. package/dist/runtime/geometry/copy.js.map +1 -0
  255. package/dist/runtime/geometry/generate.d.ts +43 -0
  256. package/dist/runtime/geometry/generate.d.ts.map +1 -0
  257. package/dist/runtime/geometry/generate.js +76 -0
  258. package/dist/runtime/geometry/generate.js.map +1 -0
  259. package/dist/runtime/geometry/groups.d.ts +18 -0
  260. package/dist/runtime/geometry/groups.d.ts.map +1 -0
  261. package/dist/runtime/geometry/groups.js +69 -0
  262. package/dist/runtime/geometry/groups.js.map +1 -0
  263. package/dist/runtime/geometry/index.d.ts +23 -0
  264. package/dist/runtime/geometry/index.d.ts.map +1 -0
  265. package/dist/runtime/geometry/index.js +23 -0
  266. package/dist/runtime/geometry/index.js.map +1 -0
  267. package/dist/runtime/geometry/matrix.d.ts +26 -0
  268. package/dist/runtime/geometry/matrix.d.ts.map +1 -0
  269. package/dist/runtime/geometry/matrix.js +27 -0
  270. package/dist/runtime/geometry/matrix.js.map +1 -0
  271. package/dist/runtime/geometry/merge.d.ts +33 -0
  272. package/dist/runtime/geometry/merge.d.ts.map +1 -0
  273. package/dist/runtime/geometry/merge.js +185 -0
  274. package/dist/runtime/geometry/merge.js.map +1 -0
  275. package/dist/runtime/geometry/primitives.d.ts +41 -0
  276. package/dist/runtime/geometry/primitives.d.ts.map +1 -0
  277. package/dist/runtime/geometry/primitives.js +131 -0
  278. package/dist/runtime/geometry/primitives.js.map +1 -0
  279. package/dist/runtime/geometry/promote.d.ts +44 -0
  280. package/dist/runtime/geometry/promote.d.ts.map +1 -0
  281. package/dist/runtime/geometry/promote.js +203 -0
  282. package/dist/runtime/geometry/promote.js.map +1 -0
  283. package/dist/runtime/geometry/resample.d.ts +29 -0
  284. package/dist/runtime/geometry/resample.d.ts.map +1 -0
  285. package/dist/runtime/geometry/resample.js +165 -0
  286. package/dist/runtime/geometry/resample.js.map +1 -0
  287. package/dist/runtime/geometry/svg.d.ts +91 -0
  288. package/dist/runtime/geometry/svg.d.ts.map +1 -0
  289. package/dist/runtime/geometry/svg.js +216 -0
  290. package/dist/runtime/geometry/svg.js.map +1 -0
  291. package/dist/runtime/geometry/transform.d.ts +18 -0
  292. package/dist/runtime/geometry/transform.d.ts.map +1 -0
  293. package/dist/runtime/geometry/transform.js +56 -0
  294. package/dist/runtime/geometry/transform.js.map +1 -0
  295. package/dist/runtime/index.d.ts +5 -0
  296. package/dist/runtime/index.d.ts.map +1 -0
  297. package/dist/runtime/index.js +4 -0
  298. package/dist/runtime/index.js.map +1 -0
  299. package/dist/runtime/node.d.ts +4 -0
  300. package/dist/runtime/node.d.ts.map +1 -0
  301. package/dist/runtime/node.js +12 -0
  302. package/dist/runtime/node.js.map +1 -0
  303. package/dist/runtime/runtime.d.ts +3 -0
  304. package/dist/runtime/runtime.d.ts.map +1 -0
  305. package/dist/runtime/runtime.js +1198 -0
  306. package/dist/runtime/runtime.js.map +1 -0
  307. package/dist/runtime/types.d.ts +241 -0
  308. package/dist/runtime/types.d.ts.map +1 -0
  309. package/dist/runtime/types.js +2 -0
  310. package/dist/runtime/types.js.map +1 -0
  311. package/dist/shell.d.ts +8 -0
  312. package/dist/shell.js +54 -0
  313. package/dist/shell.js.map +7 -0
  314. package/dist/stage.d.ts +7 -0
  315. package/dist/stage.js +84 -0
  316. package/dist/stage.js.map +7 -0
  317. package/dist/studio/panel.d.ts +48 -0
  318. package/doc/PROJECT_AUTHORING.md +360 -0
  319. package/package.json +126 -0
@@ -0,0 +1,965 @@
1
+ import{c as e,o as t}from"./nodeTypeUtils-CweA3NHd.js";import{C as n,S as r,b as i,h as a,v as o,w as s,y as c}from"./index-BXYXSdgh.js";var l={type:`Switch`,name:`Switch`,icon:`GitBranch`,description:`Switch between multiple inputs by index`,category:`routing`},u=class extends r{constructor(e,t){super(e,`Switch`,t)}get activeInputIndex(){let e=this.getVariadicInputs();return Math.min(this.props.index?.value??0,e.length-1)}isInputActive(e){let t=this.getVariadicInputs(),n=this.activeInputIndex;return t.findIndex(t=>t.id===e)===n}setup(){this.setVariadic(),this.output=this.out(`output`),this.addParm(`index`,{value:0,type:`int`,params:{min:0,max:0,step:1},displayName:`Index`}),this.watchProp(`index`,()=>this.update()),this.onUpdate=()=>this.update(),this.onReady=()=>this.update()}update(){let e=this.getVariadicInputs(),t=e.filter(e=>e.connections.length>0).length;this.updatePropParams(`index`,{max:Math.max(0,t-1)});let n=e[Math.min(this.props.index.value,e.length-1)];n?(this.output.setValue(n.value),this.preview=this.isPreviewValue(n.value)?n.value:null):(this.output.setValue(null),this.preview=null)}},d={type:`Merge`,name:`Merge`,icon:`GitMerge`,description:`Combine multiple inputs into an array`,category:`routing`},f=class extends r{constructor(e,t){super(e,`Merge`,t)}setup(){this.setVariadic(),this.output=this.out(`output`),this.addParm(`append`,{value:!1,type:`boolean`,displayName:`Append Mode`,hidden:()=>{let e=this.getVariadicInputs();return!Array.isArray(e[0]?.value)}}),this.watchProp(`append`,()=>this.update()),this.onUpdate=()=>this.update(),this.onReady=()=>this.update()}update(){let e=this.getVariadicInputs().filter(e=>e.value!==null).map(e=>e.value);if(this.props.append.value&&e.length>0&&Array.isArray(e[0])){let t=[...e[0],...e.slice(1)];this.output.setValue(t)}else this.output.setValue(e);this.preview=null;for(let t of e)if(t instanceof HTMLCanvasElement||t instanceof HTMLImageElement){this.preview=t;break}}},p={type:`Subnet`,name:`Subnet`,icon:`Folder`,description:`Network container for organizing nodes`,category:`network`},m=class extends r{constructor(e,t){super(e,`Subnet`,t)}setup(){this.onUpdate=()=>this.update(),this.onReady=()=>{this.syncPorts(),this.update()}}isNetwork(){return!0}addChild(e){e.parent=this,this._children.push(e),(e.type===`Input`||e.type===`Output`)&&this.syncPorts()}removeChild(e){let t=this._children.indexOf(e);if(t!==-1){let n=e.type===`Input`||e.type===`Output`;this._children.splice(t,1),e.parent=null,n&&this.syncPorts()}}syncPorts(){let e=this._children.filter(e=>e.type===`Input`),t=e.reduce((e,t)=>{let n=t.inputIndex??0;return Math.max(e,n)},-1),n=this._children.filter(e=>e.type===`Output`),r=n.reduce((e,t)=>{let n=t.outputIndex??0;return Math.max(e,n)},-1),i=t+1,a=this.inputs.length;for(let t=a;t<i;t++){let n=e.find(e=>e.inputIndex===t),r=this.in(n?.inputName||`input_${t}`,null,{type:n?.dataType||`any`});r.onChange=e=>{this._children.filter(e=>e.type===`Input`&&e.inputIndex===t).forEach(e=>e.markDirty())}}for(let e=i;e<a;e++)this.inputs[e]&&(this.inputs[e].options={...this.inputs[e].options,hidden:!0});for(let t=0;t<i;t++)if(this.inputs[t]){let n=e.find(e=>e.inputIndex===t);this.inputs[t].name=n?.inputName||`input_${t}`,this.inputs[t].dataType=n?.dataType||`any`,this.inputs[t].options={...this.inputs[t].options,hidden:!1}}let o=r+1,s=this.outputs.length;for(let e=s;e<o;e++){let t=n.find(t=>t.outputIndex===e);this.out(t?.outputName||`output_${e}`,`param`,{type:t?.dataType||`any`})}for(let e=o;e<s;e++)this.outputs[e]&&(this.outputs[e].options={...this.outputs[e].options,hidden:!0});for(let e=0;e<o;e++)if(this.outputs[e]){let t=n.find(t=>t.outputIndex===e);this.outputs[e].name=t?.outputName||`output_${e}`,this.outputs[e].dataType=t?.dataType||`any`,this.outputs[e].options={...this.outputs[e].options,hidden:!1}}this.inputs=[...this.inputs],this.outputs=[...this.outputs]}outputNode(){return this._children.find(e=>e.type===`Output`)||this._children.find(e=>e.cook)||(this._children.length>0?this._children[this._children.length-1]:null)}displayNode(){return this._children.find(e=>e.cook)??null}indirectInputs(){return this._children.filter(e=>e.type===`Input`)}update(){let e=this._children.filter(e=>e.type===`Output`),t=new Map;for(let n of e){let e=n.outputIndex??0;t.set(e,n)}for(let e=0;e<this.outputs.length;e++){let n=t.get(e);if(n&&n.inputs.length>0){let t=n.inputs[0].value;this.outputs[e].setValue(t),e===0&&(t instanceof HTMLCanvasElement||t instanceof HTMLImageElement)&&(this.preview=t)}else if(e===0){let t=this._children.find(e=>e.cook);t&&t.outputs.length>0?(this.outputs[e].setValue(t.outputs[0].value),t.preview&&(this.preview=t.preview)):this.outputs[e].setValue(null)}else this.outputs[e].setValue(null)}(this.outputs.length===0||!t.has(0))&&(this._children.find(e=>e.cook)?.preview||(this.preview=null))}},h=c.map(e=>({value:e,label:e})),g={type:`Input`,name:`Input`,icon:`LogIn`,description:`Represents an external input to a subnet`,category:`network`},_=class extends r{constructor(e,t){super(e,`Input`,t)}setup(){this.output=this.out(`output`),this.addParm(`inputIndex`,{value:0,type:`int`,params:{min:0,step:1},displayName:`Input Index`}),this.addParm(`inputName`,{value:``,type:`text`,displayName:`Input Name`}),this.addParm(`dataType`,{value:`any`,type:`select`,params:{options:h},displayName:`Data Type`});let e=()=>{this.parent&&this.parent.syncPorts&&this.parent.syncPorts(),this.update()};this.watchProp(`inputIndex`,e),this.watchProp(`inputName`,e),this.watchProp(`dataType`,()=>{this.output.dataType=this.dataType,e()}),this.onUpdate=()=>this.update(),this.onReady=()=>this.update()}get inputIndex(){return this.props.inputIndex?.value??0}get inputName(){return this.props.inputName?.value??``}get dataType(){let e=this.props.dataType?.value;return typeof e==`string`&&i(e)?e:`any`}update(){if(this.parent&&this.parent.inputs.length>0){let e=this.inputIndex,t=this.parent.inputs[e];if(t){this.output.setValue(t.value),this.preview=this.isPreviewValue(t.value)?t.value:null;return}}this.output.setValue(null),this.preview=null}},v=c.map(e=>({value:e,label:e})),y={type:`Output`,name:`Output`,icon:`LogOut`,description:`Defines the output of a subnet`,category:`network`},b=class extends r{constructor(e,t){super(e,`Output`,t)}setup(){this.in(`input`,null),this.addParm(`outputIndex`,{value:0,type:`int`,params:{min:0,step:1},displayName:`Output Index`}),this.addParm(`outputName`,{value:``,type:`text`,displayName:`Output Name`}),this.addParm(`dataType`,{value:`any`,type:`select`,params:{options:v},displayName:`Data Type`});let e=()=>{this.parent&&this.parent.syncPorts&&this.parent.syncPorts(),this.update()};this.watchProp(`outputIndex`,e),this.watchProp(`outputName`,e),this.watchProp(`dataType`,()=>{this.inputs[0]&&(this.inputs[0].dataType=this.dataType),e()}),this.onUpdate=()=>this.update(),this.onReady=()=>this.update()}get outputIndex(){return this.props.outputIndex?.value??0}get outputName(){return this.props.outputName?.value??``}get dataType(){let e=this.props.dataType?.value;return typeof e==`string`&&i(e)?e:`any`}update(){let e=this.inputs[0];e&&(this.preview=this.isPreviewValue(e.value)?e.value:null)}};function x(e,t=0){let n=((Math.trunc(e)^Math.imul(Math.trunc(t),2654435761))>>>0)+1831565813>>>0;return n=Math.imul(n^n>>>15,n|1),n^=n+Math.imul(n^n>>>7,n|61),((n^n>>>14)>>>0)/4294967296}var S={type:`Random`,name:`Random`,icon:`Dice5`,description:`Generate a deterministic value from an explicit seed`,category:`utility`},C=class extends r{constructor(e,t){super(e,`Random`,t)}setup(){let e=this.in(`seed`,0,{type:`int`}),t=this.in(`sample`,0,{type:`int`}),n=this.out(`value`),r=()=>n.setValue(x(e.value,t.value));e.onChange=r,t.onChange=r,this.onUpdate=r,this.onReady=r}};function w(e,t,n,r,i,a){if(t===n)return r;let o=(e-t)/(n-t);return r+(a?Math.min(1,Math.max(0,o)):o)*(i-r)}var T={type:`Remap`,name:`Remap`,icon:`ArrowRightLeft`,description:`Map a number from one range into another`,category:`utility`},E=class extends r{constructor(e,t){super(e,`Remap`,t)}setup(){let e=this.in(`value`,0,{type:`float`}),t=this.in(`inMin`,0,{type:`float`}),n=this.in(`inMax`,1,{type:`float`}),r=this.in(`outMin`,0,{type:`float`}),i=this.in(`outMax`,1,{type:`float`}),a=this.out(`result`);this.addParm(`clamp`,{value:!1,type:`boolean`,displayName:`Clamp`});let o=()=>a.setValue(w(e.value,t.value,n.value,r.value,i.value,this.props.clamp.value));for(let a of[e,t,n,r,i])a.onChange=o;this.watchProp(`clamp`,o),this.onUpdate=o,this.onReady=o}},D={type:`Select`,name:`Select`,icon:`ListFilter`,description:`Pick an item from an array by index`,category:`utility`},O=class extends r{constructor(e,t){super(e,`Select`,t)}setup(){this.arrayInput=this.in(`array`,[],{type:`array`}),this.itemOutput=this.out(`item`,`param`),this.countOutput=this.out(`count`,`param`),this.addParm(`index`,{value:0,type:`int`,params:{min:0,max:0,step:1},displayName:`Index`}),this.addParm(`wrap`,{value:!0,type:`boolean`,displayName:`Wrap Index`}),this.watchProp(`index`,()=>this.update()),this.watchProp(`wrap`,()=>this.update()),this.onUpdate=()=>this.update(),this.onReady=()=>this.update()}update(){let e=this.arrayInput.value;if(!Array.isArray(e)||e.length===0){this.itemOutput.setValue(null),this.countOutput.setValue(0),this.updatePropParams(`index`,{max:0});return}this.updatePropParams(`index`,{max:e.length-1});let t=this.props.index?.value??0;t=(this.props.wrap?.value??!0)&&e.length>0?(t%e.length+e.length)%e.length:Math.max(0,Math.min(t,e.length-1));let n=e[t];this.itemOutput.setValue(n),this.countOutput.setValue(e.length),this.preview=n instanceof HTMLCanvasElement||n instanceof HTMLImageElement?n:null}},k={type:`Null`,name:`Null`,icon:`Circle`,description:`Pass its input through unchanged`,category:`routing`},A=class extends r{constructor(e,t){super(e,`Null`,t)}setup(){let e=this.in(`input`,null,{type:`any`}),t=this.out(`output`),n=()=>t.setValue(e.value);e.onChange=n,this.onUpdate=n,this.onReady=n}},j={type:`Freeze`,name:`Freeze`,icon:`Snowflake`,description:`Capture and lock a value`,category:`utility`},M=class extends r{constructor(e,t){super(e,`Freeze`,t),this.frozenValue=null,this.hasCaptured=!1}setup(){this.input=this.in(`input`,null,{type:`any`}),this.output=this.out(`output`,`param`),this.addParm(`frozen`,{value:!1,type:`boolean`,displayName:`Frozen`}),this.addAction(`capture`,{label:`Capture`,icon:`Camera`,callback:()=>this.capture()}),this.addAction(`clear`,{label:`Clear`,icon:`Trash2`,callback:()=>this.clear()}),this.watchProp(`frozen`,()=>this.update()),this.onUpdate=()=>this.update(),this.onReady=()=>this.update()}capture(){this.frozenValue=this.deepClone(this.input.value),this.hasCaptured=!0,this.setParm(`frozen`,!0),this.update()}clear(){this.frozenValue=null,this.hasCaptured=!1,this.setParm(`frozen`,!1),this.update()}deepClone(e){if(e==null)return e;if(e instanceof HTMLCanvasElement){let t=document.createElement(`canvas`);return t.width=e.width,t.height=e.height,t.getContext(`2d`)?.drawImage(e,0,0),t}if(e instanceof HTMLImageElement){let t=document.createElement(`canvas`);return t.width=e.naturalWidth||e.width,t.height=e.naturalHeight||e.height,t.getContext(`2d`)?.drawImage(e,0,0),t}if(Array.isArray(e))return e.map(e=>this.deepClone(e));if(typeof e==`object`)try{return JSON.parse(JSON.stringify(e))}catch{return e}return e}update(){(this.props.frozen?.value??!1)&&this.hasCaptured?(this.output.setValue(this.frozenValue),(this.frozenValue instanceof HTMLCanvasElement||this.frozenValue instanceof HTMLImageElement)&&(this.preview=this.frozenValue)):(this.output.setValue(this.input.value),this.preview=this.input.value instanceof HTMLCanvasElement||this.input.value instanceof HTMLImageElement?this.input.value:null)}serialize(){return{hasCaptured:this.hasCaptured}}deserialize(e){this.hasCaptured=e.hasCaptured===!0}},N=`/**
2
+ * SwitchNode - routes one of multiple inputs to output based on index
3
+ * Connect multiple inputs and use the index parameter to select which one passes through
4
+ */
5
+
6
+ import { Node } from '../../Node.js';
7
+ import type { Graph } from '../../Graph.js';
8
+ import type { OutputPort } from '@/types/node.types';
9
+
10
+ export const nodeMetadata = {
11
+ type: 'Switch',
12
+ name: 'Switch',
13
+ icon: 'GitBranch',
14
+ description: 'Switch between multiple inputs by index',
15
+ category: 'routing'
16
+ };
17
+
18
+ export class SwitchNode extends Node {
19
+ private output!: OutputPort<any>;
20
+
21
+ constructor(id: string, graph: Graph) {
22
+ super(id, 'Switch', graph);
23
+ }
24
+
25
+ /**
26
+ * Get the index of the currently active input
27
+ * Used by connection rendering to grey out inactive wires
28
+ */
29
+ get activeInputIndex(): number {
30
+ const inputs = this.getVariadicInputs();
31
+ return Math.min(this.props.index?.value ?? 0, inputs.length - 1);
32
+ }
33
+
34
+ /**
35
+ * Check if a specific input port is active (for connection coloring)
36
+ */
37
+ isInputActive(portId: string): boolean {
38
+ const inputs = this.getVariadicInputs();
39
+ const activeIdx = this.activeInputIndex;
40
+ const portIndex = inputs.findIndex(p => p.id === portId);
41
+ return portIndex === activeIdx;
42
+ }
43
+
44
+ protected setup(): void {
45
+ this.setVariadic();
46
+ this.output = this.out('output');
47
+
48
+ this.addParm('index', {
49
+ value: 0,
50
+ type: 'int',
51
+ params: { min: 0, max: 0, step: 1 },
52
+ displayName: 'Index'
53
+ });
54
+
55
+ this.watchProp('index', () => this.update());
56
+
57
+ this.onUpdate = () => this.update();
58
+ this.onReady = () => this.update();
59
+ }
60
+
61
+ private update(): void {
62
+ const inputs = this.getVariadicInputs();
63
+
64
+ // Update index max based on connected inputs (triggers UI reactivity)
65
+ const connectedCount = inputs.filter(p => p.connections.length > 0).length;
66
+ this.updatePropParams('index', { max: Math.max(0, connectedCount - 1) });
67
+
68
+ const idx = Math.min(this.props.index.value, inputs.length - 1);
69
+ const selectedInput = inputs[idx];
70
+
71
+ if (selectedInput) {
72
+ this.output.setValue(selectedInput.value);
73
+
74
+ // Use input's preview if it's a canvas/image
75
+ if (this.isPreviewValue(selectedInput.value)) {
76
+ this.preview = selectedInput.value;
77
+ } else {
78
+ this.preview = null;
79
+ }
80
+ } else {
81
+ this.output.setValue(null);
82
+ this.preview = null;
83
+ }
84
+ }
85
+ }
86
+ `,P=`/**
87
+ * MergeNode - combines multiple inputs into an array
88
+ * Connect multiple inputs to create an array of values
89
+ */
90
+
91
+ import { Node } from '../../Node.js';
92
+ import type { Graph } from '../../Graph.js';
93
+ import type { OutputPort } from '@/types/node.types';
94
+
95
+ export const nodeMetadata = {
96
+ type: 'Merge',
97
+ name: 'Merge',
98
+ icon: 'GitMerge',
99
+ description: 'Combine multiple inputs into an array',
100
+ category: 'routing'
101
+ };
102
+
103
+ export class MergeNode extends Node {
104
+ private output!: OutputPort<any[]>;
105
+
106
+ constructor(id: string, graph: Graph) {
107
+ super(id, 'Merge', graph);
108
+ }
109
+
110
+ protected setup(): void {
111
+ this.setVariadic();
112
+ this.output = this.out('output');
113
+
114
+ // Append mode - when first input is an array, append others to it
115
+ this.addParm('append', {
116
+ value: false,
117
+ type: 'boolean',
118
+ displayName: 'Append Mode',
119
+ hidden: () => {
120
+ const inputs = this.getVariadicInputs();
121
+ return !Array.isArray(inputs[0]?.value);
122
+ }
123
+ });
124
+
125
+ this.watchProp('append', () => this.update());
126
+
127
+ this.onUpdate = () => this.update();
128
+ this.onReady = () => this.update();
129
+ }
130
+
131
+ private update(): void {
132
+ const inputs = this.getVariadicInputs();
133
+
134
+ // Collect non-null values
135
+ const values = inputs
136
+ .filter(p => p.value !== null)
137
+ .map(p => p.value);
138
+
139
+ // Handle append mode
140
+ const appendMode = this.props.append.value;
141
+ if (appendMode && values.length > 0 && Array.isArray(values[0])) {
142
+ // Append subsequent values to the first array
143
+ const result = [...values[0], ...values.slice(1)];
144
+ this.output.setValue(result);
145
+ } else {
146
+ this.output.setValue(values);
147
+ }
148
+
149
+ // Set preview to first visual element if available
150
+ this.preview = null;
151
+ for (const val of values) {
152
+ if (val instanceof HTMLCanvasElement || val instanceof HTMLImageElement) {
153
+ this.preview = val;
154
+ break;
155
+ }
156
+ }
157
+ }
158
+ }
159
+ `,F=`/**
160
+ * SubnetNode - Network container for organizing nodes hierarchically
161
+ * A subnet is a node that can contain child nodes, creating a nested graph
162
+ */
163
+
164
+ import { Node } from '../../Node.js';
165
+ import type { Graph } from '../../Graph.js';
166
+ import type { InputPort, OutputPort } from '@/types/node.types';
167
+
168
+ export const nodeMetadata = {
169
+ type: 'Subnet',
170
+ name: 'Subnet',
171
+ icon: 'Folder',
172
+ description: 'Network container for organizing nodes',
173
+ category: 'network'
174
+ };
175
+
176
+ export class SubnetNode extends Node {
177
+ constructor(id: string, graph: Graph) {
178
+ super(id, 'Subnet', graph);
179
+ }
180
+
181
+ protected setup(): void {
182
+ // Ports are dynamically created based on child Input/Output nodes
183
+ // Start with no ports - they'll be synced when children are added
184
+ this.onUpdate = () => this.update();
185
+ this.onReady = () => {
186
+ this.syncPorts();
187
+ this.update();
188
+ };
189
+ }
190
+
191
+ /**
192
+ * Override: Subnets are networks and can contain children
193
+ */
194
+ isNetwork(): boolean {
195
+ return true;
196
+ }
197
+
198
+ /**
199
+ * Add a child node to this subnet
200
+ */
201
+ addChild(node: Node): void {
202
+ node.parent = this;
203
+ this._children.push(node);
204
+ // Sync ports when Input/Output nodes are added
205
+ if (node.type === 'Input' || node.type === 'Output') {
206
+ this.syncPorts();
207
+ }
208
+ }
209
+
210
+ /**
211
+ * Remove a child node from this subnet
212
+ */
213
+ removeChild(node: Node): void {
214
+ const index = this._children.indexOf(node);
215
+ if (index !== -1) {
216
+ const wasInputOutput = node.type === 'Input' || node.type === 'Output';
217
+ this._children.splice(index, 1);
218
+ node.parent = null;
219
+ // Sync ports when Input/Output nodes are removed
220
+ if (wasInputOutput) {
221
+ this.syncPorts();
222
+ }
223
+ }
224
+ }
225
+
226
+ /**
227
+ * Sync input/output ports based on child Input/Output nodes
228
+ */
229
+ syncPorts(): void {
230
+ // Find all Input nodes and determine required input ports
231
+ const inputNodes = this._children.filter(n => n.type === 'Input');
232
+ const maxInputIndex = inputNodes.reduce((max, node) => {
233
+ const idx = (node as any).inputIndex ?? 0;
234
+ return Math.max(max, idx);
235
+ }, -1);
236
+
237
+ // Find all Output nodes and determine required output ports
238
+ const outputNodes = this._children.filter(n => n.type === 'Output');
239
+ const maxOutputIndex = outputNodes.reduce((max, node) => {
240
+ const idx = (node as any).outputIndex ?? 0;
241
+ return Math.max(max, idx);
242
+ }, -1);
243
+
244
+ // Sync input ports
245
+ const requiredInputs = maxInputIndex + 1;
246
+ const currentInputs = this.inputs.length;
247
+
248
+ // Add missing input ports
249
+ for (let i = currentInputs; i < requiredInputs; i++) {
250
+ const boundary = inputNodes.find(n => (n as any).inputIndex === i) as any;
251
+ const port = this.in(boundary?.inputName || \`input_\${i}\`, null, {
252
+ type: boundary?.dataType || 'any'
253
+ });
254
+ // When input value changes, update any Input nodes referencing this index
255
+ port.onChange = (value: any) => {
256
+ this._children
257
+ .filter(n => n.type === 'Input' && (n as any).inputIndex === i)
258
+ .forEach(n => n.markDirty());
259
+ };
260
+ }
261
+
262
+ // Hide excess input ports (don't remove to preserve connections)
263
+ for (let i = requiredInputs; i < currentInputs; i++) {
264
+ if (this.inputs[i]) {
265
+ this.inputs[i].options = { ...this.inputs[i].options, hidden: true };
266
+ }
267
+ }
268
+ // Unhide needed ports
269
+ for (let i = 0; i < requiredInputs; i++) {
270
+ if (this.inputs[i]) {
271
+ const boundary = inputNodes.find(n => (n as any).inputIndex === i) as any;
272
+ this.inputs[i].name = boundary?.inputName || \`input_\${i}\`;
273
+ this.inputs[i].dataType = boundary?.dataType || 'any';
274
+ this.inputs[i].options = { ...this.inputs[i].options, hidden: false };
275
+ }
276
+ }
277
+
278
+ // Sync output ports - only create if there are Output nodes
279
+ const requiredOutputs = maxOutputIndex + 1; // 0 if no Output nodes
280
+ const currentOutputs = this.outputs.length;
281
+
282
+ // Add missing output ports
283
+ for (let i = currentOutputs; i < requiredOutputs; i++) {
284
+ const boundary = outputNodes.find(n => (n as any).outputIndex === i) as any;
285
+ this.out(boundary?.outputName || \`output_\${i}\`, 'param', {
286
+ type: boundary?.dataType || 'any'
287
+ });
288
+ }
289
+
290
+ // Hide excess output ports
291
+ for (let i = requiredOutputs; i < currentOutputs; i++) {
292
+ if (this.outputs[i]) {
293
+ this.outputs[i].options = { ...this.outputs[i].options, hidden: true };
294
+ }
295
+ }
296
+ // Unhide needed ports
297
+ for (let i = 0; i < requiredOutputs; i++) {
298
+ if (this.outputs[i]) {
299
+ const boundary = outputNodes.find(n => (n as any).outputIndex === i) as any;
300
+ this.outputs[i].name = boundary?.outputName || \`output_\${i}\`;
301
+ this.outputs[i].dataType = boundary?.dataType || 'any';
302
+ this.outputs[i].options = { ...this.outputs[i].options, hidden: false };
303
+ }
304
+ }
305
+
306
+ // Trigger reactivity
307
+ this.inputs = [...this.inputs];
308
+ this.outputs = [...this.outputs];
309
+ }
310
+
311
+ /**
312
+ * Get the node that defines this subnet's output
313
+ * Priority: Output node > cooking node > last node
314
+ */
315
+ outputNode(): Node | null {
316
+ // 1. Check for explicit Output node
317
+ const outputNode = this._children.find(n => n.type === 'Output');
318
+ if (outputNode) return outputNode;
319
+
320
+ // 2. Use cooking node
321
+ const cookingNode = this._children.find(n => n.cook);
322
+ if (cookingNode) return cookingNode;
323
+
324
+ // 3. Fall back to last node
325
+ return this._children.length > 0 ? this._children[this._children.length - 1] : null;
326
+ }
327
+
328
+ /**
329
+ * Get the cooking (display) node in this subnet
330
+ */
331
+ displayNode(): Node | null {
332
+ return this._children.find(n => n.cook) ?? null;
333
+ }
334
+
335
+ /**
336
+ * Get all Input nodes inside this subnet
337
+ */
338
+ indirectInputs(): Node[] {
339
+ return this._children.filter(n => n.type === 'Input');
340
+ }
341
+
342
+ private update(): void {
343
+ // Update each output based on corresponding Output nodes
344
+ const outputNodes = this._children.filter(n => n.type === 'Output');
345
+
346
+ // Group output nodes by their outputIndex
347
+ const outputByIndex = new Map<number, Node>();
348
+ for (const node of outputNodes) {
349
+ const idx = (node as any).outputIndex ?? 0;
350
+ outputByIndex.set(idx, node);
351
+ }
352
+
353
+ // Update each output port
354
+ for (let i = 0; i < this.outputs.length; i++) {
355
+ const outNode = outputByIndex.get(i);
356
+ if (outNode && outNode.inputs.length > 0) {
357
+ const value = outNode.inputs[0].value;
358
+ this.outputs[i].setValue(value);
359
+
360
+ // Set preview from first output
361
+ if (i === 0 && (value instanceof HTMLCanvasElement || value instanceof HTMLImageElement)) {
362
+ this.preview = value;
363
+ }
364
+ } else if (i === 0) {
365
+ // Fallback for first output: use cooking node if no Output node
366
+ const cookingNode = this._children.find(n => n.cook);
367
+ if (cookingNode && cookingNode.outputs.length > 0) {
368
+ this.outputs[i].setValue(cookingNode.outputs[0].value);
369
+ if (cookingNode.preview) {
370
+ this.preview = cookingNode.preview;
371
+ }
372
+ } else {
373
+ this.outputs[i].setValue(null);
374
+ }
375
+ } else {
376
+ this.outputs[i].setValue(null);
377
+ }
378
+ }
379
+
380
+ // Clear preview if no outputs set it
381
+ if (this.outputs.length === 0 || !outputByIndex.has(0)) {
382
+ const cookingNode = this._children.find(n => n.cook);
383
+ if (!cookingNode?.preview) {
384
+ this.preview = null;
385
+ }
386
+ }
387
+ }
388
+ }
389
+ `,I=`/**
390
+ * InputNode - Represents an external input to a subnet
391
+ * Auto-created when wiring into a subnet, or manually for documentation
392
+ */
393
+
394
+ import { Node } from '../../Node.js';
395
+ import type { Graph } from '../../Graph.js';
396
+ import type { DataType, OutputPort } from '@/types/node.types';
397
+ import { CORE_TYPES, isCoreType } from '@/types/coreTypes';
398
+
399
+ const TYPE_CHOICES = CORE_TYPES.map(type => ({ value: type, label: type }));
400
+
401
+ export const nodeMetadata = {
402
+ type: 'Input',
403
+ name: 'Input',
404
+ icon: 'LogIn',
405
+ description: 'Represents an external input to a subnet',
406
+ category: 'network'
407
+ };
408
+
409
+ export class InputNode extends Node {
410
+ private output!: OutputPort<any>;
411
+
412
+ constructor(id: string, graph: Graph) {
413
+ super(id, 'Input', graph);
414
+ }
415
+
416
+ protected setup(): void {
417
+ // Output passes through the external input value
418
+ this.output = this.out('output');
419
+
420
+ // Input index - which external input this represents
421
+ this.addParm('inputIndex', {
422
+ value: 0,
423
+ type: 'int',
424
+ params: { min: 0, step: 1 },
425
+ displayName: 'Input Index'
426
+ });
427
+
428
+ // Optional name for documentation
429
+ this.addParm('inputName', {
430
+ value: '',
431
+ type: 'text',
432
+ displayName: 'Input Name'
433
+ });
434
+
435
+ this.addParm('dataType', {
436
+ value: 'any',
437
+ type: 'select',
438
+ params: { options: TYPE_CHOICES },
439
+ displayName: 'Data Type'
440
+ });
441
+
442
+ // Watch for index changes to trigger parent port sync
443
+ const syncParent = () => {
444
+ if (this.parent && (this.parent as any).syncPorts) {
445
+ (this.parent as any).syncPorts();
446
+ }
447
+ this.update();
448
+ };
449
+ this.watchProp('inputIndex', syncParent);
450
+ this.watchProp('inputName', syncParent);
451
+ this.watchProp('dataType', () => {
452
+ this.output.dataType = this.dataType;
453
+ syncParent();
454
+ });
455
+
456
+ this.onUpdate = () => this.update();
457
+ this.onReady = () => this.update();
458
+ }
459
+
460
+ /**
461
+ * Get the input index this node represents
462
+ */
463
+ get inputIndex(): number {
464
+ return this.props.inputIndex?.value ?? 0;
465
+ }
466
+
467
+ /**
468
+ * Get the input name (for documentation)
469
+ */
470
+ get inputName(): string {
471
+ return this.props.inputName?.value ?? '';
472
+ }
473
+
474
+ get dataType(): DataType {
475
+ const value = this.props.dataType?.value;
476
+ return typeof value === 'string' && isCoreType(value) ? value : 'any';
477
+ }
478
+
479
+ private update(): void {
480
+ // Get value from parent subnet's corresponding input
481
+ if (this.parent && this.parent.inputs.length > 0) {
482
+ const idx = this.inputIndex;
483
+ const parentInput = this.parent.inputs[idx];
484
+ if (parentInput) {
485
+ this.output.setValue(parentInput.value);
486
+
487
+ // Pass through preview
488
+ if (this.isPreviewValue(parentInput.value)) {
489
+ this.preview = parentInput.value;
490
+ } else {
491
+ this.preview = null;
492
+ }
493
+ return;
494
+ }
495
+ }
496
+
497
+ this.output.setValue(null);
498
+ this.preview = null;
499
+ }
500
+ }
501
+ `,L=`/**
502
+ * OutputNode - Explicitly defines a subnet's output
503
+ * Overrides the cooking node when present
504
+ */
505
+
506
+ import { Node } from '../../Node.js';
507
+ import type { Graph } from '../../Graph.js';
508
+ import type { DataType } from '@/types/node.types';
509
+ import { CORE_TYPES, isCoreType } from '@/types/coreTypes';
510
+
511
+ const TYPE_CHOICES = CORE_TYPES.map(type => ({ value: type, label: type }));
512
+
513
+ export const nodeMetadata = {
514
+ type: 'Output',
515
+ name: 'Output',
516
+ icon: 'LogOut',
517
+ description: 'Defines the output of a subnet',
518
+ category: 'network'
519
+ };
520
+
521
+ export class OutputNode extends Node {
522
+ constructor(id: string, graph: Graph) {
523
+ super(id, 'Output', graph);
524
+ }
525
+
526
+ protected setup(): void {
527
+ // Input receives the value to output from the subnet
528
+ this.in('input', null);
529
+
530
+ // Output index - for multiple outputs from a subnet
531
+ this.addParm('outputIndex', {
532
+ value: 0,
533
+ type: 'int',
534
+ params: { min: 0, step: 1 },
535
+ displayName: 'Output Index'
536
+ });
537
+
538
+ this.addParm('outputName', {
539
+ value: '',
540
+ type: 'text',
541
+ displayName: 'Output Name'
542
+ });
543
+
544
+ this.addParm('dataType', {
545
+ value: 'any',
546
+ type: 'select',
547
+ params: { options: TYPE_CHOICES },
548
+ displayName: 'Data Type'
549
+ });
550
+
551
+ // Watch for index changes to trigger parent port sync
552
+ const syncParent = () => {
553
+ if (this.parent && (this.parent as any).syncPorts) {
554
+ (this.parent as any).syncPorts();
555
+ }
556
+ this.update();
557
+ };
558
+ this.watchProp('outputIndex', syncParent);
559
+ this.watchProp('outputName', syncParent);
560
+ this.watchProp('dataType', () => {
561
+ if (this.inputs[0]) this.inputs[0].dataType = this.dataType;
562
+ syncParent();
563
+ });
564
+
565
+ this.onUpdate = () => this.update();
566
+ this.onReady = () => this.update();
567
+ }
568
+
569
+ /**
570
+ * Get the output index this node represents
571
+ */
572
+ get outputIndex(): number {
573
+ return this.props.outputIndex?.value ?? 0;
574
+ }
575
+
576
+ get outputName(): string {
577
+ return this.props.outputName?.value ?? '';
578
+ }
579
+
580
+ get dataType(): DataType {
581
+ const value = this.props.dataType?.value;
582
+ return typeof value === 'string' && isCoreType(value) ? value : 'any';
583
+ }
584
+
585
+ private update(): void {
586
+ // Pass through the input value and preview
587
+ const input = this.inputs[0];
588
+ if (input) {
589
+ if (this.isPreviewValue(input.value)) {
590
+ this.preview = input.value;
591
+ } else {
592
+ this.preview = null;
593
+ }
594
+ }
595
+ }
596
+ }
597
+ `,R=`import { randomFromSeed } from '../../../../packages/runtime/src/builtins/core/random.js';
598
+ import { Node } from '../../Node.js';
599
+ import type { Graph } from '../../Graph.js';
600
+
601
+ export const nodeMetadata = {
602
+ type: 'Random',
603
+ name: 'Random',
604
+ icon: 'Dice5',
605
+ description: 'Generate a deterministic value from an explicit seed',
606
+ category: 'utility'
607
+ };
608
+
609
+ export class RandomNode extends Node {
610
+ constructor(id: string, graph: Graph) {
611
+ super(id, 'Random', graph);
612
+ }
613
+
614
+ protected setup(): void {
615
+ const seed = this.in('seed', 0, { type: 'int' });
616
+ const sample = this.in('sample', 0, { type: 'int' });
617
+ const value = this.out<number>('value');
618
+ const update = () => value.setValue(randomFromSeed(seed.value, sample.value));
619
+ seed.onChange = update;
620
+ sample.onChange = update;
621
+ this.onUpdate = update;
622
+ this.onReady = update;
623
+ }
624
+ }
625
+ `,z=`import { remap } from '../../../../packages/runtime/src/builtins/core/remap.js';
626
+ import { Node } from '../../Node.js';
627
+ import type { Graph } from '../../Graph.js';
628
+
629
+ export const nodeMetadata = {
630
+ type: 'Remap',
631
+ name: 'Remap',
632
+ icon: 'ArrowRightLeft',
633
+ description: 'Map a number from one range into another',
634
+ category: 'utility'
635
+ };
636
+
637
+ export class RemapNode extends Node {
638
+ constructor(id: string, graph: Graph) {
639
+ super(id, 'Remap', graph);
640
+ }
641
+
642
+ protected setup(): void {
643
+ const value = this.in('value', 0, { type: 'float' });
644
+ const inMin = this.in('inMin', 0, { type: 'float' });
645
+ const inMax = this.in('inMax', 1, { type: 'float' });
646
+ const outMin = this.in('outMin', 0, { type: 'float' });
647
+ const outMax = this.in('outMax', 1, { type: 'float' });
648
+ const result = this.out<number>('result');
649
+ this.addParm('clamp', { value: false, type: 'boolean', displayName: 'Clamp' });
650
+
651
+ const update = () => result.setValue(remap(
652
+ value.value,
653
+ inMin.value,
654
+ inMax.value,
655
+ outMin.value,
656
+ outMax.value,
657
+ this.props.clamp.value,
658
+ ));
659
+ for (const input of [value, inMin, inMax, outMin, outMax]) input.onChange = update;
660
+ this.watchProp('clamp', update);
661
+ this.onUpdate = update;
662
+ this.onReady = update;
663
+ }
664
+ }
665
+ `,B=`/**
666
+ * SelectNode - Pick an item from an array by index
667
+ *
668
+ * Takes an array input and outputs the item at the specified index.
669
+ * Supports wrapping so indices beyond array length wrap around.
670
+ */
671
+
672
+ import { Node } from '../../Node.js';
673
+ import type { Graph } from '../../Graph.js';
674
+ import type { InputPort, OutputPort } from '@/types/node.types';
675
+
676
+ export const nodeMetadata = {
677
+ type: 'Select',
678
+ name: 'Select',
679
+ icon: 'ListFilter',
680
+ description: 'Pick an item from an array by index',
681
+ category: 'utility'
682
+ };
683
+
684
+ export class SelectNode extends Node {
685
+ private arrayInput!: InputPort<unknown[]>;
686
+ private itemOutput!: OutputPort<unknown>;
687
+ private countOutput!: OutputPort<number>;
688
+
689
+ constructor(id: string, graph: Graph) {
690
+ super(id, 'Select', graph);
691
+ }
692
+
693
+ protected setup(): void {
694
+ // Inputs (default to empty array, type is 'array')
695
+ this.arrayInput = this.in<unknown[]>('array', [], { type: 'array' });
696
+
697
+ // Outputs (second param is PortType: 'param' | 'trigger')
698
+ this.itemOutput = this.out('item', 'param');
699
+ this.countOutput = this.out('count', 'param');
700
+
701
+ // Parameters
702
+ this.addParm('index', {
703
+ value: 0,
704
+ type: 'int',
705
+ params: { min: 0, max: 0, step: 1 },
706
+ displayName: 'Index'
707
+ });
708
+
709
+ this.addParm('wrap', {
710
+ value: true,
711
+ type: 'boolean',
712
+ displayName: 'Wrap Index'
713
+ });
714
+
715
+ // Watch for changes
716
+ this.watchProp('index', () => this.update());
717
+ this.watchProp('wrap', () => this.update());
718
+
719
+ this.onUpdate = () => this.update();
720
+ this.onReady = () => this.update();
721
+ }
722
+
723
+ private update(): void {
724
+ const array = this.arrayInput.value;
725
+
726
+ // Handle non-array or empty input
727
+ if (!Array.isArray(array) || array.length === 0) {
728
+ this.itemOutput.setValue(null);
729
+ this.countOutput.setValue(0);
730
+ this.updatePropParams('index', { max: 0 });
731
+ return;
732
+ }
733
+
734
+ // Update index max based on array length
735
+ this.updatePropParams('index', { max: array.length - 1 });
736
+
737
+ // Get the index, applying wrapping if enabled
738
+ let index = this.props.index?.value ?? 0;
739
+ const wrap = this.props.wrap?.value ?? true;
740
+
741
+ if (wrap && array.length > 0) {
742
+ index = ((index % array.length) + array.length) % array.length;
743
+ } else {
744
+ index = Math.max(0, Math.min(index, array.length - 1));
745
+ }
746
+
747
+ const item = array[index];
748
+
749
+ this.itemOutput.setValue(item);
750
+ this.countOutput.setValue(array.length);
751
+
752
+ // If the item is a canvas or image, show as preview
753
+ if (
754
+ item instanceof HTMLCanvasElement ||
755
+ item instanceof HTMLImageElement
756
+ ) {
757
+ this.preview = item;
758
+ } else {
759
+ this.preview = null;
760
+ }
761
+ }
762
+ }
763
+ `,V=`import { Node } from '../../Node.js';
764
+ import type { Graph } from '../../Graph.js';
765
+
766
+ export const nodeMetadata = {
767
+ type: 'Null',
768
+ name: 'Null',
769
+ icon: 'Circle',
770
+ description: 'Pass its input through unchanged',
771
+ category: 'routing',
772
+ };
773
+
774
+ export class NullNode extends Node {
775
+ constructor(id: string, graph: Graph) {
776
+ super(id, 'Null', graph);
777
+ }
778
+
779
+ protected setup(): void {
780
+ const input = this.in('input', null, { type: 'any' });
781
+ const output = this.out('output');
782
+ const update = () => output.setValue(input.value);
783
+ input.onChange = update;
784
+ this.onUpdate = update;
785
+ this.onReady = update;
786
+ }
787
+ }
788
+ `,H=`/**
789
+ * FreezeNode - Capture and lock a value in place
790
+ *
791
+ * When frozen, the node outputs its captured value regardless of input changes.
792
+ * Useful for preserving a specific state in a workflow.
793
+ */
794
+
795
+ import { Node } from '../../Node.js';
796
+ import type { Graph } from '../../Graph.js';
797
+ import type { InputPort, OutputPort } from '@/types/node.types';
798
+
799
+ export const nodeMetadata = {
800
+ type: 'Freeze',
801
+ name: 'Freeze',
802
+ icon: 'Snowflake',
803
+ description: 'Capture and lock a value',
804
+ category: 'utility'
805
+ };
806
+
807
+ export class FreezeNode extends Node {
808
+ private input!: InputPort<unknown>;
809
+ private output!: OutputPort<unknown>;
810
+ private frozenValue: unknown = null;
811
+ private hasCaptured: boolean = false;
812
+
813
+ constructor(id: string, graph: Graph) {
814
+ super(id, 'Freeze', graph);
815
+ }
816
+
817
+ protected setup(): void {
818
+ // Input (default to null, type is 'any')
819
+ this.input = this.in<unknown>('input', null, { type: 'any' });
820
+
821
+ // Output (second param is PortType: 'param' | 'trigger')
822
+ this.output = this.out<unknown>('output', 'param');
823
+
824
+ // Parameters
825
+ this.addParm('frozen', {
826
+ value: false,
827
+ type: 'boolean',
828
+ displayName: 'Frozen'
829
+ });
830
+
831
+ // Actions
832
+ this.addAction('capture', {
833
+ label: 'Capture',
834
+ icon: 'Camera',
835
+ callback: () => this.capture()
836
+ });
837
+
838
+ this.addAction('clear', {
839
+ label: 'Clear',
840
+ icon: 'Trash2',
841
+ callback: () => this.clear()
842
+ });
843
+
844
+ // Watch frozen state
845
+ this.watchProp('frozen', () => this.update());
846
+
847
+ this.onUpdate = () => this.update();
848
+ this.onReady = () => this.update();
849
+ }
850
+
851
+ /**
852
+ * Capture the current input value
853
+ */
854
+ capture(): void {
855
+ this.frozenValue = this.deepClone(this.input.value);
856
+ this.hasCaptured = true;
857
+ this.setParm('frozen', true);
858
+ this.update();
859
+ }
860
+
861
+ /**
862
+ * Clear the frozen value
863
+ */
864
+ clear(): void {
865
+ this.frozenValue = null;
866
+ this.hasCaptured = false;
867
+ this.setParm('frozen', false);
868
+ this.update();
869
+ }
870
+
871
+ /**
872
+ * Deep clone a value if possible
873
+ */
874
+ private deepClone(value: unknown): unknown {
875
+ if (value === null || value === undefined) {
876
+ return value;
877
+ }
878
+
879
+ // Handle canvas - create a copy
880
+ if (value instanceof HTMLCanvasElement) {
881
+ const canvas = document.createElement('canvas');
882
+ canvas.width = value.width;
883
+ canvas.height = value.height;
884
+ const ctx = canvas.getContext('2d');
885
+ ctx?.drawImage(value, 0, 0);
886
+ return canvas;
887
+ }
888
+
889
+ // Handle image elements
890
+ if (value instanceof HTMLImageElement) {
891
+ const canvas = document.createElement('canvas');
892
+ canvas.width = value.naturalWidth || value.width;
893
+ canvas.height = value.naturalHeight || value.height;
894
+ const ctx = canvas.getContext('2d');
895
+ ctx?.drawImage(value, 0, 0);
896
+ return canvas;
897
+ }
898
+
899
+ // Handle arrays
900
+ if (Array.isArray(value)) {
901
+ return value.map((item) => this.deepClone(item));
902
+ }
903
+
904
+ // Handle plain objects
905
+ if (typeof value === 'object') {
906
+ try {
907
+ return JSON.parse(JSON.stringify(value));
908
+ } catch {
909
+ return value;
910
+ }
911
+ }
912
+
913
+ // Primitives are already immutable
914
+ return value;
915
+ }
916
+
917
+ private update(): void {
918
+ const isFrozen = this.props.frozen?.value ?? false;
919
+
920
+ if (isFrozen && this.hasCaptured) {
921
+ // Output the frozen value
922
+ this.output.setValue(this.frozenValue);
923
+
924
+ // Show preview if it's a visual type
925
+ if (
926
+ this.frozenValue instanceof HTMLCanvasElement ||
927
+ this.frozenValue instanceof HTMLImageElement
928
+ ) {
929
+ this.preview = this.frozenValue as HTMLCanvasElement | HTMLImageElement;
930
+ }
931
+ } else {
932
+ // Pass through the input
933
+ this.output.setValue(this.input.value);
934
+
935
+ // Show input preview if visual
936
+ if (
937
+ this.input.value instanceof HTMLCanvasElement ||
938
+ this.input.value instanceof HTMLImageElement
939
+ ) {
940
+ this.preview = this.input.value;
941
+ } else {
942
+ this.preview = null;
943
+ }
944
+ }
945
+ }
946
+
947
+ /**
948
+ * Serialize with frozen state
949
+ */
950
+ serialize(): Record<string, unknown> {
951
+ // Can't serialize canvas/images directly - would need to convert to data URL
952
+ // For now, just save the frozen state, not the value
953
+ return {
954
+ hasCaptured: this.hasCaptured
955
+ };
956
+ }
957
+
958
+ /**
959
+ * Deserialize and restore frozen state
960
+ */
961
+ deserialize(data: Record<string, unknown>): void {
962
+ this.hasCaptured = data.hasCaptured === true;
963
+ }
964
+ }
965
+ `,U=class{constructor(){this._graph=null,this._pwd=null,this._frame=1,this._fps=30,this._selectedNodes=new Set}setGraph(e){this._graph=e,s.setGraph(e)}getGraph(){return this._graph}node(e){return this._graph?e.startsWith(`/`)?this.resolveAbsolutePath(e):this._pwd?this._pwd.node(e):this.resolveAbsolutePath(`/`+e):null}parm(e){let t=e.lastIndexOf(`/`);if(t===-1)return null;let n=e.substring(0,t)||`/`,r=e.substring(t+1);return this.node(n)?.parm(r)??null}root(){return null}pwd(){return this._pwd}setPwd(e){this._pwd=e}cd(e){if(e===`/`){this._pwd=null;return}let t=this.node(e);t&&t.isNetwork()&&(this._pwd=t)}selectedNodes(){return this._graph?Array.from(this._selectedNodes).map(e=>this._graph.getNode(e)).filter(e=>e!==null):[]}selectedNodeIds(){return Array.from(this._selectedNodes)}setSelection(e){this._selectedNodes=new Set(e),this.onSelectionChange?.(e)}clearAllSelected(){this._selectedNodes.clear(),this.onSelectionChange?.([])}frame(){return this._frame}time(){return this._frame/this._fps}fps(){return this._fps}setFrame(e){this._frame=Math.max(1,Math.floor(e)),s.setFrame(this._frame)}setTime(e){this._frame=Math.max(1,Math.floor(e*this._fps)),s.setFrame(this._frame)}setFps(e){this._fps=Math.max(1,e),s.setFps(this._fps)}ch(e){return this.parm(e)?.evalAsFloat()??0}chs(e){return this.parm(e)?.evalAsString()??``}chv(e){let t=this.parm(e)?.eval();return Array.isArray(t)?t:typeof t==`number`?[t]:[]}markTimeDependentDirty(){if(this._graph)for(let e of this._graph.nodes)e.isTimeDependent&&e.markDirty()}getTimeDependentNodes(){return this._graph?this._graph.nodes.filter(e=>e.isTimeDependent):[]}nextFrame(){return this.setFrame(this._frame+1),this.markTimeDependentDirty(),this._frame}resolveAbsolutePath(e){if(!this._graph)return null;let t=e.replace(/^\//,``).split(`/`).filter(e=>e.length>0);if(t.length===0)return null;let n=null,r=this._graph.nodes.filter(e=>!e.parent);for(let e=0;e<t.length;e++){let i=t[e],a=(n?n.children():r).find(e=>e.id===i);if(!a)return null;n=a}return n}},W=new U,G=[l,d,p,g,y,S,T,D,k,j],K={Switch:u,Merge:f,Subnet:m,Input:_,Output:b,Random:C,Remap:E,Select:O,Null:A,Freeze:M};t(`core`,K),e(`Switch`,N),e(`Merge`,P),e(`Subnet`,F),e(`Input`,I),e(`Output`,L),e(`Random`,R),e(`Remap`,z),e(`Select`,B),e(`Null`,V),e(`Freeze`,H);export{U as CascadeContext,n as ExpressionEngine,M as FreezeNode,o as Graph,_ as InputNode,f as MergeNode,r as Node,A as NullNode,b as OutputNode,C as RandomNode,E as RemapNode,O as SelectNode,m as SubnetNode,u as SwitchNode,W as cascade,a as coreLibrary,K as coreNodeClasses,s as expressionEngine,G as nodeMetadataList};