divyamagrawal06 commited on
Commit
6fffa8d
·
verified ·
1 Parent(s): 3bd41d7

Mirror Venice frontend

Browse files
.dockerignore ADDED
@@ -0,0 +1,8 @@
 
 
 
 
 
 
 
 
 
1
+ node_modules
2
+ .next
3
+ .vercel
4
+ .env
5
+ .env.*
6
+ server.log
7
+ coverage
8
+ npm-debug.log*
.env.example ADDED
@@ -0,0 +1,2 @@
 
 
 
1
+ NEXT_PUBLIC_VENICE_API_URL=http://localhost:8000
2
+ VENICE_BACKEND_URL=http://localhost:8000
Dockerfile ADDED
@@ -0,0 +1,17 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ FROM node:20-bookworm-slim
2
+
3
+ WORKDIR /app
4
+
5
+ ENV NEXT_TELEMETRY_DISABLED=1
6
+ ENV NODE_ENV=production
7
+ ENV VENICE_BACKEND_URL=http://165.245.134.115:8010
8
+
9
+ COPY package.json package-lock.json ./
10
+ RUN npm ci
11
+
12
+ COPY . .
13
+ RUN npm run build
14
+
15
+ EXPOSE 7860
16
+
17
+ CMD ["npm", "run", "start", "--", "-H", "0.0.0.0", "-p", "7860"]
README.md CHANGED
@@ -1,10 +1,18 @@
1
  ---
2
  title: Venice
3
- emoji: 🏃
4
- colorFrom: red
5
- colorTo: yellow
6
  sdk: docker
 
7
  pinned: false
 
 
8
  ---
9
 
10
- Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
 
 
 
 
 
 
 
1
  ---
2
  title: Venice
3
+ colorFrom: blue
4
+ colorTo: green
 
5
  sdk: docker
6
+ app_port: 7860
7
  pinned: false
8
+ license: mit
9
+ short_description: Branching visual search on AMD GPUs.
10
  ---
11
 
12
+ # Venice
13
+
14
+ Venice is a branching visual search canvas. This Space runs the Next.js frontend
15
+ and proxies generation requests to the AMD GPU backend running on DigitalOcean.
16
+
17
+ The frontend stays lightweight on Hugging Face Spaces; image generation remains
18
+ on the AMD ROCm host.
next-env.d.ts ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
 
