Browse Source

feat: flow-editor

ryanemax 23 hours ago
parent
commit
8c805aaba3

+ 709 - 0
package-lock.json

@@ -38,6 +38,8 @@
         "fmode-ng": "^0.0.63",
         "ionicons": "^7.2.1",
         "langchain": "^0.3.7",
+        "leafer": "^1.6.1",
+        "leafer-x-connector": "^0.1.3",
         "mammoth": "^1.8.0",
         "parse": "^5.3.0",
         "pdf-parse": "^1.1.1",
@@ -6695,6 +6697,657 @@
         "@langchain/core": ">=0.2.21 <0.4.0"
       }
     },
+    "node_modules/@leafer-in/animate": {
+      "version": "1.6.1",
+      "resolved": "https://registry.npmjs.org/@leafer-in/animate/-/animate-1.6.1.tgz",
+      "integrity": "sha512-AOF45oWV4ofvKKceMlPyKoBuxRGNOfhlAeKwAQlUje6/hC2iBdPEVjJvNrMINn/t0yTimTOU5TQHbEcRzAJ7MQ==",
+      "peerDependencies": {
+        "@leafer-in/color": "^1.6.1",
+        "@leafer-in/interface": "^1.6.1",
+        "@leafer-ui/draw": "^1.6.1",
+        "@leafer-ui/interface": "^1.6.1"
+      }
+    },
+    "node_modules/@leafer-in/arrow": {
+      "version": "1.6.1",
+      "resolved": "https://registry.npmjs.org/@leafer-in/arrow/-/arrow-1.6.1.tgz",
+      "integrity": "sha512-BWo9fF73LtAlsgIN4oIGgqccdqs+MaLPYn0CDklqITB5SRb6WG2rkSIDDPBpH5WxFw5HDXz6ztRr1njUrB1WWQ==",
+      "peerDependencies": {
+        "@leafer-in/interface": "^1.6.1",
+        "@leafer-ui/draw": "^1.6.1",
+        "@leafer-ui/interface": "^1.6.1"
+      }
+    },
+    "node_modules/@leafer-in/color": {
+      "version": "1.6.1",
+      "resolved": "https://registry.npmjs.org/@leafer-in/color/-/color-1.6.1.tgz",
+      "integrity": "sha512-I3Kny9GW7Pde3+6P4yCwdCiE8SMlOXDln6AZyohYuClibw3NjJ2guhookNTEYzBMQF+F3CzG/cyckNm4SqPKkg==",
+      "peerDependencies": {
+        "@leafer-in/interface": "^1.6.1",
+        "@leafer-ui/draw": "^1.6.1",
+        "@leafer-ui/interface": "^1.6.1"
+      }
+    },
+    "node_modules/@leafer-in/editor": {
+      "version": "1.6.1",
+      "resolved": "https://registry.npmjs.org/@leafer-in/editor/-/editor-1.6.1.tgz",
+      "integrity": "sha512-EO3P+/5xHRLOM9lMm3BHmew3+C2SncobOBPPwzXwFxstmcUVRJ9RmRuo9REDaa+kqsPU86aHeDsyhE8ulys//w==",
+      "peerDependencies": {
+        "@leafer-in/interface": "^1.6.1",
+        "@leafer-in/resize": "^1.6.1",
+        "@leafer-ui/core": "^1.6.1",
+        "@leafer-ui/interface": "^1.6.1"
+      }
+    },
+    "node_modules/@leafer-in/export": {
+      "version": "1.6.1",
+      "resolved": "https://registry.npmjs.org/@leafer-in/export/-/export-1.6.1.tgz",
+      "integrity": "sha512-m5+mWEw/mNf2GdSu2JyAfqBbgWjSGIjgiPH+Y0HAwtpboJwfk0S+rifvsHZUlV7nJhRBbHNrDwzoEZ+WsOaRSQ==",
+      "peerDependencies": {
+        "@leafer-in/interface": "^1.6.1",
+        "@leafer-ui/draw": "^1.6.1",
+        "@leafer-ui/interface": "^1.6.1"
+      }
+    },
+    "node_modules/@leafer-in/filter": {
+      "version": "1.6.1",
+      "resolved": "https://registry.npmjs.org/@leafer-in/filter/-/filter-1.6.1.tgz",
+      "integrity": "sha512-7OTK1TTVqwSaqs2xwPU3SGy4EXl/UpNtKt2d2UUySgL3tVsEph9MAuiQh59Xl1HK8Bs7AVMw5gW3KkYtRVk0Pw==",
+      "peerDependencies": {
+        "@leafer-in/interface": "^1.6.1",
+        "@leafer-ui/draw": "^1.6.1",
+        "@leafer-ui/interface": "^1.6.1"
+      }
+    },
+    "node_modules/@leafer-in/find": {
+      "version": "1.6.1",
+      "resolved": "https://registry.npmjs.org/@leafer-in/find/-/find-1.6.1.tgz",
+      "integrity": "sha512-eCP9h49WCMZBwib5ooBDf76mZaU4F5kvXTfwEsbmvDwc47UraVEMJxzd0tQyGdGn4u4+zuGo/19Zq+Xvex8B8w==",
+      "peerDependencies": {
+        "@leafer-in/interface": "^1.6.1",
+        "@leafer-ui/draw": "^1.6.1",
+        "@leafer-ui/interface": "^1.6.1"
+      }
+    },
+    "node_modules/@leafer-in/flow": {
+      "version": "1.6.1",
+      "resolved": "https://registry.npmjs.org/@leafer-in/flow/-/flow-1.6.1.tgz",
+      "integrity": "sha512-BR6cKc5LDybrMxBOIJqCXlt3ahDh1QDpfFE8G5b1TZdxdFQGQpb0lpxoj1Uu/N+A9/dT7LPP0FunDCoGhnhu8w==",
+      "peerDependencies": {
+        "@leafer-in/interface": "^1.6.1",
+        "@leafer-in/resize": "^1.6.1",
+        "@leafer-ui/draw": "^1.6.1",
+        "@leafer-ui/interface": "^1.6.1"
+      }
+    },
+    "node_modules/@leafer-in/html": {
+      "version": "1.6.1",
+      "resolved": "https://registry.npmjs.org/@leafer-in/html/-/html-1.6.1.tgz",
+      "integrity": "sha512-sz2bwJSNGfSZXV8da11PANTYb8OFcDFK1xXXUKccrnJJnLgyn0o738qwziTllFBTIDBT25qzQfxzv1ZAL37hFg==",
+      "peerDependencies": {
+        "@leafer-in/interface": "^1.6.1",
+        "@leafer-ui/draw": "^1.6.1",
+        "@leafer-ui/interface": "^1.6.1"
+      }
+    },
+    "node_modules/@leafer-in/interface": {
+      "version": "1.6.1",
+      "resolved": "https://registry.npmjs.org/@leafer-in/interface/-/interface-1.6.1.tgz",
+      "integrity": "sha512-Bj50xM9arc6ijc0Gk8oAt7qKIQkCG+a9nURj92hT17DuBNQrCJbdRz2kePBKG5CXOeNe2COxmrDTNW5rF12c0w==",
+      "peerDependencies": {
+        "@leafer-ui/interface": "^1.6.1",
+        "@leafer/interface": "^1.6.1"
+      }
+    },
+    "node_modules/@leafer-in/motion-path": {
+      "version": "1.6.1",
+      "resolved": "https://registry.npmjs.org/@leafer-in/motion-path/-/motion-path-1.6.1.tgz",
+      "integrity": "sha512-fAwtNKmXLfTJMCRLMxsnXL9OEpdl1HFxw2Lc7zFIVJhvJ5+FApjgV+J7Ix3xxu8lCftPNkMH/ZBflcFL554QqQ==",
+      "peerDependencies": {
+        "@leafer-in/interface": "^1.6.1",
+        "@leafer-ui/draw": "^1.6.1",
+        "@leafer-ui/interface": "^1.6.1"
+      }
+    },
+    "node_modules/@leafer-in/resize": {
+      "version": "1.6.1",
+      "resolved": "https://registry.npmjs.org/@leafer-in/resize/-/resize-1.6.1.tgz",
+      "integrity": "sha512-rv9QOC2FOnWj6Q6kcZgAbHfteTW6NI5DN4NIrh4GKDkT1s2beJ/C3GMh15uipioXHPISK7Gz4maMSYgiwWuyhg==",
+      "peerDependencies": {
+        "@leafer-in/interface": "^1.6.1",
+        "@leafer-ui/draw": "^1.6.1",
+        "@leafer-ui/interface": "^1.6.1"
+      }
+    },
+    "node_modules/@leafer-in/robot": {
+      "version": "1.6.1",
+      "resolved": "https://registry.npmjs.org/@leafer-in/robot/-/robot-1.6.1.tgz",
+      "integrity": "sha512-fjjDqJSSqvVuzMk0IzqXNuZUx97fd6tNs5jqSfNMfvJedhpMs75O4Ubh3mrZinCTWbueyxJGV7lRu6lafFmS8A==",
+      "peerDependencies": {
+        "@leafer-in/interface": "^1.6.1",
+        "@leafer-ui/draw": "^1.6.1",
+        "@leafer-ui/interface": "^1.6.1"
+      }
+    },
+    "node_modules/@leafer-in/scroll": {
+      "version": "1.6.1",
+      "resolved": "https://registry.npmjs.org/@leafer-in/scroll/-/scroll-1.6.1.tgz",
+      "integrity": "sha512-xlWNZzCWT0TZIszcsYImAhNHN7mvrMAoPIkey2ICoGoeN6cRc9TJzMmToUG5l3ziZa6paG2XbtaWm51kcuBF7A==",
+      "peerDependencies": {
+        "@leafer-in/interface": "^1.6.1",
+        "@leafer-ui/core": "^1.6.1",
+        "@leafer-ui/interface": "^1.6.1"
+      }
+    },
+    "node_modules/@leafer-in/state": {
+      "version": "1.6.1",
+      "resolved": "https://registry.npmjs.org/@leafer-in/state/-/state-1.6.1.tgz",
+      "integrity": "sha512-X92eFCy82/MFDtcWuXzZyvIvj+R+YM9jO4Q+stJW9E3Qi29L80tcLFjzGt7QxpOxiNcfAoz+Rj5VtZenH+bxwA==",
+      "peerDependencies": {
+        "@leafer-in/interface": "^1.6.1",
+        "@leafer-ui/core": "^1.6.1",
+        "@leafer-ui/interface": "^1.6.1"
+      }
+    },
+    "node_modules/@leafer-in/text-editor": {
+      "version": "1.6.1",
+      "resolved": "https://registry.npmjs.org/@leafer-in/text-editor/-/text-editor-1.6.1.tgz",
+      "integrity": "sha512-eTLqZ73550fCYbc8pJDs2+PQHLlX+X7/FMw5fB9CR8jhuDfw3ghSex1AM12koOa72+Duo/rNjwgWui86VJ+R4A==",
+      "peerDependencies": {
+        "@leafer-in/editor": "^1.6.1",
+        "@leafer-in/interface": "^1.6.1",
+        "@leafer-ui/core": "^1.6.1",
+        "@leafer-ui/interface": "^1.6.1"
+      }
+    },
+    "node_modules/@leafer-in/view": {
+      "version": "1.6.1",
+      "resolved": "https://registry.npmjs.org/@leafer-in/view/-/view-1.6.1.tgz",
+      "integrity": "sha512-itNvBDHqZdYObY89CFoKlQtD4/sf1Xd6PWdBinruoQpVlX4ZYZFSjb4CRfVCcoSo6qUTdxzb9egkDx5i9aTENg==",
+      "peerDependencies": {
+        "@leafer-in/interface": "^1.6.1",
+        "@leafer-ui/draw": "^1.6.1",
+        "@leafer-ui/interface": "^1.6.1"
+      }
+    },
+    "node_modules/@leafer-in/viewport": {
+      "version": "1.6.1",
+      "resolved": "https://registry.npmjs.org/@leafer-in/viewport/-/viewport-1.6.1.tgz",
+      "integrity": "sha512-MkUficRaQ5qvsVm9Q7nQUyKBcXXREhO+mrr2G63OLiVLOTc8GARimBcyODNr3UNUduMg20/GQXlqitvQF40Myg==",
+      "peerDependencies": {
+        "@leafer-in/interface": "^1.6.1",
+        "@leafer-ui/core": "^1.6.1",
+        "@leafer-ui/interface": "^1.6.1"
+      }
+    },
+    "node_modules/@leafer-ui/app": {
+      "version": "1.6.1",
+      "resolved": "https://registry.npmjs.org/@leafer-ui/app/-/app-1.6.1.tgz",
+      "integrity": "sha512-sehmTxMLx+xRBfaYG1MjGgohM+mUymWOjTV4xCBaMfMY2jSHF1fllRq2OnZ4gbQt6f5Sky/AVcRUASLM4h+n+Q==",
+      "dependencies": {
+        "@leafer-ui/data": "1.6.1",
+        "@leafer-ui/display": "1.6.1",
+        "@leafer/core": "1.6.1"
+      }
+    },
+    "node_modules/@leafer-ui/bounds": {
+      "version": "1.6.1",
+      "resolved": "https://registry.npmjs.org/@leafer-ui/bounds/-/bounds-1.6.1.tgz",
+      "integrity": "sha512-8kw9eOBOcOvc9A2ZnL4bytBuUR/d+z9BZggsPpM6D918eXuNC+qwrguuc+qhRglz/aAKGWWhKnCY7Q1X59HdFw==",
+      "dependencies": {
+        "@leafer/core": "1.6.1"
+      }
+    },
+    "node_modules/@leafer-ui/color": {
+      "version": "1.6.1",
+      "resolved": "https://registry.npmjs.org/@leafer-ui/color/-/color-1.6.1.tgz",
+      "integrity": "sha512-z7ix4Ifat7GvVAIbGLCOJ9UHOh9oeqGvZNzI1ROXbpietWcSsx0O6IpqaTkkfPsZNIn5YHOR/b5ARkTEnu0wMw==",
+      "dependencies": {
+        "@leafer-ui/draw": "1.6.1"
+      }
+    },
+    "node_modules/@leafer-ui/core": {
+      "version": "1.6.1",
+      "resolved": "https://registry.npmjs.org/@leafer-ui/core/-/core-1.6.1.tgz",
+      "integrity": "sha512-kzF02FgQFh0u3s5lDV+BkmkUHoenA47wkgRCyGETAGNPMzjCthr3uhZh8IzULE+9BC34iEdeZ5bqFyrkAm/8Rg==",
+      "dependencies": {
+        "@leafer-ui/app": "1.6.1",
+        "@leafer-ui/draw": "1.6.1",
+        "@leafer-ui/event": "1.6.1",
+        "@leafer-ui/hit": "1.6.1",
+        "@leafer-ui/interaction": "1.6.1"
+      }
+    },
+    "node_modules/@leafer-ui/data": {
+      "version": "1.6.1",
+      "resolved": "https://registry.npmjs.org/@leafer-ui/data/-/data-1.6.1.tgz",
+      "integrity": "sha512-l44RqQ3W1KHID6n8pkKz8XKcOzSKR2nc8pwvZIDa4Uss5pQBUpZhNS2RY1/ldJ/7YCQ0a6Z5s3hGKFBpUdRNsA==",
+      "dependencies": {
+        "@leafer-ui/external": "1.6.1",
+        "@leafer/core": "1.6.1"
+      }
+    },
+    "node_modules/@leafer-ui/decorator": {
+      "version": "1.6.1",
+      "resolved": "https://registry.npmjs.org/@leafer-ui/decorator/-/decorator-1.6.1.tgz",
+      "integrity": "sha512-Gzu9l/L4ahmDaLEFUFePqpzhkN5xEYb0UWES2p+n/4Gg/9mAWdnW5cBEYU8XfGh+AOYlwiKj5osVnxce+YOeZw==",
+      "dependencies": {
+        "@leafer/core": "1.6.1"
+      }
+    },
+    "node_modules/@leafer-ui/display": {
+      "version": "1.6.1",
+      "resolved": "https://registry.npmjs.org/@leafer-ui/display/-/display-1.6.1.tgz",
+      "integrity": "sha512-gL4dq+gdGzJmkLjenwtcvgGm029NXrUFZrPd0kUUr42WNWktk8gmp9fWlQVCSCDTUOyg0yGd60a/jNlhBFtBhA==",
+      "dependencies": {
+        "@leafer-ui/data": "1.6.1",
+        "@leafer-ui/decorator": "1.6.1",
+        "@leafer-ui/display-module": "1.6.1",
+        "@leafer-ui/external": "1.6.1",
+        "@leafer/core": "1.6.1"
+      }
+    },
+    "node_modules/@leafer-ui/display-module": {
+      "version": "1.6.1",
+      "resolved": "https://registry.npmjs.org/@leafer-ui/display-module/-/display-module-1.6.1.tgz",
+      "integrity": "sha512-2IcgPLy+IWWDc98mCmgQIM/SLeHXNIaGA+J5dKpX1WmHF+tn4ihuzSUdLy3PSMrOccCZA53F1O7kp6g05LALgg==",
+      "dependencies": {
+        "@leafer-ui/bounds": "1.6.1",
+        "@leafer-ui/data": "1.6.1",
+        "@leafer-ui/render": "1.6.1"
+      }
+    },
+    "node_modules/@leafer-ui/draw": {
+      "version": "1.6.1",
+      "resolved": "https://registry.npmjs.org/@leafer-ui/draw/-/draw-1.6.1.tgz",
+      "integrity": "sha512-1/PrqN4pk0xLzHTczHt+soTVc7lAFqPYnSVHE3xiJYpiCaGINTMhMX2GDxbJiZPZXxPhJYLSsZquSEyk8Hc4SA==",
+      "dependencies": {
+        "@leafer-ui/decorator": "1.6.1",
+        "@leafer-ui/display": "1.6.1",
+        "@leafer-ui/display-module": "1.6.1",
+        "@leafer-ui/external": "1.6.1",
+        "@leafer/core": "1.6.1"
+      }
+    },
+    "node_modules/@leafer-ui/effect": {
+      "version": "1.6.1",
+      "resolved": "https://registry.npmjs.org/@leafer-ui/effect/-/effect-1.6.1.tgz",
+      "integrity": "sha512-is6LcfdKpTv7objz5X691ZhPKLiYc1G4RLp+Isxthk4JeJ9PZbdo5yWTDlNtL1NZR0T0c9IR88QE8q6P3Fqwjw==",
+      "dependencies": {
+        "@leafer-ui/draw": "1.6.1",
+        "@leafer/core": "1.6.1"
+      }
+    },
+    "node_modules/@leafer-ui/event": {
+      "version": "1.6.1",
+      "resolved": "https://registry.npmjs.org/@leafer-ui/event/-/event-1.6.1.tgz",
+      "integrity": "sha512-xEW/qGriHNor0n4DfHM2a0uxEV5n8kPsrpjOflb4IqU8rpWZZqVraBzCI4gI9HFm1sVnxJwWJGSaO1FX2GyllQ==",
+      "dependencies": {
+        "@leafer/core": "1.6.1"
+      }
+    },
+    "node_modules/@leafer-ui/external": {
+      "version": "1.6.1",
+      "resolved": "https://registry.npmjs.org/@leafer-ui/external/-/external-1.6.1.tgz",
+      "integrity": "sha512-/80kChWgbT4mQsD/p1IevY5V0BJC6XjNLZU5RR1nOeW+m/u8wi70aD+22piRe+1+PNJqyHfszbi2Sh2YgZSkLA==",
+      "dependencies": {
+        "@leafer/core": "1.6.1"
+      }
+    },
+    "node_modules/@leafer-ui/hit": {
+      "version": "1.6.1",
+      "resolved": "https://registry.npmjs.org/@leafer-ui/hit/-/hit-1.6.1.tgz",
+      "integrity": "sha512-A44fvMdWz0eF0co5lVxdxcNeGLbALWY0tJtYE6LbuJINlRJfnxOevgTilkfS9yUWM/OflPLlXWa/OqxLXbbu4g==",
+      "dependencies": {
+        "@leafer-ui/draw": "1.6.1",
+        "@leafer/core": "1.6.1"
+      }
+    },
+    "node_modules/@leafer-ui/interaction": {
+      "version": "1.6.1",
+      "resolved": "https://registry.npmjs.org/@leafer-ui/interaction/-/interaction-1.6.1.tgz",
+      "integrity": "sha512-ncT6WWSuDv6MfjfvEkdnwZ2YILiXsOq/y2MGvargIVWZkNEYrDFZbT1bXBRwLUUsStYFZAoBTKgdWSB2cZkYVQ==",
+      "dependencies": {
+        "@leafer-ui/draw": "1.6.1",
+        "@leafer-ui/event": "1.6.1",
+        "@leafer/core": "1.6.1"
+      }
+    },
+    "node_modules/@leafer-ui/interaction-web": {
+      "version": "1.6.1",
+      "resolved": "https://registry.npmjs.org/@leafer-ui/interaction-web/-/interaction-web-1.6.1.tgz",
+      "integrity": "sha512-Z+5927LALoss5ZhDQCrfoCFIRhTwzqVLOSnIYcFiM3zrgOzlPOewv8olQVuMfzBBWygr0uN2MH+5luMn28EGwg==",
+      "dependencies": {
+        "@leafer-ui/core": "1.6.1",
+        "@leafer/core": "1.6.1"
+      }
+    },
+    "node_modules/@leafer-ui/interface": {
+      "version": "1.6.1",
+      "resolved": "https://registry.npmjs.org/@leafer-ui/interface/-/interface-1.6.1.tgz",
+      "integrity": "sha512-zmYi5UkPIVi6k4aMKRcqcJEMo5LpRvuAX6id6ZRoYTHzmCenzEHlJrRLkGHxZ85v0BXvGCDfpNG0tQYLR1Adbg==",
+      "dependencies": {
+        "@leafer/interface": "1.6.1"
+      }
+    },
+    "node_modules/@leafer-ui/paint": {
+      "version": "1.6.1",
+      "resolved": "https://registry.npmjs.org/@leafer-ui/paint/-/paint-1.6.1.tgz",
+      "integrity": "sha512-W/+oAl53DcJxxo5OP36j92ZDiqdSqStUuh9ULkCa7kIc7dT7dNjjCrM0DNdrKFNT98b7EFYvcEuKzBWb8muWRg==",
+      "dependencies": {
+        "@leafer-ui/draw": "1.6.1",
+        "@leafer/core": "1.6.1"
+      }
+    },
+    "node_modules/@leafer-ui/partner": {
+      "version": "1.6.1",
+      "resolved": "https://registry.npmjs.org/@leafer-ui/partner/-/partner-1.6.1.tgz",
+      "integrity": "sha512-xOM69KIYNhowlRtDBzL6W7a42znqABgeK/6OcCJm/mzl/GKePsZngbAcEJ629oKN5igTMX0bmxyPUyLFVlQhAA==",
+      "dependencies": {
+        "@leafer-ui/color": "1.6.1",
+        "@leafer-ui/draw": "1.6.1",
+        "@leafer-ui/effect": "1.6.1",
+        "@leafer-ui/paint": "1.6.1",
+        "@leafer-ui/text": "1.6.1"
+      }
+    },
+    "node_modules/@leafer-ui/render": {
+      "version": "1.6.1",
+      "resolved": "https://registry.npmjs.org/@leafer-ui/render/-/render-1.6.1.tgz",
+      "integrity": "sha512-8nDmI1Is1K+EgPtSxe7AXUWJWnZKEgdKpf0s7j5/t3Aq8BQbpIntiC+4J6UylVR97vREcWsNEC5SOD5z4iwcww==",
+      "dependencies": {
+        "@leafer-ui/external": "1.6.1"
+      }
+    },
+    "node_modules/@leafer-ui/text": {
+      "version": "1.6.1",
+      "resolved": "https://registry.npmjs.org/@leafer-ui/text/-/text-1.6.1.tgz",
+      "integrity": "sha512-aS8G4wcUwEggn4Uuf5kj747V6+4ClTrPeFomwJNoP7XHkrERcFdcvNfNIShPKUqoXRT0ywryOp38xzwK4EA12g==",
+      "dependencies": {
+        "@leafer/core": "1.6.1"
+      }
+    },
+    "node_modules/@leafer-ui/web": {
+      "version": "1.6.1",
+      "resolved": "https://registry.npmjs.org/@leafer-ui/web/-/web-1.6.1.tgz",
+      "integrity": "sha512-Gg7vLEq1qC3w7FhUDf2v10x/NFkd1ABUkKnRkgywAroHcd1aeZVHtoXpMoonYQZEFMR7S+8ljPTcotOkVxMkuw==",
+      "dependencies": {
+        "@leafer-in/interface": "1.6.1",
+        "@leafer-ui/core": "1.6.1",
+        "@leafer-ui/draw": "1.6.1",
+        "@leafer-ui/interaction-web": "1.6.1",
+        "@leafer-ui/interface": "1.6.1",
+        "@leafer-ui/partner": "1.6.1",
+        "@leafer/canvas-web": "1.6.1",
+        "@leafer/core": "1.6.1",
+        "@leafer/image-web": "1.6.1",
+        "@leafer/interface": "1.6.1",
+        "@leafer/partner": "1.6.1"
+      }
+    },
+    "node_modules/@leafer/canvas": {
+      "version": "1.6.1",
+      "resolved": "https://registry.npmjs.org/@leafer/canvas/-/canvas-1.6.1.tgz",
+      "integrity": "sha512-KLsiFDvnijlyDCx2VEqdrFU8PjRbNY2dMA/CE9yUDT7lC83IjtvsFwpIXO38ERC0ERu0i3SnxggLgLvgmhEKFQ==",
+      "dependencies": {
+        "@leafer/data": "1.6.1",
+        "@leafer/debug": "1.6.1",
+        "@leafer/file": "1.6.1",
+        "@leafer/list": "1.6.1",
+        "@leafer/math": "1.6.1",
+        "@leafer/path": "1.6.1",
+        "@leafer/platform": "1.6.1"
+      }
+    },
+    "node_modules/@leafer/canvas-web": {
+      "version": "1.6.1",
+      "resolved": "https://registry.npmjs.org/@leafer/canvas-web/-/canvas-web-1.6.1.tgz",
+      "integrity": "sha512-B9qmH99SxAzur+AfdQaQnkQZj2uwnlPMRbCica36gW+Epa2icxgaTP+ubBMa8FpA9LPcN/8GM5DIDcBWfu4Sig==",
+      "dependencies": {
+        "@leafer/core": "1.6.1"
+      }
+    },
+    "node_modules/@leafer/core": {
+      "version": "1.6.1",
+      "resolved": "https://registry.npmjs.org/@leafer/core/-/core-1.6.1.tgz",
+      "integrity": "sha512-n1vbSoaQCIZPk/PvsJXY7uV6ubzsmiEAuOs/ejC9sHWqi/GrJ6ii7iIaX60A77bWTJG4ROuSofezIRplHYwJDg==",
+      "dependencies": {
+        "@leafer/canvas": "1.6.1",
+        "@leafer/data": "1.6.1",
+        "@leafer/debug": "1.6.1",
+        "@leafer/decorator": "1.6.1",
+        "@leafer/display": "1.6.1",
+        "@leafer/display-module": "1.6.1",
+        "@leafer/event": "1.6.1",
+        "@leafer/file": "1.6.1",
+        "@leafer/helper": "1.6.1",
+        "@leafer/image": "1.6.1",
+        "@leafer/layout": "1.6.1",
+        "@leafer/list": "1.6.1",
+        "@leafer/math": "1.6.1",
+        "@leafer/path": "1.6.1",
+        "@leafer/platform": "1.6.1",
+        "@leafer/task": "1.6.1"
+      }
+    },
+    "node_modules/@leafer/data": {
+      "version": "1.6.1",
+      "resolved": "https://registry.npmjs.org/@leafer/data/-/data-1.6.1.tgz",
+      "integrity": "sha512-wYLBAaAkCzGOD4XlK8AeBVne9ruhpIQc2gO0mziL8VqdSCqFkxS8PYj5NyMPqInQdXEQK7mFVTdkTjPmr+ANmQ=="
+    },
+    "node_modules/@leafer/debug": {
+      "version": "1.6.1",
+      "resolved": "https://registry.npmjs.org/@leafer/debug/-/debug-1.6.1.tgz",
+      "integrity": "sha512-9mQuUfOyH4cjFeIJBnnCteKioLdJcoZILNCpfTuL+J8a/Clh6DyzBnOGw9uLQdHBFBHEmhkx0Dzx5P6ZOCDJnw==",
+      "dependencies": {
+        "@leafer/math": "1.6.1"
+      }
+    },
+    "node_modules/@leafer/decorator": {
+      "version": "1.6.1",
+      "resolved": "https://registry.npmjs.org/@leafer/decorator/-/decorator-1.6.1.tgz",
+      "integrity": "sha512-JtA8T3z1fK5yMDHuMStO85LtgwDXoUeZ2K2DsH6U7qf1CnyN6b+IT6nlJNzgBVqrYLSR55z0Wr/kP4BViGAJLw==",
+      "dependencies": {
+        "@leafer/data": "1.6.1",
+        "@leafer/debug": "1.6.1",
+        "@leafer/platform": "1.6.1"
+      }
+    },
+    "node_modules/@leafer/display": {
+      "version": "1.6.1",
+      "resolved": "https://registry.npmjs.org/@leafer/display/-/display-1.6.1.tgz",
+      "integrity": "sha512-q8IhsTuWKwwFGJqesiMXGwV6rIPFF6Ikpgey242v+ieE6kkjOEYevZUw5+PlEyHpB2nacBvHoP0FxSePQ1HLxA==",
+      "dependencies": {
+        "@leafer/data": "1.6.1",
+        "@leafer/debug": "1.6.1",
+        "@leafer/decorator": "1.6.1",
+        "@leafer/display-module": "1.6.1",
+        "@leafer/event": "1.6.1",
+        "@leafer/helper": "1.6.1",
+        "@leafer/layout": "1.6.1",
+        "@leafer/math": "1.6.1",
+        "@leafer/platform": "1.6.1"
+      }
+    },
+    "node_modules/@leafer/display-module": {
+      "version": "1.6.1",
+      "resolved": "https://registry.npmjs.org/@leafer/display-module/-/display-module-1.6.1.tgz",
+      "integrity": "sha512-48sYM3+gJbDrO4TDCfprH/73NrVvayTpLUu0CU8gEEJUiPr6YyMF5tS4XOhbn44HIrsly90pzjxHDM5Ux0yp3g==",
+      "dependencies": {
+        "@leafer/debug": "1.6.1",
+        "@leafer/event": "1.6.1",
+        "@leafer/helper": "1.6.1",
+        "@leafer/math": "1.6.1"
+      }
+    },
+    "node_modules/@leafer/event": {
+      "version": "1.6.1",
+      "resolved": "https://registry.npmjs.org/@leafer/event/-/event-1.6.1.tgz",
+      "integrity": "sha512-4m4XsyaoMJ/GX6QiFC/JQt/t+4i1/QobL2Nkf3bJl+5D89ZS4pksyAaBfJsyW8gwUIAXdvLrdxTtNJ+/G9IxSw==",
+      "dependencies": {
+        "@leafer/decorator": "1.6.1",
+        "@leafer/math": "1.6.1",
+        "@leafer/platform": "1.6.1"
+      }
+    },
+    "node_modules/@leafer/file": {
+      "version": "1.6.1",
+      "resolved": "https://registry.npmjs.org/@leafer/file/-/file-1.6.1.tgz",
+      "integrity": "sha512-Cd4XSm6uhX1yvhosbSHaoHHNI6mdSTg6kIsfRGkkGHLqc0+CAfbQ1nBXeMsfHaQUqeNYGTiS8YUjmwO3mfNLtQ==",
+      "dependencies": {
+        "@leafer/debug": "1.6.1"
+      }
+    },
+    "node_modules/@leafer/helper": {
+      "version": "1.6.1",
+      "resolved": "https://registry.npmjs.org/@leafer/helper/-/helper-1.6.1.tgz",
+      "integrity": "sha512-EjIrgsjq+Ecd4hNug8JIhw9NbWQUrj9R0i1ivq3rUqEcAvB/kkQt18NRDUqpqgrlqpxYjNVZE5YLlOS8xwOMgg==",
+      "dependencies": {
+        "@leafer/math": "1.6.1"
+      }
+    },
+    "node_modules/@leafer/image": {
+      "version": "1.6.1",
+      "resolved": "https://registry.npmjs.org/@leafer/image/-/image-1.6.1.tgz",
+      "integrity": "sha512-WesEZr0fR8svtlqiKE24cEsXzeBVehZRNtHmc09ckx6hpFNQdttH9ONwbzBes477sbAnQKotNcSTVDDpcX74EA==",
+      "dependencies": {
+        "@leafer/file": "1.6.1",
+        "@leafer/platform": "1.6.1",
+        "@leafer/task": "1.6.1"
+      }
+    },
+    "node_modules/@leafer/image-web": {
+      "version": "1.6.1",
+      "resolved": "https://registry.npmjs.org/@leafer/image-web/-/image-web-1.6.1.tgz",
+      "integrity": "sha512-NlzB9mAX/6tiBeW1wEXVlr3Ft9guA0Gzpx3i0J5SAWX3gg43xExETJjxkuTTuBqahuGD7tN9/Of+F9hcRBbbmA==",
+      "dependencies": {
+        "@leafer/core": "1.6.1"
+      }
+    },
+    "node_modules/@leafer/interface": {
+      "version": "1.6.1",
+      "resolved": "https://registry.npmjs.org/@leafer/interface/-/interface-1.6.1.tgz",
+      "integrity": "sha512-ek+Oz1XjyuIyatgyHJYDplqxfGqXNzyuu4XaaJhzAnVOj4d4rhD9S8/zzl+JbuIADvpg9RrZQX1aCYVS4YaFLQ=="
+    },
+    "node_modules/@leafer/layout": {
+      "version": "1.6.1",
+      "resolved": "https://registry.npmjs.org/@leafer/layout/-/layout-1.6.1.tgz",
+      "integrity": "sha512-rf2l6VaasrqTFPmBW6+ZPw1GP+4VVgr0QtpAznQavUBh/X/RCpcvSUE2BIQtEjNN61EvWziMLMNn1DKYRsfQug==",
+      "dependencies": {
+        "@leafer/helper": "1.6.1",
+        "@leafer/math": "1.6.1",
+        "@leafer/platform": "1.6.1"
+      }
+    },
+    "node_modules/@leafer/layouter": {
+      "version": "1.6.1",
+      "resolved": "https://registry.npmjs.org/@leafer/layouter/-/layouter-1.6.1.tgz",
+      "integrity": "sha512-c70xBMB/e7KgjhscDPXmpJ65+jVWXJ9hq0iKIB2g8YsZaBdGHZrYm9JlzSWc5BFSAQ8H+WnH/82WVOn2ljKVpg==",
+      "dependencies": {
+        "@leafer/core": "1.6.1"
+      }
+    },
+    "node_modules/@leafer/list": {
+      "version": "1.6.1",
+      "resolved": "https://registry.npmjs.org/@leafer/list/-/list-1.6.1.tgz",
+      "integrity": "sha512-HptUgCUk30pVi7O/5bG0+B6wxmR8Qy9UIww2PAMilN9XIq+kyusyIxgPlcpu1SgAAWCSonKaZLUjTLlGUKA4zQ=="
+    },
+    "node_modules/@leafer/math": {
+      "version": "1.6.1",
+      "resolved": "https://registry.npmjs.org/@leafer/math/-/math-1.6.1.tgz",
+      "integrity": "sha512-Xl/p0KDjQVVwXP139WD0Imemn7IRp2rMPndzdePBceHxWeap1Mx+TQLj8Ofs53zjHgI7t2Fzrnq1pP/gODG8VA=="
+    },
+    "node_modules/@leafer/partner": {
+      "version": "1.6.1",
+      "resolved": "https://registry.npmjs.org/@leafer/partner/-/partner-1.6.1.tgz",
+      "integrity": "sha512-MVvF3hKlyRrlgCLqCDRRqi0PBI3Ne6RQHpDk73LJ/77VXC0A1i5Z72GShsvtmhTv5AzphUJVTJIcHFU8rdiNxQ==",
+      "dependencies": {
+        "@leafer/core": "1.6.1",
+        "@leafer/layouter": "1.6.1",
+        "@leafer/renderer": "1.6.1",
+        "@leafer/selector": "1.6.1",
+        "@leafer/watcher": "1.6.1"
+      }
+    },
+    "node_modules/@leafer/path": {
+      "version": "1.6.1",
+      "resolved": "https://registry.npmjs.org/@leafer/path/-/path-1.6.1.tgz",
+      "integrity": "sha512-xafmu7sZMQNtdJdv4+npgyONLJ+iaCZmtveUhB8PbZu/PhMtGPYQwI4Nt3CZJ6KmN2AE8z/XXIG/rIRHNnHCJg==",
+      "dependencies": {
+        "@leafer/debug": "1.6.1",
+        "@leafer/math": "1.6.1"
+      }
+    },
+    "node_modules/@leafer/platform": {
+      "version": "1.6.1",
+      "resolved": "https://registry.npmjs.org/@leafer/platform/-/platform-1.6.1.tgz",
+      "integrity": "sha512-3/0SzI5czDJlb4081E3lzKu1yORouj9yxJ+2cC9U3LWckk58rPXQ6/X4h9LxMlXvy1kX20LvOEiImE9q3gF5Zg==",
+      "dependencies": {
+        "@leafer/debug": "1.6.1",
+        "@leafer/layouter": "1.6.1"
+      }
+    },
+    "node_modules/@leafer/renderer": {
+      "version": "1.6.1",
+      "resolved": "https://registry.npmjs.org/@leafer/renderer/-/renderer-1.6.1.tgz",
+      "integrity": "sha512-rRdr51x0xtelhmFuOWzsq4miqUXu7gRuLcDRaypOtJ6lFezrllmVNXYLJQ8sc+2msqfpCRm8j6db19X2e5vywg==",
+      "dependencies": {
+        "@leafer/core": "1.6.1"
+      }
+    },
+    "node_modules/@leafer/selector": {
+      "version": "1.6.1",
+      "resolved": "https://registry.npmjs.org/@leafer/selector/-/selector-1.6.1.tgz",
+      "integrity": "sha512-aeaCtDrcSLQJzPcxIZUTg7JCYSrz/7OoHhhSvGS8exVYf+OQCx8tncNqsGpcixpe7Zj9t5ylxOZ2wMK0FQ1Asw==",
+      "dependencies": {
+        "@leafer/core": "1.6.1"
+      }
+    },
+    "node_modules/@leafer/task": {
+      "version": "1.6.1",
+      "resolved": "https://registry.npmjs.org/@leafer/task/-/task-1.6.1.tgz",
+      "integrity": "sha512-QbAKt3gg2UGClhweCakfepaEevaKG82Q9pQSsP2DSGsY0mXUzBvzwsZ8pIYh2NDvuZYGiAT8yYekiiI1brG5Gg==",
+      "dependencies": {
+        "@leafer/debug": "1.6.1",
+        "@leafer/math": "1.6.1"
+      }
+    },
+    "node_modules/@leafer/watcher": {
+      "version": "1.6.1",
+      "resolved": "https://registry.npmjs.org/@leafer/watcher/-/watcher-1.6.1.tgz",
+      "integrity": "sha512-ZRRUg0gFjWPDM2TC3EtpfR1LOofkVFmLlU7gVbhYuwZdLE0LtEi0cx0onJSUtxji2ldzSmgvquFAC0vG6Kle8w==",
+      "dependencies": {
+        "@leafer/data": "1.6.1",
+        "@leafer/event": "1.6.1",
+        "@leafer/list": "1.6.1"
+      }
+    },
+    "node_modules/@leafer/web": {
+      "version": "1.6.1",
+      "resolved": "https://registry.npmjs.org/@leafer/web/-/web-1.6.1.tgz",
+      "integrity": "sha512-GsNyFuiD2jcufIZf1+2gS7HmdrpC2KqoJXGEm0nLOPYoizIzWYJLjfv+kQ2oF93Zg6ZMofmyDp2dOHMcK/+vWA==",
+      "dependencies": {
+        "@leafer-in/animate": "1.6.1",
+        "@leafer-in/arrow": "1.6.1",
+        "@leafer-in/color": "1.6.1",
+        "@leafer-in/editor": "1.6.1",
+        "@leafer-in/export": "1.6.1",
+        "@leafer-in/filter": "1.6.1",
+        "@leafer-in/find": "1.6.1",
+        "@leafer-in/flow": "1.6.1",
+        "@leafer-in/html": "1.6.1",
+        "@leafer-in/interface": "1.6.1",
+        "@leafer-in/motion-path": "1.6.1",
+        "@leafer-in/resize": "1.6.1",
+        "@leafer-in/robot": "1.6.1",
+        "@leafer-in/scroll": "1.6.1",
+        "@leafer-in/state": "1.6.1",
+        "@leafer-in/text-editor": "1.6.1",
+        "@leafer-in/view": "1.6.1",
+        "@leafer-in/viewport": "1.6.1",
+        "leafer-ui": "1.6.1"
+      }
+    },
     "node_modules/@leichtgewicht/ip-codec": {
       "version": "2.0.5",
       "resolved": "https://registry.npmmirror.com/@leichtgewicht/ip-codec/-/ip-codec-2.0.5.tgz",
@@ -15743,6 +16396,62 @@
         "shell-quote": "^1.8.1"
       }
     },
