machinaos 0.0.18 → 0.0.20
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/README.md +47 -60
- package/bin/cli.js +5 -5
- package/client/dist/assets/index-DFSC53FP.css +1 -0
- package/client/dist/assets/index-YVvAiByx.js +703 -0
- package/client/dist/index.html +14 -0
- package/client/package.json +1 -1
- package/install.ps1 +40 -147
- package/install.sh +204 -43
- package/package.json +1 -1
- package/scripts/build.js +5 -6
- package/scripts/install.js +2 -2
- package/scripts/start.js +2 -2
package/README.md
CHANGED
|
@@ -1,12 +1,25 @@
|
|
|
1
1
|
# MachinaOS
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
<a href="https://www.npmjs.com/package/machinaos" target="_blank"><img src="https://img.shields.io/npm/v/machinaos.svg" alt="npm version"></a>
|
|
4
|
+
<a href="https://opensource.org/licenses/MIT" target="_blank"><img src="https://img.shields.io/badge/License-MIT-yellow.svg" alt="License: MIT"></a>
|
|
5
|
+
<a href="https://discord.gg/NHUEQVSC" target="_blank"><img src="https://img.shields.io/discord/1455977012308086895?logo=discord&logoColor=white&label=Discord" alt="Discord"></a>
|
|
4
6
|
|
|
5
|
-
|
|
7
|
+
Open-source platform to build your own personal AI assistant. A mashup of Claude Code and n8n with better UI, full visibility of each action, and restricted control access.
|
|
8
|
+
|
|
9
|
+
## Demo
|
|
10
|
+
|
|
11
|
+
[](https://www.youtube.com/watch?v=z_TEyGmeuyQ)
|
|
12
|
+
|
|
13
|
+
## Full Capabilities
|
|
6
14
|
|
|
7
15
|
<img width="1280" height="671" alt="func_img" src="https://github.com/user-attachments/assets/2f14b6c8-3995-4ccc-b076-e40749a83df2" />
|
|
8
16
|
|
|
9
|
-
**
|
|
17
|
+
**77 nodes** | **6 AI providers** | **12 specialized agents** | **WebSocket-first** | **Self-hosted**
|
|
18
|
+
|
|
19
|
+
## Prerequisites
|
|
20
|
+
|
|
21
|
+
- **Node.js 22+** - https://nodejs.org/
|
|
22
|
+
- **Python 3.12+** - https://python.org/
|
|
10
23
|
|
|
11
24
|
## Quick Start
|
|
12
25
|
|
|
@@ -17,10 +30,7 @@ machinaos start
|
|
|
17
30
|
|
|
18
31
|
Open http://localhost:3000
|
|
19
32
|
|
|
20
|
-
|
|
21
|
-
<summary><b>Other Install Options</b></summary>
|
|
22
|
-
|
|
23
|
-
### One-Line Install (installs all dependencies automatically)
|
|
33
|
+
## One-Line Install (auto-installs dependencies)
|
|
24
34
|
|
|
25
35
|
**Linux/macOS:**
|
|
26
36
|
```bash
|
|
@@ -32,7 +42,7 @@ curl -fsSL https://raw.githubusercontent.com/trohitg/MachinaOS/main/install.sh |
|
|
|
32
42
|
iwr -useb https://raw.githubusercontent.com/trohitg/MachinaOS/main/install.ps1 | iex
|
|
33
43
|
```
|
|
34
44
|
|
|
35
|
-
|
|
45
|
+
## Clone & Run
|
|
36
46
|
|
|
37
47
|
```bash
|
|
38
48
|
git clone https://github.com/trohitg/MachinaOS.git
|
|
@@ -41,16 +51,6 @@ npm run build
|
|
|
41
51
|
npm run start
|
|
42
52
|
```
|
|
43
53
|
|
|
44
|
-
### Docker
|
|
45
|
-
|
|
46
|
-
```bash
|
|
47
|
-
git clone https://github.com/trohitg/MachinaOS.git
|
|
48
|
-
cd MachinaOS
|
|
49
|
-
npm run docker:up
|
|
50
|
-
```
|
|
51
|
-
|
|
52
|
-
</details>
|
|
53
|
-
|
|
54
54
|
## Features
|
|
55
55
|
|
|
56
56
|
### AI Integration (6 Providers)
|
|
@@ -68,14 +68,14 @@ npm run docker:up
|
|
|
68
68
|
|
|
69
69
|
- **AI Agent** - LangGraph-powered with tool calling and iterative reasoning
|
|
70
70
|
- **Chat Agent** - Conversational agent with skill support for multi-turn chat
|
|
71
|
-
- **
|
|
72
|
-
- **
|
|
71
|
+
- **12 Specialized Agents** - Android, Coding, Web, Task, Social, Travel, Tool, Productivity, Payments, Consumer, Autonomous, Orchestrator
|
|
72
|
+
- **11 Skills** - WhatsApp, Maps, HTTP, Scheduler, Android, Code, Memory, Web Search, Custom
|
|
73
73
|
- **Simple Memory** - Markdown-based conversation history with vector storage
|
|
74
74
|
|
|
75
75
|
### Platform Integrations
|
|
76
76
|
|
|
77
77
|
- **WhatsApp** - Send/receive messages with QR pairing, filters, group support
|
|
78
|
-
- **Android** -
|
|
78
|
+
- **Android** - 16 service nodes for device control (battery, WiFi, Bluetooth, apps, camera, sensors)
|
|
79
79
|
- **HTTP/Webhooks** - REST API integration with event-driven triggers
|
|
80
80
|
- **Google Maps** - Geocoding, nearby places, directions
|
|
81
81
|
|
|
@@ -94,26 +94,17 @@ npm run docker:up
|
|
|
94
94
|
|----------|-------|-------------|
|
|
95
95
|
| AI Models | 6 | OpenAI, Anthropic, Google, OpenRouter, Groq, Cerebras |
|
|
96
96
|
| AI Agents | 3 | AI Agent, Chat Agent, Simple Memory |
|
|
97
|
-
|
|
|
98
|
-
| AI
|
|
97
|
+
| Specialized Agents | 12 | Android, Coding, Web, Task, Social, Travel, etc. |
|
|
98
|
+
| AI Skills | 11 | WhatsApp, Maps, HTTP, Scheduler, Android, Code, etc. |
|
|
99
|
+
| AI Tools | 9 | Calculator, Time, Search, Android Toolkit, Code Executors |
|
|
99
100
|
| WhatsApp | 3 | Send, Receive, Database |
|
|
100
|
-
| Android |
|
|
101
|
+
| Android | 16 | Device control and monitoring |
|
|
101
102
|
| Documents | 6 | RAG pipeline nodes |
|
|
102
103
|
| Utilities | 5 | HTTP, Webhooks, Chat Trigger, Console |
|
|
103
104
|
| Location | 3 | Google Maps integration |
|
|
104
|
-
|
|
|
105
|
-
| Workflow | 1 | Start node |
|
|
106
|
-
|
|
107
|
-
**Total: 60 nodes**
|
|
108
|
-
|
|
109
|
-
## Prerequisites
|
|
110
|
-
|
|
111
|
-
The install script handles these automatically, but for manual installation:
|
|
105
|
+
| Workflow | 3 | Start, Timer, Cron Scheduler |
|
|
112
106
|
|
|
113
|
-
|
|
114
|
-
- **Python 3.11+** - https://python.org/
|
|
115
|
-
- **uv** - `curl -LsSf https://astral.sh/uv/install.sh | sh`
|
|
116
|
-
- **Go 1.21+** - https://go.dev/dl/ (for WhatsApp service)
|
|
107
|
+
**Total: 77 nodes**
|
|
117
108
|
|
|
118
109
|
## CLI Commands
|
|
119
110
|
|
|
@@ -133,24 +124,27 @@ The install script handles these automatically, but for manual installation:
|
|
|
133
124
|
|
|
134
125
|
**Environment:** Copy `.env.template` to `.env` and customize ports, auth settings, database location.
|
|
135
126
|
|
|
136
|
-
##
|
|
127
|
+
## Other Install Options
|
|
137
128
|
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
| `machinaos docker:up` | Start containers (detached) |
|
|
141
|
-
| `machinaos docker:down` | Stop containers |
|
|
142
|
-
| `machinaos docker:build` | Rebuild images |
|
|
143
|
-
| `machinaos docker:logs` | View logs (follows) |
|
|
144
|
-
|
|
145
|
-
**Redis (optional):** Set `REDIS_ENABLED=true` in `.env`
|
|
129
|
+
<details>
|
|
130
|
+
<summary><b>Docker</b></summary>
|
|
146
131
|
|
|
147
|
-
|
|
132
|
+
```bash
|
|
133
|
+
git clone https://github.com/trohitg/MachinaOS.git
|
|
134
|
+
cd MachinaOS
|
|
135
|
+
npm run docker:up
|
|
136
|
+
```
|
|
148
137
|
|
|
138
|
+
**Production Docker:**
|
|
149
139
|
```bash
|
|
150
140
|
npm run docker:prod:build
|
|
151
141
|
npm run docker:prod:up
|
|
152
142
|
```
|
|
153
143
|
|
|
144
|
+
**Redis (optional):** Set `REDIS_ENABLED=true` in `.env`
|
|
145
|
+
|
|
146
|
+
</details>
|
|
147
|
+
|
|
154
148
|
## Project Structure
|
|
155
149
|
|
|
156
150
|
```
|
|
@@ -158,8 +152,7 @@ MachinaOS/
|
|
|
158
152
|
├── client/ # React frontend (localhost:3000)
|
|
159
153
|
├── server/ # Python FastAPI backend (localhost:3010)
|
|
160
154
|
│ ├── services/ # Workflow execution, AI, handlers
|
|
161
|
-
│
|
|
162
|
-
│ └── whatsapp-rpc/ # WhatsApp Go service
|
|
155
|
+
│ └── routers/ # API endpoints, WebSocket
|
|
163
156
|
├── scripts/ # Cross-platform Node.js scripts
|
|
164
157
|
└── bin/cli.js # CLI entry point
|
|
165
158
|
```
|
|
@@ -167,20 +160,10 @@ MachinaOS/
|
|
|
167
160
|
## Tech Stack
|
|
168
161
|
|
|
169
162
|
- **Frontend:** React 19, TypeScript, React Flow, Zustand
|
|
170
|
-
- **Backend:** Python 3.
|
|
171
|
-
- **Services:** WhatsApp (
|
|
163
|
+
- **Backend:** Python 3.12+, FastAPI, SQLite, LangChain/LangGraph
|
|
164
|
+
- **Services:** WhatsApp (whatsapp-rpc npm package), WebSocket relay
|
|
172
165
|
- **Package Manager:** uv (Python), npm (Node.js)
|
|
173
166
|
|
|
174
|
-
## Documentation
|
|
175
|
-
|
|
176
|
-
Full documentation available at: https://docs.machinaos.dev
|
|
177
|
-
|
|
178
|
-
- [Installation Guide](https://docs.machinaos.dev/installation)
|
|
179
|
-
- [Quick Start](https://docs.machinaos.dev/quickstart)
|
|
180
|
-
- [Node Catalog](https://docs.machinaos.dev/nodes/overview)
|
|
181
|
-
- [AI Models](https://docs.machinaos.dev/nodes/ai-models)
|
|
182
|
-
- [AI Agents](https://docs.machinaos.dev/nodes/ai-agent)
|
|
183
|
-
|
|
184
167
|
## Troubleshooting
|
|
185
168
|
|
|
186
169
|
**Port already in use:**
|
|
@@ -200,6 +183,10 @@ machinaos clean # Remove node_modules, .venv, dist
|
|
|
200
183
|
machinaos build # Reinstall everything
|
|
201
184
|
```
|
|
202
185
|
|
|
186
|
+
## Documentation
|
|
187
|
+
|
|
188
|
+
Full documentation: https://docs.machinaos.dev
|
|
189
|
+
|
|
203
190
|
## Contributing
|
|
204
191
|
|
|
205
192
|
1. Fork the repository
|
package/bin/cli.js
CHANGED
|
@@ -70,20 +70,20 @@ function checkDeps() {
|
|
|
70
70
|
|
|
71
71
|
// Node.js version check
|
|
72
72
|
const nodeVersion = parseInt(process.version.slice(1));
|
|
73
|
-
if (nodeVersion <
|
|
74
|
-
errors.push(`Node.js
|
|
73
|
+
if (nodeVersion < 22) {
|
|
74
|
+
errors.push(`Node.js 22+ required (found ${process.version})`);
|
|
75
75
|
}
|
|
76
76
|
|
|
77
77
|
// Python version check
|
|
78
78
|
let pyVersion = getVersion('python --version') || getVersion('python3 --version');
|
|
79
79
|
if (!pyVersion) {
|
|
80
|
-
errors.push('Python 3.
|
|
80
|
+
errors.push('Python 3.12+ - https://python.org/');
|
|
81
81
|
} else {
|
|
82
82
|
const match = pyVersion.match(/Python (\d+)\.(\d+)/);
|
|
83
83
|
if (match) {
|
|
84
84
|
const [, major, minor] = match.map(Number);
|
|
85
|
-
if (major < 3 || (major === 3 && minor <
|
|
86
|
-
errors.push(`Python 3.
|
|
85
|
+
if (major < 3 || (major === 3 && minor < 12)) {
|
|
86
|
+
errors.push(`Python 3.12+ required (found ${pyVersion})`);
|
|
87
87
|
}
|
|
88
88
|
}
|
|
89
89
|
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
@tailwind base;@tailwind components;@tailwind utilities;@layer base{:root{--background: 0 0% 100%;--foreground: 222.2 84% 4.9%;--card: 0 0% 100%;--card-foreground: 222.2 84% 4.9%;--popover: 0 0% 100%;--popover-foreground: 222.2 84% 4.9%;--primary: 221.2 83.2% 53.3%;--primary-foreground: 210 40% 98%;--secondary: 210 40% 96%;--secondary-foreground: 222.2 84% 4.9%;--muted: 210 40% 96%;--muted-foreground: 215.4 16.3% 46.9%;--accent: 210 40% 96%;--accent-foreground: 222.2 84% 4.9%;--destructive: 0 84.2% 60.2%;--destructive-foreground: 210 40% 98%;--border: 214.3 31.8% 91.4%;--input: 214.3 31.8% 91.4%;--ring: 221.2 83.2% 53.3%;--radius: .5rem}.dark{--background: 222.2 84% 4.9%;--foreground: 210 40% 98%;--card: 222.2 84% 4.9%;--card-foreground: 210 40% 98%;--popover: 222.2 84% 4.9%;--popover-foreground: 210 40% 98%;--primary: 217.2 91.2% 59.8%;--primary-foreground: 222.2 84% 4.9%;--secondary: 217.2 32.6% 17.5%;--secondary-foreground: 210 40% 98%;--muted: 217.2 32.6% 17.5%;--muted-foreground: 215 20.2% 65.1%;--accent: 217.2 32.6% 17.5%;--accent-foreground: 210 40% 98%;--destructive: 0 62.8% 30.6%;--destructive-foreground: 210 40% 98%;--border: 217.2 32.6% 17.5%;--input: 217.2 32.6% 17.5%;--ring: 224.3 76.3% 94.1%}}@layer base{*{@apply border-border;box-sizing:border-box}html,body{height:100vh;width:100vw;margin:0;padding:0;@apply bg-background text-foreground;font-feature-settings:"rlig" 1,"calt" 1;font-family:system-ui,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,sans-serif}#root{height:100vh;width:100vw;margin:0;padding:0;display:flex;flex-direction:column}}.react-flow{background-color:#e8ecf1!important}.react-flow__background pattern circle{fill:#9ca3af!important}.react-flow__controls{background:#fff;border:1px solid #e2e8f0;border-radius:8px;box-shadow:0 2px 8px #0000000f,0 1px 2px #0000000a}.react-flow__controls button,.react-flow__controls-button{background:#fff;border:none;border-bottom:1px solid #f1f5f9;color:#475569}.react-flow__controls button:last-child,.react-flow__controls-button:last-child{border-bottom:none}.react-flow__controls button:hover,.react-flow__controls-button:hover{background:#f8fafc}.react-flow__controls button svg,.react-flow__controls-button svg{fill:#475569!important}.react-flow__controls button svg path,.react-flow__controls-button svg path{fill:#475569!important}.react-flow__minimap{background:#fff;border:1px solid #e2e8f0;border-radius:8px;box-shadow:0 2px 8px #0000000f}.react-flow__attribution{background:#ffffffe6;color:#94a3b8}::-webkit-scrollbar{width:8px;height:8px}::-webkit-scrollbar-track{background:#f1f5f9;border-radius:4px}::-webkit-scrollbar-thumb{background:#cbd5e1;border-radius:4px}::-webkit-scrollbar-thumb:hover{background:#94a3b8}::-webkit-scrollbar-corner{background:#f1f5f9}html{scrollbar-width:thin;scrollbar-color:#cbd5e1 #f1f5f9}.react-flow__selection{background:#3b82f614;border:1px solid rgba(59,130,246,.4)}.react-flow__connection-line{stroke:#94a3b8;stroke-width:2}.dark .react-flow{background-color:hsl(var(--background))!important}.dark .react-flow__node{color:hsl(var(--foreground))}.dark .react-flow__edge{stroke:hsl(var(--border))}.dark .react-flow__controls{background:#1f2937;border:1px solid #374151;border-radius:8px;box-shadow:0 4px 12px #0000004d}.dark .react-flow__controls button,.dark .react-flow__controls-button{background:#1f2937;border:none;border-bottom:1px solid #374151;color:#e5e7eb}.dark .react-flow__controls button:last-child,.dark .react-flow__controls-button:last-child{border-bottom:none}.dark .react-flow__controls button:hover,.dark .react-flow__controls-button:hover{background:#374151}.dark .react-flow__controls button svg,.dark .react-flow__controls-button svg{fill:#e5e7eb!important}.dark .react-flow__controls button svg path,.dark .react-flow__controls-button svg path{fill:#e5e7eb!important}.dark .react-flow__minimap{background:#1f2937;border:1px solid #374151;border-radius:8px}.dark .react-flow__background{background-color:hsl(var(--background))}.dark .react-flow__attribution{background:hsl(var(--card));color:hsl(var(--muted-foreground))}@keyframes pulse{0%,to{opacity:1;transform:scale(1)}50%{opacity:.9;transform:scale(1.03)}}@keyframes pulseLight{0%,to{opacity:1;transform:scale(1);filter:brightness(1)}50%{opacity:.95;transform:scale(1.04);filter:brightness(1.05)}}@keyframes spin{0%{transform:rotate(0)}to{transform:rotate(360deg)}}.dark ::-webkit-scrollbar{width:8px;height:8px}.dark ::-webkit-scrollbar-track{background:#073642;border-radius:4px}.dark ::-webkit-scrollbar-thumb{background:#586e75;border-radius:4px;border:1px solid #073642}.dark ::-webkit-scrollbar-thumb:hover{background:#657b83}.dark ::-webkit-scrollbar-corner{background:#073642}.dark{scrollbar-width:thin;scrollbar-color:#586e75 #073642}.react-flow{direction:ltr}.react-flow__container{position:absolute;width:100%;height:100%;top:0;left:0}.react-flow__pane{z-index:1;cursor:-webkit-grab;cursor:grab}.react-flow__pane.selection{cursor:pointer}.react-flow__pane.dragging{cursor:-webkit-grabbing;cursor:grabbing}.react-flow__viewport{transform-origin:0 0;z-index:2;pointer-events:none}.react-flow__renderer{z-index:4}.react-flow__selection{z-index:6}.react-flow__nodesselection-rect:focus,.react-flow__nodesselection-rect:focus-visible{outline:none}.react-flow .react-flow__edges{pointer-events:none;overflow:visible}.react-flow__edge-path,.react-flow__connection-path{stroke:#b1b1b7;stroke-width:1;fill:none}.react-flow__edge{pointer-events:visibleStroke;cursor:pointer}.react-flow__edge.animated path{stroke-dasharray:5;-webkit-animation:dashdraw .5s linear infinite;animation:dashdraw .5s linear infinite}.react-flow__edge.animated path.react-flow__edge-interaction{stroke-dasharray:none;-webkit-animation:none;animation:none}.react-flow__edge.inactive{pointer-events:none}.react-flow__edge.selected,.react-flow__edge:focus,.react-flow__edge:focus-visible{outline:none}.react-flow__edge.selected .react-flow__edge-path,.react-flow__edge:focus .react-flow__edge-path,.react-flow__edge:focus-visible .react-flow__edge-path{stroke:#555}.react-flow__edge-textwrapper{pointer-events:all}.react-flow__edge-textbg{fill:#fff}.react-flow__edge .react-flow__edge-text{pointer-events:none;-webkit-user-select:none;-moz-user-select:none;user-select:none}.react-flow__connection{pointer-events:none}.react-flow__connection .animated{stroke-dasharray:5;-webkit-animation:dashdraw .5s linear infinite;animation:dashdraw .5s linear infinite}.react-flow__connectionline{z-index:1001}.react-flow__nodes{pointer-events:none;transform-origin:0 0}.react-flow__node{position:absolute;-webkit-user-select:none;-moz-user-select:none;user-select:none;pointer-events:all;transform-origin:0 0;box-sizing:border-box;cursor:-webkit-grab;cursor:grab}.react-flow__node.dragging{cursor:-webkit-grabbing;cursor:grabbing}.react-flow__nodesselection{z-index:3;transform-origin:left top;pointer-events:none}.react-flow__nodesselection-rect{position:absolute;pointer-events:all;cursor:-webkit-grab;cursor:grab}.react-flow__handle{position:absolute;pointer-events:none;min-width:5px;min-height:5px;width:6px;height:6px;background:#1a192b;border:1px solid white;border-radius:100%}.react-flow__handle.connectionindicator{pointer-events:all;cursor:crosshair}.react-flow__handle-bottom{top:auto;left:50%;bottom:-4px;transform:translate(-50%)}.react-flow__handle-top{left:50%;top:-4px;transform:translate(-50%)}.react-flow__handle-left{top:50%;left:-4px;transform:translateY(-50%)}.react-flow__handle-right{right:-4px;top:50%;transform:translateY(-50%)}.react-flow__edgeupdater{cursor:move;pointer-events:all}.react-flow__panel{position:absolute;z-index:5;margin:15px}.react-flow__panel.top{top:0}.react-flow__panel.bottom{bottom:0}.react-flow__panel.left{left:0}.react-flow__panel.right{right:0}.react-flow__panel.center{left:50%;transform:translate(-50%)}.react-flow__attribution{font-size:10px;background:#ffffff80;padding:2px 3px;margin:0}.react-flow__attribution a{text-decoration:none;color:#999}@-webkit-keyframes dashdraw{0%{stroke-dashoffset:10}}@keyframes dashdraw{0%{stroke-dashoffset:10}}.react-flow__edgelabel-renderer{position:absolute;width:100%;height:100%;pointer-events:none;-webkit-user-select:none;-moz-user-select:none;user-select:none}.react-flow__edge.updating .react-flow__edge-path{stroke:#777}.react-flow__edge-text{font-size:10px}.react-flow__node.selectable:focus,.react-flow__node.selectable:focus-visible{outline:none}.react-flow__node-default,.react-flow__node-input,.react-flow__node-output,.react-flow__node-group{padding:10px;border-radius:3px;width:150px;font-size:12px;color:#222;text-align:center;border-width:1px;border-style:solid;border-color:#1a192b;background-color:#fff}.react-flow__node-default.selectable:hover,.react-flow__node-input.selectable:hover,.react-flow__node-output.selectable:hover,.react-flow__node-group.selectable:hover{box-shadow:0 1px 4px 1px #00000014}.react-flow__node-default.selectable.selected,.react-flow__node-default.selectable:focus,.react-flow__node-default.selectable:focus-visible,.react-flow__node-input.selectable.selected,.react-flow__node-input.selectable:focus,.react-flow__node-input.selectable:focus-visible,.react-flow__node-output.selectable.selected,.react-flow__node-output.selectable:focus,.react-flow__node-output.selectable:focus-visible,.react-flow__node-group.selectable.selected,.react-flow__node-group.selectable:focus,.react-flow__node-group.selectable:focus-visible{box-shadow:0 0 0 .5px #1a192b}.react-flow__node-group{background-color:#f0f0f040}.react-flow__nodesselection-rect,.react-flow__selection{background:#0059dc14;border:1px dotted rgba(0,89,220,.8)}.react-flow__nodesselection-rect:focus,.react-flow__nodesselection-rect:focus-visible,.react-flow__selection:focus,.react-flow__selection:focus-visible{outline:none}.react-flow__controls{box-shadow:0 0 2px 1px #00000014}.react-flow__controls-button{border:none;background:#fefefe;border-bottom:1px solid #eee;box-sizing:content-box;display:flex;justify-content:center;align-items:center;width:16px;height:16px;cursor:pointer;-webkit-user-select:none;-moz-user-select:none;user-select:none;padding:5px}.react-flow__controls-button:hover{background:#f4f4f4}.react-flow__controls-button svg{width:100%;max-width:12px;max-height:12px}.react-flow__controls-button:disabled{pointer-events:none}.react-flow__controls-button:disabled svg{fill-opacity:.4}.react-flow__minimap{background-color:#fff}.react-flow__minimap svg{display:block}.react-flow__resize-control{position:absolute}.react-flow__resize-control.left,.react-flow__resize-control.right{cursor:ew-resize}.react-flow__resize-control.top,.react-flow__resize-control.bottom{cursor:ns-resize}.react-flow__resize-control.top.left,.react-flow__resize-control.bottom.right{cursor:nwse-resize}.react-flow__resize-control.bottom.left,.react-flow__resize-control.top.right{cursor:nesw-resize}.react-flow__resize-control.handle{width:4px;height:4px;border:1px solid #fff;border-radius:1px;background-color:#3367d9;transform:translate(-50%,-50%)}.react-flow__resize-control.handle.left{left:0;top:50%}.react-flow__resize-control.handle.right{left:100%;top:50%}.react-flow__resize-control.handle.top{left:50%;top:0}.react-flow__resize-control.handle.bottom{left:50%;top:100%}.react-flow__resize-control.handle.top.left,.react-flow__resize-control.handle.bottom.left{left:0}.react-flow__resize-control.handle.top.right,.react-flow__resize-control.handle.bottom.right{left:100%}.react-flow__resize-control.line{border-color:#3367d9;border-width:0;border-style:solid}.react-flow__resize-control.line.left,.react-flow__resize-control.line.right{width:1px;transform:translate(-50%);top:0;height:100%}.react-flow__resize-control.line.left{left:0;border-left-width:1px}.react-flow__resize-control.line.right{left:100%;border-right-width:1px}.react-flow__resize-control.line.top,.react-flow__resize-control.line.bottom{height:1px;transform:translateY(-50%);left:0;width:100%}.react-flow__resize-control.line.top{top:0;border-top-width:1px}.react-flow__resize-control.line.bottom{border-bottom-width:1px;top:100%}
|