1
+ /// <reference types="next" />
2
+ /// <reference types="next/image-types/global" />
3
+
4
+ // NOTE: This file should not be edited
5
+ // see https://nextjs.org/docs/app/building-your-application/configuring/typescript for more information.
next.config.mjs ADDED
@@ -0,0 +1,17 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /** @type {import('next').NextConfig} */
2
+ const nextConfig = {
3
+ images: {
4
+ remotePatterns: [
5
+ {
6
+ protocol: "http",
7
+ hostname: "localhost",
8
+ },
9
+ {
10
+ protocol: "https",
11
+ hostname: "**",
12
+ },
13
+ ],
14
+ },
15
+ };
16
+
17
+ export default nextConfig;
package-lock.json ADDED
@@ -0,0 +1,2109 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "name": "venice-frontend",
3
+ "version": "0.1.0",
4
+ "lockfileVersion": 3,
5
+ "requires": true,
6
+ "packages": {
7
+ "": {
8
+ "name": "venice-frontend",
9
+ "version": "0.1.0",
10
+ "dependencies": {
11
+ "@xyflow/react": "^12.10.0",
12
+ "lucide-react": "^0.468.0",
13
+ "next": "^14.2.22",
14
+ "react": "^18.3.1",
15
+ "react-dom": "^18.3.1"
16
+ },
17
+ "devDependencies": {
18
+ "@types/node": "^20.17.17",
19
+ "@types/react": "^18.3.18",
20
+ "@types/react-dom": "^18.3.5",
21
+ "typescript": "^5.7.3",
22
+ "vitest": "^2.1.8"
23
+ }
24
+ },
25
+ "node_modules/@esbuild/aix-ppc64": {
26
+ "version": "0.21.5",
27
+ "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz",
28
+ "integrity": "sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==",
29
+ "cpu": [
30
+ "ppc64"
31
+ ],
32
+ "dev": true,
33
+ "license": "MIT",
34
+ "optional": true,
35
+ "os": [
36
+ "aix"
37
+ ],
38
+ "engines": {
39
+ "node": ">=12"
40
+ }
41
+ },
42
+ "node_modules/@esbuild/android-arm": {
43
+ "version": "0.21.5",
44
+ "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.21.5.tgz",
45
+ "integrity": "sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==",
46
+ "cpu": [
47
+ "arm"
48
+ ],
49
+ "dev": true,
50
+ "license": "MIT",
51
+ "optional": true,
52
+ "os": [
53
+ "android"
54
+ ],
55
+ "engines": {
56
+ "node": ">=12"
57
+ }
58
+ },
59
+ "node_modules/@esbuild/android-arm64": {
60
+ "version": "0.21.5",
61
+ "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.21.5.tgz",
62
+ "integrity": "sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==",
63
+ "cpu": [
64
+ "arm64"
65
+ ],
66
+ "dev": true,
67
+ "license": "MIT",
68
+ "optional": true,
69
+ "os": [
70
+ "android"
71
+ ],
72
+ "engines": {
73
+ "node": ">=12"
74
+ }
75
+ },
76
+ "node_modules/@esbuild/android-x64": {
77
+ "version": "0.21.5",
78
+ "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.21.5.tgz",
79
+ "integrity": "sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==",
80
+ "cpu": [
81
+ "x64"
82
+ ],
83
+ "dev": true,
84
+ "license": "MIT",
85
+ "optional": true,
86
+ "os": [
87
+ "android"
88
+ ],
89
+ "engines": {
90
+ "node": ">=12"
91
+ }
92
+ },
93
+ "node_modules/@esbuild/darwin-arm64": {
94
+ "version": "0.21.5",
95
+ "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.21.5.tgz",
96
+ "integrity": "sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==",
97
+ "cpu": [
98
+ "arm64"
99
+ ],
100
+ "dev": true,
101
+ "license": "MIT",
102
+ "optional": true,
103
+ "os": [
104
+ "darwin"
105
+ ],
106
+ "engines": {
107
+ "node": ">=12"
108
+ }
109
+ },
110
+ "node_modules/@esbuild/darwin-x64": {
111
+ "version": "0.21.5",
112
+ "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.21.5.tgz",
113
+ "integrity": "sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==",
114
+ "cpu": [
115
+ "x64"
116
+ ],
117
+ "dev": true,
118
+ "license": "MIT",
119
+ "optional": true,
120
+ "os": [
121
+ "darwin"
122
+ ],
123
+ "engines": {
124
+ "node": ">=12"
125
+ }
126
+ },
127
+ "node_modules/@esbuild/freebsd-arm64": {
128
+ "version": "0.21.5",
129
+ "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.21.5.tgz",
130
+ "integrity": "sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==",
131
+ "cpu": [
132
+ "arm64"
133
+ ],
134
+ "dev": true,
135
+ "license": "MIT",
136
+ "optional": true,
137
+ "os": [
138
+ "freebsd"
139
+ ],
140
+ "engines": {
141
+ "node": ">=12"
142
+ }
143
+ },
144
+ "node_modules/@esbuild/freebsd-x64": {
145
+ "version": "0.21.5",
146
+ "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.21.5.tgz",
147
+ "integrity": "sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==",
148
+ "cpu": [
149
+ "x64"
150
+ ],
151
+ "dev": true,
152
+ "license": "MIT",
153
+ "optional": true,
154
+ "os": [
155
+ "freebsd"
156
+ ],
157
+ "engines": {
158
+ "node": ">=12"
159
+ }
160
+ },
161
+ "node_modules/@esbuild/linux-arm": {
162
+ "version": "0.21.5",
163
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.21.5.tgz",
164
+ "integrity": "sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==",
165
+ "cpu": [
166
+ "arm"
167
+ ],
168
+ "dev": true,
169
+ "license": "MIT",
170
+ "optional": true,
171
+ "os": [
172
+ "linux"
173
+ ],
174
+ "engines": {
175
+ "node": ">=12"
176
+ }
177
+ },
178
+ "node_modules/@esbuild/linux-arm64": {
179
+ "version": "0.21.5",
180
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.21.5.tgz",
181
+ "integrity": "sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==",
182
+ "cpu": [
183
+ "arm64"
184
+ ],
185
+ "dev": true,
186
+ "license": "MIT",
187
+ "optional": true,
188
+ "os": [
189
+ "linux"
190
+ ],
191
+ "engines": {
192
+ "node": ">=12"
193
+ }
194
+ },
195
+ "node_modules/@esbuild/linux-ia32": {
196
+ "version": "0.21.5",
197
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.21.5.tgz",
198
+ "integrity": "sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==",
199
+ "cpu": [
200
+ "ia32"
201
+ ],
202
+ "dev": true,
203
+ "license": "MIT",
204
+ "optional": true,
205
+ "os": [
206
+ "linux"
207
+ ],
208
+ "engines": {
209
+ "node": ">=12"
210
+ }
211
+ },
212
+ "node_modules/@esbuild/linux-loong64": {
213
+ "version": "0.21.5",
214
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.21.5.tgz",
215
+ "integrity": "sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==",
216
+ "cpu": [
217
+ "loong64"
218
+ ],
219
+ "dev": true,
220
+ "license": "MIT",
221
+ "optional": true,
222
+ "os": [
223
+ "linux"
224
+ ],
225
+ "engines": {
226
+ "node": ">=12"
227
+ }
228
+ },
229
+ "node_modules/@esbuild/linux-mips64el": {
230
+ "version": "0.21.5",
231
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.21.5.tgz",
232
+ "integrity": "sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==",
233
+ "cpu": [
234
+ "mips64el"
235
+ ],
236
+ "dev": true,
237
+ "license": "MIT",
238
+ "optional": true,
239
+ "os": [
240
+ "linux"
241
+ ],
242
+ "engines": {
243
+ "node": ">=12"
244
+ }
245
+ },
246
+ "node_modules/@esbuild/linux-ppc64": {
247
+ "version": "0.21.5",
248
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.21.5.tgz",
249
+ "integrity": "sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==",
250
+ "cpu": [
251
+ "ppc64"
252
+ ],
253
+ "dev": true,
254
+ "license": "MIT",
255
+ "optional": true,
256
+ "os": [
257
+ "linux"
258
+ ],
259
+ "engines": {
260
+ "node": ">=12"
261
+ }
262
+ },
263
+ "node_modules/@esbuild/linux-riscv64": {
264
+ "version": "0.21.5",
265
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.21.5.tgz",
266
+ "integrity": "sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==",
267
+ "cpu": [
268
+ "riscv64"
269
+ ],
270
+ "dev": true,
271
+ "license": "MIT",
272
+ "optional": true,
273
+ "os": [
274
+ "linux"
275
+ ],
276
+ "engines": {
277
+ "node": ">=12"
278
+ }
279
+ },
280
+ "node_modules/@esbuild/linux-s390x": {
281
+ "version": "0.21.5",
282
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.21.5.tgz",
283
+ "integrity": "sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==",
284
+ "cpu": [
285
+ "s390x"
286
+ ],
287
+ "dev": true,
288
+ "license": "MIT",
289
+ "optional": true,
290
+ "os": [
291
+ "linux"
292
+ ],
293
+ "engines": {
294
+ "node": ">=12"
295
+ }
296
+ },
297
+ "node_modules/@esbuild/linux-x64": {
298
+ "version": "0.21.5",
299
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.21.5.tgz",
300
+ "integrity": "sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==",
301
+ "cpu": [
302
+ "x64"
303
+ ],
304
+ "dev": true,
305
+ "license": "MIT",
306
+ "optional": true,
307
+ "os": [
308
+ "linux"
309
+ ],
310
+ "engines": {
311
+ "node": ">=12"
312
+ }
313
+ },
314
+ "node_modules/@esbuild/netbsd-x64": {
315
+ "version": "0.21.5",
316
+ "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.21.5.tgz",
317
+ "integrity": "sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==",
318
+ "cpu": [
319
+ "x64"
320
+ ],
321
+ "dev": true,
322
+ "license": "MIT",
323
+ "optional": true,
324
+ "os": [
325
+ "netbsd"
326
+ ],
327
+ "engines": {
328
+ "node": ">=12"
329
+ }
330
+ },
331
+ "node_modules/@esbuild/openbsd-x64": {
332
+ "version": "0.21.5",
333
+ "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.21.5.tgz",
334
+ "integrity": "sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==",
335
+ "cpu": [
336
+ "x64"
337
+ ],
338
+ "dev": true,
339
+ "license": "MIT",
340
+ "optional": true,
341
+ "os": [
342
+ "openbsd"
343
+ ],
344
+ "engines": {
345
+ "node": ">=12"
346
+ }
347
+ },
348
+ "node_modules/@esbuild/sunos-x64": {
349
+ "version": "0.21.5",
350
+ "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.21.5.tgz",
351
+ "integrity": "sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==",
352
+ "cpu": [
353
+ "x64"
354
+ ],
355
+ "dev": true,
356
+ "license": "MIT",
357
+ "optional": true,
358
+ "os": [
359
+ "sunos"
360
+ ],
361
+ "engines": {
362
+ "node": ">=12"
363
+ }
364
+ },
365
+ "node_modules/@esbuild/win32-arm64": {
366
+ "version": "0.21.5",
367
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.21.5.tgz",
368
+ "integrity": "sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==",
369
+ "cpu": [
370
+ "arm64"
371
+ ],
372
+ "dev": true,
373
+ "license": "MIT",
374
+ "optional": true,
375
+ "os": [
376
+ "win32"
377
+ ],
378
+ "engines": {
379
+ "node": ">=12"
380
+ }
381
+ },
382
+ "node_modules/@esbuild/win32-ia32": {
383
+ "version": "0.21.5",
384
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.21.5.tgz",
385
+ "integrity": "sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==",
386
+ "cpu": [
387
+ "ia32"
388
+ ],
389
+ "dev": true,
390
+ "license": "MIT",
391
+ "optional": true,
392
+ "os": [
393
+ "win32"
394
+ ],
395
+ "engines": {
396
+ "node": ">=12"
397
+ }
398
+ },
399
+ "node_modules/@esbuild/win32-x64": {
400
+ "version": "0.21.5",
401
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.21.5.tgz",
402
+ "integrity": "sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==",
403
+ "cpu": [
404
+ "x64"
405
+ ],
406
+ "dev": true,
407
+ "license": "MIT",
408
+ "optional": true,
409
+ "os": [
410
+ "win32"
411
+ ],
412
+ "engines": {
413
+ "node": ">=12"
414
+ }
415
+ },
416
+ "node_modules/@jridgewell/sourcemap-codec": {
417
+ "version": "1.5.5",
418
+ "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz",
419
+ "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==",
420
+ "dev": true,
421
+ "license": "MIT"
422
+ },
423
+ "node_modules/@next/env": {
424
+ "version": "14.2.35",
425
+ "resolved": "https://registry.npmjs.org/@next/env/-/env-14.2.35.tgz",
426
+ "integrity": "sha512-DuhvCtj4t9Gwrx80dmz2F4t/zKQ4ktN8WrMwOuVzkJfBilwAwGr6v16M5eI8yCuZ63H9TTuEU09Iu2HqkzFPVQ==",
427
+ "license": "MIT"
428
+ },
429
+ "node_modules/@next/swc-darwin-arm64": {
430
+ "version": "14.2.33",
431
+ "resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-14.2.33.tgz",
432
+ "integrity": "sha512-HqYnb6pxlsshoSTubdXKu15g3iivcbsMXg4bYpjL2iS/V6aQot+iyF4BUc2qA/J/n55YtvE4PHMKWBKGCF/+wA==",
433
+ "cpu": [
434
+ "arm64"
435
+ ],
436
+ "license": "MIT",
437
+ "optional": true,
438
+ "os": [
439
+ "darwin"
440
+ ],
441
+ "engines": {
442
+ "node": ">= 10"
443
+ }
444
+ },
445
+ "node_modules/@next/swc-darwin-x64": {
446
+ "version": "14.2.33",
447
+ "resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-14.2.33.tgz",
448
+ "integrity": "sha512-8HGBeAE5rX3jzKvF593XTTFg3gxeU4f+UWnswa6JPhzaR6+zblO5+fjltJWIZc4aUalqTclvN2QtTC37LxvZAA==",
449
+ "cpu": [
450
+ "x64"
451
+ ],
452
+ "license": "MIT",
453
+ "optional": true,
454
+ "os": [
455
+ "darwin"
456
+ ],
457
+ "engines": {
458
+ "node": ">= 10"
459
+ }
460
+ },
461
+ "node_modules/@next/swc-linux-arm64-gnu": {
462
+ "version": "14.2.33",
463
+ "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-14.2.33.tgz",
464
+ "integrity": "sha512-JXMBka6lNNmqbkvcTtaX8Gu5by9547bukHQvPoLe9VRBx1gHwzf5tdt4AaezW85HAB3pikcvyqBToRTDA4DeLw==",
465
+ "cpu": [
466
+ "arm64"
467
+ ],
468
+ "license": "MIT",
469
+ "optional": true,
470
+ "os": [
471
+ "linux"
472
+ ],
473
+ "engines": {
474
+ "node": ">= 10"
475
+ }
476
+ },
477
+ "node_modules/@next/swc-linux-arm64-musl": {
478
+ "version": "14.2.33",
479
+ "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-14.2.33.tgz",
480
+ "integrity": "sha512-Bm+QulsAItD/x6Ih8wGIMfRJy4G73tu1HJsrccPW6AfqdZd0Sfm5Imhgkgq2+kly065rYMnCOxTBvmvFY1BKfg==",
481
+ "cpu": [
482
+ "arm64"
483
+ ],
484
+ "license": "MIT",
485
+ "optional": true,
486
+ "os": [
487
+ "linux"
488
+ ],
489
+ "engines": {
490
+ "node": ">= 10"
491
+ }
492
+ },
493
+ "node_modules/@next/swc-linux-x64-gnu": {
494
+ "version": "14.2.33",
495
+ "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-14.2.33.tgz",
496
+ "integrity": "sha512-FnFn+ZBgsVMbGDsTqo8zsnRzydvsGV8vfiWwUo1LD8FTmPTdV+otGSWKc4LJec0oSexFnCYVO4hX8P8qQKaSlg==",
497
+ "cpu": [
498
+ "x64"
499
+ ],
500
+ "license": "MIT",
501
+ "optional": true,
502
+ "os": [
503
+ "linux"
504
+ ],
505
+ "engines": {
506
+ "node": ">= 10"
507
+ }
508
+ },
509
+ "node_modules/@next/swc-linux-x64-musl": {
510
+ "version": "14.2.33",
511
+ "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-14.2.33.tgz",
512
+ "integrity": "sha512-345tsIWMzoXaQndUTDv1qypDRiebFxGYx9pYkhwY4hBRaOLt8UGfiWKr9FSSHs25dFIf8ZqIFaPdy5MljdoawA==",
513
+ "cpu": [
514
+ "x64"
515
+ ],
516
+ "license": "MIT",
517
+ "optional": true,
518
+ "os": [
519
+ "linux"
520
+ ],
521
+ "engines": {
522
+ "node": ">= 10"
523
+ }
524
+ },
525
+ "node_modules/@next/swc-win32-arm64-msvc": {
526
+ "version": "14.2.33",
527
+ "resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-14.2.33.tgz",
528
+ "integrity": "sha512-nscpt0G6UCTkrT2ppnJnFsYbPDQwmum4GNXYTeoTIdsmMydSKFz9Iny2jpaRupTb+Wl298+Rh82WKzt9LCcqSQ==",
529
+ "cpu": [
530
+ "arm64"
531
+ ],
532
+ "license": "MIT",
533
+ "optional": true,
534
+ "os": [
535
+ "win32"
536
+ ],
537
+ "engines": {
538
+ "node": ">= 10"
539
+ }
540
+ },
541
+ "node_modules/@next/swc-win32-ia32-msvc": {
542
+ "version": "14.2.33",
543
+ "resolved": "https://registry.npmjs.org/@next/swc-win32-ia32-msvc/-/swc-win32-ia32-msvc-14.2.33.tgz",
544
+ "integrity": "sha512-pc9LpGNKhJ0dXQhZ5QMmYxtARwwmWLpeocFmVG5Z0DzWq5Uf0izcI8tLc+qOpqxO1PWqZ5A7J1blrUIKrIFc7Q==",
545
+ "cpu": [
546
+ "ia32"
547
+ ],
548
+ "license": "MIT",
549
+ "optional": true,
550
+ "os": [
551
+ "win32"
552
+ ],
553
+ "engines": {
554
+ "node": ">= 10"
555
+ }
556
+ },
557
+ "node_modules/@next/swc-win32-x64-msvc": {
558
+ "version": "14.2.33",
559
+ "resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-14.2.33.tgz",
560
+ "integrity": "sha512-nOjfZMy8B94MdisuzZo9/57xuFVLHJaDj5e/xrduJp9CV2/HrfxTRH2fbyLe+K9QT41WBLUd4iXX3R7jBp0EUg==",
561
+ "cpu": [
562
+ "x64"
563
+ ],
564
+ "license": "MIT",
565
+ "optional": true,
566
+ "os": [
567
+ "win32"
568
+ ],
569
+ "engines": {
570
+ "node": ">= 10"
571
+ }
572
+ },
573
+ "node_modules/@rollup/rollup-android-arm-eabi": {
574
+ "version": "4.60.3",
575
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.60.3.tgz",
576
+ "integrity": "sha512-x35CNW/ANXG3hE/EZpRU8MXX1JDN86hBb2wMGAtltkz7pc6cxgjpy1OMMfDosOQ+2hWqIkag/fGok1Yady9nGw==",
577
+ "cpu": [
578
+ "arm"
579
+ ],
580
+ "dev": true,
581
+ "license": "MIT",
582
+ "optional": true,
583
+ "os": [
584
+ "android"
585
+ ]
586
+ },
587
+ "node_modules/@rollup/rollup-android-arm64": {
588
+ "version": "4.60.3",
589
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.60.3.tgz",
590
+ "integrity": "sha512-xw3xtkDApIOGayehp2+Rz4zimfkaX65r4t47iy+ymQB2G4iJCBBfj0ogVg5jpvjpn8UWn/+q9tprxleYeNp3Hw==",
591
+ "cpu": [
592
+ "arm64"
593
+ ],
594
+ "dev": true,
595
+ "license": "MIT",
596
+ "optional": true,
597
+ "os": [
598
+ "android"
599
+ ]
600
+ },
601
+ "node_modules/@rollup/rollup-darwin-arm64": {
602
+ "version": "4.60.3",
603
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.60.3.tgz",
604
+ "integrity": "sha512-vo6Y5Qfpx7/5EaamIwi0WqW2+zfiusVihKatLvtN1VFVy3D13uERk/6gZLU1UiHRL6fDXqj/ELIeVRGnvcTE1g==",
605
+ "cpu": [
606
+ "arm64"
607
+ ],
608
+ "dev": true,
609
+ "license": "MIT",
610
+ "optional": true,
611
+ "os": [
612
+ "darwin"
613
+ ]
614
+ },
615
+ "node_modules/@rollup/rollup-darwin-x64": {
616
+ "version": "4.60.3",
617
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.60.3.tgz",
618
+ "integrity": "sha512-D+0QGcZhBzTN82weOnsSlY7V7+RMmPuF1CkbxyMAGE8+ZHeUjyb76ZiWmBlCu//AQQONvxcqRbwZTajZKqjuOw==",
619
+ "cpu": [
620
+ "x64"
621
+ ],
622
+ "dev": true,
623
+ "license": "MIT",
624
+ "optional": true,
625
+ "os": [
626
+ "darwin"
627
+ ]
628
+ },
629
+ "node_modules/@rollup/rollup-freebsd-arm64": {
630
+ "version": "4.60.3",
631
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.60.3.tgz",
632
+ "integrity": "sha512-6HnvHCT7fDyj6R0Ph7A6x8dQS/S38MClRWeDLqc0MdfWkxjiu1HSDYrdPhqSILzjTIC/pnXbbJbo+ft+gy/9hQ==",
633
+ "cpu": [
634
+ "arm64"
635
+ ],
636
+ "dev": true,
637
+ "license": "MIT",
638
+ "optional": true,
639
+ "os": [
640
+ "freebsd"
641
+ ]
642
+ },
643
+ "node_modules/@rollup/rollup-freebsd-x64": {
644
+ "version": "4.60.3",
645
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.60.3.tgz",
646
+ "integrity": "sha512-KHLgC3WKlUYW3ShFKnnosZDOJ0xjg9zp7au3sIm2bs/tGBeC2ipmvRh/N7JKi0t9Ue20C0dpEshi8WUubg+cnA==",
647
+ "cpu": [
648
+ "x64"
649
+ ],
650
+ "dev": true,
651
+ "license": "MIT",
652
+ "optional": true,
653
+ "os": [
654
+ "freebsd"
655
+ ]
656
+ },
657
+ "node_modules/@rollup/rollup-linux-arm-gnueabihf": {
658
+ "version": "4.60.3",
659
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.60.3.tgz",
660
+ "integrity": "sha512-DV6fJoxEYWJOvaZIsok7KrYl0tPvga5OZ2yvKHNNYyk/2roMLqQAbGhr78EQ5YhHpnhLKJD3S1WFusAkmUuV5g==",
661
+ "cpu": [
662
+ "arm"
663
+ ],
664
+ "dev": true,
665
+ "license": "MIT",
666
+ "optional": true,
667
+ "os": [
668
+ "linux"
669
+ ]
670
+ },
671
+ "node_modules/@rollup/rollup-linux-arm-musleabihf": {
672
+ "version": "4.60.3",
673
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.60.3.tgz",
674
+ "integrity": "sha512-mQKoJAzvuOs6F+TZybQO4GOTSMUu7v0WdxEk24krQ/uUxXoPTtHjuaUuPmFhtBcM4K0ons8nrE3JyhTuCFtT/w==",
675
+ "cpu": [
676
+ "arm"
677
+ ],
678
+ "dev": true,
679
+ "license": "MIT",
680
+ "optional": true,
681
+ "os": [
682
+ "linux"
683
+ ]
684
+ },
685
+ "node_modules/@rollup/rollup-linux-arm64-gnu": {
686
+ "version": "4.60.3",
687
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.60.3.tgz",
688
+ "integrity": "sha512-Whjj2qoiJ6+OOJMGptTYazaJvjOJm+iKHpXQM1P3LzGjt7Ff++Tp7nH4N8J/BUA7R9IHfDyx4DJIflifwnbmIA==",
689
+ "cpu": [
690
+ "arm64"
691
+ ],
692
+ "dev": true,
693
+ "license": "MIT",
694
+ "optional": true,
695
+ "os": [
696
+ "linux"
697
+ ]
698
+ },
699
+ "node_modules/@rollup/rollup-linux-arm64-musl": {
700
+ "version": "4.60.3",
701
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.60.3.tgz",
702
+ "integrity": "sha512-4YTNHKqGng5+yiZt3mg77nmyuCfmNfX4fPmyUapBcIk+BdwSwmCWGXOUxhXbBEkFHtoN5boLj/5NON+u5QC9tg==",
703
+ "cpu": [
704
+ "arm64"
705
+ ],
706
+ "dev": true,
707
+ "license": "MIT",
708
+ "optional": true,
709
+ "os": [
710
+ "linux"
711
+ ]
712
+ },
713
+ "node_modules/@rollup/rollup-linux-loong64-gnu": {
714
+ "version": "4.60.3",
715
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.60.3.tgz",
716
+ "integrity": "sha512-SU3kNlhkpI4UqlUc2VXPGK9o886ZsSeGfMAX2ba2b8DKmMXq4AL7KUrkSWVbb7koVqx41Yczx6dx5PNargIrEA==",
717
+ "cpu": [
718
+ "loong64"
719
+ ],
720
+ "dev": true,
721
+ "license": "MIT",
722
+ "optional": true,
723
+ "os": [
724
+ "linux"
725
+ ]
726
+ },
727
+ "node_modules/@rollup/rollup-linux-loong64-musl": {
728
+ "version": "4.60.3",
729
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-musl/-/rollup-linux-loong64-musl-4.60.3.tgz",
730
+ "integrity": "sha512-6lDLl5h4TXpB1mTf2rQWnAk/LcXrx9vBfu/DT5TIPhvMhRWaZ5MxkIc8u4lJAmBo6klTe1ywXIUHFjylW505sg==",
731
+ "cpu": [
732
+ "loong64"
733
+ ],
734
+ "dev": true,
735
+ "license": "MIT",
736
+ "optional": true,
737
+ "os": [
738
+ "linux"
739
+ ]
740
+ },
741
+ "node_modules/@rollup/rollup-linux-ppc64-gnu": {
742
+ "version": "4.60.3",
743
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.60.3.tgz",
744
+ "integrity": "sha512-BMo8bOw8evlup/8G+cj5xWtPyp93xPdyoSN16Zy90Q2QZ0ZYRhCt6ZJSwbrRzG9HApFabjwj2p25TUPDWrhzqQ==",
745
+ "cpu": [
746
+ "ppc64"
747
+ ],
748
+ "dev": true,
749
+ "license": "MIT",
750
+ "optional": true,
751
+ "os": [
752
+ "linux"
753
+ ]
754
+ },
755
+ "node_modules/@rollup/rollup-linux-ppc64-musl": {
756
+ "version": "4.60.3",
757
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-musl/-/rollup-linux-ppc64-musl-4.60.3.tgz",
758
+ "integrity": "sha512-E0L8X1dZN1/Rph+5VPF6Xj2G7JJvMACVXtamTJIDrVI44Y3K+G8gQaMEAavbqCGTa16InptiVrX6eM6pmJ+7qA==",
759
+ "cpu": [
760
+ "ppc64"
761
+ ],
762
+ "dev": true,
763
+ "license": "MIT",
764
+ "optional": true,
765
+ "os": [
766
+ "linux"
767
+ ]
768
+ },
769
+ "node_modules/@rollup/rollup-linux-riscv64-gnu": {
770
+ "version": "4.60.3",
771
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.60.3.tgz",
772
+ "integrity": "sha512-oZJ/WHaVfHUiRAtmTAeo3DcevNsVvH8mbvodjZy7D5QKvCefO371SiKRpxoDcCxB3PTRTLayWBkvmDQKTcX/sw==",
773
+ "cpu": [
774
+ "riscv64"
775
+ ],
776
+ "dev": true,
777
+ "license": "MIT",
778
+ "optional": true,
779
+ "os": [
780
+ "linux"
781
+ ]
782
+ },
783
+ "node_modules/@rollup/rollup-linux-riscv64-musl": {
784
+ "version": "4.60.3",
785
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.60.3.tgz",
786
+ "integrity": "sha512-Dhbyh7j9FybM3YaTgaHmVALwA8AkUwTPccyCQ79TG9AJUsMQqgN1DDEZNr4+QUfwiWvLDumW5vdwzoeUF+TNxQ==",
787
+ "cpu": [
788
+ "riscv64"
789
+ ],
790
+ "dev": true,
791
+ "license": "MIT",
792
+ "optional": true,
793
+ "os": [
794
+ "linux"
795
+ ]
796
+ },
797
+ "node_modules/@rollup/rollup-linux-s390x-gnu": {
798
+ "version": "4.60.3",
799
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.60.3.tgz",
800
+ "integrity": "sha512-cJd1X5XhHHlltkaypz1UcWLA8AcoIi1aWhsvaWDskD1oz2eKCypnqvTQ8ykMNI0RSmm7NkTdSqSSD7zM0xa6Ig==",
801
+ "cpu": [
802
+ "s390x"
803
+ ],
804
+ "dev": true,
805
+ "license": "MIT",
806
+ "optional": true,
807
+ "os": [
808
+ "linux"
809
+ ]
810
+ },
811
+ "node_modules/@rollup/rollup-linux-x64-gnu": {
812
+ "version": "4.60.3",
813
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.60.3.tgz",
814
+ "integrity": "sha512-DAZDBHQfG2oQuhY7mc6I3/qB4LU2fQCjRvxbDwd/Jdvb9fypP4IJ4qmtu6lNjes6B531AI8cg1aKC2di97bUxA==",
815
+ "cpu": [
816
+ "x64"
817
+ ],
818
+ "dev": true,
819
+ "license": "MIT",
820
+ "optional": true,
821
+ "os": [
822
+ "linux"
823
+ ]
824
+ },
825
+ "node_modules/@rollup/rollup-linux-x64-musl": {
826
+ "version": "4.60.3",
827
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.60.3.tgz",
828
+ "integrity": "sha512-cRxsE8c13mZOh3vP+wLDxpQBRrOHDIGOWyDL93Sy0Ga8y515fBcC2pjUfFwUe5T7tqvTvWbCpg1URM/AXdWIXA==",
829
+ "cpu": [
830
+ "x64"
831
+ ],
832
+ "dev": true,
833
+ "license": "MIT",
834
+ "optional": true,
835
+ "os": [
836
+ "linux"
837
+ ]
838
+ },
839
+ "node_modules/@rollup/rollup-openbsd-x64": {
840
+ "version": "4.60.3",
841
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-openbsd-x64/-/rollup-openbsd-x64-4.60.3.tgz",
842
+ "integrity": "sha512-QaWcIgRxqEdQdhJqW4DJctsH6HCmo5vHxY0krHSX4jMtOqfzC+dqDGuHM87bu4H8JBeibWx7jFz+h6/4C8wA5Q==",
843
+ "cpu": [
844
+ "x64"
845
+ ],
846
+ "dev": true,
847
+ "license": "MIT",
848
+ "optional": true,
849
+ "os": [
850
+ "openbsd"
851
+ ]
852
+ },
853
+ "node_modules/@rollup/rollup-openharmony-arm64": {
854
+ "version": "4.60.3",
855
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.60.3.tgz",
856
+ "integrity": "sha512-AaXwSvUi3QIPtroAUw1t5yHGIyqKEXwH54WUocFolZhpGDruJcs8c+xPNDRn4XiQsS7MEwnYsHW2l0MBLDMkWg==",
857
+ "cpu": [
858
+ "arm64"
859
+ ],
860
+ "dev": true,
861
+ "license": "MIT",
862
+ "optional": true,
863
+ "os": [
864
+ "openharmony"
865
+ ]
866
+ },
867
+ "node_modules/@rollup/rollup-win32-arm64-msvc": {
868
+ "version": "4.60.3",
869
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.60.3.tgz",
870
+ "integrity": "sha512-65LAKM/bAWDqKNEelHlcHvm2V+Vfb8C6INFxQXRHCvaVN1rJfwr4NvdP4FyzUaLqWfaCGaadf6UbTm8xJeYfEg==",
871
+ "cpu": [
872
+ "arm64"
873
+ ],
874
+ "dev": true,
875
+ "license": "MIT",
876
+ "optional": true,
877
+ "os": [
878
+ "win32"
879
+ ]
880
+ },
881
+ "node_modules/@rollup/rollup-win32-ia32-msvc": {
882
+ "version": "4.60.3",
883
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.60.3.tgz",
884
+ "integrity": "sha512-EEM2gyhBF5MFnI6vMKdX1LAosE627RGBzIoGMdLloPZkXrUN0Ckqgr2Qi8+J3zip/8NVVro3/FjB+tjhZUgUHA==",
885
+ "cpu": [
886
+ "ia32"
887
+ ],
888
+ "dev": true,
889
+ "license": "MIT",
890
+ "optional": true,
891
+ "os": [
892
+ "win32"
893
+ ]
894
+ },
895
+ "node_modules/@rollup/rollup-win32-x64-gnu": {
896
+ "version": "4.60.3",
897
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.60.3.tgz",
898
+ "integrity": "sha512-E5Eb5H/DpxaoXH++Qkv28RcUJboMopmdDUALBczvHMf7hNIxaDZqwY5lK12UK1BHacSmvupoEWGu+n993Z0y1A==",
899
+ "cpu": [
900
+ "x64"
901
+ ],
902
+ "dev": true,
903
+ "license": "MIT",
904
+ "optional": true,
905
+ "os": [
906
+ "win32"
907
+ ]
908
+ },
909
+ "node_modules/@rollup/rollup-win32-x64-msvc": {
910
+ "version": "4.60.3",
911
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.60.3.tgz",
912
+ "integrity": "sha512-hPt/bgL5cE+Qp+/TPHBqptcAgPzgj46mPcg/16zNUmbQk0j+mOEQV/+Lqu8QRtDV3Ek95Q6FeFITpuhl6OTsAA==",
913
+ "cpu": [
914
+ "x64"
915
+ ],
916
+ "dev": true,
917
+ "license": "MIT",
918
+ "optional": true,
919
+ "os": [
920
+ "win32"
921
+ ]
922
+ },
923
+ "node_modules/@swc/counter": {
924
+ "version": "0.1.3",
925
+ "resolved": "https://registry.npmjs.org/@swc/counter/-/counter-0.1.3.tgz",
926
+ "integrity": "sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ==",
927
+ "license": "Apache-2.0"
928
+ },
929
+ "node_modules/@swc/helpers": {
930
+ "version": "0.5.5",
931
+ "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.5.tgz",
932
+ "integrity": "sha512-KGYxvIOXcceOAbEk4bi/dVLEK9z8sZ0uBB3Il5b1rhfClSpcX0yfRO0KmTkqR2cnQDymwLB+25ZyMzICg/cm/A==",
933
+ "license": "Apache-2.0",
934
+ "dependencies": {
935
+ "@swc/counter": "^0.1.3",
936
+ "tslib": "^2.4.0"
937
+ }
938
+ },
939
+ "node_modules/@types/d3-color": {
940
+ "version": "3.1.3",
941
+ "resolved": "https://registry.npmjs.org/@types/d3-color/-/d3-color-3.1.3.tgz",
942
+ "integrity": "sha512-iO90scth9WAbmgv7ogoq57O9YpKmFBbmoEoCHDB2xMBY0+/KVrqAaCDyCE16dUspeOvIxFFRI+0sEtqDqy2b4A==",
943
+ "license": "MIT"
944
+ },
945
+ "node_modules/@types/d3-drag": {
946
+ "version": "3.0.7",
947
+ "resolved": "https://registry.npmjs.org/@types/d3-drag/-/d3-drag-3.0.7.tgz",
948
+ "integrity": "sha512-HE3jVKlzU9AaMazNufooRJ5ZpWmLIoc90A37WU2JMmeq28w1FQqCZswHZ3xR+SuxYftzHq6WU6KJHvqxKzTxxQ==",
949
+ "license": "MIT",
950
+ "dependencies": {
951
+ "@types/d3-selection": "*"
952
+ }
953
+ },
954
+ "node_modules/@types/d3-interpolate": {
955
+ "version": "3.0.4",
956
+ "resolved": "https://registry.npmjs.org/@types/d3-interpolate/-/d3-interpolate-3.0.4.tgz",
957
+ "integrity": "sha512-mgLPETlrpVV1YRJIglr4Ez47g7Yxjl1lj7YKsiMCb27VJH9W8NVM6Bb9d8kkpG/uAQS5AmbA48q2IAolKKo1MA==",
958
+ "license": "MIT",
959
+ "dependencies": {
960
+ "@types/d3-color": "*"
961
+ }
962
+ },
963
+ "node_modules/@types/d3-selection": {
964
+ "version": "3.0.11",
965
+ "resolved": "https://registry.npmjs.org/@types/d3-selection/-/d3-selection-3.0.11.tgz",
966
+ "integrity": "sha512-bhAXu23DJWsrI45xafYpkQ4NtcKMwWnAC/vKrd2l+nxMFuvOT3XMYTIj2opv8vq8AO5Yh7Qac/nSeP/3zjTK0w==",
967
+ "license": "MIT"
968
+ },
969
+ "node_modules/@types/d3-transition": {
970
+ "version": "3.0.9",
971
+ "resolved": "https://registry.npmjs.org/@types/d3-transition/-/d3-transition-3.0.9.tgz",
972
+ "integrity": "sha512-uZS5shfxzO3rGlu0cC3bjmMFKsXv+SmZZcgp0KD22ts4uGXp5EVYGzu/0YdwZeKmddhcAccYtREJKkPfXkZuCg==",
973
+ "license": "MIT",
974
+ "dependencies": {
975
+ "@types/d3-selection": "*"
976
+ }
977
+ },
978
+ "node_modules/@types/d3-zoom": {
979
+ "version": "3.0.8",
980
+ "resolved": "https://registry.npmjs.org/@types/d3-zoom/-/d3-zoom-3.0.8.tgz",
981
+ "integrity": "sha512-iqMC4/YlFCSlO8+2Ii1GGGliCAY4XdeG748w5vQUbevlbDu0zSjH/+jojorQVBK/se0j6DUFNPBGSqD3YWYnDw==",
982
+ "license": "MIT",
983
+ "dependencies": {
984
+ "@types/d3-interpolate": "*",
985
+ "@types/d3-selection": "*"
986
+ }
987
+ },
988
+ "node_modules/@types/estree": {
989
+ "version": "1.0.8",
990
+ "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz",
991
+ "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==",
992
+ "dev": true,
993
+ "license": "MIT"
994
+ },
995
+ "node_modules/@types/node": {
996
+ "version": "20.19.39",
997
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-20.19.39.tgz",
998
+ "integrity": "sha512-orrrD74MBUyK8jOAD/r0+lfa1I2MO6I+vAkmAWzMYbCcgrN4lCrmK52gRFQq/JRxfYPfonkr4b0jcY7Olqdqbw==",
999
+ "dev": true,
1000
+ "license": "MIT",
1001
+ "dependencies": {
1002
+ "undici-types": "~6.21.0"
1003
+ }
1004
+ },
1005
+ "node_modules/@types/prop-types": {
1006
+ "version": "15.7.15",
1007
+ "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.15.tgz",
1008
+ "integrity": "sha512-F6bEyamV9jKGAFBEmlQnesRPGOQqS2+Uwi0Em15xenOxHaf2hv6L8YCVn3rPdPJOiJfPiCnLIRyvwVaqMY3MIw==",
1009
+ "devOptional": true,
1010
+ "license": "MIT"
1011
+ },
1012
+ "node_modules/@types/react": {
1013
+ "version": "18.3.28",
1014
+ "resolved": "https://registry.npmjs.org/@types/react/-/react-18.3.28.tgz",
1015
+ "integrity": "sha512-z9VXpC7MWrhfWipitjNdgCauoMLRdIILQsAEV+ZesIzBq/oUlxk0m3ApZuMFCXdnS4U7KrI+l3WRUEGQ8K1QKw==",
1016
+ "devOptional": true,
1017
+ "license": "MIT",
1018
+ "dependencies": {
1019
+ "@types/prop-types": "*",
1020
+ "csstype": "^3.2.2"
1021
+ }
1022
+ },
1023
+ "node_modules/@types/react-dom": {
1024
+ "version": "18.3.7",
1025
+ "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.3.7.tgz",
1026
+ "integrity": "sha512-MEe3UeoENYVFXzoXEWsvcpg6ZvlrFNlOQ7EOsvhI3CfAXwzPfO8Qwuxd40nepsYKqyyVQnTdEfv68q91yLcKrQ==",
1027
+ "dev": true,
1028
+ "license": "MIT",
1029
+ "peerDependencies": {
1030
+ "@types/react": "^18.0.0"
1031
+ }
1032
+ },
1033
+ "node_modules/@vitest/expect": {
1034
+ "version": "2.1.9",
1035
+ "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-2.1.9.tgz",
1036
+ "integrity": "sha512-UJCIkTBenHeKT1TTlKMJWy1laZewsRIzYighyYiJKZreqtdxSos/S1t+ktRMQWu2CKqaarrkeszJx1cgC5tGZw==",
1037
+ "dev": true,
1038
+ "license": "MIT",
1039
+ "dependencies": {
1040
+ "@vitest/spy": "2.1.9",
1041
+ "@vitest/utils": "2.1.9",
1042
+ "chai": "^5.1.2",
1043
+ "tinyrainbow": "^1.2.0"
1044
+ },
1045
+ "funding": {
1046
+ "url": "https://opencollective.com/vitest"
1047
+ }
1048
+ },
1049
+ "node_modules/@vitest/mocker": {
1050
+ "version": "2.1.9",
1051
+ "resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-2.1.9.tgz",
1052
+ "integrity": "sha512-tVL6uJgoUdi6icpxmdrn5YNo3g3Dxv+IHJBr0GXHaEdTcw3F+cPKnsXFhli6nO+f/6SDKPHEK1UN+k+TQv0Ehg==",
1053
+ "dev": true,
1054
+ "license": "MIT",
1055
+ "dependencies": {
1056
+ "@vitest/spy": "2.1.9",
1057
+ "estree-walker": "^3.0.3",
1058
+ "magic-string": "^0.30.12"
1059
+ },
1060
+ "funding": {
1061
+ "url": "https://opencollective.com/vitest"
1062
+ },
1063
+ "peerDependencies": {
1064
+ "msw": "^2.4.9",
1065
+ "vite": "^5.0.0"
1066
+ },
1067
+ "peerDependenciesMeta": {
1068
+ "msw": {
1069
+ "optional": true
1070
+ },
1071
+ "vite": {
1072
+ "optional": true
1073
+ }
1074
+ }
1075
+ },
1076
+ "node_modules/@vitest/pretty-format": {
1077
+ "version": "2.1.9",
1078
+ "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-2.1.9.tgz",
1079
+ "integrity": "sha512-KhRIdGV2U9HOUzxfiHmY8IFHTdqtOhIzCpd8WRdJiE7D/HUcZVD0EgQCVjm+Q9gkUXWgBvMmTtZgIG48wq7sOQ==",
1080
+ "dev": true,
1081
+ "license": "MIT",
1082
+ "dependencies": {
1083
+ "tinyrainbow": "^1.2.0"
1084
+ },
1085
+ "funding": {
1086
+ "url": "https://opencollective.com/vitest"
1087
+ }
1088
+ },
1089
+ "node_modules/@vitest/runner": {
1090
+ "version": "2.1.9",
1091
+ "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-2.1.9.tgz",
1092
+ "integrity": "sha512-ZXSSqTFIrzduD63btIfEyOmNcBmQvgOVsPNPe0jYtESiXkhd8u2erDLnMxmGrDCwHCCHE7hxwRDCT3pt0esT4g==",
1093
+ "dev": true,
1094
+ "license": "MIT",
1095
+ "dependencies": {
1096
+ "@vitest/utils": "2.1.9",
1097
+ "pathe": "^1.1.2"
1098
+ },
1099
+ "funding": {
1100
+ "url": "https://opencollective.com/vitest"
1101
+ }
1102
+ },
1103
+ "node_modules/@vitest/snapshot": {
1104
+ "version": "2.1.9",
1105
+ "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-2.1.9.tgz",
1106
+ "integrity": "sha512-oBO82rEjsxLNJincVhLhaxxZdEtV0EFHMK5Kmx5sJ6H9L183dHECjiefOAdnqpIgT5eZwT04PoggUnW88vOBNQ==",
1107
+ "dev": true,
1108
+ "license": "MIT",
1109
+ "dependencies": {
1110
+ "@vitest/pretty-format": "2.1.9",
1111
+ "magic-string": "^0.30.12",
1112
+ "pathe": "^1.1.2"
1113
+ },
1114
+ "funding": {
1115
+ "url": "https://opencollective.com/vitest"
1116
+ }
1117
+ },
1118
+ "node_modules/@vitest/spy": {
1119
+ "version": "2.1.9",
1120
+ "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-2.1.9.tgz",
1121
+ "integrity": "sha512-E1B35FwzXXTs9FHNK6bDszs7mtydNi5MIfUWpceJ8Xbfb1gBMscAnwLbEu+B44ed6W3XjL9/ehLPHR1fkf1KLQ==",
1122
+ "dev": true,
1123
+ "license": "MIT",
1124
+ "dependencies": {
1125
+ "tinyspy": "^3.0.2"
1126
+ },
1127
+ "funding": {
1128
+ "url": "https://opencollective.com/vitest"
1129
+ }
1130
+ },
1131
+ "node_modules/@vitest/utils": {
1132
+ "version": "2.1.9",
1133
+ "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-2.1.9.tgz",
1134
+ "integrity": "sha512-v0psaMSkNJ3A2NMrUEHFRzJtDPFn+/VWZ5WxImB21T9fjucJRmS7xCS3ppEnARb9y11OAzaD+P2Ps+b+BGX5iQ==",
1135
+ "dev": true,
1136
+ "license": "MIT",
1137
+ "dependencies": {
1138
+ "@vitest/pretty-format": "2.1.9",
1139
+ "loupe": "^3.1.2",
1140
+ "tinyrainbow": "^1.2.0"
1141
+ },
1142
+ "funding": {
1143
+ "url": "https://opencollective.com/vitest"
1144
+ }
1145
+ },
1146
+ "node_modules/@xyflow/react": {
1147
+ "version": "12.10.2",
1148
+ "resolved": "https://registry.npmjs.org/@xyflow/react/-/react-12.10.2.tgz",
1149
+ "integrity": "sha512-CgIi6HwlcHXwlkTpr0fxLv/0sRVNZ8IdwKLzzeCscaYBwpvfcH1QFOCeaTCuEn1FQEs/B8CjnTSjhs8udgmBgQ==",
1150
+ "license": "MIT",
1151
+ "dependencies": {
1152
+ "@xyflow/system": "0.0.76",
1153
+ "classcat": "^5.0.3",
1154
+ "zustand": "^4.4.0"
1155
+ },
1156
+ "peerDependencies": {
1157
+ "react": ">=17",
1158
+ "react-dom": ">=17"
1159
+ }
1160
+ },
1161
+ "node_modules/@xyflow/system": {
1162
+ "version": "0.0.76",
1163
+ "resolved": "https://registry.npmjs.org/@xyflow/system/-/system-0.0.76.tgz",
1164
+ "integrity": "sha512-hvwvnRS1B3REwVDlWexsq7YQaPZeG3/mKo1jv38UmnpWmxihp14bW6VtEOuHEwJX2FvzFw8k77LyKSk/wiZVNA==",
1165
+ "license": "MIT",
1166
+ "dependencies": {
1167
+ "@types/d3-drag": "^3.0.7",
1168
+ "@types/d3-interpolate": "^3.0.4",
1169
+ "@types/d3-selection": "^3.0.10",
1170
+ "@types/d3-transition": "^3.0.8",
1171
+ "@types/d3-zoom": "^3.0.8",
1172
+ "d3-drag": "^3.0.0",
1173
+ "d3-interpolate": "^3.0.1",
1174
+ "d3-selection": "^3.0.0",
1175
+ "d3-zoom": "^3.0.0"
1176
+ }
1177
+ },
1178
+ "node_modules/assertion-error": {
1179
+ "version": "2.0.1",
1180
+ "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-2.0.1.tgz",
1181
+ "integrity": "sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==",
1182
+ "dev": true,
1183
+ "license": "MIT",
1184
+ "engines": {
1185
+ "node": ">=12"
1186
+ }
1187
+ },
1188
+ "node_modules/busboy": {
1189
+ "version": "1.6.0",
1190
+ "resolved": "https://registry.npmjs.org/busboy/-/busboy-1.6.0.tgz",
1191
+ "integrity": "sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA==",
1192
+ "dependencies": {
1193
+ "streamsearch": "^1.1.0"
1194
+ },
1195
+ "engines": {
1196
+ "node": ">=10.16.0"
1197
+ }
1198
+ },
1199
+ "node_modules/cac": {
1200
+ "version": "6.7.14",
1201
+ "resolved": "https://registry.npmjs.org/cac/-/cac-6.7.14.tgz",
1202
+ "integrity": "sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==",
1203
+ "dev": true,
1204
+ "license": "MIT",
1205
+ "engines": {
1206
+ "node": ">=8"
1207
+ }
1208
+ },
1209
+ "node_modules/caniuse-lite": {
1210
+ "version": "1.0.30001792",
1211
+ "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001792.tgz",
1212
+ "integrity": "sha512-hVLMUZFgR4JJ6ACt1uEESvQN1/dBVqPAKY0hgrV70eN3391K6juAfTjKZLKvOMsx8PxA7gsY1/tLMMTcfFLLpw==",
1213
+ "funding": [
1214
+ {
1215
+ "type": "opencollective",
1216
+ "url": "https://opencollective.com/browserslist"
1217
+ },
1218
+ {
1219
+ "type": "tidelift",
1220
+ "url": "https://tidelift.com/funding/github/npm/caniuse-lite"
1221
+ },
1222
+ {
1223
+ "type": "github",
1224
+ "url": "https://github.com/sponsors/ai"
1225
+ }
1226
+ ],
1227
+ "license": "CC-BY-4.0"
1228
+ },
1229
+ "node_modules/chai": {
1230
+ "version": "5.3.3",
1231
+ "resolved": "https://registry.npmjs.org/chai/-/chai-5.3.3.tgz",
1232
+ "integrity": "sha512-4zNhdJD/iOjSH0A05ea+Ke6MU5mmpQcbQsSOkgdaUMJ9zTlDTD/GYlwohmIE2u0gaxHYiVHEn1Fw9mZ/ktJWgw==",
1233
+ "dev": true,
1234
+ "license": "MIT",
1235
+ "dependencies": {
1236
+ "assertion-error": "^2.0.1",
1237
+ "check-error": "^2.1.1",
1238
+ "deep-eql": "^5.0.1",
1239
+ "loupe": "^3.1.0",
1240
+ "pathval": "^2.0.0"
1241
+ },
1242
+ "engines": {
1243
+ "node": ">=18"
1244
+ }
1245
+ },
1246
+ "node_modules/check-error": {
1247
+ "version": "2.1.3",
1248
+ "resolved": "https://registry.npmjs.org/check-error/-/check-error-2.1.3.tgz",
1249
+ "integrity": "sha512-PAJdDJusoxnwm1VwW07VWwUN1sl7smmC3OKggvndJFadxxDRyFJBX/ggnu/KE4kQAB7a3Dp8f/YXC1FlUprWmA==",
1250
+ "dev": true,
1251
+ "license": "MIT",
1252
+ "engines": {
1253
+ "node": ">= 16"
1254
+ }
1255
+ },
1256
+ "node_modules/classcat": {
1257
+ "version": "5.0.5",
1258
+ "resolved": "https://registry.npmjs.org/classcat/-/classcat-5.0.5.tgz",
1259
+ "integrity": "sha512-JhZUT7JFcQy/EzW605k/ktHtncoo9vnyW/2GspNYwFlN1C/WmjuV/xtS04e9SOkL2sTdw0VAZ2UGCcQ9lR6p6w==",
1260
+ "license": "MIT"
1261
+ },
1262
+ "node_modules/client-only": {
1263
+ "version": "0.0.1",
1264
+ "resolved": "https://registry.npmjs.org/client-only/-/client-only-0.0.1.tgz",
1265
+ "integrity": "sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==",
1266
+ "license": "MIT"
1267
+ },
1268
+ "node_modules/csstype": {
1269
+ "version": "3.2.3",
1270
+ "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.2.3.tgz",
1271
+ "integrity": "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==",
1272
+ "devOptional": true,
1273
+ "license": "MIT"
1274
+ },
1275
+ "node_modules/d3-color": {
1276
+ "version": "3.1.0",
1277
+ "resolved": "https://registry.npmjs.org/d3-color/-/d3-color-3.1.0.tgz",
1278
+ "integrity": "sha512-zg/chbXyeBtMQ1LbD/WSoW2DpC3I0mpmPdW+ynRTj/x2DAWYrIY7qeZIHidozwV24m4iavr15lNwIwLxRmOxhA==",
1279
+ "license": "ISC",
1280
+ "engines": {
1281
+ "node": ">=12"
1282
+ }
1283
+ },
1284
+ "node_modules/d3-dispatch": {
1285
+ "version": "3.0.1",
1286
+ "resolved": "https://registry.npmjs.org/d3-dispatch/-/d3-dispatch-3.0.1.tgz",
1287
+ "integrity": "sha512-rzUyPU/S7rwUflMyLc1ETDeBj0NRuHKKAcvukozwhshr6g6c5d8zh4c2gQjY2bZ0dXeGLWc1PF174P2tVvKhfg==",
1288
+ "license": "ISC",
1289
+ "engines": {
1290
+ "node": ">=12"
1291
+ }
1292
+ },
1293
+ "node_modules/d3-drag": {
1294
+ "version": "3.0.0",
1295
+ "resolved": "https://registry.npmjs.org/d3-drag/-/d3-drag-3.0.0.tgz",
1296
+ "integrity": "sha512-pWbUJLdETVA8lQNJecMxoXfH6x+mO2UQo8rSmZ+QqxcbyA3hfeprFgIT//HW2nlHChWeIIMwS2Fq+gEARkhTkg==",
1297
+ "license": "ISC",
1298
+ "dependencies": {
1299
+ "d3-dispatch": "1 - 3",
1300
+ "d3-selection": "3"
1301
+ },
1302
+ "engines": {
1303
+ "node": ">=12"
1304
+ }
1305
+ },
1306
+ "node_modules/d3-ease": {
1307
+ "version": "3.0.1",
1308
+ "resolved": "https://registry.npmjs.org/d3-ease/-/d3-ease-3.0.1.tgz",
1309
+ "integrity": "sha512-wR/XK3D3XcLIZwpbvQwQ5fK+8Ykds1ip7A2Txe0yxncXSdq1L9skcG7blcedkOX+ZcgxGAmLX1FrRGbADwzi0w==",
1310
+ "license": "BSD-3-Clause",
1311
+ "engines": {
1312
+ "node": ">=12"
1313
+ }
1314
+ },
1315
+ "node_modules/d3-interpolate": {
1316
+ "version": "3.0.1",
1317
+ "resolved": "https://registry.npmjs.org/d3-interpolate/-/d3-interpolate-3.0.1.tgz",
1318
+ "integrity": "sha512-3bYs1rOD33uo8aqJfKP3JWPAibgw8Zm2+L9vBKEHJ2Rg+viTR7o5Mmv5mZcieN+FRYaAOWX5SJATX6k1PWz72g==",
1319
+ "license": "ISC",
1320
+ "dependencies": {
1321
+ "d3-color": "1 - 3"
1322
+ },
1323
+ "engines": {
1324
+ "node": ">=12"
1325
+ }
1326
+ },
1327
+ "node_modules/d3-selection": {
1328
+ "version": "3.0.0",
1329
+ "resolved": "https://registry.npmjs.org/d3-selection/-/d3-selection-3.0.0.tgz",
1330
+ "integrity": "sha512-fmTRWbNMmsmWq6xJV8D19U/gw/bwrHfNXxrIN+HfZgnzqTHp9jOmKMhsTUjXOJnZOdZY9Q28y4yebKzqDKlxlQ==",
1331
+ "license": "ISC",
1332
+ "engines": {
1333
+ "node": ">=12"
1334
+ }
1335
+ },
1336
+ "node_modules/d3-timer": {
1337
+ "version": "3.0.1",
1338
+ "resolved": "https://registry.npmjs.org/d3-timer/-/d3-timer-3.0.1.tgz",
1339
+ "integrity": "sha512-ndfJ/JxxMd3nw31uyKoY2naivF+r29V+Lc0svZxe1JvvIRmi8hUsrMvdOwgS1o6uBHmiz91geQ0ylPP0aj1VUA==",
1340
+ "license": "ISC",
1341
+ "engines": {
1342
+ "node": ">=12"
1343
+ }
1344
+ },
1345
+ "node_modules/d3-transition": {
1346
+ "version": "3.0.1",
1347
+ "resolved": "https://registry.npmjs.org/d3-transition/-/d3-transition-3.0.1.tgz",
1348
+ "integrity": "sha512-ApKvfjsSR6tg06xrL434C0WydLr7JewBB3V+/39RMHsaXTOG0zmt/OAXeng5M5LBm0ojmxJrpomQVZ1aPvBL4w==",
1349
+ "license": "ISC",
1350
+ "dependencies": {
1351
+ "d3-color": "1 - 3",
1352
+ "d3-dispatch": "1 - 3",
1353
+ "d3-ease": "1 - 3",
1354
+ "d3-interpolate": "1 - 3",
1355
+ "d3-timer": "1 - 3"
1356
+ },
1357
+ "engines": {
1358
+ "node": ">=12"
1359
+ },
1360
+ "peerDependencies": {
1361
+ "d3-selection": "2 - 3"
1362
+ }
1363
+ },
1364
+ "node_modules/d3-zoom": {
1365
+ "version": "3.0.0",
1366
+ "resolved": "https://registry.npmjs.org/d3-zoom/-/d3-zoom-3.0.0.tgz",
1367
+ "integrity": "sha512-b8AmV3kfQaqWAuacbPuNbL6vahnOJflOhexLzMMNLga62+/nh0JzvJ0aO/5a5MVgUFGS7Hu1P9P03o3fJkDCyw==",
1368
+ "license": "ISC",
1369
+ "dependencies": {
1370
+ "d3-dispatch": "1 - 3",
1371
+ "d3-drag": "2 - 3",
1372
+ "d3-interpolate": "1 - 3",
1373
+ "d3-selection": "2 - 3",
1374
+ "d3-transition": "2 - 3"
1375
+ },
1376
+ "engines": {
1377
+ "node": ">=12"
1378
+ }
1379
+ },
1380
+ "node_modules/debug": {
1381
+ "version": "4.4.3",
1382
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz",
1383
+ "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==",
1384
+ "dev": true,
1385
+ "license": "MIT",
1386
+ "dependencies": {
1387
+ "ms": "^2.1.3"
1388
+ },
1389
+ "engines": {
1390
+ "node": ">=6.0"
1391
+ },
1392
+ "peerDependenciesMeta": {
1393
+ "supports-color": {
1394
+ "optional": true
1395
+ }
1396
+ }
1397
+ },
1398
+ "node_modules/deep-eql": {
1399
+ "version": "5.0.2",
1400
+ "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-5.0.2.tgz",
1401
+ "integrity": "sha512-h5k/5U50IJJFpzfL6nO9jaaumfjO/f2NjK/oYB2Djzm4p9L+3T9qWpZqZ2hAbLPuuYq9wrU08WQyBTL5GbPk5Q==",
1402
+ "dev": true,
1403
+ "license": "MIT",
1404
+ "engines": {
1405
+ "node": ">=6"
1406
+ }
1407
+ },
1408
+ "node_modules/es-module-lexer": {
1409
+ "version": "1.7.0",
1410
+ "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.7.0.tgz",
1411
+ "integrity": "sha512-jEQoCwk8hyb2AZziIOLhDqpm5+2ww5uIE6lkO/6jcOCusfk6LhMHpXXfBLXTZ7Ydyt0j4VoUQv6uGNYbdW+kBA==",
1412
+ "dev": true,
1413
+ "license": "MIT"
1414
+ },
1415
+ "node_modules/esbuild": {
1416
+ "version": "0.21.5",
1417
+ "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.21.5.tgz",
1418
+ "integrity": "sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==",
1419
+ "dev": true,
1420
+ "hasInstallScript": true,
1421
+ "license": "MIT",
1422
+ "bin": {
1423
+ "esbuild": "bin/esbuild"
1424
+ },
1425
+ "engines": {
1426
+ "node": ">=12"
1427
+ },
1428
+ "optionalDependencies": {
1429
+ "@esbuild/aix-ppc64": "0.21.5",
1430
+ "@esbuild/android-arm": "0.21.5",
1431
+ "@esbuild/android-arm64": "0.21.5",
1432
+ "@esbuild/android-x64": "0.21.5",
1433
+ "@esbuild/darwin-arm64": "0.21.5",
1434
+ "@esbuild/darwin-x64": "0.21.5",
1435
+ "@esbuild/freebsd-arm64": "0.21.5",
1436
+ "@esbuild/freebsd-x64": "0.21.5",
1437
+ "@esbuild/linux-arm": "0.21.5",
1438
+ "@esbuild/linux-arm64": "0.21.5",
1439
+ "@esbuild/linux-ia32": "0.21.5",
1440
+ "@esbuild/linux-loong64": "0.21.5",
1441
+ "@esbuild/linux-mips64el": "0.21.5",
1442
+ "@esbuild/linux-ppc64": "0.21.5",
1443
+ "@esbuild/linux-riscv64": "0.21.5",
1444
+ "@esbuild/linux-s390x": "0.21.5",
1445
+ "@esbuild/linux-x64": "0.21.5",
1446
+ "@esbuild/netbsd-x64": "0.21.5",
1447
+ "@esbuild/openbsd-x64": "0.21.5",
1448
+ "@esbuild/sunos-x64": "0.21.5",
1449
+ "@esbuild/win32-arm64": "0.21.5",
1450
+ "@esbuild/win32-ia32": "0.21.5",
1451
+ "@esbuild/win32-x64": "0.21.5"
1452
+ }
1453
+ },
1454
+ "node_modules/estree-walker": {
1455
+ "version": "3.0.3",
1456
+ "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz",
1457
+ "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==",
1458
+ "dev": true,
1459
+ "license": "MIT",
1460
+ "dependencies": {
1461
+ "@types/estree": "^1.0.0"
1462
+ }
1463
+ },
1464
+ "node_modules/expect-type": {
1465
+ "version": "1.3.0",
1466
+ "resolved": "https://registry.npmjs.org/expect-type/-/expect-type-1.3.0.tgz",
1467
+ "integrity": "sha512-knvyeauYhqjOYvQ66MznSMs83wmHrCycNEN6Ao+2AeYEfxUIkuiVxdEa1qlGEPK+We3n0THiDciYSsCcgW/DoA==",
1468
+ "dev": true,
1469
+ "license": "Apache-2.0",
1470
+ "engines": {
1471
+ "node": ">=12.0.0"
1472
+ }
1473
+ },
1474
+ "node_modules/fsevents": {
1475
+ "version": "2.3.3",
1476
+ "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz",
1477
+ "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==",
1478
+ "dev": true,
1479
+ "hasInstallScript": true,
1480
+ "license": "MIT",
1481
+ "optional": true,
1482
+ "os": [
1483
+ "darwin"
1484
+ ],
1485
+ "engines": {
1486
+ "node": "^8.16.0 || ^10.6.0 || >=11.0.0"
1487
+ }
1488
+ },
1489
+ "node_modules/graceful-fs": {
1490
+ "version": "4.2.11",
1491
+ "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz",
1492
+ "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==",
1493
+ "license": "ISC"
1494
+ },
1495
+ "node_modules/js-tokens": {
1496
+ "version": "4.0.0",
1497
+ "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
1498
+ "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==",
1499
+ "license": "MIT"
1500
+ },
1501
+ "node_modules/loose-envify": {
1502
+ "version": "1.4.0",
1503
+ "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz",
1504
+ "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==",
1505
+ "license": "MIT",
1506
+ "dependencies": {
1507
+ "js-tokens": "^3.0.0 || ^4.0.0"
1508
+ },
1509
+ "bin": {
1510
+ "loose-envify": "cli.js"
1511
+ }
1512
+ },
1513
+ "node_modules/loupe": {
1514
+ "version": "3.2.1",
1515
+ "resolved": "https://registry.npmjs.org/loupe/-/loupe-3.2.1.tgz",
1516
+ "integrity": "sha512-CdzqowRJCeLU72bHvWqwRBBlLcMEtIvGrlvef74kMnV2AolS9Y8xUv1I0U/MNAWMhBlKIoyuEgoJ0t/bbwHbLQ==",
1517
+ "dev": true,
1518
+ "license": "MIT"
1519
+ },
1520
+ "node_modules/lucide-react": {
1521
+ "version": "0.468.0",
1522
+ "resolved": "https://registry.npmjs.org/lucide-react/-/lucide-react-0.468.0.tgz",
1523
+ "integrity": "sha512-6koYRhnM2N0GGZIdXzSeiNwguv1gt/FAjZOiPl76roBi3xKEXa4WmfpxgQwTTL4KipXjefrnf3oV4IsYhi4JFA==",
1524
+ "license": "ISC",
1525
+ "peerDependencies": {
1526
+ "react": "^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0-rc"
1527
+ }
1528
+ },
1529
+ "node_modules/magic-string": {
1530
+ "version": "0.30.21",
1531
+ "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.21.tgz",
1532
+ "integrity": "sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==",
1533
+ "dev": true,
1534
+ "license": "MIT",
1535
+ "dependencies": {
1536
+ "@jridgewell/sourcemap-codec": "^1.5.5"
1537
+ }
1538
+ },
1539
+ "node_modules/ms": {
1540
+ "version": "2.1.3",
1541
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
1542
+ "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
1543
+ "dev": true,
1544
+ "license": "MIT"
1545
+ },
1546
+ "node_modules/nanoid": {
1547
+ "version": "3.3.12",
1548
+ "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.12.tgz",
1549
+ "integrity": "sha512-ZB9RH/39qpq5Vu6Y+NmUaFhQR6pp+M2Xt76XBnEwDaGcVAqhlvxrl3B2bKS5D3NH3QR76v3aSrKaF/Kiy7lEtQ==",
1550
+ "funding": [
1551
+ {
1552
+ "type": "github",
1553
+ "url": "https://github.com/sponsors/ai"
1554
+ }
1555
+ ],
1556
+ "license": "MIT",
1557
+ "bin": {
1558
+ "nanoid": "bin/nanoid.cjs"
1559
+ },
1560
+ "engines": {
1561
+ "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1"
1562
+ }
1563
+ },
1564
+ "node_modules/next": {
1565
+ "version": "14.2.35",
1566
+ "resolved": "https://registry.npmjs.org/next/-/next-14.2.35.tgz",
1567
+ "integrity": "sha512-KhYd2Hjt/O1/1aZVX3dCwGXM1QmOV4eNM2UTacK5gipDdPN/oHHK/4oVGy7X8GMfPMsUTUEmGlsy0EY1YGAkig==",
1568
+ "license": "MIT",
1569
+ "dependencies": {
1570
+ "@next/env": "14.2.35",
1571
+ "@swc/helpers": "0.5.5",
1572
+ "busboy": "1.6.0",
1573
+ "caniuse-lite": "^1.0.30001579",
1574
+ "graceful-fs": "^4.2.11",
1575
+ "postcss": "8.4.31",
1576
+ "styled-jsx": "5.1.1"
1577
+ },
1578
+ "bin": {
1579
+ "next": "dist/bin/next"
1580
+ },
1581
+ "engines": {
1582
+ "node": ">=18.17.0"
1583
+ },
1584
+ "optionalDependencies": {
1585
+ "@next/swc-darwin-arm64": "14.2.33",
1586
+ "@next/swc-darwin-x64": "14.2.33",
1587
+ "@next/swc-linux-arm64-gnu": "14.2.33",
1588
+ "@next/swc-linux-arm64-musl": "14.2.33",
1589
+ "@next/swc-linux-x64-gnu": "14.2.33",
1590
+ "@next/swc-linux-x64-musl": "14.2.33",
1591
+ "@next/swc-win32-arm64-msvc": "14.2.33",
1592
+ "@next/swc-win32-ia32-msvc": "14.2.33",
1593
+ "@next/swc-win32-x64-msvc": "14.2.33"
1594
+ },
1595
+ "peerDependencies": {
1596
+ "@opentelemetry/api": "^1.1.0",
1597
+ "@playwright/test": "^1.41.2",
1598
+ "react": "^18.2.0",
1599
+ "react-dom": "^18.2.0",
1600
+ "sass": "^1.3.0"
1601
+ },
1602
+ "peerDependenciesMeta": {
1603
+ "@opentelemetry/api": {
1604
+ "optional": true
1605
+ },
1606
+ "@playwright/test": {
1607
+ "optional": true
1608
+ },
1609
+ "sass": {
1610
+ "optional": true
1611
+ }
1612
+ }
1613
+ },
1614
+ "node_modules/pathe": {
1615
+ "version": "1.1.2",
1616
+ "resolved": "https://registry.npmjs.org/pathe/-/pathe-1.1.2.tgz",
1617
+ "integrity": "sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==",
1618
+ "dev": true,
1619
+ "license": "MIT"
1620
+ },
1621
+ "node_modules/pathval": {
1622
+ "version": "2.0.1",
1623
+ "resolved": "https://registry.npmjs.org/pathval/-/pathval-2.0.1.tgz",
1624
+ "integrity": "sha512-//nshmD55c46FuFw26xV/xFAaB5HF9Xdap7HJBBnrKdAd6/GxDBaNA1870O79+9ueg61cZLSVc+OaFlfmObYVQ==",
1625
+ "dev": true,
1626
+ "license": "MIT",
1627
+ "engines": {
1628
+ "node": ">= 14.16"
1629
+ }
1630
+ },
1631
+ "node_modules/picocolors": {
1632
+ "version": "1.1.1",
1633
+ "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz",
1634
+ "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==",
1635
+ "license": "ISC"
1636
+ },
1637
+ "node_modules/postcss": {
1638
+ "version": "8.4.31",
1639
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.31.tgz",
1640
+ "integrity": "sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ==",
1641
+ "funding": [
1642
+ {
1643
+ "type": "opencollective",
1644
+ "url": "https://opencollective.com/postcss/"
1645
+ },
1646
+ {
1647
+ "type": "tidelift",
1648
+ "url": "https://tidelift.com/funding/github/npm/postcss"
1649
+ },
1650
+ {
1651
+ "type": "github",
1652
+ "url": "https://github.com/sponsors/ai"
1653
+ }
1654
+ ],
1655
+ "license": "MIT",
1656
+ "dependencies": {
1657
+ "nanoid": "^3.3.6",
1658
+ "picocolors": "^1.0.0",
1659
+ "source-map-js": "^1.0.2"
1660
+ },
1661
+ "engines": {
1662
+ "node": "^10 || ^12 || >=14"
1663
+ }
1664
+ },
1665
+ "node_modules/react": {
1666
+ "version": "18.3.1",
1667
+ "resolved": "https://registry.npmjs.org/react/-/react-18.3.1.tgz",
1668
+ "integrity": "sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==",
1669
+ "license": "MIT",
1670
+ "dependencies": {
1671
+ "loose-envify": "^1.1.0"
1672
+ },
1673
+ "engines": {
1674
+ "node": ">=0.10.0"
1675
+ }
1676
+ },
1677
+ "node_modules/react-dom": {
1678
+ "version": "18.3.1",
1679
+ "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.3.1.tgz",
1680
+ "integrity": "sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==",
1681
+ "license": "MIT",
1682
+ "dependencies": {
1683
+ "loose-envify": "^1.1.0",
1684
+ "scheduler": "^0.23.2"
1685
+ },
1686
+ "peerDependencies": {
1687
+ "react": "^18.3.1"
1688
+ }
1689
+ },
1690
+ "node_modules/rollup": {
1691
+ "version": "4.60.3",
1692
+ "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.60.3.tgz",
1693
+ "integrity": "sha512-pAQK9HalE84QSm4Po3EmWIZPd3FnjkShVkiMlz1iligWYkWQ7wHYd1PF/T7QZ5TVSD6uSTon5gBVMSM4JfBV+A==",
1694
+ "dev": true,
1695
+ "license": "MIT",
1696
+ "dependencies": {
1697
+ "@types/estree": "1.0.8"
1698
+ },
1699
+ "bin": {
1700
+ "rollup": "dist/bin/rollup"
1701
+ },
1702
+ "engines": {
1703
+ "node": ">=18.0.0",
1704
+ "npm": ">=8.0.0"
1705
+ },
1706
+ "optionalDependencies": {
1707
+ "@rollup/rollup-android-arm-eabi": "4.60.3",
1708
+ "@rollup/rollup-android-arm64": "4.60.3",
1709
+ "@rollup/rollup-darwin-arm64": "4.60.3",
1710
+ "@rollup/rollup-darwin-x64": "4.60.3",
1711
+ "@rollup/rollup-freebsd-arm64": "4.60.3",
1712
+ "@rollup/rollup-freebsd-x64": "4.60.3",
1713
+ "@rollup/rollup-linux-arm-gnueabihf": "4.60.3",
1714
+ "@rollup/rollup-linux-arm-musleabihf": "4.60.3",
1715
+ "@rollup/rollup-linux-arm64-gnu": "4.60.3",
1716
+ "@rollup/rollup-linux-arm64-musl": "4.60.3",
1717
+ "@rollup/rollup-linux-loong64-gnu": "4.60.3",
1718
+ "@rollup/rollup-linux-loong64-musl": "4.60.3",
1719
+ "@rollup/rollup-linux-ppc64-gnu": "4.60.3",
1720
+ "@rollup/rollup-linux-ppc64-musl": "4.60.3",
1721
+ "@rollup/rollup-linux-riscv64-gnu": "4.60.3",
1722
+ "@rollup/rollup-linux-riscv64-musl": "4.60.3",
1723
+ "@rollup/rollup-linux-s390x-gnu": "4.60.3",
1724
+ "@rollup/rollup-linux-x64-gnu": "4.60.3",
1725
+ "@rollup/rollup-linux-x64-musl": "4.60.3",
1726
+ "@rollup/rollup-openbsd-x64": "4.60.3",
1727
+ "@rollup/rollup-openharmony-arm64": "4.60.3",
1728
+ "@rollup/rollup-win32-arm64-msvc": "4.60.3",
1729
+ "@rollup/rollup-win32-ia32-msvc": "4.60.3",
1730
+ "@rollup/rollup-win32-x64-gnu": "4.60.3",
1731
+ "@rollup/rollup-win32-x64-msvc": "4.60.3",
1732
+ "fsevents": "~2.3.2"
1733
+ }
1734
+ },
1735
+ "node_modules/scheduler": {
1736
+ "version": "0.23.2",
1737
+ "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.2.tgz",
1738
+ "integrity": "sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ==",
1739
+ "license": "MIT",
1740
+ "dependencies": {
1741
+ "loose-envify": "^1.1.0"
1742
+ }
1743
+ },
1744
+ "node_modules/siginfo": {
1745
+ "version": "2.0.0",
1746
+ "resolved": "https://registry.npmjs.org/siginfo/-/siginfo-2.0.0.tgz",
1747
+ "integrity": "sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==",
1748
+ "dev": true,
1749
+ "license": "ISC"
1750
+ },
1751
+ "node_modules/source-map-js": {
1752
+ "version": "1.2.1",
1753
+ "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz",
1754
+ "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==",
1755
+ "license": "BSD-3-Clause",
1756
+ "engines": {
1757
+ "node": ">=0.10.0"
1758
+ }
1759
+ },
1760
+ "node_modules/stackback": {
1761
+ "version": "0.0.2",
1762
+ "resolved": "https://registry.npmjs.org/stackback/-/stackback-0.0.2.tgz",
1763
+ "integrity": "sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==",
1764
+ "dev": true,
1765
+ "license": "MIT"
1766
+ },
1767
+ "node_modules/std-env": {
1768
+ "version": "3.10.0",
1769
+ "resolved": "https://registry.npmjs.org/std-env/-/std-env-3.10.0.tgz",
1770
+ "integrity": "sha512-5GS12FdOZNliM5mAOxFRg7Ir0pWz8MdpYm6AY6VPkGpbA7ZzmbzNcBJQ0GPvvyWgcY7QAhCgf9Uy89I03faLkg==",
1771
+ "dev": true,
1772
+ "license": "MIT"
1773
+ },
1774
+ "node_modules/streamsearch": {
1775
+ "version": "1.1.0",
1776
+ "resolved": "https://registry.npmjs.org/streamsearch/-/streamsearch-1.1.0.tgz",
1777
+ "integrity": "sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==",
1778
+ "engines": {
1779
+ "node": ">=10.0.0"
1780
+ }
1781
+ },
1782
+ "node_modules/styled-jsx": {
1783
+ "version": "5.1.1",
1784
+ "resolved": "https://registry.npmjs.org/styled-jsx/-/styled-jsx-5.1.1.tgz",
1785
+ "integrity": "sha512-pW7uC1l4mBZ8ugbiZrcIsiIvVx1UmTfw7UkC3Um2tmfUq9Bhk8IiyEIPl6F8agHgjzku6j0xQEZbfA5uSgSaCw==",
1786
+ "license": "MIT",
1787
+ "dependencies": {
1788
+ "client-only": "0.0.1"
1789
+ },
1790
+ "engines": {
1791
+ "node": ">= 12.0.0"
1792
+ },
1793
+ "peerDependencies": {
1794
+ "react": ">= 16.8.0 || 17.x.x || ^18.0.0-0"
1795
+ },
1796
+ "peerDependenciesMeta": {
1797
+ "@babel/core": {
1798
+ "optional": true
1799
+ },
1800
+ "babel-plugin-macros": {
1801
+ "optional": true
1802
+ }
1803
+ }
1804
+ },
1805
+ "node_modules/tinybench": {
1806
+ "version": "2.9.0",
1807
+ "resolved": "https://registry.npmjs.org/tinybench/-/tinybench-2.9.0.tgz",
1808
+ "integrity": "sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==",
1809
+ "dev": true,
1810
+ "license": "MIT"
1811
+ },
1812
+ "node_modules/tinyexec": {
1813
+ "version": "0.3.2",
1814
+ "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-0.3.2.tgz",
1815
+ "integrity": "sha512-KQQR9yN7R5+OSwaK0XQoj22pwHoTlgYqmUscPYoknOoWCWfj/5/ABTMRi69FrKU5ffPVh5QcFikpWJI/P1ocHA==",
1816
+ "dev": true,
1817
+ "license": "MIT"
1818
+ },
1819
+ "node_modules/tinypool": {
1820
+ "version": "1.1.1",
1821
+ "resolved": "https://registry.npmjs.org/tinypool/-/tinypool-1.1.1.tgz",
1822
+ "integrity": "sha512-Zba82s87IFq9A9XmjiX5uZA/ARWDrB03OHlq+Vw1fSdt0I+4/Kutwy8BP4Y/y/aORMo61FQ0vIb5j44vSo5Pkg==",
1823
+ "dev": true,
1824
+ "license": "MIT",
1825
+ "engines": {
1826
+ "node": "^18.0.0 || >=20.0.0"
1827
+ }
1828
+ },
1829
+ "node_modules/tinyrainbow": {
1830
+ "version": "1.2.0",
1831
+ "resolved": "https://registry.npmjs.org/tinyrainbow/-/tinyrainbow-1.2.0.tgz",
1832
+ "integrity": "sha512-weEDEq7Z5eTHPDh4xjX789+fHfF+P8boiFB+0vbWzpbnbsEr/GRaohi/uMKxg8RZMXnl1ItAi/IUHWMsjDV7kQ==",
1833
+ "dev": true,
1834
+ "license": "MIT",
1835
+ "engines": {
1836
+ "node": ">=14.0.0"
1837
+ }
1838
+ },
1839
+ "node_modules/tinyspy": {
1840
+ "version": "3.0.2",
1841
+ "resolved": "https://registry.npmjs.org/tinyspy/-/tinyspy-3.0.2.tgz",
1842
+ "integrity": "sha512-n1cw8k1k0x4pgA2+9XrOkFydTerNcJ1zWCO5Nn9scWHTD+5tp8dghT2x1uduQePZTZgd3Tupf+x9BxJjeJi77Q==",
1843
+ "dev": true,
1844
+ "license": "MIT",
1845
+ "engines": {
1846
+ "node": ">=14.0.0"
1847
+ }
1848
+ },
1849
+ "node_modules/tslib": {
1850
+ "version": "2.8.1",
1851
+ "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz",
1852
+ "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==",
1853
+ "license": "0BSD"
1854
+ },
1855
+ "node_modules/typescript": {
1856
+ "version": "5.9.3",
1857
+ "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz",
1858
+ "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==",
1859
+ "dev": true,
1860
+ "license": "Apache-2.0",
1861
+ "bin": {
1862
+ "tsc": "bin/tsc",
1863
+ "tsserver": "bin/tsserver"
1864
+ },
1865
+ "engines": {
1866
+ "node": ">=14.17"
1867
+ }
1868
+ },
1869
+ "node_modules/undici-types": {
1870
+ "version": "6.21.0",
1871
+ "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz",
1872
+ "integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==",
1873
+ "dev": true,
1874
+ "license": "MIT"
1875
+ },
1876
+ "node_modules/use-sync-external-store": {
1877
+ "version": "1.6.0",
1878
+ "resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.6.0.tgz",
1879
+ "integrity": "sha512-Pp6GSwGP/NrPIrxVFAIkOQeyw8lFenOHijQWkUTrDvrF4ALqylP2C/KCkeS9dpUM3KvYRQhna5vt7IL95+ZQ9w==",
1880
+ "license": "MIT",
1881
+ "peerDependencies": {
1882
+ "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0"
1883
+ }
1884
+ },
1885
+ "node_modules/vite": {
1886
+ "version": "5.4.21",
1887
+ "resolved": "https://registry.npmjs.org/vite/-/vite-5.4.21.tgz",
1888
+ "integrity": "sha512-o5a9xKjbtuhY6Bi5S3+HvbRERmouabWbyUcpXXUA1u+GNUKoROi9byOJ8M0nHbHYHkYICiMlqxkg1KkYmm25Sw==",
1889
+ "dev": true,
1890
+ "license": "MIT",
1891
+ "dependencies": {
1892
+ "esbuild": "^0.21.3",
1893
+ "postcss": "^8.4.43",
1894
+ "rollup": "^4.20.0"
1895
+ },
1896
+ "bin": {
1897
+ "vite": "bin/vite.js"
1898
+ },
1899
+ "engines": {
1900
+ "node": "^18.0.0 || >=20.0.0"
1901
+ },
1902
+ "funding": {
1903
+ "url": "https://github.com/vitejs/vite?sponsor=1"
1904
+ },
1905
+ "optionalDependencies": {
1906
+ "fsevents": "~2.3.3"
1907
+ },
1908
+ "peerDependencies": {
1909
+ "@types/node": "^18.0.0 || >=20.0.0",
1910
+ "less": "*",
1911
+ "lightningcss": "^1.21.0",
1912
+ "sass": "*",
1913
+ "sass-embedded": "*",
1914
+ "stylus": "*",
1915
+ "sugarss": "*",
1916
+ "terser": "^5.4.0"
1917
+ },
1918
+ "peerDependenciesMeta": {
1919
+ "@types/node": {
1920
+ "optional": true
1921
+ },
1922
+ "less": {
1923
+ "optional": true
1924
+ },
1925
+ "lightningcss": {
1926
+ "optional": true
1927
+ },
1928
+ "sass": {
1929
+ "optional": true
1930
+ },
1931
+ "sass-embedded": {
1932
+ "optional": true
1933
+ },
1934
+ "stylus": {
1935
+ "optional": true
1936
+ },
1937
+ "sugarss": {
1938
+ "optional": true
1939
+ },
1940
+ "terser": {
1941
+ "optional": true
1942
+ }
1943
+ }
1944
+ },
1945
+ "node_modules/vite-node": {
1946
+ "version": "2.1.9",
1947
+ "resolved": "https://registry.npmjs.org/vite-node/-/vite-node-2.1.9.tgz",
1948
+ "integrity": "sha512-AM9aQ/IPrW/6ENLQg3AGY4K1N2TGZdR5e4gu/MmmR2xR3Ll1+dib+nook92g4TV3PXVyeyxdWwtaCAiUL0hMxA==",
1949
+ "dev": true,
1950
+ "license": "MIT",
1951
+ "dependencies": {
1952
+ "cac": "^6.7.14",
1953
+ "debug": "^4.3.7",
1954
+ "es-module-lexer": "^1.5.4",
1955
+ "pathe": "^1.1.2",
1956
+ "vite": "^5.0.0"
1957
+ },
1958
+ "bin": {
1959
+ "vite-node": "vite-node.mjs"
1960
+ },
1961
+ "engines": {
1962
+ "node": "^18.0.0 || >=20.0.0"
1963
+ },
1964
+ "funding": {
1965
+ "url": "https://opencollective.com/vitest"
1966
+ }
1967
+ },
1968
+ "node_modules/vite/node_modules/postcss": {
1969
+ "version": "8.5.14",
1970
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.14.tgz",
1971
+ "integrity": "sha512-SoSL4+OSEtR99LHFZQiJLkT59C5B1amGO1NzTwj7TT1qCUgUO6hxOvzkOYxD+vMrXBM3XJIKzokoERdqQq/Zmg==",
1972
+ "dev": true,
1973
+ "funding": [
1974
+ {
1975
+ "type": "opencollective",
1976
+ "url": "https://opencollective.com/postcss/"
1977
+ },
1978
+ {
1979
+ "type": "tidelift",
1980
+ "url": "https://tidelift.com/funding/github/npm/postcss"
1981
+ },
1982
+ {
1983
+ "type": "github",
1984
+ "url": "https://github.com/sponsors/ai"
1985
+ }
1986
+ ],
1987
+ "license": "MIT",
1988
+ "dependencies": {
1989
+ "nanoid": "^3.3.11",
1990
+ "picocolors": "^1.1.1",
1991
+ "source-map-js": "^1.2.1"
1992
+ },
1993
+ "engines": {
1994
+ "node": "^10 || ^12 || >=14"
1995
+ }
1996
+ },
1997
+ "node_modules/vitest": {
1998
+ "version": "2.1.9",
1999
+ "resolved": "https://registry.npmjs.org/vitest/-/vitest-2.1.9.tgz",
2000
+ "integrity": "sha512-MSmPM9REYqDGBI8439mA4mWhV5sKmDlBKWIYbA3lRb2PTHACE0mgKwA8yQ2xq9vxDTuk4iPrECBAEW2aoFXY0Q==",
2001
+ "dev": true,
2002
+ "license": "MIT",
2003
+ "dependencies": {
2004
+ "@vitest/expect": "2.1.9",
2005
+ "@vitest/mocker": "2.1.9",
2006
+ "@vitest/pretty-format": "^2.1.9",
2007
+ "@vitest/runner": "2.1.9",
2008
+ "@vitest/snapshot": "2.1.9",
2009
+ "@vitest/spy": "2.1.9",
2010
+ "@vitest/utils": "2.1.9",
2011
+ "chai": "^5.1.2",
2012
+ "debug": "^4.3.7",
2013
+ "expect-type": "^1.1.0",
2014
+ "magic-string": "^0.30.12",
2015
+ "pathe": "^1.1.2",
2016
+ "std-env": "^3.8.0",
2017
+ "tinybench": "^2.9.0",
2018
+ "tinyexec": "^0.3.1",
2019
+ "tinypool": "^1.0.1",
2020
+ "tinyrainbow": "^1.2.0",
2021
+ "vite": "^5.0.0",
2022
+ "vite-node": "2.1.9",
2023
+ "why-is-node-running": "^2.3.0"
2024
+ },
2025
+ "bin": {
2026
+ "vitest": "vitest.mjs"
2027
+ },
2028
+ "engines": {
2029
+ "node": "^18.0.0 || >=20.0.0"
2030
+ },
2031
+ "funding": {
2032
+ "url": "https://opencollective.com/vitest"
2033
+ },
2034
+ "peerDependencies": {
2035
+ "@edge-runtime/vm": "*",
2036
+ "@types/node": "^18.0.0 || >=20.0.0",
2037
+ "@vitest/browser": "2.1.9",
2038
+ "@vitest/ui": "2.1.9",
2039
+ "happy-dom": "*",
2040
+ "jsdom": "*"
2041
+ },
2042
+ "peerDependenciesMeta": {
2043
+ "@edge-runtime/vm": {
2044
+ "optional": true
2045
+ },
2046
+ "@types/node": {
2047
+ "optional": true
2048
+ },
2049
+ "@vitest/browser": {
2050
+ "optional": true
2051
+ },
2052
+ "@vitest/ui": {
2053
+ "optional": true
2054
+ },
2055
+ "happy-dom": {
2056
+ "optional": true
2057
+ },
2058
+ "jsdom": {
2059
+ "optional": true
2060
+ }
2061
+ }
2062
+ },
2063
+ "node_modules/why-is-node-running": {
2064
+ "version": "2.3.0",
2065
+ "resolved": "https://registry.npmjs.org/why-is-node-running/-/why-is-node-running-2.3.0.tgz",
2066
+ "integrity": "sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w==",
2067
+ "dev": true,
2068
+ "license": "MIT",
2069
+ "dependencies": {
2070
+ "siginfo": "^2.0.0",
2071
+ "stackback": "0.0.2"
2072
+ },
2073
+ "bin": {
2074
+ "why-is-node-running": "cli.js"
2075
+ },
2076
+ "engines": {
2077
+ "node": ">=8"
2078
+ }
2079
+ },
2080
+ "node_modules/zustand": {
2081
+ "version": "4.5.7",
2082
+ "resolved": "https://registry.npmjs.org/zustand/-/zustand-4.5.7.tgz",
2083
+ "integrity": "sha512-CHOUy7mu3lbD6o6LJLfllpjkzhHXSBlX8B9+qPddUsIfeF5S/UZ5q0kmCsnRqT1UHFQZchNFDDzMbQsuesHWlw==",
2084
+ "license": "MIT",
2085
+ "dependencies": {
2086
+ "use-sync-external-store": "^1.2.2"
2087
+ },
2088
+ "engines": {
2089
+ "node": ">=12.7.0"
2090
+ },
2091
+ "peerDependencies": {
2092
+ "@types/react": ">=16.8",
2093
+ "immer": ">=9.0.6",
2094
+ "react": ">=16.8"
2095
+ },
2096
+ "peerDependenciesMeta": {
2097
+ "@types/react": {
2098
+ "optional": true
2099
+ },
2100
+ "immer": {
2101
+ "optional": true
2102
+ },
2103
+ "react": {
2104
+ "optional": true
2105
+ }
2106
+ }
2107
+ }
2108
+ }
2109
+ }
package.json ADDED
@@ -0,0 +1,26 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "name": "venice-frontend",
3
+ "version": "0.1.0",
4
+ "private": true,
5
+ "scripts": {
6
+ "dev": "next dev --hostname 0.0.0.0",
7
+ "build": "next build",
8
+ "start": "next start",
9
+ "lint": "next lint",
10
+ "test": "vitest run"
11
+ },
12
+ "dependencies": {
13
+ "@xyflow/react": "^12.10.0",
14
+ "lucide-react": "^0.468.0",
15
+ "next": "^14.2.22",
16
+ "react": "^18.3.1",
17
+ "react-dom": "^18.3.1"
18
+ },
19
+ "devDependencies": {
20
+ "@types/node": "^20.17.17",
21
+ "@types/react": "^18.3.18",
22
+ "@types/react-dom": "^18.3.5",
23
+ "typescript": "^5.7.3",
24
+ "vitest": "^2.1.8"
25
+ }
26
+ }
public/favicon.ico ADDED
src/app/api/generate-node/route.ts ADDED
@@ -0,0 +1,30 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import { NextRequest, NextResponse } from "next/server";
2
+
3
+ export const runtime = "nodejs";
4
+ export const dynamic = "force-dynamic";
5
+
6
+ export async function POST(request: NextRequest) {
7
+ const backendUrl = process.env.VENICE_BACKEND_URL;
8
+ if (!backendUrl) {
9
+ return NextResponse.json({ detail: "VENICE_BACKEND_URL is not configured" }, { status: 500 });
10
+ }
11
+
12
+ const response = await fetch(`${backendUrl.replace(/\/$/, "")}/api/generate-node`, {
13
+ method: "POST",
14
+ headers: {
15
+ "Content-Type": "application/json",
16
+ },
17
+ body: await request.text(),
18
+ cache: "no-store",
19
+ });
20
+
21
+ const payload = await response.json();
22
+ if (payload?.imageUrl) {
23
+ const filename = String(payload.imageUrl).split("/").pop();
24
+ if (filename) {
25
+ payload.imageUrl = `/api/outputs/${encodeURIComponent(filename)}`;
26
+ }
27
+ }
28
+
29
+ return NextResponse.json(payload, { status: response.status });
30
+ }
src/app/api/outputs/[filename]/route.ts ADDED
@@ -0,0 +1,31 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import { NextRequest, NextResponse } from "next/server";
2
+
3
+ export const runtime = "nodejs";
4
+ export const dynamic = "force-dynamic";
5
+
6
+ export async function GET(
7
+ _request: NextRequest,
8
+ { params }: { params: { filename: string } },
9
+ ) {
10
+ const backendUrl = process.env.VENICE_BACKEND_URL;
11
+ if (!backendUrl) {
12
+ return NextResponse.json({ detail: "VENICE_BACKEND_URL is not configured" }, { status: 500 });
13
+ }
14
+
15
+ const filename = encodeURIComponent(params.filename);
16
+ const response = await fetch(`${backendUrl.replace(/\/$/, "")}/outputs/${filename}`, {
17
+ cache: "no-store",
18
+ });
19
+
20
+ if (!response.ok || !response.body) {
21
+ return NextResponse.json({ detail: "Output not found" }, { status: response.status });
22
+ }
23
+
24
+ return new NextResponse(response.body, {
25
+ status: response.status,
26
+ headers: {
27
+ "Content-Type": response.headers.get("Content-Type") || "image/png",
28
+ "Cache-Control": "public, max-age=3600",
29
+ },
30
+ });
31
+ }
src/app/globals.css ADDED
@@ -0,0 +1,506 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ @import "@xyflow/react/dist/style.css";
2
+
3
+ :root {
4
+ --bg: #101419;
5
+ --panel: #f4f1e8;
6
+ --panel-soft: #ebe7da;
7
+ --ink: #192024;
8
+ --muted: #69706f;
9
+ --line: rgba(25, 32, 36, 0.16);
10
+ --teal: #5bb8ad;
11
+ --coral: #df765f;
12
+ --gold: #d7a64f;
13
+ --blue: #4c78c7;
14
+ --danger: #b74d4d;
15
+ }
16
+
17
+ * {
18
+ box-sizing: border-box;
19
+ }
20
+
21
+ html,
22
+ body {
23
+ height: 100%;
24
+ margin: 0;
25
+ }
26
+
27
+ body {
28
+ background:
29
+ radial-gradient(circle at 15% 18%, rgba(91, 184, 173, 0.22), transparent 30%),
30
+ radial-gradient(circle at 84% 12%, rgba(223, 118, 95, 0.18), transparent 28%),
31
+ linear-gradient(135deg, #101419 0%, #1d2427 52%, #17191f 100%);
32
+ color: var(--ink);
33
+ font-family: Arial, Helvetica, sans-serif;
34
+ letter-spacing: 0;
35
+ }
36
+
37
+ button,
38
+ input,
39
+ textarea {
40
+ font: inherit;
41
+ }
42
+
43
+ button {
44
+ cursor: pointer;
45
+ }
46
+
47
+ a {
48
+ color: inherit;
49
+ text-decoration: none;
50
+ }
51
+
52
+ .venice-shell {
53
+ height: 100vh;
54
+ overflow: hidden;
55
+ position: relative;
56
+ }
57
+
58
+ .topbar {
59
+ align-items: center;
60
+ display: flex;
61
+ gap: 14px;
62
+ left: 20px;
63
+ position: absolute;
64
+ right: 20px;
65
+ top: 18px;
66
+ z-index: 20;
67
+ }
68
+
69
+ .brand {
70
+ align-items: center;
71
+ background: rgba(244, 241, 232, 0.96);
72
+ border: 1px solid rgba(255, 255, 255, 0.55);
73
+ border-radius: 8px;
74
+ box-shadow: 0 18px 60px rgba(0, 0, 0, 0.22);
75
+ display: flex;
76
+ gap: 10px;
77
+ padding: 10px 12px;
78
+ }
79
+
80
+ .brand-mark {
81
+ align-items: center;
82
+ background: var(--ink);
83
+ border-radius: 6px;
84
+ color: var(--panel);
85
+ display: inline-flex;
86
+ height: 32px;
87
+ justify-content: center;
88
+ width: 32px;
89
+ }
90
+
91
+ .brand h1 {
92
+ font-size: 16px;
93
+ line-height: 1;
94
+ margin: 0;
95
+ }
96
+
97
+ .brand p {
98
+ color: var(--muted);
99
+ font-size: 12px;
100
+ margin: 3px 0 0;
101
+ white-space: nowrap;
102
+ }
103
+
104
+ .search-panel {
105
+ align-items: stretch;
106
+ background: rgba(244, 241, 232, 0.96);
107
+ border: 1px solid rgba(255, 255, 255, 0.58);
108
+ border-radius: 8px;
109
+ box-shadow: 0 18px 60px rgba(0, 0, 0, 0.22);
110
+ display: grid;
111
+ flex: 1;
112
+ gap: 10px;
113
+ grid-template-columns: minmax(240px, 1fr) auto auto;
114
+ min-width: 0;
115
+ padding: 10px;
116
+ }
117
+
118
+ .query-input,
119
+ .branch-input {
120
+ background: #fffdf6;
121
+ border: 1px solid var(--line);
122
+ border-radius: 6px;
123
+ color: var(--ink);
124
+ min-width: 0;
125
+ outline: none;
126
+ padding: 12px 13px;
127
+ }
128
+
129
+ .query-input:focus,
130
+ .branch-input:focus {
131
+ border-color: var(--teal);
132
+ box-shadow: 0 0 0 3px rgba(91, 184, 173, 0.18);
133
+ }
134
+
135
+ .file-button,
136
+ .primary-button,
137
+ .icon-button,
138
+ .pill-button {
139
+ align-items: center;
140
+ border: 0;
141
+ border-radius: 6px;
142
+ display: inline-flex;
143
+ font-weight: 700;
144
+ gap: 8px;
145
+ justify-content: center;
146
+ min-height: 42px;
147
+ padding: 0 14px;
148
+ }
149
+
150
+ .file-button {
151
+ background: #ebe7da;
152
+ color: var(--ink);
153
+ position: relative;
154
+ }
155
+
156
+ .file-button input {
157
+ inset: 0;
158
+ opacity: 0;
159
+ position: absolute;
160
+ }
161
+
162
+ .primary-button {
163
+ background: var(--ink);
164
+ color: var(--panel);
165
+ }
166
+
167
+ .primary-button:disabled,
168
+ .icon-button:disabled,
169
+ .pill-button:disabled {
170
+ cursor: not-allowed;
171
+ opacity: 0.55;
172
+ }
173
+
174
+ .canvas {
175
+ height: 100%;
176
+ width: 100%;
177
+ }
178
+
179
+ .react-flow__pane {
180
+ cursor: grab;
181
+ }
182
+
183
+ .react-flow__pane.dragging {
184
+ cursor: grabbing;
185
+ }
186
+
187
+ .react-flow__background {
188
+ opacity: 0.55;
189
+ }
190
+
191
+ .react-flow__controls {
192
+ background: rgba(244, 241, 232, 0.92);
193
+ border: 1px solid rgba(255, 255, 255, 0.55);
194
+ border-radius: 8px;
195
+ box-shadow: 0 16px 44px rgba(0, 0, 0, 0.22);
196
+ overflow: hidden;
197
+ }
198
+
199
+ .image-node {
200
+ background: var(--panel);
201
+ border: 1px solid rgba(255, 255, 255, 0.7);
202
+ border-radius: 8px;
203
+ box-shadow: 0 20px 70px rgba(0, 0, 0, 0.28);
204
+ overflow: hidden;
205
+ width: 760px;
206
+ }
207
+
208
+ .image-node.selected {
209
+ box-shadow:
210
+ 0 0 0 3px rgba(91, 184, 173, 0.85),
211
+ 0 24px 80px rgba(0, 0, 0, 0.34);
212
+ }
213
+
214
+ .node-handle {
215
+ background: var(--teal);
216
+ border: 2px solid var(--panel);
217
+ height: 12px;
218
+ width: 12px;
219
+ }
220
+
221
+ .node-image-wrap {
222
+ background: #192024;
223
+ height: 500px;
224
+ overflow: hidden;
225
+ position: relative;
226
+ }
227
+
228
+ .node-image-wrap img {
229
+ display: block;
230
+ height: 100%;
231
+ object-fit: cover;
232
+ width: 100%;
233
+ }
234
+
235
+ .node-badge {
236
+ background: rgba(25, 32, 36, 0.82);
237
+ border-radius: 999px;
238
+ color: #fffdf6;
239
+ font-size: 11px;
240
+ font-weight: 700;
241
+ left: 12px;
242
+ padding: 7px 10px;
243
+ position: absolute;
244
+ top: 12px;
245
+ }
246
+
247
+ .node-body {
248
+ padding: 18px;
249
+ }
250
+
251
+ .node-title {
252
+ color: var(--ink);
253
+ font-size: 24px;
254
+ line-height: 1.2;
255
+ margin: 0;
256
+ }
257
+
258
+ .node-summary {
259
+ color: var(--muted);
260
+ font-size: 15px;
261
+ line-height: 1.45;
262
+ margin: 10px 0 14px;
263
+ }
264
+
265
+ .fact-overlay {
266
+ align-items: flex-end;
267
+ background: linear-gradient(to top, rgba(16, 20, 25, 0.72), rgba(16, 20, 25, 0));
268
+ bottom: 0;
269
+ display: grid;
270
+ gap: 8px;
271
+ grid-template-columns: repeat(2, minmax(0, 1fr));
272
+ left: 0;
273
+ padding: 82px 16px 16px;
274
+ position: absolute;
275
+ right: 0;
276
+ }
277
+
278
+ .fact-pin {
279
+ background: rgba(255, 253, 246, 0.94);
280
+ border: 1px solid rgba(255, 255, 255, 0.72);
281
+ border-radius: 7px;
282
+ color: var(--ink);
283
+ min-width: 0;
284
+ padding: 9px 10px;
285
+ }
286
+
287
+ .fact-pin span,
288
+ .fact-card strong {
289
+ display: block;
290
+ font-size: 12px;
291
+ font-weight: 800;
292
+ overflow: hidden;
293
+ text-overflow: ellipsis;
294
+ white-space: nowrap;
295
+ }
296
+
297
+ .fact-pin small {
298
+ color: var(--muted);
299
+ display: block;
300
+ font-size: 11px;
301
+ line-height: 1.3;
302
+ margin-top: 3px;
303
+ overflow: hidden;
304
+ text-overflow: ellipsis;
305
+ white-space: nowrap;
306
+ }
307
+
308
+ .fact-grid {
309
+ display: grid;
310
+ gap: 8px;
311
+ grid-template-columns: repeat(3, minmax(0, 1fr));
312
+ margin: 0 0 12px;
313
+ }
314
+
315
+ .fact-card {
316
+ background: #fffdf6;
317
+ border: 1px solid var(--line);
318
+ border-radius: 6px;
319
+ min-width: 0;
320
+ padding: 9px;
321
+ }
322
+
323
+ .fact-card span {
324
+ color: var(--muted);
325
+ display: -webkit-box;
326
+ font-size: 11px;
327
+ line-height: 1.32;
328
+ margin-top: 4px;
329
+ overflow: hidden;
330
+ -webkit-box-orient: vertical;
331
+ -webkit-line-clamp: 2;
332
+ }
333
+
334
+ .source-list {
335
+ display: grid;
336
+ gap: 7px;
337
+ grid-template-columns: repeat(2, minmax(0, 1fr));
338
+ margin-top: 10px;
339
+ }
340
+
341
+ .source-chip {
342
+ align-items: center;
343
+ background: #fffdf6;
344
+ border: 1px solid var(--line);
345
+ border-radius: 6px;
346
+ color: var(--ink);
347
+ display: grid;
348
+ gap: 2px;
349
+ grid-template-columns: 1fr auto;
350
+ min-width: 0;
351
+ padding: 8px 9px;
352
+ }
353
+
354
+ .source-chip span {
355
+ font-size: 12px;
356
+ font-weight: 700;
357
+ overflow: hidden;
358
+ text-overflow: ellipsis;
359
+ white-space: nowrap;
360
+ }
361
+
362
+ .source-chip small {
363
+ color: var(--muted);
364
+ font-size: 11px;
365
+ grid-column: 1 / -1;
366
+ overflow: hidden;
367
+ text-overflow: ellipsis;
368
+ white-space: nowrap;
369
+ }
370
+
371
+ .branch-dock {
372
+ background: rgba(244, 241, 232, 0.96);
373
+ border: 1px solid rgba(255, 255, 255, 0.6);
374
+ border-radius: 8px;
375
+ bottom: 20px;
376
+ box-shadow: 0 18px 60px rgba(0, 0, 0, 0.24);
377
+ display: grid;
378
+ gap: 10px;
379
+ grid-template-columns: 1fr auto;
380
+ left: 50%;
381
+ max-width: 760px;
382
+ padding: 10px;
383
+ position: absolute;
384
+ transform: translateX(-50%);
385
+ width: calc(100% - 40px);
386
+ z-index: 20;
387
+ }
388
+
389
+ .branch-meta {
390
+ color: var(--muted);
391
+ font-size: 12px;
392
+ grid-column: 1 / -1;
393
+ padding: 0 2px;
394
+ }
395
+
396
+ .suggestions {
397
+ display: flex;
398
+ gap: 8px;
399
+ grid-column: 1 / -1;
400
+ overflow-x: auto;
401
+ padding-bottom: 2px;
402
+ }
403
+
404
+ .pill-button {
405
+ background: #ebe7da;
406
+ color: var(--ink);
407
+ font-size: 12px;
408
+ min-height: 34px;
409
+ white-space: nowrap;
410
+ }
411
+
412
+ .toast {
413
+ background: rgba(244, 241, 232, 0.96);
414
+ border: 1px solid rgba(255, 255, 255, 0.6);
415
+ border-radius: 8px;
416
+ bottom: 22px;
417
+ box-shadow: 0 18px 60px rgba(0, 0, 0, 0.24);
418
+ color: var(--ink);
419
+ left: 20px;
420
+ max-width: 360px;
421
+ padding: 13px 14px;
422
+ position: absolute;
423
+ z-index: 21;
424
+ }
425
+
426
+ .toast strong {
427
+ display: block;
428
+ font-size: 13px;
429
+ margin-bottom: 4px;
430
+ }
431
+
432
+ .toast p {
433
+ color: var(--muted);
434
+ font-size: 12px;
435
+ line-height: 1.4;
436
+ margin: 0;
437
+ }
438
+
439
+ .spin {
440
+ animation: spin 0.85s linear infinite;
441
+ }
442
+
443
+ @keyframes spin {
444
+ to {
445
+ transform: rotate(360deg);
446
+ }
447
+ }
448
+
449
+ .empty-state {
450
+ color: rgba(244, 241, 232, 0.78);
451
+ left: 50%;
452
+ max-width: 520px;
453
+ position: absolute;
454
+ text-align: center;
455
+ top: 52%;
456
+ transform: translate(-50%, -50%);
457
+ z-index: 1;
458
+ }
459
+
460
+ .empty-state h2 {
461
+ color: #fffdf6;
462
+ font-size: 42px;
463
+ line-height: 1.02;
464
+ margin: 0 0 12px;
465
+ }
466
+
467
+ .empty-state p {
468
+ line-height: 1.5;
469
+ margin: 0;
470
+ }
471
+
472
+ @media (max-width: 760px) {
473
+ .topbar {
474
+ align-items: stretch;
475
+ flex-direction: column;
476
+ }
477
+
478
+ .brand {
479
+ width: 100%;
480
+ }
481
+
482
+ .search-panel {
483
+ grid-template-columns: 1fr;
484
+ }
485
+
486
+ .empty-state h2 {
487
+ font-size: 32px;
488
+ }
489
+
490
+ .branch-dock {
491
+ grid-template-columns: 1fr;
492
+ }
493
+
494
+ .image-node {
495
+ width: 680px;
496
+ }
497
+
498
+ .node-image-wrap {
499
+ height: 440px;
500
+ }
501
+
502
+ .fact-grid,
503
+ .source-list {
504
+ grid-template-columns: 1fr;
505
+ }
506
+ }
src/app/icon.svg ADDED
src/app/layout.tsx ADDED
@@ -0,0 +1,22 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import type { Metadata } from "next";
2
+ import "./globals.css";
3
+
4
+ export const metadata: Metadata = {
5
+ title: "Venice",
6
+ description: "A branching visual search canvas powered by multimodal AI.",
7
+ icons: {
8
+ icon: "/icon.svg",
9
+ },
10
+ };
11
+
12
+ export default function RootLayout({
13
+ children,
14
+ }: Readonly<{
15
+ children: React.ReactNode;
16
+ }>) {
17
+ return (
18
+ <html lang="en">
19
+ <body>{children}</body>
20
+ </html>
21
+ );
22
+ }
src/app/page.tsx ADDED
@@ -0,0 +1,340 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ "use client";
2
+
3
+ import {
4
+ Background,
5
+ Controls,
6
+ Handle,
7
+ MiniMap,
8
+ Position,
9
+ ReactFlow,
10
+ ReactFlowProvider,
11
+ type Edge,
12
+ type NodeProps,
13
+ useEdgesState,
14
+ useNodesState,
15
+ } from "@xyflow/react";
16
+ import {
17
+ ArrowRight,
18
+ ExternalLink,
19
+ ImagePlus,
20
+ Loader2,
21
+ Network,
22
+ Search,
23
+ Sparkles,
24
+ Trash2,
25
+ } from "lucide-react";
26
+ import { memo, useCallback, useEffect, useMemo, useState } from "react";
27
+ import {
28
+ buildCanvasEdge,
29
+ createCanvasNodeFromGeneration,
30
+ getBranchPosition,
31
+ normalizeStoredCanvas,
32
+ type StoredCanvas,
33
+ type VeniceCanvasNode,
34
+ } from "@/lib/canvas-model";
35
+ import { generateVeniceNode } from "@/lib/venice-api";
36
+
37
+ const STORAGE_KEY = "venice.canvas.v1";
38
+
39
+ function VeniceImageNode({ data, selected }: NodeProps<VeniceCanvasNode>) {
40
+ const visualFacts = data.visualFacts || [];
41
+ const sources = data.sources || [];
42
+
43
+ return (
44
+ <article className={`image-node ${selected ? "selected" : ""}`}>
45
+ <Handle className="node-handle" position={Position.Left} type="target" />
46
+ <Handle className="node-handle" position={Position.Right} type="source" />
47
+ <div className="node-image-wrap">
48
+ <img src={data.imageUrl} alt={data.title} />
49
+ <div className="node-badge">grounded visual</div>
50
+ <div className="fact-overlay">
51
+ {visualFacts.slice(0, 4).map((fact) => (
52
+ <div className="fact-pin" key={`${fact.label}-${fact.detail}`}>
53
+ <span>{fact.label}</span>
54
+ <small>{fact.detail}</small>
55
+ </div>
56
+ ))}
57
+ </div>
58
+ </div>
59
+ <div className="node-body">
60
+ <h3 className="node-title">{data.title}</h3>
61
+ <p className="node-summary">{data.summary}</p>
62
+ <div className="fact-grid">
63
+ {visualFacts.slice(0, 6).map((fact) => (
64
+ <div className="fact-card" key={`${fact.label}-${fact.detail}`}>
65
+ <strong>{fact.label}</strong>
66
+ <span>{fact.detail}</span>
67
+ </div>
68
+ ))}
69
+ </div>
70
+ <div className="source-list">
71
+ {sources.slice(0, 5).map((source) => (
72
+ <a
73
+ className="source-chip nodrag"
74
+ href={source.url}
75
+ key={`${source.url}-${source.title}`}
76
+ rel="noreferrer"
77
+ target="_blank"
78
+ >
79
+ <span>{source.title}</span>
80
+ <ExternalLink size={14} />
81
+ <small>{source.snippet || source.url}</small>
82
+ </a>
83
+ ))}
84
+ </div>
85
+ </div>
86
+ </article>
87
+ );
88
+ }
89
+
90
+ const nodeTypes = {
91
+ veniceImage: memo(VeniceImageNode),
92
+ };
93
+
94
+ type VeniceCanvasEdge = Edge;
95
+
96
+ function VeniceCanvas() {
97
+ const [nodes, setNodes, onNodesChange] = useNodesState<VeniceCanvasNode>([]);
98
+ const [edges, setEdges, onEdgesChange] = useEdgesState<VeniceCanvasEdge>([]);
99
+ const [query, setQuery] = useState("");
100
+ const [branchPrompt, setBranchPrompt] = useState("");
101
+ const [imageBase64, setImageBase64] = useState<string | undefined>();
102
+ const [imageName, setImageName] = useState<string | undefined>();
103
+ const [selectedNodeId, setSelectedNodeId] = useState<string | undefined>();
104
+ const [loadingLabel, setLoadingLabel] = useState<string | undefined>();
105
+ const [error, setError] = useState<string | undefined>();
106
+ const [hasLoadedStoredCanvas, setHasLoadedStoredCanvas] = useState(false);
107
+
108
+ const selectedNode = useMemo(
109
+ () => nodes.find((node) => node.id === selectedNodeId),
110
+ [nodes, selectedNodeId],
111
+ );
112
+
113
+ useEffect(() => {
114
+ const raw = window.localStorage.getItem(STORAGE_KEY);
115
+ if (!raw) return;
116
+ try {
117
+ const saved = normalizeStoredCanvas(JSON.parse(raw));
118
+ setNodes(saved.nodes);
119
+ setEdges(saved.edges);
120
+ setSelectedNodeId(saved.nodes?.[0]?.id);
121
+ } catch {
122
+ window.localStorage.removeItem(STORAGE_KEY);
123
+ } finally {
124
+ setHasLoadedStoredCanvas(true);
125
+ }
126
+ }, [setEdges, setNodes]);
127
+
128
+ useEffect(() => {
129
+ if (!hasLoadedStoredCanvas) return;
130
+ const saved: StoredCanvas = { nodes, edges };
131
+ window.localStorage.setItem(STORAGE_KEY, JSON.stringify(saved));
132
+ }, [edges, hasLoadedStoredCanvas, nodes]);
133
+
134
+ const clearCanvas = useCallback(() => {
135
+ setNodes([]);
136
+ setEdges([]);
137
+ setSelectedNodeId(undefined);
138
+ window.localStorage.removeItem(STORAGE_KEY);
139
+ }, [setEdges, setNodes]);
140
+
141
+ const handleFile = useCallback(async (file: File | undefined) => {
142
+ if (!file) return;
143
+ const reader = new FileReader();
144
+ reader.onload = () => {
145
+ setImageBase64(String(reader.result));
146
+ setImageName(file.name);
147
+ };
148
+ reader.readAsDataURL(file);
149
+ }, []);
150
+
151
+ const createRoot = useCallback(async () => {
152
+ if (!query.trim()) return;
153
+ setError(undefined);
154
+ setLoadingLabel("Generating visual search page");
155
+ try {
156
+ const generation = await generateVeniceNode({
157
+ query: query.trim(),
158
+ imageBase64,
159
+ });
160
+ const node = createCanvasNodeFromGeneration(generation, { x: 0, y: 0 });
161
+ setNodes((current) => [...current, node]);
162
+ setSelectedNodeId(node.id);
163
+ } catch (generationError) {
164
+ setError(generationError instanceof Error ? generationError.message : "Generation failed");
165
+ } finally {
166
+ setLoadingLabel(undefined);
167
+ }
168
+ }, [imageBase64, query, setNodes]);
169
+
170
+ const createBranch = useCallback(
171
+ async (promptOverride?: string) => {
172
+ if (!selectedNode) return;
173
+ const prompt = (promptOverride || branchPrompt).trim();
174
+ if (!prompt) return;
175
+
176
+ const siblings = nodes.filter((node) => node.data.parentId === selectedNode.id).length;
177
+ setError(undefined);
178
+ setLoadingLabel("Growing a branch");
179
+
180
+ try {
181
+ const generation = await generateVeniceNode({
182
+ query: selectedNode.data.query,
183
+ branchPrompt: prompt,
184
+ parent: {
185
+ id: selectedNode.id,
186
+ title: selectedNode.data.title,
187
+ query: selectedNode.data.query,
188
+ imagePrompt: selectedNode.data.imagePrompt,
189
+ summary: selectedNode.data.summary,
190
+ visualFacts: selectedNode.data.visualFacts,
191
+ },
192
+ });
193
+ const child = createCanvasNodeFromGeneration(
194
+ generation,
195
+ getBranchPosition(selectedNode.position, siblings),
196
+ selectedNode.id,
197
+ );
198
+ setNodes((current) => [...current, child]);
199
+ setEdges((current) => [...current, buildCanvasEdge(selectedNode.id, child.id)]);
200
+ setSelectedNodeId(child.id);
201
+ setBranchPrompt("");
202
+ } catch (generationError) {
203
+ setError(generationError instanceof Error ? generationError.message : "Branch generation failed");
204
+ } finally {
205
+ setLoadingLabel(undefined);
206
+ }
207
+ },
208
+ [branchPrompt, nodes, selectedNode, setEdges, setNodes],
209
+ );
210
+
211
+ return (
212
+ <main className="venice-shell">
213
+ <div className="topbar">
214
+ <div className="brand">
215
+ <span className="brand-mark">
216
+ <Network size={18} />
217
+ </span>
218
+ <div>
219
+ <h1>Venice</h1>
220
+ <p>visual search canvas</p>
221
+ </div>
222
+ </div>
223
+
224
+ <form
225
+ className="search-panel"
226
+ onSubmit={(event) => {
227
+ event.preventDefault();
228
+ void createRoot();
229
+ }}
230
+ >
231
+ <input
232
+ className="query-input"
233
+ onChange={(event) => setQuery(event.target.value)}
234
+ placeholder="Search anything, or seed it with an image..."
235
+ value={query}
236
+ />
237
+ <label className="file-button" title={imageName || "Upload image seed"}>
238
+ <ImagePlus size={18} />
239
+ {imageName ? "Image added" : "Image"}
240
+ <input
241
+ accept="image/*"
242
+ onChange={(event) => void handleFile(event.target.files?.[0])}
243
+ type="file"
244
+ />
245
+ </label>
246
+ <button className="primary-button" disabled={!query.trim() || Boolean(loadingLabel)} type="submit">
247
+ {loadingLabel ? <Loader2 className="spin" size={18} /> : <Search size={18} />}
248
+ Generate
249
+ </button>
250
+ </form>
251
+
252
+ <button className="icon-button file-button" onClick={clearCanvas} title="Clear canvas" type="button">
253
+ <Trash2 size={18} />
254
+ </button>
255
+ </div>
256
+
257
+ {nodes.length === 0 && (
258
+ <section className="empty-state">
259
+ <h2>Search becomes a branching visual map.</h2>
260
+ <p>
261
+ Start with a query, optionally add an image, then grow each generated page into another
262
+ direction without losing the canvas.
263
+ </p>
264
+ </section>
265
+ )}
266
+
267
+ <ReactFlow
268
+ className="canvas"
269
+ edges={edges}
270
+ fitView
271
+ nodeTypes={nodeTypes}
272
+ nodes={nodes}
273
+ onEdgesChange={onEdgesChange}
274
+ onNodeClick={(_, node) => setSelectedNodeId(node.id)}
275
+ onNodesChange={onNodesChange}
276
+ >
277
+ <Background color="#f4f1e8" gap={28} size={1} />
278
+ <Controls />
279
+ <MiniMap
280
+ maskColor="rgba(16, 20, 25, 0.72)"
281
+ nodeColor={() => "#5bb8ad"}
282
+ nodeStrokeWidth={3}
283
+ pannable
284
+ zoomable
285
+ />
286
+ </ReactFlow>
287
+
288
+ {selectedNode && (
289
+ <form
290
+ className="branch-dock"
291
+ onSubmit={(event) => {
292
+ event.preventDefault();
293
+ void createBranch();
294
+ }}
295
+ >
296
+ <div className="branch-meta">Branching from: {selectedNode.data.title}</div>
297
+ <input
298
+ className="branch-input"
299
+ onChange={(event) => setBranchPrompt(event.target.value)}
300
+ placeholder="Ask about this image..."
301
+ value={branchPrompt}
302
+ />
303
+ <button className="primary-button" disabled={!branchPrompt.trim() || Boolean(loadingLabel)} type="submit">
304
+ <ArrowRight size={18} />
305
+ Branch
306
+ </button>
307
+ <div className="suggestions">
308
+ {selectedNode.data.suggestedBranches.map((suggestion) => (
309
+ <button
310
+ className="pill-button"
311
+ disabled={Boolean(loadingLabel)}
312
+ key={suggestion}
313
+ onClick={() => void createBranch(suggestion)}
314
+ type="button"
315
+ >
316
+ <Sparkles size={14} />
317
+ {suggestion}
318
+ </button>
319
+ ))}
320
+ </div>
321
+ </form>
322
+ )}
323
+
324
+ {(loadingLabel || error) && (
325
+ <div className="toast">
326
+ <strong>{loadingLabel || "Something needs attention"}</strong>
327
+ <p>{error || "Grounding sources, composing the visual prompt, and rendering the node."}</p>
328
+ </div>
329
+ )}
330
+ </main>
331
+ );
332
+ }
333
+
334
+ export default function Page() {
335
+ return (
336
+ <ReactFlowProvider>
337
+ <VeniceCanvas />
338
+ </ReactFlowProvider>
339
+ );
340
+ }
src/lib/canvas-model.test.ts ADDED
@@ -0,0 +1,103 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import { describe, expect, test } from "vitest";
2
+ import {
3
+ BRANCH_X_GAP,
4
+ BRANCH_Y_GAP,
5
+ NODE_WIDTH,
6
+ buildCanvasEdge,
7
+ createCanvasNodeFromGeneration,
8
+ getBranchPosition,
9
+ normalizeStoredCanvas
10
+ } from "./canvas-model";
11
+
12
+ const generation = {
13
+ id: "node_123",
14
+ title: "Learning AMD GPUs visually",
15
+ imageUrl: "http://localhost:8000/outputs/node_123.png",
16
+ imagePrompt: "A luminous visual research board about AMD GPUs",
17
+ summary: "A one-paragraph public summary grounded in the retrieved sources.",
18
+ query: "teach me AMD GPUs",
19
+ visualFacts: [
20
+ {
21
+ label: "ROCm stack",
22
+ detail: "AMD's software stack for accelerated AI workloads."
23
+ }
24
+ ],
25
+ sources: [
26
+ {
27
+ title: "AMD Developer Cloud",
28
+ url: "https://www.amd.com/en/developer-cloud.html",
29
+ snippet: "Cloud access to AMD GPUs."
30
+ }
31
+ ],
32
+ suggestedBranches: ["compare clouds", "show model options"]
33
+ };
34
+
35
+ describe("canvas model", () => {
36
+ test("creates a root image node at the canvas center", () => {
37
+ const node = createCanvasNodeFromGeneration(generation, { x: 0, y: 0 });
38
+
39
+ expect(node.id).toBe("node_123");
40
+ expect(node.type).toBe("veniceImage");
41
+ expect(node.position).toEqual({ x: 0, y: 0 });
42
+ expect(node.data.summary).toBe("A one-paragraph public summary grounded in the retrieved sources.");
43
+ expect(node.data.visualFacts).toEqual([
44
+ {
45
+ label: "ROCm stack",
46
+ detail: "AMD's software stack for accelerated AI workloads."
47
+ }
48
+ ]);
49
+ expect(node.data.sources).toHaveLength(1);
50
+ expect(node.data.parentId).toBeUndefined();
51
+ });
52
+
53
+ test("uses a readable visual-page node size instead of a thumbnail", () => {
54
+ expect(NODE_WIDTH).toBeGreaterThanOrEqual(700);
55
+ });
56
+
57
+ test("places branch nodes to the right and staggered by sibling index", () => {
58
+ expect(getBranchPosition({ x: 40, y: 80 }, 0)).toEqual({ x: 40 + BRANCH_X_GAP, y: 80 });
59
+ expect(getBranchPosition({ x: 40, y: 80 }, 2)).toEqual({
60
+ x: 40 + BRANCH_X_GAP,
61
+ y: 80 + BRANCH_Y_GAP * 2,
62
+ });
63
+ });
64
+
65
+ test("creates an animated edge from parent to child", () => {
66
+ const edge = buildCanvasEdge("parent", "child");
67
+
68
+ expect(edge).toMatchObject({
69
+ id: "parent-child",
70
+ source: "parent",
71
+ target: "child",
72
+ animated: true
73
+ });
74
+ });
75
+
76
+ test("normalizes legacy stored nodes that do not have summary or visual facts", () => {
77
+ const legacyCanvas = {
78
+ nodes: [
79
+ {
80
+ id: "legacy",
81
+ type: "veniceImage",
82
+ position: { x: 12, y: 34 },
83
+ data: {
84
+ title: "Legacy node",
85
+ imageUrl: "/api/outputs/legacy.png",
86
+ imagePrompt: "old prompt",
87
+ query: "old query",
88
+ sources: [],
89
+ suggestedBranches: []
90
+ }
91
+ }
92
+ ],
93
+ edges: []
94
+ };
95
+
96
+ const normalized = normalizeStoredCanvas(legacyCanvas);
97
+
98
+ expect(normalized.nodes[0].data.summary).toBe("Generated visual search node for old query.");
99
+ expect(normalized.nodes[0].data.visualFacts).toEqual([]);
100
+ expect(normalized.nodes[0].data.sources).toEqual([]);
101
+ expect(normalized.nodes[0].data.suggestedBranches).toEqual([]);
102
+ });
103
+ });
src/lib/canvas-model.ts ADDED
@@ -0,0 +1,128 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import type { Edge, Node } from "@xyflow/react";
2
+
3
+ export type VeniceSource = {
4
+ title: string;
5
+ url: string;
6
+ snippet: string;
7
+ };
8
+
9
+ export type VeniceVisualFact = {
10
+ label: string;
11
+ detail: string;
12
+ };
13
+
14
+ export type GenerateNodeResponse = {
15
+ id: string;
16
+ title: string;
17
+ imageUrl: string;
18
+ imagePrompt: string;
19
+ summary: string;
20
+ visualFacts: VeniceVisualFact[];
21
+ query: string;
22
+ sources: VeniceSource[];
23
+ suggestedBranches: string[];
24
+ };
25
+
26
+ export type VeniceNodeData = {
27
+ title: string;
28
+ imageUrl: string;
29
+ imagePrompt: string;
30
+ summary: string;
31
+ visualFacts: VeniceVisualFact[];
32
+ query: string;
33
+ sources: VeniceSource[];
34
+ suggestedBranches: string[];
35
+ parentId?: string;
36
+ };
37
+
38
+ export type VeniceCanvasNode = Node<VeniceNodeData, "veniceImage">;
39
+
40
+ export type StoredCanvas = {
41
+ nodes: VeniceCanvasNode[];
42
+ edges: Edge[];
43
+ };
44
+
45
+ export const NODE_WIDTH = 760;
46
+ export const NODE_HEIGHT = 820;
47
+ export const BRANCH_X_GAP = 880;
48
+ export const BRANCH_Y_GAP = 560;
49
+
50
+ export function createCanvasNodeFromGeneration(
51
+ generation: GenerateNodeResponse,
52
+ position: { x: number; y: number },
53
+ parentId?: string,
54
+ ): VeniceCanvasNode {
55
+ return {
56
+ id: generation.id,
57
+ type: "veniceImage",
58
+ position,
59
+ data: {
60
+ title: generation.title,
61
+ imageUrl: generation.imageUrl,
62
+ imagePrompt: generation.imagePrompt,
63
+ summary: generation.summary,
64
+ visualFacts: generation.visualFacts,
65
+ query: generation.query,
66
+ sources: generation.sources,
67
+ suggestedBranches: generation.suggestedBranches,
68
+ parentId,
69
+ },
70
+ };
71
+ }
72
+
73
+ export function getBranchPosition(
74
+ parentPosition: { x: number; y: number },
75
+ siblingIndex: number,
76
+ ): { x: number; y: number } {
77
+ return {
78
+ x: parentPosition.x + BRANCH_X_GAP,
79
+ y: parentPosition.y + siblingIndex * BRANCH_Y_GAP,
80
+ };
81
+ }
82
+
83
+ export function buildCanvasEdge(parentId: string, childId: string): Edge {
84
+ return {
85
+ id: `${parentId}-${childId}`,
86
+ source: parentId,
87
+ target: childId,
88
+ type: "smoothstep",
89
+ animated: true,
90
+ style: {
91
+ stroke: "#7ec8c2",
92
+ strokeWidth: 2,
93
+ },
94
+ };
95
+ }
96
+
97
+ export function normalizeStoredCanvas(stored: unknown): StoredCanvas {
98
+ if (!stored || typeof stored !== "object") {
99
+ return { nodes: [], edges: [] };
100
+ }
101
+
102
+ const canvas = stored as Partial<StoredCanvas>;
103
+ return {
104
+ nodes: Array.isArray(canvas.nodes) ? canvas.nodes.map(normalizeStoredNode) : [],
105
+ edges: Array.isArray(canvas.edges) ? canvas.edges : [],
106
+ };
107
+ }
108
+
109
+ function normalizeStoredNode(node: VeniceCanvasNode): VeniceCanvasNode {
110
+ const data = node.data || ({} as VeniceNodeData);
111
+ const query = data.query || data.title || "this topic";
112
+
113
+ return {
114
+ ...node,
115
+ type: "veniceImage",
116
+ data: {
117
+ title: data.title || query,
118
+ imageUrl: data.imageUrl || "",
119
+ imagePrompt: data.imagePrompt || "",
120
+ summary: data.summary || `Generated visual search node for ${query}.`,
121
+ visualFacts: Array.isArray(data.visualFacts) ? data.visualFacts : [],
122
+ query,
123
+ sources: Array.isArray(data.sources) ? data.sources : [],
124
+ suggestedBranches: Array.isArray(data.suggestedBranches) ? data.suggestedBranches : [],
125
+ parentId: data.parentId,
126
+ },
127
+ };
128
+ }
src/lib/venice-api.test.ts ADDED
@@ -0,0 +1,30 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import { describe, expect, test } from "vitest";
2
+ import { buildGenerateNodePayload } from "./venice-api";
3
+
4
+ describe("venice api", () => {
5
+ test("builds branch requests with parent context and uploaded image data", () => {
6
+ const payload = buildGenerateNodePayload({
7
+ query: "AMD GPU visual search",
8
+ branchPrompt: "compare model serving options",
9
+ imageBase64: "data:image/png;base64,abc",
10
+ parent: {
11
+ id: "node_parent",
12
+ title: "AMD GPU visual search",
13
+ query: "AMD GPU visual search",
14
+ imagePrompt: "visual board",
15
+ },
16
+ });
17
+
18
+ expect(payload).toEqual({
19
+ query: "AMD GPU visual search",
20
+ branchPrompt: "compare model serving options",
21
+ imageBase64: "data:image/png;base64,abc",
22
+ parentNodeId: "node_parent",
23
+ parentContext: {
24
+ title: "AMD GPU visual search",
25
+ query: "AMD GPU visual search",
26
+ imagePrompt: "visual board",
27
+ },
28
+ });
29
+ });
30
+ });
src/lib/venice-api.ts ADDED
@@ -0,0 +1,80 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import type { GenerateNodeResponse } from "./canvas-model";
2
+
3
+ export type ParentContext = {
4
+ id: string;
5
+ title: string;
6
+ query: string;
7
+ imagePrompt: string;
8
+ summary?: string;
9
+ visualFacts?: Array<{
10
+ label: string;
11
+ detail: string;
12
+ }>;
13
+ };
14
+
15
+ export type GenerateNodeInput = {
16
+ query: string;
17
+ branchPrompt?: string;
18
+ imageBase64?: string;
19
+ parent?: ParentContext;
20
+ };
21
+
22
+ export type GenerateNodePayload = {
23
+ query: string;
24
+ branchPrompt?: string;
25
+ imageBase64?: string;
26
+ parentNodeId?: string;
27
+ parentContext?: Omit<ParentContext, "id">;
28
+ };
29
+
30
+ export function buildGenerateNodePayload(input: GenerateNodeInput): GenerateNodePayload {
31
+ const payload: GenerateNodePayload = {
32
+ query: input.query,
33
+ };
34
+
35
+ if (input.branchPrompt) {
36
+ payload.branchPrompt = input.branchPrompt;
37
+ }
38
+ if (input.imageBase64) {
39
+ payload.imageBase64 = input.imageBase64;
40
+ }
41
+ if (input.parent) {
42
+ payload.parentNodeId = input.parent.id;
43
+ const parentContext: Omit<ParentContext, "id"> = {
44
+ title: input.parent.title,
45
+ query: input.parent.query,
46
+ imagePrompt: input.parent.imagePrompt,
47
+ };
48
+ if (input.parent.summary) {
49
+ parentContext.summary = input.parent.summary;
50
+ }
51
+ if (input.parent.visualFacts) {
52
+ parentContext.visualFacts = input.parent.visualFacts;
53
+ }
54
+ payload.parentContext = parentContext;
55
+ }
56
+
57
+ return payload;
58
+ }
59
+
60
+ export async function generateVeniceNode(input: GenerateNodeInput): Promise<GenerateNodeResponse> {
61
+ const baseUrl = process.env.NEXT_PUBLIC_VENICE_API_URL || "";
62
+ const response = await fetch(`${baseUrl}/api/generate-node`, {
63
+ method: "POST",
64
+ headers: {
65
+ "Content-Type": "application/json",
66
+ },
67
+ body: JSON.stringify(buildGenerateNodePayload(input)),
68
+ });
69
+
70
+ if (!response.ok) {
71
+ const detail = await response.text();
72
+ throw new Error(detail || `Generation failed with status ${response.status}`);
73
+ }
74
+
75
+ const payload = (await response.json()) as Omit<GenerateNodeResponse, "query">;
76
+ return {
77
+ ...payload,
78
+ query: input.branchPrompt ? `${input.query} - ${input.branchPrompt}` : input.query,
79
+ };
80
+ }
tsconfig.json ADDED
@@ -0,0 +1,23 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ES2022",
4
+ "lib": ["dom", "dom.iterable", "es2022"],
5
+ "allowJs": false,
6
+ "skipLibCheck": true,
7
+ "strict": true,
8
+ "noEmit": true,
9
+ "esModuleInterop": true,
10
+ "module": "esnext",
11
+ "moduleResolution": "bundler",
12
+ "resolveJsonModule": true,
13
+ "isolatedModules": true,
14
+ "jsx": "preserve",
15
+ "incremental": true,
16
+ "plugins": [{ "name": "next" }],
17
+ "paths": {
18
+ "@/*": ["./src/*"]
19
+ }
20
+ },
21
+ "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"],
22
+ "exclude": ["node_modules"]
23
+ }
vitest.config.ts ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
 
1
+ import { defineConfig } from "vitest/config";
2
+
3
+ export default defineConfig({
4
+ test: {
5
+ environment: "node"
6
+ }
7
+ });