+    "node_modules/leafer": {
+      "version": "1.6.1",
+      "resolved": "https://registry.npmjs.org/leafer/-/leafer-1.6.1.tgz",
+      "integrity": "sha512-zJyjh8x+OkgjaTLXvUx3cZNhVHddz3XMY1ADik+xGN1zE/jjq7gtGcW4LIs+y3EXxmIs3YJyWphfCBO/WgzsdA==",
+      "dependencies": {
+        "@leafer-in/animate": "1.6.1",
+        "@leafer-in/arrow": "1.6.1",
+        "@leafer-in/color": "1.6.1",
+        "@leafer-in/editor": "1.6.1",
+        "@leafer-in/export": "1.6.1",
+        "@leafer-in/filter": "1.6.1",
+        "@leafer-in/find": "1.6.1",
+        "@leafer-in/flow": "1.6.1",
+        "@leafer-in/html": "1.6.1",
+        "@leafer-in/interface": "1.6.1",
+        "@leafer-in/motion-path": "1.6.1",
+        "@leafer-in/resize": "1.6.1",
+        "@leafer-in/robot": "1.6.1",
+        "@leafer-in/scroll": "1.6.1",
+        "@leafer-in/state": "1.6.1",
+        "@leafer-in/text-editor": "1.6.1",
+        "@leafer-in/view": "1.6.1",
+        "@leafer-in/viewport": "1.6.1",
+        "@leafer/web": "1.6.1",
+        "leafer-ui": "1.6.1"
+      }
+    },
+    "node_modules/leafer-ui": {
+      "version": "1.6.1",
+      "resolved": "https://registry.npmjs.org/leafer-ui/-/leafer-ui-1.6.1.tgz",
+      "integrity": "sha512-jwe1qBMn8dL9yT25PMKpKwD1bdr3jTgpCguqflpiGIZXBVknswmizTSEq5CeoPUm7Xi5pfhP3sFMnogaeo86YA==",
+      "dependencies": {
+        "@leafer-in/interface": "1.6.1",
+        "@leafer-ui/core": "1.6.1",
+        "@leafer-ui/draw": "1.6.1",
+        "@leafer-ui/interaction-web": "1.6.1",
+        "@leafer-ui/interface": "1.6.1",
+        "@leafer-ui/partner": "1.6.1",
+        "@leafer-ui/web": "1.6.1",
+        "@leafer/core": "1.6.1",
+        "@leafer/interface": "1.6.1",
+        "@leafer/partner": "1.6.1"
+      }
+    },
+    "node_modules/leafer-x-connector": {
+      "version": "0.1.3",
+      "resolved": "https://registry.npmjs.org/leafer-x-connector/-/leafer-x-connector-0.1.3.tgz",
+      "integrity": "sha512-nXBBX2TNOqXFtUvywrlfHXL849x7AcEnI/sFzb5EcEDlA7Lff+LE9wGyMhMvh8WzKIm8EXh+p3cMIxiSkWIb5A==",
+      "dependencies": {
+        "@leafer-in/arrow": "^1.0.0-rc.22",
+        "@leafer-in/editor": "^1.0.0-rc.22",
+        "@leafer-in/html": "^1.0.0-rc.22",
+        "@leafer-in/state": "^1.0.0-rc.22",
+        "@leafer-ui/core": "^1.0.0-rc.22"
+      }
+    },
     "node_modules/less": {
       "version": "4.2.0",
       "resolved": "https://registry.npmmirror.com/less/-/less-4.2.0.tgz",

+ 2 - 0
package.json

@@ -43,6 +43,8 @@
     "fmode-ng": "^0.0.63",
     "ionicons": "^7.2.1",
     "langchain": "^0.3.7",
+    "leafer": "^1.6.1",
+    "leafer-x-connector": "^0.1.3",
     "mammoth": "^1.8.0",
     "parse": "^5.3.0",
     "pdf-parse": "^1.1.1",

+ 5 - 0
src/app/app.routes.ts

@@ -38,4 +38,9 @@ export const routes: Routes = [
       redirectTo: '/chat/session/chat/:chatId',
       pathMatch: 'full'
     },
+    {
+        path: "flow/editor/new",
+        loadComponent: () => import('../modules/flow/comp-flow-editor/comp-flow-editor.component').then(m => m.CompFlowEditorComponent),
+        runGuardsAndResolvers: "always",
+    },
 ];

