@synergenius/flow-weaver 0.33.1 → 0.44.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/LICENSE +201 -226
- package/NOTICE +13 -0
- package/README.md +152 -244
- package/dist/agent/agent-loop.d.ts +4 -2
- package/dist/agent/cli-session.d.ts +3 -3
- package/dist/agent/cli-session.js +511 -438
- package/dist/agent/cli-spawn-config.d.ts +4 -4
- package/dist/agent/gate.d.ts +164 -0
- package/dist/agent/index.d.ts +4 -4
- package/dist/agent/index.js +174 -28
- package/dist/agent/mcp-bridge.d.ts +1 -1
- package/dist/agent/mcp-bridge.js +114 -128
- package/dist/agent/mcp-tool-server.d.ts +2 -2
- package/dist/agent/mcp-tool-server.js +147 -189
- package/dist/agent/profiles.d.ts +69 -0
- package/dist/agent/providers/anthropic.d.ts +2 -4
- package/dist/agent/providers/claude-cli.d.ts +4 -5
- package/dist/agent/providers/openai-compat.d.ts +8 -1
- package/dist/agent/streaming.d.ts +2 -2
- package/dist/agent/types.d.ts +16 -10
- package/dist/api/builder.d.ts +3 -3
- package/dist/api/compile.d.ts +9 -4
- package/dist/api/durable-validation.d.ts +15 -0
- package/dist/api/generate-in-place.d.ts +21 -19
- package/dist/api/generate.d.ts +21 -16
- package/dist/api/generated-module/local-node-functions.d.ts +24 -0
- package/dist/api/generated-module/module-format.d.ts +23 -0
- package/dist/api/generated-module/module-writer.d.ts +34 -0
- package/dist/api/generated-module/node-type-imports.d.ts +39 -0
- package/dist/api/generated-module/preamble.d.ts +16 -0
- package/dist/api/generated-module/workflow-functions.d.ts +29 -0
- package/dist/api/graph-identity.d.ts +39 -0
- package/dist/api/helpers.d.ts +4 -60
- package/dist/api/in-place/built-in-nodes.d.ts +18 -0
- package/dist/api/in-place/function-body.d.ts +21 -0
- package/dist/api/in-place/fw-imports.d.ts +30 -0
- package/dist/api/in-place/macro-coverage.d.ts +14 -0
- package/dist/api/in-place/node-type-functions.d.ts +18 -0
- package/dist/api/in-place/node-type-jsdoc.d.ts +20 -0
- package/dist/api/in-place/orphaned-node-types.d.ts +16 -0
- package/dist/api/in-place/runtime-section.d.ts +16 -0
- package/dist/api/in-place/signature.d.ts +47 -0
- package/dist/api/in-place/source-file.d.ts +19 -0
- package/dist/api/in-place/workflow-jsdoc.d.ts +19 -0
- package/dist/api/index.d.ts +18 -21
- package/dist/api/index.js +259 -53
- package/dist/api/inline-engine.generated.d.ts +3 -0
- package/dist/api/inline-runtime.d.ts +10 -2
- package/dist/api/manipulation/connections.d.ts +1 -1
- package/dist/api/manipulation/index.d.ts +8 -8
- package/dist/api/manipulation/node-types.d.ts +1 -1
- package/dist/api/manipulation/nodes.d.ts +3 -13
- package/dist/api/manipulation/ports.d.ts +1 -1
- package/dist/api/manipulation/scopes.d.ts +1 -1
- package/dist/api/manipulation/workflow.d.ts +1 -1
- package/dist/api/modify-operation.d.ts +0 -2
- package/dist/api/parse.d.ts +22 -1
- package/dist/api/port-references.d.ts +66 -0
- package/dist/api/query.d.ts +18 -2
- package/dist/api/templates.d.ts +1 -1
- package/dist/api/transform.d.ts +1 -1
- package/dist/api/validate.d.ts +1 -1
- package/dist/api/validation-registry.d.ts +2 -2
- package/dist/artifacts/brief.d.ts +43 -0
- package/dist/artifacts/index.d.ts +31 -0
- package/dist/artifacts/pdf.d.ts +19 -0
- package/dist/ast/builder.d.ts +3 -3
- package/dist/ast/index.d.ts +4 -4
- package/dist/ast/index.js +60 -5
- package/dist/ast/serialization-node.d.ts +1 -1
- package/dist/ast/serialization.d.ts +1 -1
- package/dist/ast/types.d.ts +82 -291
- package/dist/ast/workflow-utils.d.ts +4 -4
- package/dist/built-in-nodes/coercion-types.d.ts +1 -1
- package/dist/built-in-nodes/delay.d.ts +3 -1
- package/dist/built-in-nodes/generated-registry.d.ts +1 -1
- package/dist/built-in-nodes/index.d.ts +6 -5
- package/dist/built-in-nodes/index.js +79 -5
- package/dist/built-in-nodes/invoke-workflow.d.ts +2 -1
- package/dist/built-in-nodes/mock-types.d.ts +45 -14
- package/dist/built-in-nodes/sleep.d.ts +12 -0
- package/dist/built-in-nodes/wait-for-agent.d.ts +2 -1
- package/dist/built-in-nodes/wait-for-event.d.ts +2 -1
- package/dist/chevrotain-parser/coerce-parser.d.ts +1 -1
- package/dist/chevrotain-parser/connect-parser.d.ts +1 -1
- package/dist/chevrotain-parser/grammar-diagrams.d.ts +1 -1
- package/dist/chevrotain-parser/index.d.ts +20 -23
- package/dist/chevrotain-parser/node-parser.d.ts +7 -8
- package/dist/chevrotain-parser/parse-line.d.ts +54 -0
- package/dist/chevrotain-parser/tokens.d.ts +0 -17
- package/dist/chevrotain-parser/trigger-cancel-parser.d.ts +6 -1
- package/dist/chunks/chunk-4EUSHAY6.js +298 -0
- package/dist/chunks/chunk-4KDUEOFD.js +197 -0
- package/dist/chunks/chunk-5Y3AIUWY.js +911 -0
- package/dist/chunks/chunk-6KMVP6AU.js +20 -0
- package/dist/chunks/chunk-6PNJORFL.js +128 -0
- package/dist/chunks/chunk-7AAQNGRH.js +2001 -0
- package/dist/chunks/chunk-7YYKTPJ5.js +22705 -0
- package/dist/chunks/chunk-A5MBOFVY.js +33 -0
- package/dist/chunks/chunk-AXNQRVJB.js +18 -0
- package/dist/chunks/chunk-B6HQ6YS5.js +572 -0
- package/dist/chunks/chunk-CY3RNVML.js +296 -0
- package/dist/chunks/chunk-CYHYDLV4.js +653 -0
- package/dist/chunks/chunk-CZBCCK4Y.js +82 -0
- package/dist/chunks/chunk-DCMGQP5V.js +505 -0
- package/dist/chunks/chunk-DIAA66GL.js +72 -0
- package/dist/chunks/chunk-DUO6H5PR.js +20 -0
- package/dist/chunks/chunk-E5WN7IGO.js +125 -0
- package/dist/chunks/chunk-EFGFXXQF.js +184 -0
- package/dist/chunks/chunk-F3RTZV2A.js +2811 -0
- package/dist/chunks/chunk-FMTLP5ZX.js +1397 -0
- package/dist/chunks/chunk-HKZLQJDV.js +79 -0
- package/dist/chunks/chunk-INDEVYEC.js +146 -0
- package/dist/chunks/chunk-JQTF4R5L.js +390 -0
- package/dist/chunks/chunk-KMCAYNUM.js +331 -0
- package/dist/chunks/chunk-KMWCCOUJ.js +1444 -0
- package/dist/chunks/chunk-KU3CLJI2.js +338 -0
- package/dist/chunks/chunk-NDSTGMKR.js +3300 -0
- package/dist/chunks/chunk-NQNLUAPO.js +505 -0
- package/dist/chunks/chunk-O2U2LO57.js +466 -0
- package/dist/chunks/chunk-OOQG7UPP.js +457 -0
- package/dist/chunks/chunk-OZQAW5ZG.js +112 -0
- package/dist/chunks/chunk-P2CVDGHR.js +487 -0
- package/dist/chunks/chunk-P44RIZ7C.js +592 -0
- package/dist/chunks/chunk-PEZCT37T.js +1475 -0
- package/dist/chunks/chunk-PKWSAW6O.js +152 -0
- package/dist/chunks/chunk-Q6MDDZMT.js +4373 -0
- package/dist/chunks/chunk-QDE4Z7KW.js +6 -0
- package/dist/chunks/chunk-QJDAVSNY.js +8 -0
- package/dist/chunks/chunk-QYPORSLO.js +7552 -0
- package/dist/chunks/chunk-R4QGNK34.js +183 -0
- package/dist/chunks/chunk-REEYC73I.js +3002 -0
- package/dist/chunks/chunk-SEWDMQ6Q.js +46 -0
- package/dist/chunks/chunk-TAIUWKZB.js +3057 -0
- package/dist/chunks/chunk-TN4YZ3O7.js +196 -0
- package/dist/chunks/chunk-TRMFB43C.js +143 -0
- package/dist/chunks/chunk-VO4QXG2X.js +1016 -0
- package/dist/chunks/chunk-VP2P3BPA.js +1002 -0
- package/dist/chunks/chunk-VQ7H33J4.js +2176 -0
- package/dist/chunks/chunk-VWA7MCV2.js +105 -0
- package/dist/chunks/chunk-XAV22WD7.js +253 -0
- package/dist/chunks/chunk-YSPBPZDV.js +148 -0
- package/dist/chunks/chunk-ZKEGXO73.js +282 -0
- package/dist/chunks/chunk-ZMGN6F3S.js +4256 -0
- package/dist/chunks/grammar-diagrams-AI7VDXOM.js +14 -0
- package/dist/chunks/index.min-ECJD6GZC.js +37 -0
- package/dist/chunks/manifest-EPTR5MYH.js +21 -0
- package/dist/chunks/openapi-document-6TCGVDUW.js +69 -0
- package/dist/chunks/registry-K2U5KUTY.js +23 -0
- package/dist/chunks/serialization-node-UGY6CFH6.js +38 -0
- package/dist/chunks/validate-GEKSZPIN.js +24 -0
- package/dist/chunks/validation-registry-IQZX3UE3.js +7 -0
- package/dist/chunks/validator-VXFHLPDW.js +26 -0
- package/dist/chunks/workflow-executor-KBGFKHNR.js +36 -0
- package/dist/cli/commands/agents.d.ts +16 -0
- package/dist/cli/commands/artifact.d.ts +10 -0
- package/dist/cli/commands/compile.d.ts +0 -30
- package/dist/cli/commands/console.d.ts +32 -0
- package/dist/cli/commands/context.d.ts +0 -3
- package/dist/cli/commands/describe.js +386 -352
- package/dist/cli/commands/dev.d.ts +9 -4
- package/dist/cli/commands/diagram.d.ts +3 -5
- package/dist/cli/commands/doctor.d.ts +27 -4
- package/dist/cli/commands/doctor.js +3307 -633
- package/dist/cli/commands/export.d.ts +6 -4
- package/dist/cli/commands/grammar.d.ts +0 -3
- package/dist/cli/commands/implement.d.ts +1 -1
- package/dist/cli/commands/init/agent-handoff.d.ts +28 -0
- package/dist/cli/commands/init/config.d.ts +3 -0
- package/dist/cli/commands/init/files.d.ts +12 -0
- package/dist/cli/commands/init/naming.d.ts +13 -0
- package/dist/cli/commands/init/output.d.ts +12 -0
- package/dist/cli/commands/init/setup.d.ts +21 -0
- package/dist/cli/commands/init/types.d.ts +53 -0
- package/dist/cli/commands/init-personas.d.ts +9 -1
- package/dist/cli/commands/init.d.ts +24 -88
- package/dist/cli/commands/market.d.ts +1 -1
- package/dist/cli/commands/mcp-setup.d.ts +1 -4
- package/dist/cli/commands/modify.d.ts +0 -5
- package/dist/cli/commands/openapi.d.ts +9 -11
- package/dist/cli/commands/run.d.ts +0 -4
- package/dist/cli/commands/serve.d.ts +24 -26
- package/dist/cli/commands/status.d.ts +1 -1
- package/dist/cli/exports.d.ts +3 -4
- package/dist/cli/exports.js +124 -23
- package/dist/cli/flow-weaver-agents-H653446S.mjs +81 -0
- package/dist/cli/flow-weaver-artifact-WBFYTW76.mjs +58 -0
- package/dist/cli/flow-weaver-chunk-265CEK74.mjs +2 -0
- package/dist/cli/flow-weaver-chunk-2C7PZCV5.mjs +186 -0
- package/dist/cli/flow-weaver-chunk-3BSYCWPL.mjs +3109 -0
- package/dist/cli/flow-weaver-chunk-3MKUQP3D.mjs +547 -0
- package/dist/cli/flow-weaver-chunk-3ZLMPQTH.mjs +27 -0
- package/dist/cli/flow-weaver-chunk-4DVY73ML.mjs +280 -0
- package/dist/cli/flow-weaver-chunk-54M4KNEL.mjs +200 -0
- package/dist/cli/flow-weaver-chunk-55QMUZIA.mjs +256 -0
- package/dist/cli/flow-weaver-chunk-6ZUJ7LMX.mjs +2003 -0
- package/dist/cli/flow-weaver-chunk-7ET6N32V.mjs +419 -0
- package/dist/cli/flow-weaver-chunk-7G63RR4K.mjs +8880 -0
- package/dist/cli/flow-weaver-chunk-A6M5K3W7.mjs +4418 -0
- package/dist/cli/flow-weaver-chunk-AA3NATMX.mjs +154 -0
- package/dist/cli/flow-weaver-chunk-APX6MQ5A.mjs +5652 -0
- package/dist/cli/flow-weaver-chunk-BHCC5FE5.mjs +17 -0
- package/dist/cli/flow-weaver-chunk-DM4BBRRU.mjs +35 -0
- package/dist/cli/flow-weaver-chunk-DRN7KPWY.mjs +168 -0
- package/dist/cli/flow-weaver-chunk-EKWF27G6.mjs +23 -0
- package/dist/cli/flow-weaver-chunk-EM5HWQ4R.mjs +338 -0
- package/dist/cli/flow-weaver-chunk-FPPPU2DG.mjs +226 -0
- package/dist/cli/flow-weaver-chunk-GAQXZHNO.mjs +3005 -0
- package/dist/cli/flow-weaver-chunk-GBUNNP33.mjs +1329 -0
- package/dist/cli/flow-weaver-chunk-HMAKDE55.mjs +636 -0
- package/dist/cli/flow-weaver-chunk-HQ3ZAN44.mjs +367 -0
- package/dist/cli/flow-weaver-chunk-I4APCXYN.mjs +21442 -0
- package/dist/cli/flow-weaver-chunk-IJJ4JXTL.mjs +2297 -0
- package/dist/cli/flow-weaver-chunk-J7EPZW2I.mjs +33 -0
- package/dist/cli/flow-weaver-chunk-KOEMJHLG.mjs +83 -0
- package/dist/cli/flow-weaver-chunk-M6CBWQKJ.mjs +271 -0
- package/dist/cli/flow-weaver-chunk-MHJ4N652.mjs +1580 -0
- package/dist/cli/flow-weaver-chunk-MKAFQWLP.mjs +202 -0
- package/dist/cli/flow-weaver-chunk-MMV2XGD3.mjs +3291 -0
- package/dist/cli/flow-weaver-chunk-MSI2UJES.mjs +125 -0
- package/dist/cli/flow-weaver-chunk-N767YRAI.mjs +48 -0
- package/dist/cli/flow-weaver-chunk-NQKKWDGF.mjs +56 -0
- package/dist/cli/flow-weaver-chunk-NYZDQYFU.mjs +45 -0
- package/dist/cli/flow-weaver-chunk-OMVWSNHJ.mjs +14 -0
- package/dist/cli/flow-weaver-chunk-PUWZ47H5.mjs +2188 -0
- package/dist/cli/flow-weaver-chunk-QOPRVDES.mjs +46 -0
- package/dist/cli/flow-weaver-chunk-RIWE7YTR.mjs +216 -0
- package/dist/cli/flow-weaver-chunk-S63Q3JIU.mjs +789 -0
- package/dist/cli/flow-weaver-chunk-T7X5A23H.mjs +558 -0
- package/dist/cli/flow-weaver-chunk-TLV3VZUN.mjs +2 -0
- package/dist/cli/flow-weaver-chunk-TS5P3PIN.mjs +194 -0
- package/dist/cli/flow-weaver-chunk-U3EO3X4B.mjs +649 -0
- package/dist/cli/flow-weaver-chunk-UNFS3NQP.mjs +34 -0
- package/dist/cli/flow-weaver-chunk-V6DHWFQG.mjs +2811 -0
- package/dist/cli/flow-weaver-chunk-VXWNLYQU.mjs +9 -0
- package/dist/cli/flow-weaver-chunk-W3YNK26P.mjs +149 -0
- package/dist/cli/flow-weaver-chunk-XG2WKXYZ.mjs +324 -0
- package/dist/cli/flow-weaver-chunk-YLSRZWFK.mjs +2219 -0
- package/dist/cli/flow-weaver-chunk-YVPURWS6.mjs +40 -0
- package/dist/cli/flow-weaver-chunk-Z44JK332.mjs +582 -0
- package/dist/cli/flow-weaver-chunk-Z5ZJPNSY.mjs +517 -0
- package/dist/cli/flow-weaver-chunk-ZQALO25T.mjs +594 -0
- package/dist/cli/flow-weaver-compile-A2CABDSB.mjs +37 -0
- package/dist/cli/flow-weaver-console-6EBHDBTN.mjs +71 -0
- package/dist/cli/flow-weaver-context-ECLYANFF.mjs +17 -0
- package/dist/cli/flow-weaver-context-ZRUMW2KE.mjs +69 -0
- package/dist/cli/flow-weaver-create-WIP4EFNP.mjs +124 -0
- package/dist/cli/flow-weaver-deployment-WJJRK7NO.mjs +14 -0
- package/dist/cli/flow-weaver-describe-XDIFF5LI.mjs +41 -0
- package/dist/cli/flow-weaver-dev-LG2NSQAU.mjs +196 -0
- package/dist/cli/flow-weaver-diagram-3EVQARQE.mjs +52 -0
- package/dist/cli/flow-weaver-diagram-7LR7O4M2.mjs +44 -0
- package/dist/cli/flow-weaver-diff-USF7DJLU.mjs +85 -0
- package/dist/cli/flow-weaver-docs-QU2ZOXKH.mjs +96 -0
- package/dist/cli/flow-weaver-doctor-K447YWHR.mjs +43 -0
- package/dist/cli/flow-weaver-export-LAS6N56Y.mjs +140 -0
- package/dist/cli/flow-weaver-grammar-RIRUS3Q6.mjs +49 -0
- package/dist/cli/flow-weaver-grammar-diagrams-WXRTW5SK.mjs +15 -0
- package/dist/cli/flow-weaver-implement-5JG6BCFZ.mjs +114 -0
- package/dist/cli/flow-weaver-index.min-OR5SIHXD.mjs +39 -0
- package/dist/cli/flow-weaver-init-34YZNPQX.mjs +972 -0
- package/dist/cli/flow-weaver-init-personas-NOGZTQQ2.mjs +48 -0
- package/dist/cli/flow-weaver-manifest-4JNUSEB3.mjs +18 -0
- package/dist/cli/flow-weaver-market-WA4CKHKV.mjs +444 -0
- package/dist/cli/flow-weaver-mcp-setup-O26MGXSD.mjs +22 -0
- package/dist/cli/flow-weaver-migrate-VFVEUTPH.mjs +119 -0
- package/dist/cli/flow-weaver-modify-VM3JP5K6.mjs +97 -0
- package/dist/cli/flow-weaver-openapi-IRBWI3HM.mjs +71 -0
- package/dist/cli/flow-weaver-openapi-document-7N6YMPG3.mjs +30 -0
- package/dist/cli/flow-weaver-pack-commands-OS2QRXAK.mjs +146 -0
- package/dist/cli/flow-weaver-registry-5MLFRPPT.mjs +25 -0
- package/dist/cli/flow-weaver-run-DSTLSTHR.mjs +555 -0
- package/dist/cli/flow-weaver-serialization-node-LE6PCG4M.mjs +50 -0
- package/dist/cli/flow-weaver-serve-NVLCLSOW.mjs +192 -0
- package/dist/cli/flow-weaver-server-7IERLVXE.mjs +2925 -0
- package/dist/cli/flow-weaver-server-KWF4PXYC.mjs +19112 -0
- package/dist/cli/flow-weaver-status-75W2S3YB.mjs +138 -0
- package/dist/cli/flow-weaver-strip-AZPXUYVA.mjs +79 -0
- package/dist/cli/flow-weaver-templates-DSNMB6K7.mjs +72 -0
- package/dist/cli/flow-weaver-validate-A4UWDQN6.mjs +19 -0
- package/dist/cli/flow-weaver-validate-GRBZ5W4C.mjs +296 -0
- package/dist/cli/flow-weaver-validation-registry-BINGUNXX.mjs +9 -0
- package/dist/cli/flow-weaver-validator-TY56CI42.mjs +21 -0
- package/dist/cli/flow-weaver-watch-OPPERXL6.mjs +114 -0
- package/dist/cli/flow-weaver-workflow-executor-6AHYPXAN.mjs +26 -0
- package/dist/cli/flow-weaver.mjs +3557 -89498
- package/dist/cli/index.d.ts +5 -2
- package/dist/cli/pack-commands-needed.d.ts +12 -0
- package/dist/cli/program.d.ts +14 -0
- package/dist/cli/templates/ai/mock-provider.d.ts +1 -1
- package/dist/cli/templates/index.d.ts +1 -8
- package/dist/cli/templates/nodes/agent-router.d.ts +1 -1
- package/dist/cli/templates/nodes/aggregator.d.ts +1 -1
- package/dist/cli/templates/nodes/conversation-memory.d.ts +1 -1
- package/dist/cli/templates/nodes/http.d.ts +1 -1
- package/dist/cli/templates/nodes/human-approval.d.ts +1 -1
- package/dist/cli/templates/nodes/json-extractor.d.ts +1 -1
- package/dist/cli/templates/nodes/llm-call.d.ts +1 -1
- package/dist/cli/templates/nodes/prompt-template.d.ts +1 -1
- package/dist/cli/templates/nodes/rag-retriever.d.ts +1 -1
- package/dist/cli/templates/nodes/tool-executor.d.ts +1 -1
- package/dist/cli/templates/nodes/transformer.d.ts +1 -1
- package/dist/cli/templates/nodes/validator.d.ts +1 -1
- package/dist/cli/templates/shared/approval-types.d.ts +1 -1
- package/dist/cli/templates/shared/case.d.ts +14 -0
- package/dist/cli/templates/shared/llm-types.d.ts +4 -4
- package/dist/cli/templates/workflows/aggregator.d.ts +1 -1
- package/dist/cli/templates/workflows/ai-agent.d.ts +1 -1
- package/dist/cli/templates/workflows/ai-chat.d.ts +1 -1
- package/dist/cli/templates/workflows/ai-rag.d.ts +1 -1
- package/dist/cli/templates/workflows/ai-react.d.ts +1 -1
- package/dist/cli/templates/workflows/approval.d.ts +10 -0
- package/dist/cli/templates/workflows/conditional.d.ts +2 -2
- package/dist/cli/templates/workflows/error-handler.d.ts +2 -2
- package/dist/cli/templates/workflows/foreach.d.ts +1 -1
- package/dist/cli/templates/workflows/sequential.d.ts +1 -1
- package/dist/cli/templates/workflows/webhook.d.ts +1 -1
- package/dist/cli/utils/interactive.d.ts +6 -0
- package/dist/cli/utils/json-option.d.ts +8 -0
- package/dist/cli/utils/logger.d.ts +2 -0
- package/dist/compiler/durable-source-proof.d.ts +23 -0
- package/dist/compiler/executable-artifact.d.ts +29 -0
- package/dist/compiler/index.d.ts +4 -0
- package/dist/compiler/index.js +36 -0
- package/dist/console/app.js +106 -0
- package/dist/console/assets/synergenius.svg +18 -0
- package/dist/console/author.d.ts +32 -0
- package/dist/console/cli-catalog.d.ts +21 -0
- package/dist/console/cli-run.d.ts +35 -0
- package/dist/console/cli-run.js +46 -0
- package/dist/console/debug.d.ts +67 -0
- package/dist/console/diff-view.d.ts +96 -0
- package/dist/console/export.d.ts +36 -0
- package/dist/console/git.d.ts +27 -0
- package/dist/console/index.d.ts +4 -0
- package/dist/console/index.html +16 -0
- package/dist/console/index.js +203 -0
- package/dist/console/packs.d.ts +100 -0
- package/dist/console/request-guard.d.ts +10 -0
- package/dist/console/respond.d.ts +16 -0
- package/dist/console/router.d.ts +64 -0
- package/dist/console/routes-agents.d.ts +14 -0
- package/dist/console/routes-project.d.ts +3 -0
- package/dist/console/routes-runs.d.ts +3 -0
- package/dist/console/routes-services.d.ts +7 -0
- package/dist/console/routes-tools.d.ts +3 -0
- package/dist/console/runs.d.ts +69 -0
- package/dist/console/scan.d.ts +49 -0
- package/dist/console/schema.d.ts +74 -0
- package/dist/console/server.d.ts +34 -0
- package/dist/console/server.js +43264 -0
- package/dist/console/services.d.ts +119 -0
- package/dist/console/source.d.ts +23 -0
- package/dist/console/status.d.ts +68 -0
- package/dist/console/styles.css +1023 -0
- package/dist/console/terminals.d.ts +22 -0
- package/dist/console/workflow-view.d.ts +153 -0
- package/dist/constants.d.ts +5 -1
- package/dist/constants.js +56 -167
- package/dist/context/index.d.ts +10 -0
- package/dist/context/index.js +14 -191
- package/dist/coordinator/agent-gate.d.ts +107 -0
- package/dist/coordinator/bundle-digest.d.ts +20 -0
- package/dist/coordinator/clock-tick.d.ts +4 -0
- package/dist/coordinator/effect-receipts.d.ts +10 -0
- package/dist/coordinator/errors.d.ts +31 -0
- package/dist/coordinator/file-store.d.ts +3 -0
- package/dist/coordinator/gate-labeling.d.ts +33 -0
- package/dist/coordinator/gate-resolution.d.ts +28 -0
- package/dist/coordinator/index.d.ts +12 -0
- package/dist/coordinator/index.js +107 -0
- package/dist/coordinator/memory-store.d.ts +3 -0
- package/dist/coordinator/params.d.ts +18 -0
- package/dist/coordinator/run-annotations.d.ts +6 -0
- package/dist/coordinator/run-context.d.ts +11 -0
- package/dist/coordinator/run-ending.d.ts +5 -0
- package/dist/coordinator/run-outcome.d.ts +31 -0
- package/dist/coordinator/run-resume.d.ts +6 -0
- package/dist/coordinator/run-start.d.ts +4 -0
- package/dist/coordinator/run-store.d.ts +275 -0
- package/dist/coordinator/run-trace.d.ts +41 -0
- package/dist/coordinator/run-views.d.ts +12 -0
- package/dist/coordinator/runs-dir.d.ts +26 -0
- package/dist/coordinator/store.d.ts +67 -0
- package/dist/coordinator/time.d.ts +39 -0
- package/dist/coordinator/workflow-selection.d.ts +6 -0
- package/dist/deployment/index.d.ts +11 -16
- package/dist/deployment/index.js +541 -50
- package/dist/deployment/targets/base.d.ts +11 -13
- package/dist/deployment/targets/openapi-parts.d.ts +92 -0
- package/dist/diagram/arms.d.ts +70 -0
- package/dist/diagram/ascii-renderer.d.ts +1 -1
- package/dist/diagram/geometry.d.ts +22 -29
- package/dist/diagram/graph/bounds.d.ts +30 -0
- package/dist/diagram/graph/metrics.d.ts +21 -0
- package/dist/diagram/graph/nodes.d.ts +33 -0
- package/dist/diagram/graph/placement.d.ts +22 -0
- package/dist/diagram/graph/ports.d.ts +23 -0
- package/dist/diagram/graph/routing.d.ts +40 -0
- package/dist/diagram/graph/scopes.d.ts +30 -0
- package/dist/diagram/index.d.ts +15 -23
- package/dist/diagram/index.js +632 -111
- package/dist/diagram/labels.d.ts +12 -0
- package/dist/diagram/lanes.d.ts +93 -0
- package/dist/diagram/layout.d.ts +1 -1
- package/dist/diagram/material-symbols.d.ts +7 -0
- package/dist/diagram/orthogonal-router.d.ts +15 -51
- package/dist/diagram/process-view.d.ts +79 -0
- package/dist/diagram/spine.d.ts +25 -0
- package/dist/diagram/theme.d.ts +3 -5
- package/dist/diagram/types.d.ts +6 -20
- package/dist/diff/index.js +53 -9
- package/dist/diff/types.d.ts +1 -5
- package/dist/doc-metadata/extractors/annotations.d.ts +0 -4
- package/dist/doc-metadata/extractors/cli-commands.d.ts +2 -1
- package/dist/doc-metadata/extractors/core-metadata.d.ts +19 -4
- package/dist/doc-metadata/extractors/error-codes.d.ts +1 -1
- package/dist/doc-metadata/extractors/mcp-tools.d.ts +7 -3
- package/dist/doc-metadata/index.d.ts +1 -2
- package/dist/doc-metadata/index.js +2368 -9
- package/dist/doc-metadata/types.d.ts +7 -24
- package/dist/docs/guide.d.ts +33 -0
- package/dist/docs/index.d.ts +7 -4
- package/dist/docs/index.js +298 -298
- package/dist/docs/pack-topics.d.ts +18 -0
- package/dist/editor-completions/annotationValues.d.ts +1 -1
- package/dist/editor-completions/contextParser.d.ts +3 -2
- package/dist/editor-completions/dataTypes.d.ts +1 -1
- package/dist/editor-completions/goToDefinition.d.ts +1 -1
- package/dist/editor-completions/index.d.ts +8 -8
- package/dist/editor-completions/index.js +1244 -175
- package/dist/editor-completions/jsDocAnnotations.d.ts +1 -1
- package/dist/editor-completions/modifierCompletions.d.ts +1 -1
- package/dist/export/index.d.ts +7 -1
- package/dist/generated-branding.js +8 -21
- package/dist/generated-version.d.ts +1 -1
- package/dist/generated-version.js +7 -3
- package/dist/generator/annotation-generator.d.ts +84 -0
- package/dist/generator/async-detection.d.ts +1 -1
- package/dist/{body-generator.d.ts → generator/body-generator.d.ts} +7 -3
- package/dist/generator/code-utils.d.ts +15 -60
- package/dist/generator/connection-reads.d.ts +94 -0
- package/dist/generator/control-flow-plan.d.ts +74 -0
- package/dist/generator/control-flow.d.ts +1 -1
- package/dist/generator/exit-assembly.d.ts +11 -0
- package/dist/generator/index.d.ts +4 -5
- package/dist/generator/index.js +34 -11
- package/dist/generator/input-port-values.d.ts +22 -0
- package/dist/generator/{scope-function-generator.d.ts → node-arguments.d.ts} +76 -1
- package/dist/generator/node-invocation.d.ts +74 -0
- package/dist/{node-types-generator.d.ts → generator/node-types-generator.d.ts} +3 -2
- package/dist/generator/scope-closure.d.ts +23 -0
- package/dist/generator/scoped-child.d.ts +49 -0
- package/dist/{sugar-optimizer.d.ts → generator/sugar-optimizer.d.ts} +1 -1
- package/dist/generator/unified.d.ts +14 -2
- package/dist/generator/workflow-generator.d.ts +37 -0
- package/dist/index.d.ts +29 -26
- package/dist/index.js +1322 -92
- package/dist/jsdoc-port-sync/apply-diff.d.ts +15 -0
- package/dist/jsdoc-port-sync/callback-signature.d.ts +17 -0
- package/dist/jsdoc-port-sync/diff.d.ts +5 -7
- package/dist/jsdoc-port-sync/incomplete-lines.d.ts +41 -0
- package/dist/jsdoc-port-sync/index.d.ts +11 -11
- package/dist/jsdoc-port-sync/index.js +88 -45
- package/dist/jsdoc-port-sync/jsdoc-to-signature.d.ts +66 -0
- package/dist/jsdoc-port-sync/port-parser.d.ts +6 -24
- package/dist/jsdoc-port-sync/port-tag-placement.d.ts +55 -0
- package/dist/jsdoc-port-sync/scoped-ports.d.ts +21 -0
- package/dist/jsdoc-port-sync/signature-parser.d.ts +8 -1
- package/dist/jsdoc-port-sync/signature-to-jsdoc.d.ts +77 -0
- package/dist/jsdoc-port-sync/sync.d.ts +4 -1
- package/dist/marketplace/index.d.ts +5 -3
- package/dist/marketplace/index.js +62 -10
- package/dist/marketplace/install.d.ts +24 -0
- package/dist/marketplace/manifest.d.ts +1 -1
- package/dist/marketplace/npmrc.d.ts +24 -0
- package/dist/marketplace/registry.d.ts +46 -11
- package/dist/marketplace/types.d.ts +41 -24
- package/dist/marketplace/validator.d.ts +1 -1
- package/dist/mcp/debug-session.d.ts +2 -4
- package/dist/mcp/dist-imports.d.ts +12 -0
- package/dist/mcp/response-utils.d.ts +11 -9
- package/dist/mcp/server.d.ts +0 -1
- package/dist/mcp/tools-context.d.ts +11 -0
- package/dist/mcp/tools-diagram.d.ts +1 -2
- package/dist/mcp/tools-export.d.ts +2 -2
- package/dist/mcp/tools-marketplace.d.ts +1 -1
- package/dist/mcp/tools-run.d.ts +17 -0
- package/dist/mcp/tools-workflow.d.ts +3 -0
- package/dist/mcp/types.d.ts +4 -14
- package/dist/mcp/workflow-executor.d.ts +57 -19
- package/dist/npm-packages.d.ts +1 -1
- package/dist/npm-packages.js +10 -473
- package/dist/parser/annotation-parser.d.ts +88 -0
- package/dist/parser/annotation-suggestion.d.ts +23 -0
- package/dist/parser/durable-effect-contract.d.ts +10 -0
- package/dist/parser/expression-references.d.ts +101 -0
- package/dist/parser/external-node-types.d.ts +69 -0
- package/dist/{function-like.d.ts → parser/function-like.d.ts} +10 -3
- package/dist/parser/generated-sections.d.ts +25 -0
- package/dist/parser/import-resolution.d.ts +67 -0
- package/dist/parser/import-stub.d.ts +29 -0
- package/dist/parser/jsdoc/config-types.d.ts +209 -0
- package/dist/parser/jsdoc/graph-tags.d.ts +54 -0
- package/dist/parser/jsdoc/node-type-block.d.ts +23 -0
- package/dist/parser/jsdoc/parse-line-once.d.ts +11 -0
- package/dist/parser/jsdoc/port-tags.d.ts +42 -0
- package/dist/parser/jsdoc/runtime-tags.d.ts +65 -0
- package/dist/parser/jsdoc/signature-types.d.ts +52 -0
- package/dist/parser/jsdoc/workflow-block.d.ts +22 -0
- package/dist/parser/jsdoc-parser.d.ts +23 -0
- package/dist/parser/macro-expansion.d.ts +80 -0
- package/dist/parser/module-resolution.d.ts +38 -0
- package/dist/parser/node-inference.d.ts +39 -0
- package/dist/parser/npm-node-types.d.ts +24 -0
- package/dist/parser/pack-handlers.d.ts +12 -0
- package/dist/parser/path-data-resolution.d.ts +75 -0
- package/dist/parser/port-inference.d.ts +15 -0
- package/dist/{resolve-package-types.d.ts → parser/resolve-package-types.d.ts} +4 -0
- package/dist/parser/serialize-deploy-annotations.d.ts +19 -0
- package/dist/parser/tag-registry.d.ts +22 -0
- package/dist/parser/workflow-extraction.d.ts +39 -0
- package/dist/runtime/ExecutionContext.d.ts +87 -99
- package/dist/runtime/continuation-core.d.ts +147 -0
- package/dist/runtime/continuation.d.ts +48 -0
- package/dist/runtime/debug-controller.d.ts +7 -22
- package/dist/runtime/durable-execution.d.ts +176 -0
- package/dist/runtime/events.d.ts +16 -1
- package/dist/runtime/executable-module-contract.d.ts +16 -0
- package/dist/runtime/index.d.ts +13 -10
- package/dist/runtime/index.js +947 -9
- package/dist/runtime/strict-json.d.ts +15 -0
- package/dist/server/access.d.ts +12 -0
- package/dist/server/api.d.ts +126 -0
- package/dist/server/callback-delivery.d.ts +62 -0
- package/dist/server/callback-url.d.ts +44 -0
- package/dist/server/context.d.ts +35 -0
- package/dist/server/http-error.d.ts +10 -0
- package/dist/server/index.d.ts +7 -1
- package/dist/server/index.js +125 -6
- package/dist/server/openapi-document.d.ts +33 -0
- package/dist/server/openapi.d.ts +32 -0
- package/dist/server/respond.d.ts +35 -0
- package/dist/server/route-params.d.ts +17 -0
- package/dist/server/route-plan.d.ts +41 -0
- package/dist/server/routes-catalog.d.ts +5 -0
- package/dist/server/routes-declared.d.ts +12 -0
- package/dist/server/routes-runs.d.ts +8 -0
- package/dist/server/run-driver.d.ts +58 -0
- package/dist/server/run-view.d.ts +26 -0
- package/dist/server/transport.d.ts +35 -0
- package/dist/server/types.d.ts +143 -52
- package/dist/server/webhook-server.d.ts +12 -38
- package/dist/server/workflow-registry.d.ts +7 -4
- package/dist/service-registry.d.ts +49 -0
- package/dist/service-registry.js +123 -0
- package/dist/testing/assertions.d.ts +2 -2
- package/dist/testing/index.d.ts +14 -13
- package/dist/testing/index.js +582 -24
- package/dist/testing/mock-approval.d.ts +3 -5
- package/dist/testing/mock-llm.d.ts +2 -3
- package/dist/testing/recorder.d.ts +5 -6
- package/dist/testing/replayer.d.ts +6 -7
- package/dist/testing/run-store-check.d.ts +3 -0
- package/dist/testing/token-tracker.d.ts +2 -2
- package/dist/{type-mappings.d.ts → types/type-mappings.d.ts} +13 -1
- package/dist/utils/error-utils.d.ts +4 -2
- package/dist/utils/port-ordering.d.ts +2 -2
- package/dist/utils/port-tag-utils.d.ts +1 -1
- package/dist/validation/agent-detection.d.ts +17 -5
- package/dist/validation/agent-rules.d.ts +6 -7
- package/dist/validation/core-rules.d.ts +49 -0
- package/dist/validation/design-rules.d.ts +9 -3
- package/dist/validation/rule-registry.d.ts +3 -3
- package/dist/validation/rules/connections.d.ts +27 -0
- package/dist/validation/rules/context.d.ts +11 -0
- package/dist/validation/rules/cycles.d.ts +17 -0
- package/dist/validation/rules/data-flow.d.ts +19 -0
- package/dist/validation/rules/scope-topology.d.ts +35 -0
- package/dist/validation/rules/type-compatibility.d.ts +30 -0
- package/dist/validation/type-checker.d.ts +39 -0
- package/dist/validation/validator-helpers.d.ts +31 -0
- package/dist/validation/validator.d.ts +30 -0
- package/docs/reference/advanced-annotations.md +277 -60
- package/docs/reference/built-in-nodes.md +164 -94
- package/docs/reference/cancellation.md +44 -0
- package/docs/reference/cli-reference.md +252 -234
- package/docs/reference/compilation.md +36 -109
- package/docs/reference/concepts.md +80 -63
- package/docs/reference/console.md +169 -0
- package/docs/reference/debugging.md +26 -57
- package/docs/reference/deployment.md +217 -143
- package/docs/reference/durable-gates.md +445 -0
- package/docs/reference/error-codes.md +90 -43
- package/docs/reference/export-interface.md +91 -26
- package/docs/reference/iterative-development.md +50 -28
- package/docs/reference/jsdoc-grammar.md +66 -311
- package/docs/reference/library.md +250 -0
- package/docs/reference/marketplace.md +301 -152
- package/docs/reference/mcp-tools.md +102 -0
- package/docs/reference/node-conversion.md +84 -59
- package/docs/reference/orientation.md +68 -0
- package/docs/reference/scaffold.md +5 -4
- package/docs/reference/tutorial.md +106 -166
- package/docs/reference/visual-reference.md +1 -1
- package/package.json +85 -50
- package/dist/agent/agent-loop.js +0 -156
- package/dist/agent/cli-spawn-config.js +0 -65
- package/dist/agent/device-connection.d.ts +0 -79
- package/dist/agent/device-connection.js +0 -184
- package/dist/agent/env-allowlist.js +0 -60
- package/dist/agent/providers/anthropic.js +0 -198
- package/dist/agent/providers/claude-cli.js +0 -161
- package/dist/agent/providers/openai-compat.js +0 -205
- package/dist/agent/providers/platform.d.ts +0 -23
- package/dist/agent/providers/platform.js +0 -132
- package/dist/agent/streaming.js +0 -186
- package/dist/agent/types.js +0 -20
- package/dist/annotation-generator.d.ts +0 -50
- package/dist/annotation-generator.js +0 -743
- package/dist/api/builder.js +0 -345
- package/dist/api/command-runner.js +0 -787
- package/dist/api/compile.js +0 -148
- package/dist/api/extract-types.js +0 -57
- package/dist/api/generate-in-place.js +0 -1477
- package/dist/api/generate.js +0 -514
- package/dist/api/helpers.js +0 -285
- package/dist/api/inline-runtime.js +0 -526
- package/dist/api/manipulation/connections.js +0 -151
- package/dist/api/manipulation/index.js +0 -41
- package/dist/api/manipulation/node-types.js +0 -200
- package/dist/api/manipulation/nodes.js +0 -355
- package/dist/api/manipulation/ports.js +0 -228
- package/dist/api/manipulation/scopes.js +0 -156
- package/dist/api/manipulation/workflow.js +0 -116
- package/dist/api/modify-operation.js +0 -177
- package/dist/api/parse.js +0 -115
- package/dist/api/patterns.d.ts +0 -112
- package/dist/api/patterns.js +0 -303
- package/dist/api/query.js +0 -840
- package/dist/api/templates.js +0 -117
- package/dist/api/transform.js +0 -40
- package/dist/api/validate.js +0 -64
- package/dist/api/validation-registry.js +0 -10
- package/dist/api/workflow-file-operations.js +0 -180
- package/dist/ast/builder.js +0 -395
- package/dist/ast/serialization-node.js +0 -30
- package/dist/ast/serialization.js +0 -134
- package/dist/ast/types.js +0 -2
- package/dist/ast/workflow-utils.js +0 -114
- package/dist/body-generator.js +0 -35
- package/dist/built-in-nodes/coercion-types.js +0 -61
- package/dist/built-in-nodes/delay.js +0 -29
- package/dist/built-in-nodes/generated-registry.js +0 -299
- package/dist/built-in-nodes/invoke-workflow.js +0 -36
- package/dist/built-in-nodes/mock-types.js +0 -42
- package/dist/built-in-nodes/wait-for-agent.js +0 -31
- package/dist/built-in-nodes/wait-for-event.js +0 -25
- package/dist/chevrotain-parser/coerce-parser.js +0 -103
- package/dist/chevrotain-parser/connect-parser.js +0 -136
- package/dist/chevrotain-parser/fan-parser.js +0 -149
- package/dist/chevrotain-parser/grammar-diagrams.js +0 -273
- package/dist/chevrotain-parser/index.js +0 -31
- package/dist/chevrotain-parser/map-parser.js +0 -130
- package/dist/chevrotain-parser/node-parser.js +0 -558
- package/dist/chevrotain-parser/path-parser.js +0 -140
- package/dist/chevrotain-parser/port-parser.js +0 -519
- package/dist/chevrotain-parser/position-parser.d.ts +0 -20
- package/dist/chevrotain-parser/position-parser.js +0 -83
- package/dist/chevrotain-parser/scope-parser.js +0 -104
- package/dist/chevrotain-parser/tokens.js +0 -429
- package/dist/chevrotain-parser/trigger-cancel-parser.js +0 -291
- package/dist/cli/commands/account.d.ts +0 -4
- package/dist/cli/commands/account.js +0 -50
- package/dist/cli/commands/ai-credentials.d.ts +0 -12
- package/dist/cli/commands/ai-credentials.js +0 -95
- package/dist/cli/commands/apikey.d.ts +0 -4
- package/dist/cli/commands/apikey.js +0 -64
- package/dist/cli/commands/auth.d.ts +0 -9
- package/dist/cli/commands/auth.js +0 -255
- package/dist/cli/commands/compile.js +0 -331
- package/dist/cli/commands/connect.d.ts +0 -4
- package/dist/cli/commands/connect.js +0 -163
- package/dist/cli/commands/context.js +0 -51
- package/dist/cli/commands/create.js +0 -139
- package/dist/cli/commands/deploy.d.ts +0 -6
- package/dist/cli/commands/deploy.js +0 -74
- package/dist/cli/commands/dev.js +0 -227
- package/dist/cli/commands/diagram.js +0 -39
- package/dist/cli/commands/diff.js +0 -57
- package/dist/cli/commands/docs.js +0 -74
- package/dist/cli/commands/export.js +0 -153
- package/dist/cli/commands/grammar.js +0 -40
- package/dist/cli/commands/implement.js +0 -91
- package/dist/cli/commands/init-personas.js +0 -541
- package/dist/cli/commands/init.js +0 -797
- package/dist/cli/commands/market.js +0 -440
- package/dist/cli/commands/mcp-setup.js +0 -433
- package/dist/cli/commands/migrate.js +0 -91
- package/dist/cli/commands/modify.js +0 -58
- package/dist/cli/commands/openapi.js +0 -71
- package/dist/cli/commands/org.d.ts +0 -8
- package/dist/cli/commands/org.js +0 -136
- package/dist/cli/commands/pattern.d.ts +0 -34
- package/dist/cli/commands/pattern.js +0 -186
- package/dist/cli/commands/plugin.d.ts +0 -16
- package/dist/cli/commands/plugin.js +0 -176
- package/dist/cli/commands/run.js +0 -742
- package/dist/cli/commands/serve.js +0 -93
- package/dist/cli/commands/status.js +0 -123
- package/dist/cli/commands/strip.js +0 -61
- package/dist/cli/commands/templates.js +0 -58
- package/dist/cli/commands/validate.js +0 -267
- package/dist/cli/commands/watch.js +0 -71
- package/dist/cli/config/credentials.d.ts +0 -15
- package/dist/cli/config/credentials.js +0 -43
- package/dist/cli/config/platform-client.d.ts +0 -123
- package/dist/cli/config/platform-client.js +0 -248
- package/dist/cli/env-setup.js +0 -12
- package/dist/cli/index.js +0 -850
- package/dist/cli/pack-commands.js +0 -122
- package/dist/cli/postinstall.d.ts +0 -16
- package/dist/cli/postinstall.js +0 -119
- package/dist/cli/templates/ai/mock-provider.js +0 -64
- package/dist/cli/templates/ai/types.js +0 -5
- package/dist/cli/templates/approvals/index.d.ts +0 -15
- package/dist/cli/templates/approvals/index.js +0 -241
- package/dist/cli/templates/index.js +0 -123
- package/dist/cli/templates/nodes/agent-router.js +0 -114
- package/dist/cli/templates/nodes/aggregator.js +0 -63
- package/dist/cli/templates/nodes/conversation-memory.js +0 -85
- package/dist/cli/templates/nodes/http.js +0 -80
- package/dist/cli/templates/nodes/human-approval.js +0 -109
- package/dist/cli/templates/nodes/json-extractor.js +0 -119
- package/dist/cli/templates/nodes/llm-call.js +0 -106
- package/dist/cli/templates/nodes/prompt-template.js +0 -52
- package/dist/cli/templates/nodes/rag-retriever.js +0 -128
- package/dist/cli/templates/nodes/tool-executor.js +0 -108
- package/dist/cli/templates/nodes/transformer.js +0 -68
- package/dist/cli/templates/nodes/validator.js +0 -62
- package/dist/cli/templates/pack-loader.js +0 -58
- package/dist/cli/templates/providers/index.js +0 -239
- package/dist/cli/templates/shared/approval-types.js +0 -31
- package/dist/cli/templates/shared/llm-types.js +0 -109
- package/dist/cli/templates/workflows/aggregator.js +0 -101
- package/dist/cli/templates/workflows/ai-agent.js +0 -326
- package/dist/cli/templates/workflows/ai-chat.js +0 -167
- package/dist/cli/templates/workflows/ai-rag.js +0 -184
- package/dist/cli/templates/workflows/ai-react.js +0 -293
- package/dist/cli/templates/workflows/conditional.js +0 -139
- package/dist/cli/templates/workflows/error-handler.js +0 -145
- package/dist/cli/templates/workflows/foreach.js +0 -140
- package/dist/cli/templates/workflows/sequential.js +0 -200
- package/dist/cli/templates/workflows/webhook.js +0 -158
- package/dist/cli/utils/cli-helpers.d.ts +0 -44
- package/dist/cli/utils/cli-helpers.js +0 -99
- package/dist/cli/utils/logger.js +0 -126
- package/dist/cli/utils/parse-int-strict.js +0 -17
- package/dist/cli/utils/safe-write.js +0 -54
- package/dist/deployment/config/defaults.d.ts +0 -29
- package/dist/deployment/config/defaults.js +0 -98
- package/dist/deployment/config/loader.d.ts +0 -24
- package/dist/deployment/config/loader.js +0 -237
- package/dist/deployment/config/types.d.ts +0 -117
- package/dist/deployment/config/types.js +0 -5
- package/dist/deployment/core/adapters.d.ts +0 -66
- package/dist/deployment/core/adapters.js +0 -156
- package/dist/deployment/core/executor.d.ts +0 -62
- package/dist/deployment/core/executor.js +0 -197
- package/dist/deployment/core/formatters.d.ts +0 -42
- package/dist/deployment/core/formatters.js +0 -146
- package/dist/deployment/openapi/generator.d.ts +0 -146
- package/dist/deployment/openapi/generator.js +0 -347
- package/dist/deployment/openapi/schema-converter.d.ts +0 -49
- package/dist/deployment/openapi/schema-converter.js +0 -192
- package/dist/deployment/targets/base.js +0 -855
- package/dist/deployment/types.d.ts +0 -140
- package/dist/deployment/types.js +0 -8
- package/dist/diagram/ascii-renderer.js +0 -528
- package/dist/diagram/geometry.js +0 -1267
- package/dist/diagram/html-viewer.d.ts +0 -21
- package/dist/diagram/html-viewer.js +0 -1689
- package/dist/diagram/layout.js +0 -143
- package/dist/diagram/orthogonal-router.js +0 -568
- package/dist/diagram/renderer.d.ts +0 -3
- package/dist/diagram/renderer.js +0 -266
- package/dist/diagram/theme.js +0 -282
- package/dist/diagram/types.js +0 -2
- package/dist/diff/WorkflowDiffer.js +0 -429
- package/dist/diff/formatDiff.js +0 -239
- package/dist/diff/impact.js +0 -119
- package/dist/diff/types.js +0 -35
- package/dist/doc-metadata/extractors/annotations.js +0 -638
- package/dist/doc-metadata/extractors/cli-commands.js +0 -326
- package/dist/doc-metadata/extractors/core-metadata.js +0 -61
- package/dist/doc-metadata/extractors/error-codes.js +0 -372
- package/dist/doc-metadata/extractors/grammar-rules.js +0 -51
- package/dist/doc-metadata/extractors/mcp-tools.js +0 -705
- package/dist/doc-metadata/extractors/plugin-api.d.ts +0 -19
- package/dist/doc-metadata/extractors/plugin-api.js +0 -279
- package/dist/doc-metadata/types.js +0 -5
- package/dist/editor-completions/annotationValues.js +0 -146
- package/dist/editor-completions/contextParser.js +0 -410
- package/dist/editor-completions/dataTypes.js +0 -95
- package/dist/editor-completions/goToDefinition.js +0 -112
- package/dist/editor-completions/jsDocAnnotations.js +0 -359
- package/dist/editor-completions/modifierCompletions.js +0 -197
- package/dist/editor-completions/types.js +0 -8
- package/dist/export/index.js +0 -212
- package/dist/extensions/index.d.ts +0 -16
- package/dist/extensions/index.js +0 -17
- package/dist/friendly-errors.js +0 -761
- package/dist/function-like.js +0 -84
- package/dist/generator/async-detection.js +0 -56
- package/dist/generator/code-utils.js +0 -551
- package/dist/generator/compile-target-registry.d.ts +0 -20
- package/dist/generator/compile-target-registry.js +0 -20
- package/dist/generator/control-flow.js +0 -358
- package/dist/generator/dev-mode-registry.d.ts +0 -27
- package/dist/generator/dev-mode-registry.js +0 -20
- package/dist/generator/scope-function-generator.js +0 -397
- package/dist/generator/unified.js +0 -1831
- package/dist/generator.d.ts +0 -54
- package/dist/generator.js +0 -101
- package/dist/jsdoc-parser.d.ts +0 -377
- package/dist/jsdoc-parser.js +0 -1189
- package/dist/jsdoc-port-sync/constants.js +0 -103
- package/dist/jsdoc-port-sync/diff.js +0 -319
- package/dist/jsdoc-port-sync/port-parser.js +0 -579
- package/dist/jsdoc-port-sync/rename.js +0 -256
- package/dist/jsdoc-port-sync/signature-parser.js +0 -559
- package/dist/jsdoc-port-sync/sync.js +0 -653
- package/dist/marketplace/manifest.js +0 -194
- package/dist/marketplace/registry.js +0 -198
- package/dist/marketplace/types.js +0 -9
- package/dist/marketplace/validator.js +0 -150
- package/dist/mcp/agent-channel.d.ts +0 -35
- package/dist/mcp/agent-channel.js +0 -61
- package/dist/mcp/auto-registration.d.ts +0 -3
- package/dist/mcp/auto-registration.js +0 -62
- package/dist/mcp/debug-session.js +0 -25
- package/dist/mcp/index.d.ts +0 -11
- package/dist/mcp/index.js +0 -10
- package/dist/mcp/pack-tools.js +0 -59
- package/dist/mcp/prompts.js +0 -68
- package/dist/mcp/response-utils.js +0 -97
- package/dist/mcp/run-registry.d.ts +0 -29
- package/dist/mcp/run-registry.js +0 -24
- package/dist/mcp/server.js +0 -63
- package/dist/mcp/tools-context.js +0 -51
- package/dist/mcp/tools-debug.js +0 -451
- package/dist/mcp/tools-diagram.js +0 -97
- package/dist/mcp/tools-docs.js +0 -62
- package/dist/mcp/tools-export.js +0 -222
- package/dist/mcp/tools-marketplace.js +0 -132
- package/dist/mcp/tools-model.d.ts +0 -3
- package/dist/mcp/tools-model.js +0 -279
- package/dist/mcp/tools-pattern.d.ts +0 -3
- package/dist/mcp/tools-pattern.js +0 -604
- package/dist/mcp/tools-query.js +0 -377
- package/dist/mcp/tools-resources.js +0 -41
- package/dist/mcp/tools-template.js +0 -119
- package/dist/mcp/tools-workflow-run.d.ts +0 -40
- package/dist/mcp/tools-workflow-run.js +0 -150
- package/dist/mcp/types.js +0 -2
- package/dist/mcp/workflow-executor.js +0 -242
- package/dist/migration/registry.js +0 -29
- package/dist/node-types-generator.js +0 -139
- package/dist/parser/tag-registry.js +0 -57
- package/dist/parser.d.ts +0 -232
- package/dist/parser.js +0 -2500
- package/dist/plugin/PluginPanel.d.ts +0 -12
- package/dist/plugin/PluginPanel.js +0 -5
- package/dist/plugin/index.d.ts +0 -13
- package/dist/plugin/index.js +0 -14
- package/dist/plugin/types.d.ts +0 -75
- package/dist/plugin/types.js +0 -8
- package/dist/resolve-package-types.js +0 -123
- package/dist/runtime/CancellationError.js +0 -20
- package/dist/runtime/ExecutionContext.js +0 -280
- package/dist/runtime/builtin-functions.js +0 -549
- package/dist/runtime/checkpoint.d.ts +0 -84
- package/dist/runtime/checkpoint.js +0 -225
- package/dist/runtime/debug-controller.js +0 -247
- package/dist/runtime/events.js +0 -2
- package/dist/runtime/function-registry.js +0 -66
- package/dist/runtime/parameter-resolver.js +0 -113
- package/dist/server/types.js +0 -5
- package/dist/server/webhook-server.js +0 -269
- package/dist/server/workflow-registry.js +0 -202
- package/dist/shared-project.js +0 -28
- package/dist/sugar-optimizer.js +0 -498
- package/dist/testing/assertions.js +0 -127
- package/dist/testing/mock-approval.js +0 -98
- package/dist/testing/mock-llm.js +0 -119
- package/dist/testing/recorder.js +0 -70
- package/dist/testing/replayer.js +0 -143
- package/dist/testing/token-tracker.js +0 -94
- package/dist/type-checker.d.ts +0 -42
- package/dist/type-checker.js +0 -190
- package/dist/type-mappings.js +0 -131
- package/dist/types/branded-ports.d.ts +0 -151
- package/dist/types/branded-ports.js +0 -121
- package/dist/types/index.d.ts +0 -5
- package/dist/types/index.js +0 -5
- package/dist/types.d.ts +0 -139
- package/dist/types.js +0 -15
- package/dist/utils/error-utils.js +0 -27
- package/dist/utils/lru-cache.js +0 -40
- package/dist/utils/port-ordering.js +0 -81
- package/dist/utils/port-tag-utils.js +0 -41
- package/dist/utils/string-distance.js +0 -56
- package/dist/validation/agent-detection.js +0 -115
- package/dist/validation/agent-rules.js +0 -262
- package/dist/validation/design-rules.js +0 -377
- package/dist/validation/rule-registry.js +0 -37
- package/dist/validator.d.ts +0 -113
- package/dist/validator.js +0 -1631
- package/docs/reference/patterns.md +0 -159
- package/scripts/postinstall.cjs +0 -86
- /package/dist/{shared-project.d.ts → parser/shared-project.d.ts} +0 -0
- /package/dist/{friendly-errors.d.ts → validation/friendly-errors.d.ts} +0 -0
|
@@ -1,1689 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* HTML Viewer — wraps an SVG diagram in a self-contained interactive HTML page.
|
|
3
|
-
*
|
|
4
|
-
* The SVG element itself is the canvas: zoom and pan are driven by viewBox
|
|
5
|
-
* manipulation, so nodes can be dragged anywhere without hitting a boundary.
|
|
6
|
-
* No external dependencies — works standalone or inside an iframe.
|
|
7
|
-
*/
|
|
8
|
-
/**
|
|
9
|
-
* Extract inner SVG content and viewBox from the rendered SVG string.
|
|
10
|
-
* Strips backgrounds, dot grid, and watermark (the viewer provides its own).
|
|
11
|
-
*/
|
|
12
|
-
function prepareSvgContent(svg) {
|
|
13
|
-
const vbMatch = svg.match(/viewBox="([^"]+)"/);
|
|
14
|
-
const viewBox = vbMatch ? vbMatch[1] : '0 0 800 600';
|
|
15
|
-
// Strip the outer <svg> wrapper — we inline content into the canvas SVG
|
|
16
|
-
let inner = svg.replace(/<svg[^>]*>\n?/, '').replace(/<\/svg>\s*$/, '');
|
|
17
|
-
// Remove dot-grid pattern and its fill rect (viewer uses its own)
|
|
18
|
-
inner = inner.replace(/<pattern\s+id="dot-grid"[^>]*>[\s\S]*?<\/pattern>/g, '');
|
|
19
|
-
inner = inner.replace(/<rect[^>]*fill="url\(#dot-grid\)"[^>]*\/>/g, '');
|
|
20
|
-
// Remove solid background rect (first rect after </defs>)
|
|
21
|
-
inner = inner.replace(/(<\/defs>\n)<rect[^>]*\/>\n/, '$1');
|
|
22
|
-
// Remove watermark (HTML viewer has its own branding badge)
|
|
23
|
-
inner = inner.replace(/<g opacity="0\.5">[\s\S]*?Flow Weaver<\/text>\s*<\/g>/, '');
|
|
24
|
-
return { inner, viewBox };
|
|
25
|
-
}
|
|
26
|
-
export function wrapSVGInHTML(svgContent, options = {}) {
|
|
27
|
-
const title = options.title ?? 'Workflow Diagram';
|
|
28
|
-
const theme = options.theme ?? 'dark';
|
|
29
|
-
const { inner, viewBox } = prepareSvgContent(svgContent);
|
|
30
|
-
const isDark = theme === 'dark';
|
|
31
|
-
const bg = isDark ? '#202139' : '#f6f7ff';
|
|
32
|
-
const dotColor = isDark ? 'rgba(142, 158, 255, 0.5)' : 'rgba(84, 104, 255, 0.45)';
|
|
33
|
-
const surfaceMain = isDark ? '#1a1a2e' : '#ffffff';
|
|
34
|
-
const borderSubtle = isDark ? '#313143' : '#e6e6e6';
|
|
35
|
-
const textHigh = isDark ? '#e8e8ee' : '#1a1a2e';
|
|
36
|
-
const textMed = isDark ? '#babac0' : '#606060';
|
|
37
|
-
const textLow = isDark ? '#767682' : '#999999';
|
|
38
|
-
const surfaceHigh = isDark ? '#313143' : '#f0f0f5';
|
|
39
|
-
const brandAccent = isDark ? '#8e9eff' : '#5468ff';
|
|
40
|
-
return `<!DOCTYPE html>
|
|
41
|
-
<html lang="en">
|
|
42
|
-
<head>
|
|
43
|
-
<meta charset="utf-8">
|
|
44
|
-
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
45
|
-
<title>${escapeHtml(title)} — Flow Weaver</title>
|
|
46
|
-
<style>
|
|
47
|
-
*, *::before, *::after { margin: 0; padding: 0; box-sizing: border-box; }
|
|
48
|
-
|
|
49
|
-
body {
|
|
50
|
-
width: 100vw; height: 100vh; overflow: hidden;
|
|
51
|
-
font-family: Montserrat, 'Segoe UI', Roboto, sans-serif;
|
|
52
|
-
color: ${textHigh};
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
#canvas {
|
|
56
|
-
display: block; width: 100%; height: 100%;
|
|
57
|
-
cursor: grab;
|
|
58
|
-
touch-action: none; user-select: none;
|
|
59
|
-
}
|
|
60
|
-
#canvas.dragging { cursor: grabbing; }
|
|
61
|
-
|
|
62
|
-
/* Port labels: hidden by default, shown on node hover */
|
|
63
|
-
.nodes > g .port-label,
|
|
64
|
-
.nodes > g .port-type-label,
|
|
65
|
-
.labels g[data-port-label] {
|
|
66
|
-
opacity: 0; pointer-events: none;
|
|
67
|
-
transition: opacity 0.15s ease-in-out;
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
/* Connection hover & dimming (covers paths + stub lines) */
|
|
71
|
-
[data-source] { transition: opacity 0.2s ease, stroke-width 0.15s ease; }
|
|
72
|
-
[data-source]:hover { stroke-width: 4; cursor: pointer; }
|
|
73
|
-
body.node-active [data-source].dimmed,
|
|
74
|
-
body.port-active [data-source].dimmed { opacity: 0.1; }
|
|
75
|
-
body.port-hovered [data-source].dimmed { opacity: 0.25; }
|
|
76
|
-
|
|
77
|
-
/* Port circles are interactive */
|
|
78
|
-
circle[data-port-id] { cursor: pointer; }
|
|
79
|
-
circle[data-port-id]:hover { stroke-width: 3; filter: brightness(1.3); }
|
|
80
|
-
|
|
81
|
-
/* Port-click highlighting */
|
|
82
|
-
[data-source].highlighted { opacity: 1; }
|
|
83
|
-
circle[data-port-id].port-selected { filter: drop-shadow(0 0 6px currentColor); stroke-width: 4; }
|
|
84
|
-
|
|
85
|
-
/* Node selection glow */
|
|
86
|
-
@keyframes select-pop {
|
|
87
|
-
0% { opacity: 0; stroke-width: 0; }
|
|
88
|
-
50% { opacity: 0.6; stroke-width: 12; }
|
|
89
|
-
100% { opacity: 0.35; stroke-width: 8; }
|
|
90
|
-
}
|
|
91
|
-
.node-glow { fill: none; pointer-events: none; animation: select-pop 0.3s ease-out forwards; }
|
|
92
|
-
|
|
93
|
-
/* Port hover path highlight */
|
|
94
|
-
[data-source].port-hover { opacity: 1; }
|
|
95
|
-
|
|
96
|
-
/* Node hover glow + draggable cursor */
|
|
97
|
-
.nodes g[data-node-id] { cursor: grab; }
|
|
98
|
-
.nodes g[data-node-id]:active { cursor: grabbing; }
|
|
99
|
-
.nodes g[data-node-id]:hover > rect:first-of-type {
|
|
100
|
-
filter: brightness(1.08) drop-shadow(0 0 6px ${isDark ? 'rgba(142,158,255,0.15)' : 'rgba(84,104,255,0.12)'});
|
|
101
|
-
transition: filter 0.15s ease;
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
/* Zoom controls */
|
|
105
|
-
#controls {
|
|
106
|
-
position: fixed; bottom: 16px; right: 16px;
|
|
107
|
-
display: flex; align-items: center; gap: 2px;
|
|
108
|
-
background: ${isDark ? 'rgba(26,26,46,0.85)' : 'rgba(255,255,255,0.85)'};
|
|
109
|
-
backdrop-filter: blur(8px); -webkit-backdrop-filter: blur(8px);
|
|
110
|
-
border: 1px solid ${isDark ? 'rgba(142,158,255,0.12)' : 'rgba(84,104,255,0.1)'};
|
|
111
|
-
border-radius: 8px; padding: 4px; z-index: 10;
|
|
112
|
-
}
|
|
113
|
-
.ctrl-btn {
|
|
114
|
-
display: flex; align-items: center; justify-content: center;
|
|
115
|
-
width: 28px; height: 28px; border: none; border-radius: 6px;
|
|
116
|
-
background: transparent; color: ${textMed};
|
|
117
|
-
font-size: 16px; font-weight: 600; cursor: pointer;
|
|
118
|
-
transition: background 0.15s, color 0.15s;
|
|
119
|
-
}
|
|
120
|
-
.ctrl-btn:hover { background: ${isDark ? 'rgba(142,158,255,0.08)' : 'rgba(84,104,255,0.06)'}; color: ${textHigh}; }
|
|
121
|
-
#zoom-label {
|
|
122
|
-
font-size: 11px; font-family: 'SF Mono', 'Fira Code', monospace;
|
|
123
|
-
color: ${textLow}; min-width: 36px; text-align: center;
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
/* Info panel */
|
|
127
|
-
@keyframes panelSlideIn { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: translateY(0); } }
|
|
128
|
-
#info-panel {
|
|
129
|
-
position: fixed; bottom: 52px; left: 16px;
|
|
130
|
-
max-width: 480px; min-width: 260px;
|
|
131
|
-
background: ${isDark ? 'rgba(26,26,46,0.85)' : 'rgba(255,255,255,0.85)'};
|
|
132
|
-
backdrop-filter: blur(8px); -webkit-backdrop-filter: blur(8px);
|
|
133
|
-
border: 1px solid ${isDark ? 'rgba(142,158,255,0.12)' : 'rgba(84,104,255,0.1)'};
|
|
134
|
-
border-radius: 8px; padding: 0;
|
|
135
|
-
font-size: 13px; line-height: 1.5;
|
|
136
|
-
z-index: 10; display: none;
|
|
137
|
-
max-height: calc(100vh - 120px); overflow: hidden;
|
|
138
|
-
}
|
|
139
|
-
#info-panel.visible { display: block; animation: panelSlideIn 0.2s ease-out; }
|
|
140
|
-
#info-panel h3 {
|
|
141
|
-
font-size: 14px; font-weight: 700; margin: 0;
|
|
142
|
-
white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
|
|
143
|
-
}
|
|
144
|
-
#info-panel .node-desc { color: ${textMed}; font-size: 12px; margin-bottom: 8px; font-style: italic; }
|
|
145
|
-
#info-panel .info-section { margin-bottom: 6px; }
|
|
146
|
-
#info-panel .info-label { font-size: 11px; font-weight: 600; color: ${textLow}; text-transform: uppercase; letter-spacing: 0.5px; }
|
|
147
|
-
#info-panel .info-value { color: ${textMed}; }
|
|
148
|
-
#info-panel .port-list { list-style: none; padding: 0; display: flex; flex-direction: column; gap: 2px; }
|
|
149
|
-
#info-panel .port-list li { padding: 2px 0; display: flex; align-items: center; gap: 6px; }
|
|
150
|
-
#info-panel .port-list li::before { content: '\\2022'; color: ${textLow}; flex-shrink: 0; }
|
|
151
|
-
#info-panel .port-type { color: ${textLow}; font-size: 11px; font-family: 'SF Mono', 'Fira Code', 'Consolas', monospace; }
|
|
152
|
-
#info-panel pre {
|
|
153
|
-
background: ${isDark ? '#161625' : '#f0f1fa'}; border: 1px solid ${borderSubtle};
|
|
154
|
-
border-radius: 6px; padding: 10px; overflow-x: auto;
|
|
155
|
-
font-family: 'SF Mono', 'Fira Code', 'Consolas', monospace;
|
|
156
|
-
font-size: 12px; line-height: 1.6; white-space: pre;
|
|
157
|
-
max-height: 300px; overflow-y: auto; margin: 6px 0 0;
|
|
158
|
-
color: ${isDark ? '#e6edf3' : '#1a2340'};
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
/* Custom scrollbars */
|
|
162
|
-
::-webkit-scrollbar { width: 6px; height: 6px; }
|
|
163
|
-
::-webkit-scrollbar-track { background: transparent; }
|
|
164
|
-
::-webkit-scrollbar-thumb { background: ${isDark ? 'rgba(142,158,255,0.25)' : 'rgba(84,104,255,0.2)'}; border-radius: 3px; }
|
|
165
|
-
::-webkit-scrollbar-thumb:hover { background: ${isDark ? 'rgba(142,158,255,0.45)' : 'rgba(84,104,255,0.4)'}; }
|
|
166
|
-
::-webkit-scrollbar-corner { background: transparent; }
|
|
167
|
-
* { scrollbar-width: thin; scrollbar-color: ${isDark ? 'rgba(142,158,255,0.25)' : 'rgba(84,104,255,0.2)'} transparent; }
|
|
168
|
-
|
|
169
|
-
/* Info panel header */
|
|
170
|
-
#info-header {
|
|
171
|
-
display: flex; align-items: center; gap: 6px; padding: 12px 16px;
|
|
172
|
-
border-bottom: 1px solid ${isDark ? 'rgba(142,158,255,0.08)' : 'rgba(84,104,255,0.06)'};
|
|
173
|
-
}
|
|
174
|
-
#info-header h3 { flex: 1; margin-bottom: 0; }
|
|
175
|
-
#info-body { padding: 12px 16px; overflow-y: auto; max-height: calc(100vh - 180px); }
|
|
176
|
-
.panel-btn {
|
|
177
|
-
display: flex; align-items: center; justify-content: center;
|
|
178
|
-
width: 24px; height: 24px; border: none; border-radius: 4px;
|
|
179
|
-
background: transparent; color: ${textLow};
|
|
180
|
-
cursor: pointer; transition: background 0.15s, color 0.15s;
|
|
181
|
-
flex-shrink: 0;
|
|
182
|
-
}
|
|
183
|
-
.panel-btn:hover { background: ${surfaceHigh}; color: ${textHigh}; }
|
|
184
|
-
|
|
185
|
-
/* Info panel fullscreen transitions */
|
|
186
|
-
#info-panel.fullscreen {
|
|
187
|
-
left: 16px; bottom: 16px; top: 16px; right: 16px;
|
|
188
|
-
max-width: none; min-width: 0; width: auto; max-height: none;
|
|
189
|
-
border-radius: 12px;
|
|
190
|
-
}
|
|
191
|
-
#info-panel.fullscreen pre { max-height: none; }
|
|
192
|
-
.hl-kw { color: ${isDark ? '#8e9eff' : '#4040bf'}; }
|
|
193
|
-
.hl-str { color: ${isDark ? '#ff7b72' : '#c4432b'}; }
|
|
194
|
-
.hl-num { color: ${isDark ? '#f0a050' : '#b35e14'}; }
|
|
195
|
-
.hl-cm { color: #6a737d; font-style: italic; }
|
|
196
|
-
.hl-fn { color: ${isDark ? '#d2a8ff' : '#7c3aed'}; }
|
|
197
|
-
.hl-ty { color: ${isDark ? '#d2a8ff' : '#7c3aed'}; }
|
|
198
|
-
.hl-pn { color: ${isDark ? '#b8bdd0' : '#4a5578'}; }
|
|
199
|
-
.hl-ann { color: ${isDark ? '#8e9eff' : '#4040bf'}; font-weight: 600; font-style: normal; }
|
|
200
|
-
.hl-arr { color: ${isDark ? '#79c0ff' : '#0969da'}; font-weight: 600; font-style: normal; }
|
|
201
|
-
.hl-id { color: ${isDark ? '#e6edf3' : '#1a2340'}; font-style: normal; }
|
|
202
|
-
.hl-sc { color: ${isDark ? '#d2a8ff' : '#7c3aed'}; font-style: italic; }
|
|
203
|
-
|
|
204
|
-
/* Branding badge */
|
|
205
|
-
#branding {
|
|
206
|
-
position: fixed; bottom: 16px; left: 16px;
|
|
207
|
-
display: flex; align-items: center; gap: 6px;
|
|
208
|
-
background: ${isDark ? 'rgba(26,26,46,0.85)' : 'rgba(255,255,255,0.85)'};
|
|
209
|
-
backdrop-filter: blur(8px); -webkit-backdrop-filter: blur(8px);
|
|
210
|
-
border: 1px solid ${isDark ? 'rgba(142,158,255,0.12)' : 'rgba(84,104,255,0.1)'};
|
|
211
|
-
border-radius: 8px; padding: 6px 12px;
|
|
212
|
-
font-size: 12px; font-weight: 600; color: ${textMed};
|
|
213
|
-
text-decoration: none; z-index: 9;
|
|
214
|
-
transition: color 0.15s, border-color 0.15s;
|
|
215
|
-
}
|
|
216
|
-
#branding:hover { color: ${textHigh}; border-color: ${textLow}; }
|
|
217
|
-
|
|
218
|
-
/* Scroll hint */
|
|
219
|
-
@keyframes hintFade { 0% { opacity: 1; } 80% { opacity: 1; } 100% { opacity: 0; } }
|
|
220
|
-
#scroll-hint {
|
|
221
|
-
position: fixed; top: 50%; left: 50%;
|
|
222
|
-
transform: translate(-50%, -50%);
|
|
223
|
-
background: ${isDark ? 'rgba(26,26,46,0.92)' : 'rgba(255,255,255,0.92)'};
|
|
224
|
-
backdrop-filter: blur(8px); -webkit-backdrop-filter: blur(8px);
|
|
225
|
-
border: 1px solid ${isDark ? 'rgba(142,158,255,0.12)' : 'rgba(84,104,255,0.1)'};
|
|
226
|
-
color: ${textHigh};
|
|
227
|
-
padding: 6px 14px; border-radius: 8px;
|
|
228
|
-
font-size: 13px; pointer-events: none;
|
|
229
|
-
z-index: 20; opacity: 0; transition: opacity 0.3s;
|
|
230
|
-
}
|
|
231
|
-
#scroll-hint.visible { opacity: 1; }
|
|
232
|
-
#scroll-hint kbd {
|
|
233
|
-
display: inline-block; padding: 1px 5px;
|
|
234
|
-
border: 1px solid ${isDark ? 'rgba(255,255,255,0.15)' : 'rgba(0,0,0,0.15)'};
|
|
235
|
-
border-radius: 3px; font-family: 'SF Mono', 'Fira Code', monospace;
|
|
236
|
-
font-size: 12px; background: ${isDark ? 'rgba(255,255,255,0.06)' : 'rgba(0,0,0,0.04)'};
|
|
237
|
-
}
|
|
238
|
-
|
|
239
|
-
/* Studio nudge toast */
|
|
240
|
-
#studio-hint {
|
|
241
|
-
position: fixed; bottom: 60px; left: 50%;
|
|
242
|
-
transform: translateX(-50%);
|
|
243
|
-
background: ${isDark ? 'rgba(26,26,46,0.85)' : 'rgba(255,255,255,0.85)'};
|
|
244
|
-
backdrop-filter: blur(8px); -webkit-backdrop-filter: blur(8px);
|
|
245
|
-
border: 1px solid ${isDark ? 'rgba(142,158,255,0.12)' : 'rgba(84,104,255,0.1)'};
|
|
246
|
-
padding: 8px 16px; border-radius: 8px;
|
|
247
|
-
font-size: 13px; color: ${textMed};
|
|
248
|
-
z-index: 20; opacity: 0; transition: opacity 0.4s;
|
|
249
|
-
pointer-events: none;
|
|
250
|
-
}
|
|
251
|
-
#studio-hint.visible { opacity: 1; pointer-events: auto; }
|
|
252
|
-
#studio-hint a { color: ${brandAccent}; text-decoration: none; font-weight: 600; }
|
|
253
|
-
#studio-hint a:hover { text-decoration: underline; }
|
|
254
|
-
|
|
255
|
-
/* Reduced motion */
|
|
256
|
-
@media (prefers-reduced-motion: reduce) {
|
|
257
|
-
.node-glow { animation: none; opacity: 0.35; stroke-width: 8; }
|
|
258
|
-
#info-panel { animation: none; }
|
|
259
|
-
* { transition-duration: 0s !important; }
|
|
260
|
-
}
|
|
261
|
-
|
|
262
|
-
/* Responsive: mobile */
|
|
263
|
-
@media (max-width: 768px) {
|
|
264
|
-
#controls { bottom: 12px; right: 12px; padding: 3px; }
|
|
265
|
-
.ctrl-btn { width: 24px; height: 24px; font-size: 14px; }
|
|
266
|
-
#zoom-label { font-size: 10px; min-width: 30px; }
|
|
267
|
-
#branding { bottom: 12px; left: 12px; padding: 4px 8px; font-size: 11px; }
|
|
268
|
-
#studio-hint { max-width: 90vw; text-align: center; white-space: normal; }
|
|
269
|
-
#info-panel {
|
|
270
|
-
left: 0 !important; right: 0 !important; bottom: 0 !important;
|
|
271
|
-
max-width: none; min-width: 0; width: 100%;
|
|
272
|
-
border-radius: 12px 12px 0 0;
|
|
273
|
-
max-height: 60vh;
|
|
274
|
-
}
|
|
275
|
-
#info-panel::before {
|
|
276
|
-
content: ''; display: block; width: 32px; height: 4px;
|
|
277
|
-
background: ${isDark ? 'rgba(142,158,255,0.3)' : 'rgba(84,104,255,0.2)'};
|
|
278
|
-
border-radius: 2px; margin: 8px auto 4px;
|
|
279
|
-
}
|
|
280
|
-
#info-body { max-height: calc(60vh - 80px); }
|
|
281
|
-
}
|
|
282
|
-
</style>
|
|
283
|
-
</head>
|
|
284
|
-
<body>
|
|
285
|
-
<svg id="canvas" xmlns="http://www.w3.org/2000/svg" viewBox="${viewBox}">
|
|
286
|
-
<defs>
|
|
287
|
-
<pattern id="viewer-dots" width="20" height="20" patternUnits="userSpaceOnUse">
|
|
288
|
-
<circle cx="10" cy="10" r="1.5" fill="${dotColor}" opacity="0.6"/>
|
|
289
|
-
</pattern>
|
|
290
|
-
</defs>
|
|
291
|
-
<rect x="-100000" y="-100000" width="200000" height="200000" fill="${bg}" pointer-events="none"/>
|
|
292
|
-
<rect x="-100000" y="-100000" width="200000" height="200000" fill="url(#viewer-dots)" pointer-events="none"/>
|
|
293
|
-
<g id="diagram">${inner}</g>
|
|
294
|
-
</svg>
|
|
295
|
-
<div id="controls">
|
|
296
|
-
<button class="ctrl-btn" id="btn-in" title="Zoom in" aria-label="Zoom in">+</button>
|
|
297
|
-
<span id="zoom-label">100%</span>
|
|
298
|
-
<button class="ctrl-btn" id="btn-out" title="Zoom out" aria-label="Zoom out">−</button>
|
|
299
|
-
<button class="ctrl-btn" id="btn-fit" title="Fit to view" aria-label="Fit to view">
|
|
300
|
-
<svg width="14" height="14" viewBox="0 0 14 14" fill="none" stroke="currentColor" stroke-width="1.5">
|
|
301
|
-
<rect x="1" y="1" width="12" height="12" rx="2"/>
|
|
302
|
-
<path d="M1 5h12M1 9h12M5 1v12M9 1v12" opacity="0.4"/>
|
|
303
|
-
</svg>
|
|
304
|
-
</button>
|
|
305
|
-
<button class="ctrl-btn" id="btn-reset" title="Reset layout" aria-label="Reset layout">
|
|
306
|
-
<svg width="14" height="14" viewBox="0 0 14 14" fill="none" stroke="currentColor" stroke-width="1.5">
|
|
307
|
-
<path d="M1.5 2v3.5h3.5"/>
|
|
308
|
-
<path d="M2.1 8.5a5 5 0 1 0 .9-4L1.5 5.5"/>
|
|
309
|
-
</svg>
|
|
310
|
-
</button>
|
|
311
|
-
</div>
|
|
312
|
-
<div id="info-panel">
|
|
313
|
-
<div id="info-header">
|
|
314
|
-
<h3 id="info-title"></h3>
|
|
315
|
-
<button class="panel-btn" id="btn-expand" title="Expand panel" aria-label="Expand panel">
|
|
316
|
-
<svg width="14" height="14" viewBox="0 0 14 14" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round">
|
|
317
|
-
<path d="M1 5V1h4M9 1h4v4M13 9v4H9M5 13H1V9"/>
|
|
318
|
-
</svg>
|
|
319
|
-
</button>
|
|
320
|
-
<button class="panel-btn" id="btn-close-panel" title="Close panel" aria-label="Close panel">
|
|
321
|
-
<svg width="14" height="14" viewBox="0 0 14 14" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round">
|
|
322
|
-
<path d="M2 2l10 10M12 2L2 12"/>
|
|
323
|
-
</svg>
|
|
324
|
-
</button>
|
|
325
|
-
</div>
|
|
326
|
-
<div id="info-body"></div>
|
|
327
|
-
</div>
|
|
328
|
-
<a id="branding" href="https://flowweaver.ai" target="_blank" rel="noopener">
|
|
329
|
-
<svg width="16" height="16" viewBox="0 0 256 256" fill="none"><path d="M80 128C134 128 122 49 176 49" stroke="${brandAccent}" stroke-width="14" stroke-linecap="round"/><path d="M80 128C134 128 122 207 176 207" stroke="${brandAccent}" stroke-width="14" stroke-linecap="round"/><rect x="28" y="102" width="52" height="52" rx="10" stroke="${brandAccent}" stroke-width="14"/><rect x="176" y="23" width="52" height="52" rx="10" stroke="${brandAccent}" stroke-width="14"/><rect x="176" y="181" width="52" height="52" rx="10" stroke="${brandAccent}" stroke-width="14"/></svg>
|
|
330
|
-
<span>Flow Weaver</span>
|
|
331
|
-
</a>
|
|
332
|
-
<div id="scroll-hint">Use <kbd id="mod-key">Ctrl</kbd> + scroll to zoom</div>
|
|
333
|
-
<div id="studio-hint">Like rearranging? <a href="https://flowweaver.ai" target="_blank" rel="noopener">Flow Weaver Studio</a> saves your layouts.</div>
|
|
334
|
-
<script>var nodeSources = ${JSON.stringify(options.nodeSources ?? {})};</script>
|
|
335
|
-
<script>
|
|
336
|
-
(function() {
|
|
337
|
-
'use strict';
|
|
338
|
-
|
|
339
|
-
var MIN_ZOOM = 0.25, MAX_ZOOM = 3;
|
|
340
|
-
var canvas = document.getElementById('canvas');
|
|
341
|
-
var content = document.getElementById('diagram');
|
|
342
|
-
var zoomLabel = document.getElementById('zoom-label');
|
|
343
|
-
var infoPanel = document.getElementById('info-panel');
|
|
344
|
-
var infoTitle = document.getElementById('info-title');
|
|
345
|
-
var infoBody = document.getElementById('info-body');
|
|
346
|
-
var btnExpand = document.getElementById('btn-expand');
|
|
347
|
-
var btnClosePanel = document.getElementById('btn-close-panel');
|
|
348
|
-
var scrollHint = document.getElementById('scroll-hint');
|
|
349
|
-
var studioHint = document.getElementById('studio-hint');
|
|
350
|
-
var expandIcon = '<svg width="14" height="14" viewBox="0 0 14 14" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"><path d="M1 5V1h4M9 1h4v4M13 9v4H9M5 13H1V9"/></svg>';
|
|
351
|
-
var collapseIcon = '<svg width="14" height="14" viewBox="0 0 14 14" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"><path d="M5 1v4H1M13 5H9V1M9 13V9h4M1 9h4v4"/></svg>';
|
|
352
|
-
|
|
353
|
-
// Parse the original viewBox (diagram bounding box)
|
|
354
|
-
var vbParts = '${viewBox}'.split(/\\s+/).map(Number);
|
|
355
|
-
var origX = vbParts[0], origY = vbParts[1], origW = vbParts[2], origH = vbParts[3];
|
|
356
|
-
var vbX = origX, vbY = origY, vbW = origW, vbH = origH;
|
|
357
|
-
var baseW = origW; // reference width for 100% zoom
|
|
358
|
-
|
|
359
|
-
var pointerDown = false, didDrag = false, dragLast = { x: 0, y: 0 };
|
|
360
|
-
var selectedNodeId = null;
|
|
361
|
-
var selectedPortId = null;
|
|
362
|
-
var hintTimer = null;
|
|
363
|
-
|
|
364
|
-
// Detect Mac for modifier key
|
|
365
|
-
var isMac = /Mac/.test(navigator.userAgent);
|
|
366
|
-
document.getElementById('mod-key').textContent = isMac ? '\\u2318' : 'Ctrl';
|
|
367
|
-
|
|
368
|
-
function clamp(v, min, max) { return Math.min(max, Math.max(min, v)); }
|
|
369
|
-
|
|
370
|
-
function applyViewBox() {
|
|
371
|
-
canvas.setAttribute('viewBox', vbX + ' ' + vbY + ' ' + vbW + ' ' + vbH);
|
|
372
|
-
zoomLabel.textContent = Math.round(baseW / vbW * 100) + '%';
|
|
373
|
-
}
|
|
374
|
-
|
|
375
|
-
function fitToView() {
|
|
376
|
-
var pad = 60;
|
|
377
|
-
var cw = canvas.clientWidth, ch = canvas.clientHeight;
|
|
378
|
-
if (!cw || !ch) return;
|
|
379
|
-
var dw = origW + pad * 2, dh = origH + pad * 2;
|
|
380
|
-
var vpRatio = cw / ch;
|
|
381
|
-
var dRatio = dw / dh;
|
|
382
|
-
if (vpRatio > dRatio) {
|
|
383
|
-
vbH = dh; vbW = dh * vpRatio;
|
|
384
|
-
} else {
|
|
385
|
-
vbW = dw; vbH = dw / vpRatio;
|
|
386
|
-
}
|
|
387
|
-
vbX = origX - pad - (vbW - dw) / 2;
|
|
388
|
-
vbY = origY - pad - (vbH - dh) / 2;
|
|
389
|
-
baseW = vbW;
|
|
390
|
-
applyViewBox();
|
|
391
|
-
}
|
|
392
|
-
|
|
393
|
-
// Convert pixel delta to SVG coordinate delta
|
|
394
|
-
function pxToSvg() { return vbW / canvas.clientWidth; }
|
|
395
|
-
|
|
396
|
-
// ---- Zoom (Ctrl/Cmd + scroll) ----
|
|
397
|
-
canvas.addEventListener('wheel', function(e) {
|
|
398
|
-
if (!e.ctrlKey && !e.metaKey) {
|
|
399
|
-
scrollHint.classList.add('visible');
|
|
400
|
-
clearTimeout(hintTimer);
|
|
401
|
-
hintTimer = setTimeout(function() { scrollHint.classList.remove('visible'); }, 1500);
|
|
402
|
-
return;
|
|
403
|
-
}
|
|
404
|
-
e.preventDefault();
|
|
405
|
-
var rect = canvas.getBoundingClientRect();
|
|
406
|
-
var mx = (e.clientX - rect.left) / rect.width;
|
|
407
|
-
var my = (e.clientY - rect.top) / rect.height;
|
|
408
|
-
var pivotX = vbX + mx * vbW;
|
|
409
|
-
var pivotY = vbY + my * vbH;
|
|
410
|
-
var delta = clamp(e.deltaY, -10, 10);
|
|
411
|
-
var factor = 1 + delta * 0.005;
|
|
412
|
-
var newW = clamp(vbW * factor, baseW / MAX_ZOOM, baseW / MIN_ZOOM);
|
|
413
|
-
var ratio = vbH / vbW;
|
|
414
|
-
var newH = newW * ratio;
|
|
415
|
-
vbX = pivotX - mx * newW;
|
|
416
|
-
vbY = pivotY - my * newH;
|
|
417
|
-
vbW = newW; vbH = newH;
|
|
418
|
-
applyViewBox();
|
|
419
|
-
}, { passive: false });
|
|
420
|
-
|
|
421
|
-
// ---- Pan (drag) + Node drag ----
|
|
422
|
-
var draggedNodeId = null, dragNodeStart = null, didDragNode = false;
|
|
423
|
-
var clickTarget = null; // stash the real target before setPointerCapture steals it
|
|
424
|
-
var dragCount = 0, nudgeIndex = 0, nudgeTimer = null;
|
|
425
|
-
var nudgeMessages = [
|
|
426
|
-
'Like rearranging? <a href="https://flowweaver.ai" target="_blank" rel="noopener">Flow Weaver Studio</a> saves your layouts.',
|
|
427
|
-
'Changes here are temporary. <a href="https://flowweaver.ai" target="_blank" rel="noopener">Try the Studio</a> to keep them.',
|
|
428
|
-
'Want to collaborate? <a href="https://flowweaver.ai" target="_blank" rel="noopener">Flow Weaver Studio</a> has real-time sharing.',
|
|
429
|
-
'Build and deploy from the cloud with <a href="https://flowweaver.ai" target="_blank" rel="noopener">Flow Weaver Studio</a>.',
|
|
430
|
-
'This viewer is read-only. <a href="https://flowweaver.ai" target="_blank" rel="noopener">Build workflows</a> in the Studio.',
|
|
431
|
-
'Version history, diff viewer, rollbacks. All in <a href="https://flowweaver.ai" target="_blank" rel="noopener">the Studio</a>.',
|
|
432
|
-
'Debug workflows step by step in <a href="https://flowweaver.ai" target="_blank" rel="noopener">Flow Weaver Studio</a>.',
|
|
433
|
-
'Ship faster. <a href="https://flowweaver.ai" target="_blank" rel="noopener">Flow Weaver Studio</a> runs your workflows in the cloud.'
|
|
434
|
-
];
|
|
435
|
-
|
|
436
|
-
canvas.addEventListener('pointerdown', function(e) {
|
|
437
|
-
if (e.button !== 0) return;
|
|
438
|
-
clickTarget = e.target; // stash before setPointerCapture redirects events
|
|
439
|
-
didDrag = false;
|
|
440
|
-
// Check if clicking on a node body (walk up to detect data-node-id)
|
|
441
|
-
var t = e.target;
|
|
442
|
-
while (t && t !== canvas) {
|
|
443
|
-
if (t.hasAttribute && t.hasAttribute('data-node-id')) {
|
|
444
|
-
// Don't start node drag if clicking on a port circle
|
|
445
|
-
if (e.target.hasAttribute && e.target.hasAttribute('data-port-id')) break;
|
|
446
|
-
draggedNodeId = t.getAttribute('data-node-id');
|
|
447
|
-
dragNodeStart = { x: e.clientX, y: e.clientY };
|
|
448
|
-
didDragNode = false;
|
|
449
|
-
canvas.setPointerCapture(e.pointerId);
|
|
450
|
-
return;
|
|
451
|
-
}
|
|
452
|
-
t = t.parentElement;
|
|
453
|
-
}
|
|
454
|
-
// Canvas pan
|
|
455
|
-
pointerDown = true;
|
|
456
|
-
dragLast = { x: e.clientX, y: e.clientY };
|
|
457
|
-
canvas.setPointerCapture(e.pointerId);
|
|
458
|
-
});
|
|
459
|
-
|
|
460
|
-
canvas.addEventListener('pointermove', function(e) {
|
|
461
|
-
var ratio = pxToSvg();
|
|
462
|
-
|
|
463
|
-
// Node drag
|
|
464
|
-
if (draggedNodeId) {
|
|
465
|
-
var dx = (e.clientX - dragNodeStart.x) * ratio;
|
|
466
|
-
var dy = (e.clientY - dragNodeStart.y) * ratio;
|
|
467
|
-
if (!didDragNode && (Math.abs(dx) > 3 || Math.abs(dy) > 3)) {
|
|
468
|
-
didDragNode = true;
|
|
469
|
-
canvas.classList.add('dragging');
|
|
470
|
-
}
|
|
471
|
-
if (didDragNode) {
|
|
472
|
-
moveNode(draggedNodeId, dx, dy);
|
|
473
|
-
}
|
|
474
|
-
dragNodeStart = { x: e.clientX, y: e.clientY };
|
|
475
|
-
return;
|
|
476
|
-
}
|
|
477
|
-
|
|
478
|
-
// Canvas pan — shift the viewBox origin
|
|
479
|
-
if (!pointerDown) return;
|
|
480
|
-
var dxPx = e.clientX - dragLast.x, dyPx = e.clientY - dragLast.y;
|
|
481
|
-
if (!didDrag && (Math.abs(dxPx) > 3 || Math.abs(dyPx) > 3)) {
|
|
482
|
-
didDrag = true;
|
|
483
|
-
canvas.classList.add('dragging');
|
|
484
|
-
}
|
|
485
|
-
if (didDrag) {
|
|
486
|
-
vbX -= dxPx * ratio;
|
|
487
|
-
vbY -= dyPx * ratio;
|
|
488
|
-
applyViewBox();
|
|
489
|
-
}
|
|
490
|
-
dragLast = { x: e.clientX, y: e.clientY };
|
|
491
|
-
});
|
|
492
|
-
|
|
493
|
-
function endDrag() {
|
|
494
|
-
if (didDragNode) {
|
|
495
|
-
dragCount++;
|
|
496
|
-
var threshold = nudgeIndex === 0 ? 3 : 5;
|
|
497
|
-
if (dragCount >= threshold) {
|
|
498
|
-
dragCount = 0;
|
|
499
|
-
studioHint.innerHTML = nudgeMessages[nudgeIndex % nudgeMessages.length];
|
|
500
|
-
nudgeIndex++;
|
|
501
|
-
studioHint.classList.add('visible');
|
|
502
|
-
clearTimeout(nudgeTimer);
|
|
503
|
-
nudgeTimer = setTimeout(function() { studioHint.classList.remove('visible'); }, 5000);
|
|
504
|
-
}
|
|
505
|
-
}
|
|
506
|
-
pointerDown = false;
|
|
507
|
-
draggedNodeId = null;
|
|
508
|
-
canvas.classList.remove('dragging');
|
|
509
|
-
}
|
|
510
|
-
canvas.addEventListener('pointerup', endDrag);
|
|
511
|
-
canvas.addEventListener('pointercancel', endDrag);
|
|
512
|
-
|
|
513
|
-
// ---- Zoom buttons ----
|
|
514
|
-
function zoomBy(dir) {
|
|
515
|
-
var cx = vbX + vbW / 2, cy = vbY + vbH / 2;
|
|
516
|
-
var factor = dir > 0 ? 0.85 : 1.18;
|
|
517
|
-
var newW = clamp(vbW * factor, baseW / MAX_ZOOM, baseW / MIN_ZOOM);
|
|
518
|
-
var ratio = vbH / vbW;
|
|
519
|
-
var newH = newW * ratio;
|
|
520
|
-
vbX = cx - newW / 2;
|
|
521
|
-
vbY = cy - newH / 2;
|
|
522
|
-
vbW = newW; vbH = newH;
|
|
523
|
-
applyViewBox();
|
|
524
|
-
}
|
|
525
|
-
document.getElementById('btn-in').addEventListener('click', function() { zoomBy(1); });
|
|
526
|
-
document.getElementById('btn-out').addEventListener('click', function() { zoomBy(-1); });
|
|
527
|
-
document.getElementById('btn-fit').addEventListener('click', fitToView);
|
|
528
|
-
|
|
529
|
-
// ---- Keyboard shortcuts ----
|
|
530
|
-
document.addEventListener('keydown', function(e) {
|
|
531
|
-
if (e.target.tagName === 'INPUT' || e.target.tagName === 'TEXTAREA') return;
|
|
532
|
-
if (e.key === '+' || e.key === '=') zoomBy(1);
|
|
533
|
-
else if (e.key === '-') zoomBy(-1);
|
|
534
|
-
else if (e.key === '0') fitToView();
|
|
535
|
-
else if (e.key === 'Escape') { deselectPort(); deselectNode(); }
|
|
536
|
-
});
|
|
537
|
-
|
|
538
|
-
// ---- Port label visibility ----
|
|
539
|
-
var labelMap = {};
|
|
540
|
-
content.querySelectorAll('.labels g[data-port-label]').forEach(function(lbl) {
|
|
541
|
-
labelMap[lbl.getAttribute('data-port-label')] = lbl;
|
|
542
|
-
});
|
|
543
|
-
|
|
544
|
-
// Build adjacency: portId -> array of connected portIds (covers paths + stubs)
|
|
545
|
-
var portConnections = {};
|
|
546
|
-
var seenEdges = {};
|
|
547
|
-
content.querySelectorAll('[data-source]').forEach(function(p) {
|
|
548
|
-
var src = p.getAttribute('data-source');
|
|
549
|
-
var tgt = p.getAttribute('data-target');
|
|
550
|
-
if (!src || !tgt) return;
|
|
551
|
-
var key = src + '|' + tgt;
|
|
552
|
-
if (seenEdges[key]) return; // avoid duplicates from path+stub pairs
|
|
553
|
-
seenEdges[key] = true;
|
|
554
|
-
if (!portConnections[src]) portConnections[src] = [];
|
|
555
|
-
if (!portConnections[tgt]) portConnections[tgt] = [];
|
|
556
|
-
portConnections[src].push(tgt);
|
|
557
|
-
portConnections[tgt].push(src);
|
|
558
|
-
});
|
|
559
|
-
|
|
560
|
-
// ---- Connection path computation (bezier from geometry.ts + orthogonal router) ----
|
|
561
|
-
var TRACK_SPACING = 15, EDGE_OFFSET = 5, MAX_CANDIDATES = 5;
|
|
562
|
-
var MIN_SEG_LEN = 3, JOG_THRESHOLD = 10, ORTHO_THRESHOLD = 300;
|
|
563
|
-
var STUB_THRESHOLD = 500, STUB_LEN = 30;
|
|
564
|
-
|
|
565
|
-
function quadCurveControl(ax, ay, bx, by, ux, uy) {
|
|
566
|
-
var dn = Math.abs(ay - by);
|
|
567
|
-
return [bx + (ux * dn) / Math.abs(uy), ay];
|
|
568
|
-
}
|
|
569
|
-
|
|
570
|
-
function computeConnectionPath(sx, sy, tx, ty) {
|
|
571
|
-
var e = 0.0001;
|
|
572
|
-
var ax = sx + e, ay = sy + e, hx = tx - e, hy = ty - e;
|
|
573
|
-
var ramp = Math.min(20, (hx - ax) / 10);
|
|
574
|
-
var bx = ax + ramp, by = ay + e, gx = hx - ramp, gy = hy - e;
|
|
575
|
-
var curveSizeX = Math.min(60, Math.abs(ax - hx) / 4);
|
|
576
|
-
var curveSizeY = Math.min(60, Math.abs(ay - hy) / 4);
|
|
577
|
-
var curveMag = Math.sqrt(curveSizeX * curveSizeX + curveSizeY * curveSizeY);
|
|
578
|
-
var bgX = gx - bx, bgY = gy - by;
|
|
579
|
-
var bgLen = Math.sqrt(bgX * bgX + bgY * bgY);
|
|
580
|
-
var bgUx = bgX / bgLen, bgUy = bgY / bgLen;
|
|
581
|
-
var dx = bx + bgUx * curveMag, dy = by + (bgUy * curveMag) / 2;
|
|
582
|
-
var ex = gx - bgUx * curveMag, ey = gy - (bgUy * curveMag) / 2;
|
|
583
|
-
var deX = ex - dx, deY = ey - dy;
|
|
584
|
-
var deLen = Math.sqrt(deX * deX + deY * deY);
|
|
585
|
-
var deUx = deX / deLen, deUy = deY / deLen;
|
|
586
|
-
var c = quadCurveControl(bx, by, dx, dy, -deUx, -deUy);
|
|
587
|
-
var f = quadCurveControl(gx, gy, ex, ey, deUx, deUy);
|
|
588
|
-
return 'M ' + c[0] + ',' + c[1] + ' M ' + ax + ',' + ay +
|
|
589
|
-
' L ' + bx + ',' + by + ' Q ' + c[0] + ',' + c[1] + ' ' + dx + ',' + dy +
|
|
590
|
-
' L ' + ex + ',' + ey + ' Q ' + f[0] + ',' + f[1] + ' ' + gx + ',' + gy +
|
|
591
|
-
' L ' + hx + ',' + hy;
|
|
592
|
-
}
|
|
593
|
-
|
|
594
|
-
// ---- Orthogonal router (ported from orthogonal-router.ts) ----
|
|
595
|
-
function createAllocator() {
|
|
596
|
-
var claims = [], vclaims = [];
|
|
597
|
-
function isOcc(xn, xx, y) {
|
|
598
|
-
for (var i = 0; i < claims.length; i++) {
|
|
599
|
-
var c = claims[i];
|
|
600
|
-
if (c.xn < xx && c.xx > xn && Math.abs(c.y - y) < TRACK_SPACING) return true;
|
|
601
|
-
}
|
|
602
|
-
return false;
|
|
603
|
-
}
|
|
604
|
-
function isOccV(yn, yx, x) {
|
|
605
|
-
for (var i = 0; i < vclaims.length; i++) {
|
|
606
|
-
var c = vclaims[i];
|
|
607
|
-
if (c.yn < yx && c.yx > yn && Math.abs(c.x - x) < TRACK_SPACING) return true;
|
|
608
|
-
}
|
|
609
|
-
return false;
|
|
610
|
-
}
|
|
611
|
-
function blockedByNode(xn, xx, y, boxes) {
|
|
612
|
-
for (var i = 0; i < boxes.length; i++) {
|
|
613
|
-
var b = boxes[i]; if (xn < b.r && xx > b.l && y >= b.t && y <= b.b) return true;
|
|
614
|
-
}
|
|
615
|
-
return false;
|
|
616
|
-
}
|
|
617
|
-
function blockedByNodeV(yn, yx, x, boxes) {
|
|
618
|
-
for (var i = 0; i < boxes.length; i++) {
|
|
619
|
-
var b = boxes[i]; if (x >= b.l && x <= b.r && yn < b.b && yx > b.t) return true;
|
|
620
|
-
}
|
|
621
|
-
return false;
|
|
622
|
-
}
|
|
623
|
-
function countHCross(xn, xx, y) {
|
|
624
|
-
var n = 0;
|
|
625
|
-
for (var i = 0; i < vclaims.length; i++) {
|
|
626
|
-
var c = vclaims[i]; if (c.x > xn && c.x < xx && y >= c.yn && y <= c.yx) n++;
|
|
627
|
-
}
|
|
628
|
-
return n;
|
|
629
|
-
}
|
|
630
|
-
function countVCross(yn, yx, x) {
|
|
631
|
-
var n = 0;
|
|
632
|
-
for (var i = 0; i < claims.length; i++) {
|
|
633
|
-
var c = claims[i]; if (c.y > yn && c.y < yx && x >= c.xn && x <= c.xx) n++;
|
|
634
|
-
}
|
|
635
|
-
return n;
|
|
636
|
-
}
|
|
637
|
-
return {
|
|
638
|
-
findFreeY: function(xn, xx, cy, nb) {
|
|
639
|
-
var free = function(y) { return !isOcc(xn, xx, y) && (!nb || !blockedByNode(xn, xx, y, nb)); };
|
|
640
|
-
if (free(cy)) return cy;
|
|
641
|
-
var cands = [];
|
|
642
|
-
for (var off = TRACK_SPACING; off < 800 && cands.length < MAX_CANDIDATES * 2; off += TRACK_SPACING) {
|
|
643
|
-
if (free(cy - off)) cands.push({ y: cy - off, d: off });
|
|
644
|
-
if (free(cy + off)) cands.push({ y: cy + off, d: off });
|
|
645
|
-
}
|
|
646
|
-
if (!cands.length) return cy;
|
|
647
|
-
var best = cands[0].y, bc = countHCross(xn, xx, cands[0].y), bd = cands[0].d;
|
|
648
|
-
for (var i = 1; i < cands.length; i++) {
|
|
649
|
-
var cr = countHCross(xn, xx, cands[i].y);
|
|
650
|
-
if (cr < bc || (cr === bc && cands[i].d < bd)) { best = cands[i].y; bc = cr; bd = cands[i].d; }
|
|
651
|
-
}
|
|
652
|
-
return best;
|
|
653
|
-
},
|
|
654
|
-
findFreeX: function(yn, yx, cx, nb) {
|
|
655
|
-
var free = function(x) { return !isOccV(yn, yx, x) && (!nb || !blockedByNodeV(yn, yx, x, nb)); };
|
|
656
|
-
if (free(cx)) return cx;
|
|
657
|
-
var cands = [];
|
|
658
|
-
for (var off = TRACK_SPACING; off < 800 && cands.length < MAX_CANDIDATES * 2; off += TRACK_SPACING) {
|
|
659
|
-
if (free(cx - off)) cands.push({ x: cx - off, d: off });
|
|
660
|
-
if (free(cx + off)) cands.push({ x: cx + off, d: off });
|
|
661
|
-
}
|
|
662
|
-
if (!cands.length) return cx;
|
|
663
|
-
var best = cands[0].x, bc = countVCross(yn, yx, cands[0].x), bd = cands[0].d;
|
|
664
|
-
for (var i = 1; i < cands.length; i++) {
|
|
665
|
-
var cr = countVCross(yn, yx, cands[i].x);
|
|
666
|
-
if (cr < bc || (cr === bc && cands[i].d < bd)) { best = cands[i].x; bc = cr; bd = cands[i].d; }
|
|
667
|
-
}
|
|
668
|
-
return best;
|
|
669
|
-
},
|
|
670
|
-
claim: function(xn, xx, y) { claims.push({ xn: xn, xx: xx, y: y }); },
|
|
671
|
-
claimV: function(yn, yx, x) { vclaims.push({ yn: yn, yx: yx, x: x }); }
|
|
672
|
-
};
|
|
673
|
-
}
|
|
674
|
-
|
|
675
|
-
function inflateBox(b, pad) { return { l: b.x - pad, r: b.x + b.w + pad, t: b.y - pad, b: b.y + b.h + pad }; }
|
|
676
|
-
function segOvlp(xn, xx, y, bx) { return xn < bx.r && xx > bx.l && y >= bx.t && y <= bx.b; }
|
|
677
|
-
function vSegClear(x, yn, yx, boxes) {
|
|
678
|
-
for (var i = 0; i < boxes.length; i++) { var b = boxes[i]; if (x >= b.l && x <= b.r && yn < b.b && yx > b.t) return false; }
|
|
679
|
-
return true;
|
|
680
|
-
}
|
|
681
|
-
|
|
682
|
-
function findClearY(xn, xx, cy, boxes) {
|
|
683
|
-
var blocked = function(y) { for (var i = 0; i < boxes.length; i++) if (segOvlp(xn, xx, y, boxes[i])) return true; return false; };
|
|
684
|
-
if (!blocked(cy)) return cy;
|
|
685
|
-
var edges = [];
|
|
686
|
-
for (var i = 0; i < boxes.length; i++) { var b = boxes[i]; if (xn < b.r && xx > b.l) { edges.push(b.t); edges.push(b.b); } }
|
|
687
|
-
if (!edges.length) return cy;
|
|
688
|
-
edges.sort(function(a, b) { return a - b; });
|
|
689
|
-
var best = cy, bd = Infinity;
|
|
690
|
-
for (var i = 0; i < edges.length; i++) {
|
|
691
|
-
var vals = [edges[i] - EDGE_OFFSET, edges[i] + EDGE_OFFSET];
|
|
692
|
-
for (var j = 0; j < 2; j++) { if (!blocked(vals[j])) { var d = Math.abs(vals[j] - cy); if (d < bd) { bd = d; best = vals[j]; } } }
|
|
693
|
-
}
|
|
694
|
-
if (bd === Infinity) {
|
|
695
|
-
var mn = Math.min.apply(null, edges) - EDGE_OFFSET * 2, mx = Math.max.apply(null, edges) + EDGE_OFFSET * 2;
|
|
696
|
-
best = Math.abs(mn - cy) <= Math.abs(mx - cy) ? mn : mx;
|
|
697
|
-
if (blocked(best)) { for (var off = TRACK_SPACING; off < 800; off += TRACK_SPACING) { if (!blocked(best - off)) { best -= off; break; } if (!blocked(best + off)) { best += off; break; } } }
|
|
698
|
-
}
|
|
699
|
-
return best;
|
|
700
|
-
}
|
|
701
|
-
|
|
702
|
-
function findClearX(yn, yx, cx, boxes) {
|
|
703
|
-
var blocked = function(x) { for (var i = 0; i < boxes.length; i++) { var b = boxes[i]; if (x >= b.l && x <= b.r && yn < b.b && yx > b.t) return true; } return false; };
|
|
704
|
-
if (!blocked(cx)) return cx;
|
|
705
|
-
var edges = [];
|
|
706
|
-
for (var i = 0; i < boxes.length; i++) { var b = boxes[i]; if (yn < b.b && yx > b.t) { edges.push(b.l); edges.push(b.r); } }
|
|
707
|
-
if (!edges.length) return cx;
|
|
708
|
-
edges.sort(function(a, b) { return a - b; });
|
|
709
|
-
var best = cx, bd = Infinity;
|
|
710
|
-
for (var i = 0; i < edges.length; i++) {
|
|
711
|
-
var vals = [edges[i] - EDGE_OFFSET, edges[i] + EDGE_OFFSET];
|
|
712
|
-
for (var j = 0; j < 2; j++) { if (!blocked(vals[j])) { var d = Math.abs(vals[j] - cx); if (d < bd) { bd = d; best = vals[j]; } } }
|
|
713
|
-
}
|
|
714
|
-
if (bd === Infinity) {
|
|
715
|
-
var mn = Math.min.apply(null, edges) - EDGE_OFFSET * 2, mx = Math.max.apply(null, edges) + EDGE_OFFSET * 2;
|
|
716
|
-
best = Math.abs(mn - cx) <= Math.abs(mx - cx) ? mn : mx;
|
|
717
|
-
if (blocked(best)) { for (var off = TRACK_SPACING; off < 800; off += TRACK_SPACING) { if (!blocked(best - off)) { best -= off; break; } if (!blocked(best + off)) { best += off; break; } } }
|
|
718
|
-
}
|
|
719
|
-
return best;
|
|
720
|
-
}
|
|
721
|
-
|
|
722
|
-
function simplifyWaypoints(pts) {
|
|
723
|
-
if (pts.length <= 2) return pts;
|
|
724
|
-
var jogFound = true;
|
|
725
|
-
while (jogFound) {
|
|
726
|
-
jogFound = false;
|
|
727
|
-
for (var i = 0; i < pts.length - 3; i++) {
|
|
728
|
-
var a = pts[i], b = pts[i+1], c = pts[i+2], d = pts[i+3];
|
|
729
|
-
var jogH = Math.abs(b[1] - c[1]);
|
|
730
|
-
if (Math.abs(a[1] - b[1]) < 0.5 && Math.abs(b[0] - c[0]) < 0.5 && Math.abs(c[1] - d[1]) < 0.5 && jogH > 0.5 && jogH < JOG_THRESHOLD) {
|
|
731
|
-
var mid = (b[1] + c[1]) / 2, snap = Math.abs(a[1] - mid) <= Math.abs(d[1] - mid) ? a[1] : d[1];
|
|
732
|
-
pts = pts.slice(); pts[i+1] = [b[0], snap]; pts[i+2] = [c[0], snap]; jogFound = true; break;
|
|
733
|
-
}
|
|
734
|
-
var jogW = Math.abs(b[0] - c[0]);
|
|
735
|
-
if (Math.abs(a[0] - b[0]) < 0.5 && Math.abs(b[1] - c[1]) < 0.5 && Math.abs(c[0] - d[0]) < 0.5 && jogW > 0.5 && jogW < JOG_THRESHOLD) {
|
|
736
|
-
var mid = (b[0] + c[0]) / 2, snap = Math.abs(a[0] - mid) <= Math.abs(d[0] - mid) ? a[0] : d[0];
|
|
737
|
-
pts = pts.slice(); pts[i+1] = [snap, b[1]]; pts[i+2] = [snap, c[1]]; jogFound = true; break;
|
|
738
|
-
}
|
|
739
|
-
}
|
|
740
|
-
}
|
|
741
|
-
var res = [pts[0]];
|
|
742
|
-
for (var i = 1; i < pts.length - 1; i++) {
|
|
743
|
-
var prev = res[res.length - 1], cur = pts[i], next = pts[i+1];
|
|
744
|
-
if (Math.abs(prev[0] - cur[0]) + Math.abs(prev[1] - cur[1]) < MIN_SEG_LEN) continue;
|
|
745
|
-
var sameX = Math.abs(prev[0] - cur[0]) < 0.01 && Math.abs(cur[0] - next[0]) < 0.01;
|
|
746
|
-
var sameY = Math.abs(prev[1] - cur[1]) < 0.01 && Math.abs(cur[1] - next[1]) < 0.01;
|
|
747
|
-
if (!sameX && !sameY) res.push(cur);
|
|
748
|
-
}
|
|
749
|
-
res.push(pts[pts.length - 1]);
|
|
750
|
-
return res;
|
|
751
|
-
}
|
|
752
|
-
|
|
753
|
-
function waypointsToPath(wp, cr) {
|
|
754
|
-
if (wp.length < 2) return '';
|
|
755
|
-
if (wp.length === 2) return 'M ' + wp[0][0] + ',' + wp[0][1] + ' L ' + wp[1][0] + ',' + wp[1][1];
|
|
756
|
-
var radii = [];
|
|
757
|
-
for (var i = 0; i < wp.length; i++) radii[i] = 0;
|
|
758
|
-
for (var i = 1; i < wp.length - 1; i++) {
|
|
759
|
-
var p = wp[i-1], c = wp[i], n = wp[i+1];
|
|
760
|
-
var lp = Math.sqrt((p[0]-c[0])*(p[0]-c[0]) + (p[1]-c[1])*(p[1]-c[1]));
|
|
761
|
-
var ln = Math.sqrt((n[0]-c[0])*(n[0]-c[0]) + (n[1]-c[1])*(n[1]-c[1]));
|
|
762
|
-
radii[i] = (lp < 0.01 || ln < 0.01) ? 0 : Math.min(cr, lp / 2, ln / 2);
|
|
763
|
-
}
|
|
764
|
-
for (var i = 1; i < wp.length - 2; i++) {
|
|
765
|
-
var c = wp[i], n = wp[i+1];
|
|
766
|
-
var sl = Math.sqrt((n[0]-c[0])*(n[0]-c[0]) + (n[1]-c[1])*(n[1]-c[1]));
|
|
767
|
-
var tot = radii[i] + radii[i+1];
|
|
768
|
-
if (tot > sl && tot > 0) { var sc = sl / tot; radii[i] *= sc; radii[i+1] *= sc; }
|
|
769
|
-
}
|
|
770
|
-
var path = 'M ' + wp[0][0] + ',' + wp[0][1];
|
|
771
|
-
for (var i = 1; i < wp.length - 1; i++) {
|
|
772
|
-
var p = wp[i-1], c = wp[i], n = wp[i+1], r = radii[i];
|
|
773
|
-
if (r < 2) { path += ' L ' + c[0] + ',' + c[1]; continue; }
|
|
774
|
-
var dpx = p[0]-c[0], dpy = p[1]-c[1], dnx = n[0]-c[0], dny = n[1]-c[1];
|
|
775
|
-
var lp = Math.sqrt(dpx*dpx + dpy*dpy), ln = Math.sqrt(dnx*dnx + dny*dny);
|
|
776
|
-
var upx = dpx/lp, upy = dpy/lp, unx = dnx/ln, uny = dny/ln;
|
|
777
|
-
var asx = c[0] + upx*r, asy = c[1] + upy*r, aex = c[0] + unx*r, aey = c[1] + uny*r;
|
|
778
|
-
var cross = dpx*dny - dpy*dnx, sweep = cross > 0 ? 0 : 1;
|
|
779
|
-
path += ' L ' + asx + ',' + asy + ' A ' + r + ' ' + r + ' 0 0 ' + sweep + ' ' + aex + ',' + aey;
|
|
780
|
-
}
|
|
781
|
-
path += ' L ' + wp[wp.length-1][0] + ',' + wp[wp.length-1][1];
|
|
782
|
-
return path;
|
|
783
|
-
}
|
|
784
|
-
|
|
785
|
-
function computeWaypoints(from, to, nboxes, srcId, tgtId, pad, exitStub, entryStub, alloc) {
|
|
786
|
-
var isSelf = srcId === tgtId;
|
|
787
|
-
var iboxes = [];
|
|
788
|
-
for (var i = 0; i < nboxes.length; i++) {
|
|
789
|
-
var b = nboxes[i];
|
|
790
|
-
if (isSelf || (b.id !== srcId && b.id !== tgtId)) iboxes.push(inflateBox(b, pad));
|
|
791
|
-
}
|
|
792
|
-
var se = [from[0] + exitStub, from[1]], sn = [to[0] - entryStub, to[1]];
|
|
793
|
-
var xn = Math.min(se[0], sn[0]), xx = Math.max(se[0], sn[0]);
|
|
794
|
-
|
|
795
|
-
if (!isSelf && to[0] > from[0]) {
|
|
796
|
-
var cy = (from[1] + to[1]) / 2;
|
|
797
|
-
var intBoxes = [];
|
|
798
|
-
for (var i = 0; i < iboxes.length; i++) { var b = iboxes[i]; if (b.l < xx && b.r > xn) intBoxes.push(b); }
|
|
799
|
-
if (intBoxes.length >= 2) {
|
|
800
|
-
var ct = Infinity, cb = -Infinity;
|
|
801
|
-
for (var i = 0; i < intBoxes.length; i++) { ct = Math.min(ct, intBoxes[i].t); cb = Math.max(cb, intBoxes[i].b); }
|
|
802
|
-
if (cy > ct && cy < cb) { cy = (cy - ct <= cb - cy) ? ct - pad : cb + pad; }
|
|
803
|
-
}
|
|
804
|
-
var clearY = findClearY(xn, xx, cy, iboxes);
|
|
805
|
-
if (Math.abs(from[1] - to[1]) < JOG_THRESHOLD && Math.abs(clearY - from[1]) < JOG_THRESHOLD) return null;
|
|
806
|
-
|
|
807
|
-
var midX = (se[0] + sn[0]) / 2, ymn = Math.min(from[1], to[1]), ymx = Math.max(from[1], to[1]);
|
|
808
|
-
var cmx = findClearX(ymn, ymx, midX, iboxes);
|
|
809
|
-
var fmx = alloc.findFreeX(ymn, ymx, cmx, iboxes);
|
|
810
|
-
if (ymx - ymn >= JOG_THRESHOLD && fmx > se[0] && fmx < sn[0] &&
|
|
811
|
-
vSegClear(fmx, ymn, ymx, iboxes) &&
|
|
812
|
-
alloc.findFreeY(from[0], fmx, from[1], iboxes) === from[1] &&
|
|
813
|
-
alloc.findFreeY(fmx, to[0], to[1], iboxes) === to[1]) {
|
|
814
|
-
alloc.claim(from[0], fmx, from[1]); alloc.claim(fmx, to[0], to[1]); alloc.claimV(ymn, ymx, fmx);
|
|
815
|
-
return simplifyWaypoints([from, [fmx, from[1]], [fmx, to[1]], to]);
|
|
816
|
-
}
|
|
817
|
-
|
|
818
|
-
clearY = alloc.findFreeY(xn, xx, clearY, iboxes);
|
|
819
|
-
if (Math.abs(clearY - from[1]) < JOG_THRESHOLD && !iboxes.some(function(b) { return segOvlp(xn, xx, from[1], b); })) clearY = from[1];
|
|
820
|
-
else if (Math.abs(clearY - to[1]) < JOG_THRESHOLD && !iboxes.some(function(b) { return segOvlp(xn, xx, to[1], b); })) clearY = to[1];
|
|
821
|
-
alloc.claim(xn, xx, clearY);
|
|
822
|
-
|
|
823
|
-
var eymn = Math.min(from[1], clearY), eymx = Math.max(from[1], clearY);
|
|
824
|
-
var exX = findClearX(eymn, eymx, se[0], iboxes); exX = alloc.findFreeX(eymn, eymx, exX, iboxes);
|
|
825
|
-
if (exX < from[0]) { exX = se[0]; if (!vSegClear(exX, eymn, eymx, iboxes)) { exX = findClearX(eymn, eymx, se[0] + TRACK_SPACING, iboxes); exX = alloc.findFreeX(eymn, eymx, exX, iboxes); } }
|
|
826
|
-
alloc.claimV(eymn, eymx, exX);
|
|
827
|
-
|
|
828
|
-
var nymn = Math.min(to[1], clearY), nymx = Math.max(to[1], clearY);
|
|
829
|
-
var nxX = findClearX(nymn, nymx, sn[0], iboxes); nxX = alloc.findFreeX(nymn, nymx, nxX, iboxes);
|
|
830
|
-
if (nxX > to[0]) { nxX = sn[0]; if (!vSegClear(nxX, nymn, nymx, iboxes)) { nxX = findClearX(nymn, nymx, sn[0] - TRACK_SPACING, iboxes); nxX = alloc.findFreeX(nymn, nymx, nxX, iboxes); } }
|
|
831
|
-
alloc.claimV(nymn, nymx, nxX);
|
|
832
|
-
|
|
833
|
-
return simplifyWaypoints([from, [exX, from[1]], [exX, clearY], [nxX, clearY], [nxX, to[1]], to]);
|
|
834
|
-
} else {
|
|
835
|
-
var srcBox = null, tgtBox = null;
|
|
836
|
-
for (var i = 0; i < nboxes.length; i++) { if (nboxes[i].id === srcId) srcBox = nboxes[i]; if (nboxes[i].id === tgtId) tgtBox = nboxes[i]; }
|
|
837
|
-
var corBoxes = []; for (var i = 0; i < iboxes.length; i++) { var b = iboxes[i]; if (b.l < xx && b.r > xn) corBoxes.push(b); }
|
|
838
|
-
var bots = corBoxes.map(function(b) { return b.b; }), tops = corBoxes.map(function(b) { return b.t; });
|
|
839
|
-
if (srcBox) { bots.push(srcBox.y + srcBox.h + pad); tops.push(srcBox.y - pad); }
|
|
840
|
-
if (tgtBox) { bots.push(tgtBox.y + tgtBox.h + pad); tops.push(tgtBox.y - pad); }
|
|
841
|
-
var maxBot = Math.max.apply(null, bots.concat([from[1] + 50, to[1] + 50]));
|
|
842
|
-
var minTop = Math.min.apply(null, tops.concat([from[1] - 50, to[1] - 50]));
|
|
843
|
-
var avgY = (from[1] + to[1]) / 2;
|
|
844
|
-
var escBelow = maxBot + pad, escAbove = minTop - pad;
|
|
845
|
-
var escY = Math.abs(escAbove - avgY) <= Math.abs(escBelow - avgY) ? escAbove : escBelow;
|
|
846
|
-
escY = findClearY(xn, xx, escY, iboxes); escY = alloc.findFreeY(xn, xx, escY, iboxes); alloc.claim(xn, xx, escY);
|
|
847
|
-
|
|
848
|
-
var bymn = Math.min(from[1], escY), bymx = Math.max(from[1], escY);
|
|
849
|
-
var bexX = findClearX(bymn, bymx, se[0], iboxes); bexX = alloc.findFreeX(bymn, bymx, bexX, iboxes); alloc.claimV(bymn, bymx, bexX);
|
|
850
|
-
|
|
851
|
-
var bnmn = Math.min(to[1], escY), bnmx = Math.max(to[1], escY);
|
|
852
|
-
var bnxX = findClearX(bnmn, bnmx, sn[0], iboxes); bnxX = alloc.findFreeX(bnmn, bnmx, bnxX, iboxes); alloc.claimV(bnmn, bnmx, bnxX);
|
|
853
|
-
|
|
854
|
-
return simplifyWaypoints([from, [bexX, from[1]], [bexX, escY], [bnxX, escY], [bnxX, to[1]], to]);
|
|
855
|
-
}
|
|
856
|
-
}
|
|
857
|
-
|
|
858
|
-
function calcOrthogonalPath(from, to, nboxes, srcId, tgtId, fromIdx, toIdx, alloc) {
|
|
859
|
-
var pad = 15, stubLen = 20, stubSpc = 12, maxStub = 80, cr = 10;
|
|
860
|
-
var exitStub = Math.min(stubLen + fromIdx * stubSpc, maxStub);
|
|
861
|
-
var entryStub = Math.min(stubLen + toIdx * stubSpc, maxStub);
|
|
862
|
-
try {
|
|
863
|
-
var wp = computeWaypoints(from, to, nboxes, srcId, tgtId, pad, exitStub, entryStub, alloc);
|
|
864
|
-
if (!wp) return null;
|
|
865
|
-
var p = waypointsToPath(wp, cr);
|
|
866
|
-
return (p && p.length >= 5) ? p : null;
|
|
867
|
-
} catch (e) { return null; }
|
|
868
|
-
}
|
|
869
|
-
|
|
870
|
-
// ---- Port position + node box + connection path indexes ----
|
|
871
|
-
var portPositions = {};
|
|
872
|
-
content.querySelectorAll('[data-port-id]').forEach(function(el) {
|
|
873
|
-
var id = el.getAttribute('data-port-id');
|
|
874
|
-
portPositions[id] = { cx: parseFloat(el.getAttribute('cx')), cy: parseFloat(el.getAttribute('cy')) };
|
|
875
|
-
});
|
|
876
|
-
|
|
877
|
-
// Extract node bounding boxes from SVG rect elements
|
|
878
|
-
var nodeBoxMap = {};
|
|
879
|
-
content.querySelectorAll('.nodes [data-node-id]').forEach(function(g) {
|
|
880
|
-
var nid = g.getAttribute('data-node-id');
|
|
881
|
-
var rect = g.querySelector(':scope > rect');
|
|
882
|
-
if (!rect) return;
|
|
883
|
-
nodeBoxMap[nid] = {
|
|
884
|
-
id: nid,
|
|
885
|
-
x: parseFloat(rect.getAttribute('x')),
|
|
886
|
-
y: parseFloat(rect.getAttribute('y')),
|
|
887
|
-
w: parseFloat(rect.getAttribute('width')),
|
|
888
|
-
h: parseFloat(rect.getAttribute('height'))
|
|
889
|
-
};
|
|
890
|
-
});
|
|
891
|
-
|
|
892
|
-
// Build port-to-node mapping and compute port indices within each node
|
|
893
|
-
var portNodeMap = {};
|
|
894
|
-
var portIndexMap = {};
|
|
895
|
-
content.querySelectorAll('[data-port-id]').forEach(function(el) {
|
|
896
|
-
var id = el.getAttribute('data-port-id');
|
|
897
|
-
var dir = el.getAttribute('data-direction');
|
|
898
|
-
var parts = id.split('.');
|
|
899
|
-
var nodeId = parts[0];
|
|
900
|
-
portNodeMap[id] = nodeId;
|
|
901
|
-
if (!portIndexMap[nodeId]) portIndexMap[nodeId] = { input: [], output: [] };
|
|
902
|
-
portIndexMap[nodeId][dir].push(id);
|
|
903
|
-
});
|
|
904
|
-
|
|
905
|
-
var nodeOffsets = {};
|
|
906
|
-
var connIndex = [];
|
|
907
|
-
content.querySelectorAll('path[data-source]').forEach(function(p) {
|
|
908
|
-
var src = p.getAttribute('data-source'), tgt = p.getAttribute('data-target');
|
|
909
|
-
var srcNode = src.split('.')[0], tgtNode = tgt.split('.')[0];
|
|
910
|
-
var srcIdx = portIndexMap[srcNode] ? portIndexMap[srcNode].output.indexOf(src) : 0;
|
|
911
|
-
var tgtIdx = portIndexMap[tgtNode] ? portIndexMap[tgtNode].input.indexOf(tgt) : 0;
|
|
912
|
-
connIndex.push({ el: p, src: src, tgt: tgt, srcNode: srcNode, tgtNode: tgtNode,
|
|
913
|
-
scopeOf: p.getAttribute('data-scope') || null, srcIdx: Math.max(0, srcIdx), tgtIdx: Math.max(0, tgtIdx),
|
|
914
|
-
stubs: null });
|
|
915
|
-
});
|
|
916
|
-
|
|
917
|
-
// Build stub index and link to connIndex entries.
|
|
918
|
-
// Compute labelOffset per stub (distance from port center to SVG stub start).
|
|
919
|
-
// In HTML, stubs start from port center; on label hover they push out past the badge.
|
|
920
|
-
var stubMap = {};
|
|
921
|
-
content.querySelectorAll('.stubs g.stub[data-source]').forEach(function(el) {
|
|
922
|
-
var src = el.getAttribute('data-source');
|
|
923
|
-
var tgt = el.getAttribute('data-target');
|
|
924
|
-
var key = src + '|' + tgt;
|
|
925
|
-
if (!stubMap[key]) stubMap[key] = { src: null, tgt: null, srcOff: 0, tgtOff: 0 };
|
|
926
|
-
var dir = el.getAttribute('data-stub');
|
|
927
|
-
var line = el.querySelector('line');
|
|
928
|
-
if (dir === 'source') {
|
|
929
|
-
stubMap[key].src = el;
|
|
930
|
-
if (line) {
|
|
931
|
-
var pp = portPositions[src];
|
|
932
|
-
if (pp) stubMap[key].srcOff = parseFloat(line.getAttribute('x1')) - pp.cx;
|
|
933
|
-
}
|
|
934
|
-
} else {
|
|
935
|
-
stubMap[key].tgt = el;
|
|
936
|
-
if (line) {
|
|
937
|
-
var pp = portPositions[tgt];
|
|
938
|
-
if (pp) stubMap[key].tgtOff = parseFloat(line.getAttribute('x1')) - pp.cx;
|
|
939
|
-
}
|
|
940
|
-
}
|
|
941
|
-
});
|
|
942
|
-
for (var ci = 0; ci < connIndex.length; ci++) {
|
|
943
|
-
var entry = connIndex[ci];
|
|
944
|
-
var stubKey = entry.src + '|' + entry.tgt;
|
|
945
|
-
if (stubMap[stubKey]) entry.stubs = stubMap[stubKey];
|
|
946
|
-
}
|
|
947
|
-
|
|
948
|
-
// Pull all visible stubs to port center on init (labels are hidden in HTML)
|
|
949
|
-
for (var si = 0; si < connIndex.length; si++) {
|
|
950
|
-
var sc = connIndex[si];
|
|
951
|
-
if (!sc.stubs) continue;
|
|
952
|
-
if (sc.stubs.src) {
|
|
953
|
-
var sLine = sc.stubs.src.querySelector('line');
|
|
954
|
-
var sCirc = sc.stubs.src.querySelector('circle');
|
|
955
|
-
var spp = portPositions[sc.src];
|
|
956
|
-
if (sLine && spp) {
|
|
957
|
-
sLine.setAttribute('x1', spp.cx); sLine.setAttribute('y1', spp.cy);
|
|
958
|
-
sLine.setAttribute('x2', spp.cx + STUB_LEN); sLine.setAttribute('y2', spp.cy);
|
|
959
|
-
if (sCirc) { sCirc.setAttribute('cx', spp.cx + STUB_LEN); sCirc.setAttribute('cy', spp.cy); }
|
|
960
|
-
}
|
|
961
|
-
}
|
|
962
|
-
if (sc.stubs.tgt) {
|
|
963
|
-
var tLine = sc.stubs.tgt.querySelector('line');
|
|
964
|
-
var tCirc = sc.stubs.tgt.querySelector('circle');
|
|
965
|
-
var tpp = portPositions[sc.tgt];
|
|
966
|
-
if (tLine && tpp) {
|
|
967
|
-
tLine.setAttribute('x1', tpp.cx); tLine.setAttribute('y1', tpp.cy);
|
|
968
|
-
tLine.setAttribute('x2', tpp.cx - STUB_LEN); tLine.setAttribute('y2', tpp.cy);
|
|
969
|
-
if (tCirc) { tCirc.setAttribute('cx', tpp.cx - STUB_LEN); tCirc.setAttribute('cy', tpp.cy); }
|
|
970
|
-
}
|
|
971
|
-
}
|
|
972
|
-
}
|
|
973
|
-
|
|
974
|
-
// Snapshot of original port positions for reset
|
|
975
|
-
var origPortPositions = {};
|
|
976
|
-
for (var pid in portPositions) {
|
|
977
|
-
origPortPositions[pid] = { cx: portPositions[pid].cx, cy: portPositions[pid].cy };
|
|
978
|
-
}
|
|
979
|
-
var origNodeBoxMap = {};
|
|
980
|
-
for (var nid in nodeBoxMap) {
|
|
981
|
-
var b = nodeBoxMap[nid];
|
|
982
|
-
origNodeBoxMap[nid] = { id: b.id, x: b.x, y: b.y, w: b.w, h: b.h };
|
|
983
|
-
}
|
|
984
|
-
|
|
985
|
-
// ---- Recalculate all connection paths + stubs using orthogonal + bezier routing ----
|
|
986
|
-
function recalcAllPaths() {
|
|
987
|
-
// Cancel all running stub animations since we're hard-repositioning
|
|
988
|
-
for (var ak in activeAnims) { cancelAnimationFrame(activeAnims[ak]); delete activeAnims[ak]; }
|
|
989
|
-
var boxes = [];
|
|
990
|
-
for (var nid in nodeBoxMap) boxes.push(nodeBoxMap[nid]);
|
|
991
|
-
var sorted = connIndex.slice().sort(function(a, b) {
|
|
992
|
-
var spa = portPositions[a.src] && portPositions[a.tgt] ? Math.abs(portPositions[a.tgt].cx - portPositions[a.src].cx) : 0;
|
|
993
|
-
var spb = portPositions[b.src] && portPositions[b.tgt] ? Math.abs(portPositions[b.tgt].cx - portPositions[b.src].cx) : 0;
|
|
994
|
-
if (Math.abs(spa - spb) > 1) return spa - spb;
|
|
995
|
-
var sxa = portPositions[a.src] ? portPositions[a.src].cx : 0, sxb = portPositions[b.src] ? portPositions[b.src].cx : 0;
|
|
996
|
-
if (Math.abs(sxa - sxb) > 1) return sxa - sxb;
|
|
997
|
-
var sya = portPositions[a.src] ? portPositions[a.src].cy : 0, syb = portPositions[b.src] ? portPositions[b.src].cy : 0;
|
|
998
|
-
return sya - syb;
|
|
999
|
-
});
|
|
1000
|
-
var alloc = createAllocator();
|
|
1001
|
-
for (var i = 0; i < sorted.length; i++) {
|
|
1002
|
-
var c = sorted[i];
|
|
1003
|
-
var sp = portPositions[c.src], tp = portPositions[c.tgt];
|
|
1004
|
-
if (!sp || !tp) continue;
|
|
1005
|
-
var sx = sp.cx, sy = sp.cy, tx = tp.cx, ty = tp.cy;
|
|
1006
|
-
// For scope connections, use parent-local coords
|
|
1007
|
-
if (c.scopeOf) {
|
|
1008
|
-
var pOff = nodeOffsets[c.scopeOf] || { dx: 0, dy: 0 };
|
|
1009
|
-
sx -= pOff.dx; sy -= pOff.dy; tx -= pOff.dx; ty -= pOff.dy;
|
|
1010
|
-
}
|
|
1011
|
-
var xDist = Math.abs(tx - sx);
|
|
1012
|
-
|
|
1013
|
-
if (xDist > STUB_THRESHOLD) {
|
|
1014
|
-
// Stub mode: hide path, show and reposition stubs
|
|
1015
|
-
c.el.setAttribute('display', 'none');
|
|
1016
|
-
if (c.stubs) {
|
|
1017
|
-
if (c.stubs.src) {
|
|
1018
|
-
var sLen = isLabelVisible(c.src) ? c.stubs.srcOff + STUB_LEN : STUB_LEN;
|
|
1019
|
-
var sLine = c.stubs.src.querySelector('line');
|
|
1020
|
-
var sCirc = c.stubs.src.querySelector('circle');
|
|
1021
|
-
if (sLine) { sLine.setAttribute('x1', sx); sLine.setAttribute('y1', sy); sLine.setAttribute('x2', sx + sLen); sLine.setAttribute('y2', sy); }
|
|
1022
|
-
if (sCirc) { sCirc.setAttribute('cx', sx + sLen); sCirc.setAttribute('cy', sy); }
|
|
1023
|
-
c.stubs.src.removeAttribute('display');
|
|
1024
|
-
}
|
|
1025
|
-
if (c.stubs.tgt) {
|
|
1026
|
-
var tLen = isLabelVisible(c.tgt) ? c.stubs.tgtOff - STUB_LEN : -STUB_LEN;
|
|
1027
|
-
var tLine = c.stubs.tgt.querySelector('line');
|
|
1028
|
-
var tCirc = c.stubs.tgt.querySelector('circle');
|
|
1029
|
-
if (tLine) { tLine.setAttribute('x1', tx); tLine.setAttribute('y1', ty); tLine.setAttribute('x2', tx + tLen); tLine.setAttribute('y2', ty); }
|
|
1030
|
-
if (tCirc) { tCirc.setAttribute('cx', tx + tLen); tCirc.setAttribute('cy', ty); }
|
|
1031
|
-
c.stubs.tgt.removeAttribute('display');
|
|
1032
|
-
}
|
|
1033
|
-
}
|
|
1034
|
-
} else {
|
|
1035
|
-
// Path mode: show path, hide stubs
|
|
1036
|
-
var ddx = tx - sx, ddy = ty - sy, dist = Math.sqrt(ddx * ddx + ddy * ddy);
|
|
1037
|
-
var path;
|
|
1038
|
-
if (dist > ORTHO_THRESHOLD) {
|
|
1039
|
-
path = calcOrthogonalPath([sx, sy], [tx, ty], boxes, c.srcNode, c.tgtNode, c.srcIdx, c.tgtIdx, alloc);
|
|
1040
|
-
if (!path) path = computeConnectionPath(sx, sy, tx, ty);
|
|
1041
|
-
} else {
|
|
1042
|
-
path = computeConnectionPath(sx, sy, tx, ty);
|
|
1043
|
-
}
|
|
1044
|
-
c.el.setAttribute('d', path);
|
|
1045
|
-
c.el.removeAttribute('display');
|
|
1046
|
-
if (c.stubs) {
|
|
1047
|
-
if (c.stubs.src) c.stubs.src.setAttribute('display', 'none');
|
|
1048
|
-
if (c.stubs.tgt) c.stubs.tgt.setAttribute('display', 'none');
|
|
1049
|
-
}
|
|
1050
|
-
}
|
|
1051
|
-
}
|
|
1052
|
-
}
|
|
1053
|
-
|
|
1054
|
-
function resetLayout() {
|
|
1055
|
-
for (var nid in nodeOffsets) {
|
|
1056
|
-
var esc = CSS.escape(nid);
|
|
1057
|
-
var nodeG = content.querySelector('.nodes [data-node-id="' + esc + '"]');
|
|
1058
|
-
if (nodeG) nodeG.removeAttribute('transform');
|
|
1059
|
-
var labelG = content.querySelector('[data-label-for="' + esc + '"]');
|
|
1060
|
-
if (labelG) labelG.removeAttribute('transform');
|
|
1061
|
-
allLabelIds.forEach(function(id) {
|
|
1062
|
-
if (id.indexOf(nid + '.') === 0) {
|
|
1063
|
-
var el = labelMap[id];
|
|
1064
|
-
if (el) el.removeAttribute('transform');
|
|
1065
|
-
}
|
|
1066
|
-
});
|
|
1067
|
-
}
|
|
1068
|
-
nodeOffsets = {};
|
|
1069
|
-
for (var pid in origPortPositions) {
|
|
1070
|
-
portPositions[pid] = { cx: origPortPositions[pid].cx, cy: origPortPositions[pid].cy };
|
|
1071
|
-
}
|
|
1072
|
-
for (var nid in origNodeBoxMap) {
|
|
1073
|
-
var b = origNodeBoxMap[nid];
|
|
1074
|
-
nodeBoxMap[nid] = { id: b.id, x: b.x, y: b.y, w: b.w, h: b.h };
|
|
1075
|
-
}
|
|
1076
|
-
recalcAllPaths();
|
|
1077
|
-
fitToView();
|
|
1078
|
-
}
|
|
1079
|
-
document.getElementById('btn-reset').addEventListener('click', resetLayout);
|
|
1080
|
-
|
|
1081
|
-
// ---- Node drag: moveNode ----
|
|
1082
|
-
function moveNode(nodeId, dx, dy) {
|
|
1083
|
-
if (!nodeOffsets[nodeId]) nodeOffsets[nodeId] = { dx: 0, dy: 0 };
|
|
1084
|
-
var off = nodeOffsets[nodeId];
|
|
1085
|
-
off.dx += dx; off.dy += dy;
|
|
1086
|
-
var tr = 'translate(' + off.dx + ',' + off.dy + ')';
|
|
1087
|
-
|
|
1088
|
-
// Move node group (if nested inside a scoped parent, subtract parent offset)
|
|
1089
|
-
var nodeG = content.querySelector('.nodes [data-node-id="' + CSS.escape(nodeId) + '"]');
|
|
1090
|
-
if (nodeG) {
|
|
1091
|
-
var parentNodeG = nodeG.parentElement ? nodeG.parentElement.closest('[data-node-id]') : null;
|
|
1092
|
-
if (parentNodeG) {
|
|
1093
|
-
var parentId = parentNodeG.getAttribute('data-node-id');
|
|
1094
|
-
var parentOff = nodeOffsets[parentId] || { dx: 0, dy: 0 };
|
|
1095
|
-
nodeG.setAttribute('transform', 'translate(' + (off.dx - parentOff.dx) + ',' + (off.dy - parentOff.dy) + ')');
|
|
1096
|
-
} else {
|
|
1097
|
-
nodeG.setAttribute('transform', tr);
|
|
1098
|
-
}
|
|
1099
|
-
}
|
|
1100
|
-
|
|
1101
|
-
// Move label
|
|
1102
|
-
var labelG = content.querySelector('[data-label-for="' + CSS.escape(nodeId) + '"]');
|
|
1103
|
-
if (labelG) labelG.setAttribute('transform', tr);
|
|
1104
|
-
|
|
1105
|
-
// Move port labels
|
|
1106
|
-
allLabelIds.forEach(function(id) {
|
|
1107
|
-
if (id.indexOf(nodeId + '.') === 0) {
|
|
1108
|
-
var el = labelMap[id];
|
|
1109
|
-
if (el) el.setAttribute('transform', tr);
|
|
1110
|
-
}
|
|
1111
|
-
});
|
|
1112
|
-
|
|
1113
|
-
// Update port positions
|
|
1114
|
-
for (var pid in portPositions) {
|
|
1115
|
-
if (pid.indexOf(nodeId + '.') === 0) {
|
|
1116
|
-
portPositions[pid].cx += dx;
|
|
1117
|
-
portPositions[pid].cy += dy;
|
|
1118
|
-
}
|
|
1119
|
-
}
|
|
1120
|
-
|
|
1121
|
-
// Move child nodes inside scoped parents
|
|
1122
|
-
if (nodeG) {
|
|
1123
|
-
var children = nodeG.querySelectorAll(':scope > g[data-node-id]');
|
|
1124
|
-
children.forEach(function(childG) {
|
|
1125
|
-
var childId = childG.getAttribute('data-node-id');
|
|
1126
|
-
if (!nodeOffsets[childId]) nodeOffsets[childId] = { dx: 0, dy: 0 };
|
|
1127
|
-
nodeOffsets[childId].dx += dx;
|
|
1128
|
-
nodeOffsets[childId].dy += dy;
|
|
1129
|
-
for (var pid in portPositions) {
|
|
1130
|
-
if (pid.indexOf(childId + '.') === 0) {
|
|
1131
|
-
portPositions[pid].cx += dx;
|
|
1132
|
-
portPositions[pid].cy += dy;
|
|
1133
|
-
}
|
|
1134
|
-
}
|
|
1135
|
-
var childLabel = content.querySelector('[data-label-for="' + CSS.escape(childId) + '"]');
|
|
1136
|
-
if (childLabel) childLabel.setAttribute('transform', 'translate(' + nodeOffsets[childId].dx + ',' + nodeOffsets[childId].dy + ')');
|
|
1137
|
-
allLabelIds.forEach(function(id) {
|
|
1138
|
-
if (id.indexOf(childId + '.') === 0) {
|
|
1139
|
-
var el = labelMap[id];
|
|
1140
|
-
if (el) el.setAttribute('transform', 'translate(' + nodeOffsets[childId].dx + ',' + nodeOffsets[childId].dy + ')');
|
|
1141
|
-
}
|
|
1142
|
-
});
|
|
1143
|
-
});
|
|
1144
|
-
}
|
|
1145
|
-
|
|
1146
|
-
// Update node box positions for orthogonal routing
|
|
1147
|
-
if (nodeBoxMap[nodeId]) {
|
|
1148
|
-
var nb = origNodeBoxMap[nodeId];
|
|
1149
|
-
if (nb) nodeBoxMap[nodeId] = { id: nb.id, x: nb.x + off.dx, y: nb.y + off.dy, w: nb.w, h: nb.h };
|
|
1150
|
-
}
|
|
1151
|
-
if (nodeG) {
|
|
1152
|
-
var children = nodeG.querySelectorAll(':scope > g[data-node-id]');
|
|
1153
|
-
children.forEach(function(childG) {
|
|
1154
|
-
var childId = childG.getAttribute('data-node-id');
|
|
1155
|
-
var cnb = origNodeBoxMap[childId];
|
|
1156
|
-
if (cnb && nodeOffsets[childId]) {
|
|
1157
|
-
nodeBoxMap[childId] = { id: cnb.id, x: cnb.x + nodeOffsets[childId].dx, y: cnb.y + nodeOffsets[childId].dy, w: cnb.w, h: cnb.h };
|
|
1158
|
-
}
|
|
1159
|
-
});
|
|
1160
|
-
}
|
|
1161
|
-
|
|
1162
|
-
// Recalculate all connection paths with orthogonal routing
|
|
1163
|
-
recalcAllPaths();
|
|
1164
|
-
}
|
|
1165
|
-
|
|
1166
|
-
var allLabelIds = Object.keys(labelMap);
|
|
1167
|
-
var hoveredPort = null;
|
|
1168
|
-
var hoveredNode = null;
|
|
1169
|
-
var activeAnims = {};
|
|
1170
|
-
|
|
1171
|
-
// Build reverse map: portId -> array of { connEntry, isSource }
|
|
1172
|
-
var portStubMap = {};
|
|
1173
|
-
for (var psi = 0; psi < connIndex.length; psi++) {
|
|
1174
|
-
var psc = connIndex[psi];
|
|
1175
|
-
if (!psc.stubs) continue;
|
|
1176
|
-
if (psc.stubs.src) {
|
|
1177
|
-
if (!portStubMap[psc.src]) portStubMap[psc.src] = [];
|
|
1178
|
-
portStubMap[psc.src].push({ c: psc, isSource: true });
|
|
1179
|
-
}
|
|
1180
|
-
if (psc.stubs.tgt) {
|
|
1181
|
-
if (!portStubMap[psc.tgt]) portStubMap[psc.tgt] = [];
|
|
1182
|
-
portStubMap[psc.tgt].push({ c: psc, isSource: false });
|
|
1183
|
-
}
|
|
1184
|
-
}
|
|
1185
|
-
|
|
1186
|
-
function isLabelVisible(id) {
|
|
1187
|
-
var l = labelMap[id];
|
|
1188
|
-
return l && l.style.opacity === '1';
|
|
1189
|
-
}
|
|
1190
|
-
|
|
1191
|
-
// Batch mode: defer stub sync until all label changes are done
|
|
1192
|
-
var stubSyncDeferred = false;
|
|
1193
|
-
var stubSyncPorts = {};
|
|
1194
|
-
|
|
1195
|
-
function showLabel(id) {
|
|
1196
|
-
var l = labelMap[id];
|
|
1197
|
-
if (l) { l.style.opacity = '1'; l.style.pointerEvents = 'auto'; }
|
|
1198
|
-
if (stubSyncDeferred) { stubSyncPorts[id] = true; }
|
|
1199
|
-
else { syncStubsForPort(id); }
|
|
1200
|
-
}
|
|
1201
|
-
function hideLabel(id) {
|
|
1202
|
-
var l = labelMap[id];
|
|
1203
|
-
if (l) { l.style.opacity = '0'; l.style.pointerEvents = 'none'; }
|
|
1204
|
-
if (stubSyncDeferred) { stubSyncPorts[id] = true; }
|
|
1205
|
-
else { syncStubsForPort(id); }
|
|
1206
|
-
}
|
|
1207
|
-
|
|
1208
|
-
// Batch label changes: do all shows/hides, then sync stubs once
|
|
1209
|
-
function batchLabelChanges(fn) {
|
|
1210
|
-
stubSyncDeferred = true;
|
|
1211
|
-
stubSyncPorts = {};
|
|
1212
|
-
fn();
|
|
1213
|
-
stubSyncDeferred = false;
|
|
1214
|
-
for (var pid in stubSyncPorts) syncStubsForPort(pid);
|
|
1215
|
-
}
|
|
1216
|
-
|
|
1217
|
-
function syncStubsForPort(portId) {
|
|
1218
|
-
var entries = portStubMap[portId];
|
|
1219
|
-
if (!entries) return;
|
|
1220
|
-
var visible = isLabelVisible(portId);
|
|
1221
|
-
for (var ei = 0; ei < entries.length; ei++) {
|
|
1222
|
-
growStub(entries[ei].c.stubs, entries[ei].c, entries[ei].isSource, visible);
|
|
1223
|
-
}
|
|
1224
|
-
}
|
|
1225
|
-
|
|
1226
|
-
// Safety net: verify all stubs match their port label visibility.
|
|
1227
|
-
// Runs as a rAF so it fires after all events and microtasks settle.
|
|
1228
|
-
var stubVerifyScheduled = false;
|
|
1229
|
-
function scheduleStubVerify() {
|
|
1230
|
-
if (stubVerifyScheduled) return;
|
|
1231
|
-
stubVerifyScheduled = true;
|
|
1232
|
-
requestAnimationFrame(function() {
|
|
1233
|
-
stubVerifyScheduled = false;
|
|
1234
|
-
for (var pid in portStubMap) syncStubsForPort(pid);
|
|
1235
|
-
});
|
|
1236
|
-
}
|
|
1237
|
-
|
|
1238
|
-
function showLabelsFor(nodeId) {
|
|
1239
|
-
allLabelIds.forEach(function(id) {
|
|
1240
|
-
if (id.indexOf(nodeId + '.') === 0) showLabel(id);
|
|
1241
|
-
});
|
|
1242
|
-
}
|
|
1243
|
-
function hideLabelsFor(nodeId) {
|
|
1244
|
-
allLabelIds.forEach(function(id) {
|
|
1245
|
-
if (id.indexOf(nodeId + '.') === 0) hideLabel(id);
|
|
1246
|
-
});
|
|
1247
|
-
}
|
|
1248
|
-
|
|
1249
|
-
// Animate a stub growing/shrinking. The line x1 stays at port center,
|
|
1250
|
-
// x2 and circle cx extend to targetLen from port center (signed: positive=right, negative=left).
|
|
1251
|
-
function animateStub(stubG, targetLen, key) {
|
|
1252
|
-
if (!stubG) return;
|
|
1253
|
-
var line = stubG.querySelector('line');
|
|
1254
|
-
var circ = stubG.querySelector('circle');
|
|
1255
|
-
if (!line) return;
|
|
1256
|
-
var x1 = parseFloat(line.getAttribute('x1'));
|
|
1257
|
-
var curX2 = parseFloat(line.getAttribute('x2'));
|
|
1258
|
-
var curLen = curX2 - x1;
|
|
1259
|
-
var goalX2 = x1 + targetLen;
|
|
1260
|
-
if (Math.abs(curLen - targetLen) < 0.5) {
|
|
1261
|
-
line.setAttribute('x2', goalX2);
|
|
1262
|
-
if (circ) circ.setAttribute('cx', goalX2);
|
|
1263
|
-
return;
|
|
1264
|
-
}
|
|
1265
|
-
if (activeAnims[key]) cancelAnimationFrame(activeAnims[key]);
|
|
1266
|
-
var start = null, duration = 150, startLen = curLen;
|
|
1267
|
-
function step(ts) {
|
|
1268
|
-
if (!start) start = ts;
|
|
1269
|
-
var t = Math.min((ts - start) / duration, 1);
|
|
1270
|
-
t = t * (2 - t); // ease-out quad
|
|
1271
|
-
var len = startLen + (targetLen - startLen) * t;
|
|
1272
|
-
var x2 = x1 + len;
|
|
1273
|
-
line.setAttribute('x2', x2);
|
|
1274
|
-
if (circ) circ.setAttribute('cx', x2);
|
|
1275
|
-
if (t < 1) activeAnims[key] = requestAnimationFrame(step);
|
|
1276
|
-
else delete activeAnims[key];
|
|
1277
|
-
}
|
|
1278
|
-
activeAnims[key] = requestAnimationFrame(step);
|
|
1279
|
-
}
|
|
1280
|
-
|
|
1281
|
-
function growStub(stubs, connEntry, isSource, grow) {
|
|
1282
|
-
if (!stubs) return;
|
|
1283
|
-
var stubG = isSource ? stubs.src : stubs.tgt;
|
|
1284
|
-
if (!stubG) return;
|
|
1285
|
-
var off = isSource ? stubs.srcOff : stubs.tgtOff;
|
|
1286
|
-
// Source stubs grow right (+), target stubs grow left (-).
|
|
1287
|
-
// off is already signed (positive for source, negative for target).
|
|
1288
|
-
var shortLen = isSource ? STUB_LEN : -STUB_LEN;
|
|
1289
|
-
var fullLen = off + shortLen;
|
|
1290
|
-
var targetLen = grow ? fullLen : shortLen;
|
|
1291
|
-
var key = connEntry.src + '|' + connEntry.tgt + (isSource ? ':s' : ':t');
|
|
1292
|
-
animateStub(stubG, targetLen, key);
|
|
1293
|
-
}
|
|
1294
|
-
|
|
1295
|
-
// Node hover: show all port labels for the hovered node
|
|
1296
|
-
var nodeEls = content.querySelectorAll('.nodes g[data-node-id]');
|
|
1297
|
-
nodeEls.forEach(function(nodeG) {
|
|
1298
|
-
var nodeId = nodeG.getAttribute('data-node-id');
|
|
1299
|
-
var parentNodeG = nodeG.parentElement ? nodeG.parentElement.closest('g[data-node-id]') : null;
|
|
1300
|
-
var parentId = parentNodeG ? parentNodeG.getAttribute('data-node-id') : null;
|
|
1301
|
-
nodeG.addEventListener('mouseenter', function() {
|
|
1302
|
-
hoveredNode = nodeId;
|
|
1303
|
-
if (hoveredPort) return;
|
|
1304
|
-
batchLabelChanges(function() {
|
|
1305
|
-
if (parentId) hideLabelsFor(parentId);
|
|
1306
|
-
showLabelsFor(nodeId);
|
|
1307
|
-
});
|
|
1308
|
-
scheduleStubVerify();
|
|
1309
|
-
});
|
|
1310
|
-
nodeG.addEventListener('mouseleave', function() {
|
|
1311
|
-
// Defer so port mouseenter can set hoveredPort first
|
|
1312
|
-
var nid = nodeId, pid = parentId;
|
|
1313
|
-
if (hoveredNode === nodeId) hoveredNode = null;
|
|
1314
|
-
Promise.resolve().then(function() {
|
|
1315
|
-
if (hoveredPort) return;
|
|
1316
|
-
if (hoveredNode === nid) return; // re-entered the node
|
|
1317
|
-
batchLabelChanges(function() {
|
|
1318
|
-
hideLabelsFor(nid);
|
|
1319
|
-
if (pid) showLabelsFor(pid);
|
|
1320
|
-
});
|
|
1321
|
-
scheduleStubVerify();
|
|
1322
|
-
});
|
|
1323
|
-
});
|
|
1324
|
-
});
|
|
1325
|
-
|
|
1326
|
-
// Port hover: show this port's label + all connected port labels
|
|
1327
|
-
content.querySelectorAll('[data-port-id]').forEach(function(portEl) {
|
|
1328
|
-
var portId = portEl.getAttribute('data-port-id');
|
|
1329
|
-
var nodeId = portId.split('.')[0];
|
|
1330
|
-
var peers = (portConnections[portId] || []).concat(portId);
|
|
1331
|
-
|
|
1332
|
-
portEl.addEventListener('mouseenter', function() {
|
|
1333
|
-
hoveredPort = portId;
|
|
1334
|
-
batchLabelChanges(function() {
|
|
1335
|
-
hideLabelsFor(nodeId);
|
|
1336
|
-
peers.forEach(showLabel);
|
|
1337
|
-
});
|
|
1338
|
-
scheduleStubVerify();
|
|
1339
|
-
document.body.classList.add('port-hovered');
|
|
1340
|
-
content.querySelectorAll('[data-source]').forEach(function(p) {
|
|
1341
|
-
if (p.getAttribute('data-source') === portId || p.getAttribute('data-target') === portId) {
|
|
1342
|
-
p.classList.remove('dimmed');
|
|
1343
|
-
} else {
|
|
1344
|
-
p.classList.add('dimmed');
|
|
1345
|
-
}
|
|
1346
|
-
});
|
|
1347
|
-
});
|
|
1348
|
-
portEl.addEventListener('mouseleave', function() {
|
|
1349
|
-
hoveredPort = null;
|
|
1350
|
-
// Defer so if entering another port, its mouseenter sets hoveredPort first
|
|
1351
|
-
var myPeers = peers, myNodeId = nodeId;
|
|
1352
|
-
Promise.resolve().then(function() {
|
|
1353
|
-
if (hoveredPort) return; // moved to another port
|
|
1354
|
-
batchLabelChanges(function() {
|
|
1355
|
-
myPeers.forEach(hideLabel);
|
|
1356
|
-
showLabelsFor(myNodeId);
|
|
1357
|
-
});
|
|
1358
|
-
document.body.classList.remove('port-hovered');
|
|
1359
|
-
content.querySelectorAll('[data-source].dimmed').forEach(function(p) {
|
|
1360
|
-
p.classList.remove('dimmed');
|
|
1361
|
-
});
|
|
1362
|
-
scheduleStubVerify();
|
|
1363
|
-
});
|
|
1364
|
-
});
|
|
1365
|
-
});
|
|
1366
|
-
|
|
1367
|
-
// ---- Node glow helpers ----
|
|
1368
|
-
function removeNodeGlow() {
|
|
1369
|
-
var glow = content.querySelector('.node-glow');
|
|
1370
|
-
if (glow) glow.remove();
|
|
1371
|
-
}
|
|
1372
|
-
|
|
1373
|
-
function addNodeGlow(nodeG) {
|
|
1374
|
-
removeNodeGlow();
|
|
1375
|
-
var rect = nodeG.querySelector('rect');
|
|
1376
|
-
if (!rect) return;
|
|
1377
|
-
var ns = 'http://www.w3.org/2000/svg';
|
|
1378
|
-
var glow = document.createElementNS(ns, 'rect');
|
|
1379
|
-
glow.setAttribute('x', rect.getAttribute('x'));
|
|
1380
|
-
glow.setAttribute('y', rect.getAttribute('y'));
|
|
1381
|
-
glow.setAttribute('width', rect.getAttribute('width'));
|
|
1382
|
-
glow.setAttribute('height', rect.getAttribute('height'));
|
|
1383
|
-
glow.setAttribute('rx', rect.getAttribute('rx') || '0');
|
|
1384
|
-
glow.setAttribute('stroke', rect.getAttribute('stroke') || '#5468ff');
|
|
1385
|
-
glow.setAttribute('class', 'node-glow');
|
|
1386
|
-
nodeG.insertBefore(glow, rect);
|
|
1387
|
-
}
|
|
1388
|
-
|
|
1389
|
-
// ---- Port selection ----
|
|
1390
|
-
function deselectPort() {
|
|
1391
|
-
if (!selectedPortId) return;
|
|
1392
|
-
selectedPortId = null;
|
|
1393
|
-
document.body.classList.remove('port-active');
|
|
1394
|
-
content.querySelectorAll('circle.port-selected').forEach(function(c) {
|
|
1395
|
-
c.classList.remove('port-selected');
|
|
1396
|
-
});
|
|
1397
|
-
content.querySelectorAll('[data-source].dimmed, [data-source].highlighted').forEach(function(p) {
|
|
1398
|
-
p.classList.remove('dimmed');
|
|
1399
|
-
p.classList.remove('highlighted');
|
|
1400
|
-
});
|
|
1401
|
-
}
|
|
1402
|
-
|
|
1403
|
-
function selectPort(portId) {
|
|
1404
|
-
if (selectedPortId === portId) { deselectPort(); return; }
|
|
1405
|
-
if (selectedNodeId) deselectNode();
|
|
1406
|
-
deselectPort();
|
|
1407
|
-
selectedPortId = portId;
|
|
1408
|
-
document.body.classList.add('port-active');
|
|
1409
|
-
|
|
1410
|
-
var portEl = content.querySelector('[data-port-id="' + CSS.escape(portId) + '"]');
|
|
1411
|
-
if (portEl) portEl.classList.add('port-selected');
|
|
1412
|
-
|
|
1413
|
-
content.querySelectorAll('[data-source]').forEach(function(p) {
|
|
1414
|
-
if (p.getAttribute('data-source') === portId || p.getAttribute('data-target') === portId) {
|
|
1415
|
-
p.classList.add('highlighted');
|
|
1416
|
-
} else {
|
|
1417
|
-
p.classList.add('dimmed');
|
|
1418
|
-
}
|
|
1419
|
-
});
|
|
1420
|
-
|
|
1421
|
-
var peers = (portConnections[portId] || []).concat(portId);
|
|
1422
|
-
peers.forEach(showLabel);
|
|
1423
|
-
}
|
|
1424
|
-
|
|
1425
|
-
// ---- Click to inspect node ----
|
|
1426
|
-
function deselectNode() {
|
|
1427
|
-
selectedNodeId = null;
|
|
1428
|
-
document.body.classList.remove('node-active');
|
|
1429
|
-
infoPanel.classList.remove('visible');
|
|
1430
|
-
infoPanel.classList.remove('fullscreen');
|
|
1431
|
-
btnExpand.innerHTML = expandIcon;
|
|
1432
|
-
removeNodeGlow();
|
|
1433
|
-
content.querySelectorAll('[data-source].dimmed').forEach(function(p) {
|
|
1434
|
-
p.classList.remove('dimmed');
|
|
1435
|
-
});
|
|
1436
|
-
}
|
|
1437
|
-
|
|
1438
|
-
function selectNode(nodeId) {
|
|
1439
|
-
if (selectedNodeId === nodeId) { deselectNode(); return; }
|
|
1440
|
-
selectedNodeId = nodeId;
|
|
1441
|
-
document.body.classList.add('node-active');
|
|
1442
|
-
|
|
1443
|
-
var nodeG = content.querySelector('[data-node-id="' + CSS.escape(nodeId) + '"]');
|
|
1444
|
-
addNodeGlow(nodeG);
|
|
1445
|
-
|
|
1446
|
-
var labelG = content.querySelector('[data-label-for="' + CSS.escape(nodeId) + '"]');
|
|
1447
|
-
var labelText = labelG ? (labelG.querySelector('.node-label') || {}).textContent || nodeId : nodeId;
|
|
1448
|
-
|
|
1449
|
-
// Ports
|
|
1450
|
-
var ports = content.querySelectorAll('[data-port-id^="' + CSS.escape(nodeId) + '."]');
|
|
1451
|
-
var inputs = [], outputs = [];
|
|
1452
|
-
ports.forEach(function(p) {
|
|
1453
|
-
var id = p.getAttribute('data-port-id');
|
|
1454
|
-
var dir = p.getAttribute('data-direction');
|
|
1455
|
-
var name = id.split('.').slice(1).join('.').replace(/:(?:input|output)$/, '');
|
|
1456
|
-
if (dir === 'input') inputs.push(name);
|
|
1457
|
-
else outputs.push(name);
|
|
1458
|
-
});
|
|
1459
|
-
|
|
1460
|
-
// Connected paths
|
|
1461
|
-
var allPaths = content.querySelectorAll('[data-source]');
|
|
1462
|
-
var connectedNodes = new Set();
|
|
1463
|
-
allPaths.forEach(function(p) {
|
|
1464
|
-
var src = p.getAttribute('data-source') || '';
|
|
1465
|
-
var tgt = p.getAttribute('data-target') || '';
|
|
1466
|
-
var srcNode = src.split('.')[0];
|
|
1467
|
-
var tgtNode = tgt.split('.')[0];
|
|
1468
|
-
if (srcNode === nodeId || tgtNode === nodeId) {
|
|
1469
|
-
if (srcNode !== nodeId) connectedNodes.add(srcNode);
|
|
1470
|
-
if (tgtNode !== nodeId) connectedNodes.add(tgtNode);
|
|
1471
|
-
p.classList.remove('dimmed');
|
|
1472
|
-
} else {
|
|
1473
|
-
p.classList.add('dimmed');
|
|
1474
|
-
}
|
|
1475
|
-
});
|
|
1476
|
-
|
|
1477
|
-
// Build info panel
|
|
1478
|
-
infoTitle.textContent = labelText;
|
|
1479
|
-
var html = '';
|
|
1480
|
-
var src = nodeSources[nodeId];
|
|
1481
|
-
if (src && src.description) {
|
|
1482
|
-
html += '<div class="node-desc">' + escapeH(src.description) + '</div>';
|
|
1483
|
-
}
|
|
1484
|
-
var portInfo = (src && src.ports) ? src.ports : {};
|
|
1485
|
-
function portLabel(name) {
|
|
1486
|
-
var p = portInfo[name];
|
|
1487
|
-
var label = escapeH(name);
|
|
1488
|
-
if (p) {
|
|
1489
|
-
var typeStr = p.tsType || p.type;
|
|
1490
|
-
if (typeStr) label += ' <span class="port-type">' + escapeH(typeStr) + '</span>';
|
|
1491
|
-
}
|
|
1492
|
-
return label;
|
|
1493
|
-
}
|
|
1494
|
-
if (inputs.length) {
|
|
1495
|
-
html += '<div class="info-section"><div class="info-label">Inputs</div><ul class="port-list">';
|
|
1496
|
-
inputs.forEach(function(n) { html += '<li>' + portLabel(n) + '</li>'; });
|
|
1497
|
-
html += '</ul></div>';
|
|
1498
|
-
}
|
|
1499
|
-
if (outputs.length) {
|
|
1500
|
-
html += '<div class="info-section"><div class="info-label">Outputs</div><ul class="port-list">';
|
|
1501
|
-
outputs.forEach(function(n) { html += '<li>' + portLabel(n) + '</li>'; });
|
|
1502
|
-
html += '</ul></div>';
|
|
1503
|
-
}
|
|
1504
|
-
if (connectedNodes.size) {
|
|
1505
|
-
html += '<div class="info-section"><div class="info-label">Connected to</div><div class="info-value">';
|
|
1506
|
-
html += Array.from(connectedNodes).map(escapeH).join(', ');
|
|
1507
|
-
html += '</div></div>';
|
|
1508
|
-
}
|
|
1509
|
-
if (src && src.source) {
|
|
1510
|
-
html += '<div class="info-section"><div class="info-label">Source</div>';
|
|
1511
|
-
html += '<pre><code>' + highlightTS(src.source) + '</code></pre></div>';
|
|
1512
|
-
}
|
|
1513
|
-
infoBody.innerHTML = html;
|
|
1514
|
-
infoPanel.classList.add('visible');
|
|
1515
|
-
}
|
|
1516
|
-
|
|
1517
|
-
function escapeH(s) {
|
|
1518
|
-
return s.replace(/&/g,'&').replace(/</g,'<').replace(/>/g,'>');
|
|
1519
|
-
}
|
|
1520
|
-
|
|
1521
|
-
var fwAnnotations = 'flowWeaver,input,output,step,node,connect,param,returns,fwImport,label,scope,position,color,icon,tag,map,path,name,description,expression,executeWhen,pullExecution,strictTypes,autoConnect,port,trigger,cancelOn,retries,timeout,throttle';
|
|
1522
|
-
|
|
1523
|
-
function highlightJSDoc(block) {
|
|
1524
|
-
var annSet = fwAnnotations.split(',');
|
|
1525
|
-
var out = '';
|
|
1526
|
-
var re = /(@[a-zA-Z]+)|(->)|(\\.[a-zA-Z_][a-zA-Z0-9_]*)|("[^"]*")|('\\''[^'\\'']*'\\'')|(-?[0-9]+(?:\\.[0-9]+)?)|([a-zA-Z_][a-zA-Z0-9_]*)|([^@a-zA-Z0-9"'\\-.]+)/g;
|
|
1527
|
-
var m;
|
|
1528
|
-
while ((m = re.exec(block)) !== null) {
|
|
1529
|
-
if (m[1]) {
|
|
1530
|
-
var tag = m[1].slice(1);
|
|
1531
|
-
if (annSet.indexOf(tag) >= 0) {
|
|
1532
|
-
out += '<span class="hl-ann">' + m[0] + '</span>';
|
|
1533
|
-
} else {
|
|
1534
|
-
out += '<span class="hl-ann">' + m[0] + '</span>';
|
|
1535
|
-
}
|
|
1536
|
-
} else if (m[2]) {
|
|
1537
|
-
out += '<span class="hl-arr">' + m[2] + '</span>';
|
|
1538
|
-
} else if (m[3]) {
|
|
1539
|
-
// .portName scope reference
|
|
1540
|
-
out += '<span class="hl-sc">' + m[3] + '</span>';
|
|
1541
|
-
} else if (m[4] || m[5]) {
|
|
1542
|
-
out += '<span class="hl-str">' + (m[4] || m[5]) + '</span>';
|
|
1543
|
-
} else if (m[6]) {
|
|
1544
|
-
out += '<span class="hl-num">' + m[6] + '</span>';
|
|
1545
|
-
} else if (m[7]) {
|
|
1546
|
-
var tys = 'string,number,boolean,any,void,never,unknown,STEP,STRING,NUMBER,BOOLEAN,ARRAY,OBJECT,FUNCTION,ANY';
|
|
1547
|
-
if (tys.split(',').indexOf(m[7]) >= 0) {
|
|
1548
|
-
out += '<span class="hl-ty">' + m[7] + '</span>';
|
|
1549
|
-
} else {
|
|
1550
|
-
out += '<span class="hl-id">' + m[7] + '</span>';
|
|
1551
|
-
}
|
|
1552
|
-
} else {
|
|
1553
|
-
out += m[0];
|
|
1554
|
-
}
|
|
1555
|
-
}
|
|
1556
|
-
return out;
|
|
1557
|
-
}
|
|
1558
|
-
|
|
1559
|
-
function highlightTS(code) {
|
|
1560
|
-
var tokens = [];
|
|
1561
|
-
var i = 0;
|
|
1562
|
-
while (i < code.length) {
|
|
1563
|
-
// Line comments
|
|
1564
|
-
if (code[i] === '/' && code[i+1] === '/') {
|
|
1565
|
-
var end = code.indexOf('\\n', i);
|
|
1566
|
-
if (end === -1) end = code.length;
|
|
1567
|
-
tokens.push({ t: 'cm', v: code.slice(i, end) });
|
|
1568
|
-
i = end;
|
|
1569
|
-
continue;
|
|
1570
|
-
}
|
|
1571
|
-
// Block comments (detect JSDoc for annotation highlighting)
|
|
1572
|
-
if (code[i] === '/' && code[i+1] === '*') {
|
|
1573
|
-
var end = code.indexOf('*/', i + 2);
|
|
1574
|
-
if (end === -1) end = code.length; else end += 2;
|
|
1575
|
-
var block = code.slice(i, end);
|
|
1576
|
-
var hasFW = /@(flowWeaver|input|output|step|node|connect|param|returns)/.test(block);
|
|
1577
|
-
if (hasFW) {
|
|
1578
|
-
tokens.push({ t: 'jsdoc', v: block });
|
|
1579
|
-
} else {
|
|
1580
|
-
tokens.push({ t: 'cm', v: block });
|
|
1581
|
-
}
|
|
1582
|
-
i = end;
|
|
1583
|
-
continue;
|
|
1584
|
-
}
|
|
1585
|
-
// Strings
|
|
1586
|
-
if (code[i] === "'" || code[i] === '"' || code[i] === '\`') {
|
|
1587
|
-
var q = code[i], j = i + 1;
|
|
1588
|
-
while (j < code.length && code[j] !== q) { if (code[j] === '\\\\') j++; j++; }
|
|
1589
|
-
tokens.push({ t: 'str', v: code.slice(i, j + 1) });
|
|
1590
|
-
i = j + 1;
|
|
1591
|
-
continue;
|
|
1592
|
-
}
|
|
1593
|
-
// Numbers
|
|
1594
|
-
if (/[0-9]/.test(code[i]) && (i === 0 || /[^a-zA-Z_$]/.test(code[i-1]))) {
|
|
1595
|
-
var j = i;
|
|
1596
|
-
while (j < code.length && /[0-9a-fA-FxX._]/.test(code[j])) j++;
|
|
1597
|
-
tokens.push({ t: 'num', v: code.slice(i, j) });
|
|
1598
|
-
i = j;
|
|
1599
|
-
continue;
|
|
1600
|
-
}
|
|
1601
|
-
// Words
|
|
1602
|
-
if (/[a-zA-Z_$]/.test(code[i])) {
|
|
1603
|
-
var j = i;
|
|
1604
|
-
while (j < code.length && /[a-zA-Z0-9_$]/.test(code[j])) j++;
|
|
1605
|
-
var w = code.slice(i, j);
|
|
1606
|
-
var kws = 'async,await,break,case,catch,class,const,continue,default,delete,do,else,export,extends,finally,for,from,function,if,import,in,instanceof,let,new,of,return,switch,throw,try,typeof,var,void,while,yield';
|
|
1607
|
-
var tys = 'string,number,boolean,any,void,never,unknown,null,undefined,true,false,Promise,Record,Map,Set,Array,Partial,Required,Omit,Pick';
|
|
1608
|
-
if (kws.split(',').indexOf(w) >= 0) {
|
|
1609
|
-
tokens.push({ t: 'kw', v: w });
|
|
1610
|
-
} else if (tys.split(',').indexOf(w) >= 0) {
|
|
1611
|
-
tokens.push({ t: 'ty', v: w });
|
|
1612
|
-
} else if (j < code.length && code[j] === '(') {
|
|
1613
|
-
tokens.push({ t: 'fn', v: w });
|
|
1614
|
-
} else {
|
|
1615
|
-
tokens.push({ t: '', v: w });
|
|
1616
|
-
}
|
|
1617
|
-
i = j;
|
|
1618
|
-
continue;
|
|
1619
|
-
}
|
|
1620
|
-
// Punctuation
|
|
1621
|
-
if (/[{}()\\[\\];:.,<>=!&|?+\\-*/%^~@]/.test(code[i])) {
|
|
1622
|
-
tokens.push({ t: 'pn', v: code[i] });
|
|
1623
|
-
i++;
|
|
1624
|
-
continue;
|
|
1625
|
-
}
|
|
1626
|
-
// Whitespace and other
|
|
1627
|
-
tokens.push({ t: '', v: code[i] });
|
|
1628
|
-
i++;
|
|
1629
|
-
}
|
|
1630
|
-
return tokens.map(function(tk) {
|
|
1631
|
-
if (tk.t === 'jsdoc') {
|
|
1632
|
-
return '<span class="hl-cm">' + highlightJSDoc(escapeH(tk.v)) + '</span>';
|
|
1633
|
-
}
|
|
1634
|
-
var v = escapeH(tk.v);
|
|
1635
|
-
return tk.t ? '<span class="hl-' + tk.t + '">' + v + '</span>' : v;
|
|
1636
|
-
}).join('');
|
|
1637
|
-
}
|
|
1638
|
-
|
|
1639
|
-
// Delegate click: port click > node click > background
|
|
1640
|
-
// Use clickTarget (stashed from pointerdown) because setPointerCapture redirects click to canvas
|
|
1641
|
-
canvas.addEventListener('click', function(e) {
|
|
1642
|
-
if (didDrag || didDragNode) { didDragNode = false; return; }
|
|
1643
|
-
var target = clickTarget || e.target;
|
|
1644
|
-
clickTarget = null;
|
|
1645
|
-
while (target && target !== canvas) {
|
|
1646
|
-
if (target.hasAttribute && target.hasAttribute('data-port-id')) {
|
|
1647
|
-
e.stopPropagation();
|
|
1648
|
-
selectPort(target.getAttribute('data-port-id'));
|
|
1649
|
-
return;
|
|
1650
|
-
}
|
|
1651
|
-
if (target.hasAttribute && target.hasAttribute('data-node-id')) {
|
|
1652
|
-
e.stopPropagation();
|
|
1653
|
-
deselectPort();
|
|
1654
|
-
selectNode(target.getAttribute('data-node-id'));
|
|
1655
|
-
return;
|
|
1656
|
-
}
|
|
1657
|
-
target = target.parentElement;
|
|
1658
|
-
}
|
|
1659
|
-
deselectPort();
|
|
1660
|
-
deselectNode();
|
|
1661
|
-
});
|
|
1662
|
-
|
|
1663
|
-
// ---- Panel expand/collapse ----
|
|
1664
|
-
btnExpand.addEventListener('click', function(e) {
|
|
1665
|
-
e.stopPropagation();
|
|
1666
|
-
infoPanel.classList.toggle('fullscreen');
|
|
1667
|
-
btnExpand.innerHTML = infoPanel.classList.contains('fullscreen') ? collapseIcon : expandIcon;
|
|
1668
|
-
btnExpand.title = infoPanel.classList.contains('fullscreen') ? 'Collapse panel' : 'Expand panel';
|
|
1669
|
-
});
|
|
1670
|
-
btnClosePanel.addEventListener('click', function(e) {
|
|
1671
|
-
e.stopPropagation();
|
|
1672
|
-
deselectPort();
|
|
1673
|
-
deselectNode();
|
|
1674
|
-
infoPanel.classList.remove('fullscreen');
|
|
1675
|
-
btnExpand.innerHTML = expandIcon;
|
|
1676
|
-
});
|
|
1677
|
-
|
|
1678
|
-
// ---- Init ----
|
|
1679
|
-
requestAnimationFrame(fitToView);
|
|
1680
|
-
window.addEventListener('resize', fitToView);
|
|
1681
|
-
})();
|
|
1682
|
-
</script>
|
|
1683
|
-
</body>
|
|
1684
|
-
</html>`;
|
|
1685
|
-
}
|
|
1686
|
-
function escapeHtml(s) {
|
|
1687
|
-
return s.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>').replace(/"/g, '"');
|
|
1688
|
-
}
|
|
1689
|
-
//# sourceMappingURL=html-viewer.js.map
|