+ 2 - 2
src/global.scss

@@ -33,5 +33,5 @@
  */
 
 /* @import "@ionic/angular/css/palettes/dark.always.css"; */
-/* @import "@ionic/angular/css/palettes/dark.class.css"; */
-@import '@ionic/angular/css/palettes/dark.system.css';
+@import "@ionic/angular/css/palettes/dark.class.css";
+// @import '@ionic/angular/css/palettes/dark.system.css';

+ 1 - 0
src/modules/flow/comp-flow-editor/comp-flow-editor.component.html

@@ -0,0 +1 @@
+  <div #container class="editor-container"></div>

+ 3 - 0
src/modules/flow/comp-flow-editor/comp-flow-editor.component.scss

@@ -0,0 +1,3 @@
+.editor-container { width: 100%; height: 600px; border: 1px solid #ddd; }
+.toolbar { padding: 10px; background: #f5f5f5; }
+button { margin-right: 8px; }

+ 22 - 0
src/modules/flow/comp-flow-editor/comp-flow-editor.component.spec.ts

@@ -0,0 +1,22 @@
+import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
+
+import { CompFlowEditorComponent } from './comp-flow-editor.component';
+
+describe('CompFlowEditorComponent', () => {
+  let component: CompFlowEditorComponent;
+  let fixture: ComponentFixture<CompFlowEditorComponent>;
+
+  beforeEach(waitForAsync(() => {
+    TestBed.configureTestingModule({
+      imports: [CompFlowEditorComponent],
+    }).compileComponents();
+
+    fixture = TestBed.createComponent(CompFlowEditorComponent);
+    component = fixture.componentInstance;
+    fixture.detectChanges();
+  }));
+
+  it('should create', () => {
+    expect(component).toBeTruthy();
+  });
+});

+ 155 - 0
src/modules/flow/comp-flow-editor/comp-flow-editor.component.ts

@@ -0,0 +1,155 @@
+import { Component, ElementRef, AfterViewInit } from '@angular/core';
+import { Leafer, Rect, Box, PointerEvent, DragEvent } from 'leafer-ui';
+
+@Component({
+  selector: 'comp-flow-editor',
+  templateUrl: './comp-flow-editor.component.html',
+  styleUrls: ['./comp-flow-editor.component.scss'],
+  standalone: true,
+})
+export class CompFlowEditorComponent implements AfterViewInit {
+  private leafer: Leafer|undefined;
+  private nodeBox: Box|undefined;
+  
+  constructor(private el: ElementRef) {}
+
+  ngAfterViewInit(): void {
+    this.initLeafer();
+    this.createBlueprintNode();
+  }
+
+  private initLeafer(): void {
+    const container = this.el.nativeElement.querySelector('.editor-container');
+    this.leafer = new Leafer({
+      view: container,
+      width: 800,
+      height: 600,
+      fill: '#1E1E1E' // UE5 风格的暗色背景
+    });
+  }
+
+  private createBlueprintNode(): void {
+    // 创建节点容器
+    this.nodeBox = new Box({
+      x: 100,
+      y: 100,
+      width: 300,
+      height: 200,
+      fill: '#2A2A2A',
+      stroke: '#3D3D3D',
+      strokeWidth: 2,
+      cornerRadius: 4,
+      draggable: true,
+      shadow: {
+        x:4,
+        y:4,
+        color: '#00000080',
+        blur: 10,
+        // offsetY: 4
+      }
+    });
+
+    // 创建标题栏
+    const titleBar = new Rect({
+      x: 0,
+      y: 0,
+      width: 300,
+      height: 32,
+      fill: '#0078D7', // UE5 蓝色
+      cornerRadius: [4, 4, 0, 0]
+    });
+
+    // 创建标题文本
+    const titleText = new Rect({
+      x: 10,
+      y: 5,
+      width: 280,
+      height: 22,
+      fill: '#FFFFFF',
+      // text: {
+      //   text: 'Blueprint Node',
+      //   fontSize: 14,
+      //   fontFamily: 'Arial',
+      //   fontWeight: 'bold'
+      // }
+    });
+
+    // 创建主体区域
+    const body = new Rect({
+      x: 0,
+      y: 32,
+      width: 300,
+      height: 168,
+      fill: '#252526',
+      cornerRadius: [0, 0, 4, 4]
+    });
+
+    // 创建输入引脚
+    const inputPin = this.createPin(10, 60, 'Input', true);
+    
+    // 创建输出引脚
+    const outputPin = this.createPin(270, 60, 'Output', false);
+
+    // 组装节点
+    this.nodeBox.add(titleBar);
+    this.nodeBox.add(titleText);
+    this.nodeBox.add(body);
+    this.nodeBox.add(inputPin);
+    this.nodeBox.add(outputPin);
+
+    // 添加到画布
+    this.leafer?.add(this.nodeBox);
+
+    // 添加拖拽事件
+    this.setupDragEvents();
+  }
+
+  private createPin(x: number, y: number, label: string, isInput: boolean): Box {
+    const pinBox = new Box({
+      x,
+      y,
+      width: 20,
+      height: 20,
+      draggable: false
+    });
+
+    const pinCircle = new Rect({
+      x: isInput ? 0 : 10,
+      y: 0,
+      width: 10,
+      height: 10,
+      fill: '#FFA500',
+      cornerRadius: 5
+    });
+
+    const pinLabel = new Rect({
+      x: isInput ? 15 : -60,
+      y: 0,
+      width: 50,
+      height: 20,
+      fill: '#FFFFFF',
+      // text: {
+      //   text: label,
+      //   fontSize: 12,
+      //   fontFamily: 'Arial',
+      //   align: isInput ? 'left' : 'right'
+      // }
+    });
+
+    pinBox.add(pinCircle);
+    pinBox.add(pinLabel);
+    return pinBox;
+  }
+
+  private setupDragEvents(): void {
+    if(this.nodeBox){
+      this.nodeBox.on(DragEvent.DRAG, (event) => {
+        if(this.nodeBox){
+            // 拖拽时更新位置
+            this.nodeBox.x = event.x;
+            this.nodeBox.y = event.y;
+        }
+      });
+    }
+  }
+}