├── .gitignore
├── .prettierrc
├── README.md
├── index.html
├── package.json
├── pnpm-lock.yaml
├── public
└── vite.svg
├── screenshot.jpg
├── src
├── App.css
├── App.tsx
├── colors
│ ├── useDisplay.ts
│ ├── useHeightMap.ts
│ └── useNaturalColor.ts
├── components
│ ├── GUI.tsx
│ ├── Gizmo.tsx
│ ├── Lights.tsx
│ ├── Terrain.tsx
│ └── TerrainStats.tsx
├── geometry
│ ├── useFbmNoise.ts
│ ├── useProceduralTerrain.ts
│ └── useSquareSurface.ts
├── lib
│ └── three-noise.module.ts
├── main.tsx
├── state
│ └── useSettings.ts
└── vite-env.d.ts
├── tsconfig.json
├── tsconfig.node.json
└── vite.config.ts
/.gitignore:
--------------------------------------------------------------------------------
1 | # Logs
2 | logs
3 | *.log
4 | npm-debug.log*
5 | yarn-debug.log*
6 | yarn-error.log*
7 | pnpm-debug.log*
8 | lerna-debug.log*
9 |
10 | node_modules
11 | dist
12 | dist-ssr
13 | *.local
14 | stats.html
15 |
16 | # Editor directories and files
17 | .vscode/*
18 | !.vscode/extensions.json
19 | .idea
20 | .DS_Store
21 | *.suo
22 | *.ntvs*
23 | *.njsproj
24 | *.sln
25 | *.sw?
26 |
--------------------------------------------------------------------------------
/.prettierrc:
--------------------------------------------------------------------------------
1 | {
2 | "printWidth": 90,
3 | "trailingComma": "none"
4 | }
5 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Procedural 3D Terrain with react-three-fiber
2 |
3 | Inspired by a Codesandbox by Faraz Shaikh.
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | 3D Terrain
8 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "3d-terrain-r3f",
3 | "version": "0.0.0",
4 | "private": true,
5 | "type": "module",
6 | "scripts": {
7 | "build": "tsc && vite build",
8 | "dev": "vite",
9 | "preview": "vite preview"
10 | },
11 | "dependencies": {
12 | "@react-three/drei": "9.29.1",
13 | "@react-three/fiber": "8.7.2",
14 | "immer": "9.0.15",
15 | "leva": "0.9.31",
16 | "react": "18.2.0",
17 | "react-dom": "18.2.0",
18 | "three": "0.144.0",
19 | "zustand": "4.1.1"
20 | },
21 | "devDependencies": {
22 | "@types/react": "18.0.17",
23 | "@types/react-dom": "18.0.6",
24 | "@types/three": "0.144.0",
25 | "@vitejs/plugin-react": "2.1.0",
26 | "rollup-plugin-visualizer": "5.8.1",
27 | "typescript": "4.6.4",
28 | "vite": "3.1.0"
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/pnpm-lock.yaml:
--------------------------------------------------------------------------------
1 | lockfileVersion: 5.4
2 |
3 | specifiers:
4 | '@react-three/drei': 9.29.1
5 | '@react-three/fiber': 8.7.2
6 | '@types/react': 18.0.17
7 | '@types/react-dom': 18.0.6
8 | '@types/three': 0.144.0
9 | '@vitejs/plugin-react': 2.1.0
10 | immer: 9.0.15
11 | leva: 0.9.31
12 | react: 18.2.0
13 | react-dom: 18.2.0
14 | rollup-plugin-visualizer: 5.8.1
15 | three: 0.144.0
16 | typescript: 4.6.4
17 | vite: 3.1.0
18 | zustand: 4.1.1
19 |
20 | dependencies:
21 | '@react-three/drei': 9.29.1_gjrj76muidflkn6okfckfwmak4
22 | '@react-three/fiber': 8.7.2_ww22p6cticflcq7fk2rysgxj34
23 | immer: 9.0.15
24 | leva: 0.9.31_biqbaboplfbrettd7655fr4n2y
25 | react: 18.2.0
26 | react-dom: 18.2.0_react@18.2.0
27 | three: 0.144.0
28 | zustand: 4.1.1_immer@9.0.15+react@18.2.0
29 |
30 | devDependencies:
31 | '@types/react': 18.0.17
32 | '@types/react-dom': 18.0.6
33 | '@types/three': 0.144.0
34 | '@vitejs/plugin-react': 2.1.0_vite@3.1.0
35 | rollup-plugin-visualizer: 5.8.1
36 | typescript: 4.6.4
37 | vite: 3.1.0
38 |
39 | packages:
40 |
41 | /@ampproject/remapping/2.2.0:
42 | resolution: {integrity: sha512-qRmjj8nj9qmLTQXXmaR1cck3UXSRMPrbsLJAasZpF+t3riI71BXed5ebIOYwQntykeZuhjsdweEc9BxH5Jc26w==}
43 | engines: {node: '>=6.0.0'}
44 | dependencies:
45 | '@jridgewell/gen-mapping': 0.1.1
46 | '@jridgewell/trace-mapping': 0.3.15
47 | dev: true
48 |
49 | /@babel/code-frame/7.18.6:
50 | resolution: {integrity: sha512-TDCmlK5eOvH+eH7cdAFlNXeVJqWIQ7gW9tY1GJIpUtFb6CmjVyq2VM3u71bOyR8CRihcCgMUYoDNyLXao3+70Q==}
51 | engines: {node: '>=6.9.0'}
52 | dependencies:
53 | '@babel/highlight': 7.18.6
54 | dev: true
55 |
56 | /@babel/compat-data/7.19.0:
57 | resolution: {integrity: sha512-y5rqgTTPTmaF5e2nVhOxw+Ur9HDJLsWb6U/KpgUzRZEdPfE6VOubXBKLdbcUTijzRptednSBDQbYZBOSqJxpJw==}
58 | engines: {node: '>=6.9.0'}
59 | dev: true
60 |
61 | /@babel/core/7.19.0:
62 | resolution: {integrity: sha512-reM4+U7B9ss148rh2n1Qs9ASS+w94irYXga7c2jaQv9RVzpS7Mv1a9rnYYwuDa45G+DkORt9g6An2k/V4d9LbQ==}
63 | engines: {node: '>=6.9.0'}
64 | dependencies:
65 | '@ampproject/remapping': 2.2.0
66 | '@babel/code-frame': 7.18.6
67 | '@babel/generator': 7.19.0
68 | '@babel/helper-compilation-targets': 7.19.0_@babel+core@7.19.0
69 | '@babel/helper-module-transforms': 7.19.0
70 | '@babel/helpers': 7.19.0
71 | '@babel/parser': 7.19.0
72 | '@babel/template': 7.18.10
73 | '@babel/traverse': 7.19.0
74 | '@babel/types': 7.19.0
75 | convert-source-map: 1.8.0
76 | debug: 4.3.4
77 | gensync: 1.0.0-beta.2
78 | json5: 2.2.1
79 | semver: 6.3.0
80 | transitivePeerDependencies:
81 | - supports-color
82 | dev: true
83 |
84 | /@babel/generator/7.19.0:
85 | resolution: {integrity: sha512-S1ahxf1gZ2dpoiFgA+ohK9DIpz50bJ0CWs7Zlzb54Z4sG8qmdIrGrVqmy1sAtTVRb+9CU6U8VqT9L0Zj7hxHVg==}
86 | engines: {node: '>=6.9.0'}
87 | dependencies:
88 | '@babel/types': 7.19.0
89 | '@jridgewell/gen-mapping': 0.3.2
90 | jsesc: 2.5.2
91 | dev: true
92 |
93 | /@babel/helper-annotate-as-pure/7.18.6:
94 | resolution: {integrity: sha512-duORpUiYrEpzKIop6iNbjnwKLAKnJ47csTyRACyEmWj0QdUrm5aqNJGHSSEQSUAvNW0ojX0dOmK9dZduvkfeXA==}
95 | engines: {node: '>=6.9.0'}
96 | dependencies:
97 | '@babel/types': 7.19.0
98 | dev: true
99 |
100 | /@babel/helper-compilation-targets/7.19.0_@babel+core@7.19.0:
101 | resolution: {integrity: sha512-Ai5bNWXIvwDvWM7njqsG3feMlL9hCVQsPYXodsZyLwshYkZVJt59Gftau4VrE8S9IT9asd2uSP1hG6wCNw+sXA==}
102 | engines: {node: '>=6.9.0'}
103 | peerDependencies:
104 | '@babel/core': ^7.0.0
105 | dependencies:
106 | '@babel/compat-data': 7.19.0
107 | '@babel/core': 7.19.0
108 | '@babel/helper-validator-option': 7.18.6
109 | browserslist: 4.21.3
110 | semver: 6.3.0
111 | dev: true
112 |
113 | /@babel/helper-environment-visitor/7.18.9:
114 | resolution: {integrity: sha512-3r/aACDJ3fhQ/EVgFy0hpj8oHyHpQc+LPtJoY9SzTThAsStm4Ptegq92vqKoE3vD706ZVFWITnMnxucw+S9Ipg==}
115 | engines: {node: '>=6.9.0'}
116 | dev: true
117 |
118 | /@babel/helper-function-name/7.19.0:
119 | resolution: {integrity: sha512-WAwHBINyrpqywkUH0nTnNgI5ina5TFn85HKS0pbPDfxFfhyR/aNQEn4hGi1P1JyT//I0t4OgXUlofzWILRvS5w==}
120 | engines: {node: '>=6.9.0'}
121 | dependencies:
122 | '@babel/template': 7.18.10
123 | '@babel/types': 7.19.0
124 | dev: true
125 |
126 | /@babel/helper-hoist-variables/7.18.6:
127 | resolution: {integrity: sha512-UlJQPkFqFULIcyW5sbzgbkxn2FKRgwWiRexcuaR8RNJRy8+LLveqPjwZV/bwrLZCN0eUHD/x8D0heK1ozuoo6Q==}
128 | engines: {node: '>=6.9.0'}
129 | dependencies:
130 | '@babel/types': 7.19.0
131 | dev: true
132 |
133 | /@babel/helper-module-imports/7.18.6:
134 | resolution: {integrity: sha512-0NFvs3VkuSYbFi1x2Vd6tKrywq+z/cLeYC/RJNFrIX/30Bf5aiGYbtvGXolEktzJH8o5E5KJ3tT+nkxuuZFVlA==}
135 | engines: {node: '>=6.9.0'}
136 | dependencies:
137 | '@babel/types': 7.19.0
138 | dev: true
139 |
140 | /@babel/helper-module-transforms/7.19.0:
141 | resolution: {integrity: sha512-3HBZ377Fe14RbLIA+ac3sY4PTgpxHVkFrESaWhoI5PuyXPBBX8+C34qblV9G89ZtycGJCmCI/Ut+VUDK4bltNQ==}
142 | engines: {node: '>=6.9.0'}
143 | dependencies:
144 | '@babel/helper-environment-visitor': 7.18.9
145 | '@babel/helper-module-imports': 7.18.6
146 | '@babel/helper-simple-access': 7.18.6
147 | '@babel/helper-split-export-declaration': 7.18.6
148 | '@babel/helper-validator-identifier': 7.18.6
149 | '@babel/template': 7.18.10
150 | '@babel/traverse': 7.19.0
151 | '@babel/types': 7.19.0
152 | transitivePeerDependencies:
153 | - supports-color
154 | dev: true
155 |
156 | /@babel/helper-plugin-utils/7.19.0:
157 | resolution: {integrity: sha512-40Ryx7I8mT+0gaNxm8JGTZFUITNqdLAgdg0hXzeVZxVD6nFsdhQvip6v8dqkRHzsz1VFpFAaOCHNn0vKBL7Czw==}
158 | engines: {node: '>=6.9.0'}
159 | dev: true
160 |
161 | /@babel/helper-simple-access/7.18.6:
162 | resolution: {integrity: sha512-iNpIgTgyAvDQpDj76POqg+YEt8fPxx3yaNBg3S30dxNKm2SWfYhD0TGrK/Eu9wHpUW63VQU894TsTg+GLbUa1g==}
163 | engines: {node: '>=6.9.0'}
164 | dependencies:
165 | '@babel/types': 7.19.0
166 | dev: true
167 |
168 | /@babel/helper-split-export-declaration/7.18.6:
169 | resolution: {integrity: sha512-bde1etTx6ZyTmobl9LLMMQsaizFVZrquTEHOqKeQESMKo4PlObf+8+JA25ZsIpZhT/WEd39+vOdLXAFG/nELpA==}
170 | engines: {node: '>=6.9.0'}
171 | dependencies:
172 | '@babel/types': 7.19.0
173 | dev: true
174 |
175 | /@babel/helper-string-parser/7.18.10:
176 | resolution: {integrity: sha512-XtIfWmeNY3i4t7t4D2t02q50HvqHybPqW2ki1kosnvWCwuCMeo81Jf0gwr85jy/neUdg5XDdeFE/80DXiO+njw==}
177 | engines: {node: '>=6.9.0'}
178 | dev: true
179 |
180 | /@babel/helper-validator-identifier/7.18.6:
181 | resolution: {integrity: sha512-MmetCkz9ej86nJQV+sFCxoGGrUbU3q02kgLciwkrt9QqEB7cP39oKEY0PakknEO0Gu20SskMRi+AYZ3b1TpN9g==}
182 | engines: {node: '>=6.9.0'}
183 | dev: true
184 |
185 | /@babel/helper-validator-option/7.18.6:
186 | resolution: {integrity: sha512-XO7gESt5ouv/LRJdrVjkShckw6STTaB7l9BrpBaAHDeF5YZT+01PCwmR0SJHnkW6i8OwW/EVWRShfi4j2x+KQw==}
187 | engines: {node: '>=6.9.0'}
188 | dev: true
189 |
190 | /@babel/helpers/7.19.0:
191 | resolution: {integrity: sha512-DRBCKGwIEdqY3+rPJgG/dKfQy9+08rHIAJx8q2p+HSWP87s2HCrQmaAMMyMll2kIXKCW0cO1RdQskx15Xakftg==}
192 | engines: {node: '>=6.9.0'}
193 | dependencies:
194 | '@babel/template': 7.18.10
195 | '@babel/traverse': 7.19.0
196 | '@babel/types': 7.19.0
197 | transitivePeerDependencies:
198 | - supports-color
199 | dev: true
200 |
201 | /@babel/highlight/7.18.6:
202 | resolution: {integrity: sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g==}
203 | engines: {node: '>=6.9.0'}
204 | dependencies:
205 | '@babel/helper-validator-identifier': 7.18.6
206 | chalk: 2.4.2
207 | js-tokens: 4.0.0
208 | dev: true
209 |
210 | /@babel/parser/7.19.0:
211 | resolution: {integrity: sha512-74bEXKX2h+8rrfQUfsBfuZZHzsEs6Eql4pqy/T4Nn6Y9wNPggQOqD6z6pn5Bl8ZfysKouFZT/UXEH94ummEeQw==}
212 | engines: {node: '>=6.0.0'}
213 | hasBin: true
214 | dependencies:
215 | '@babel/types': 7.19.0
216 | dev: true
217 |
218 | /@babel/plugin-syntax-jsx/7.18.6_@babel+core@7.19.0:
219 | resolution: {integrity: sha512-6mmljtAedFGTWu2p/8WIORGwy+61PLgOMPOdazc7YoJ9ZCWUyFy3A6CpPkRKLKD1ToAesxX8KGEViAiLo9N+7Q==}
220 | engines: {node: '>=6.9.0'}
221 | peerDependencies:
222 | '@babel/core': ^7.0.0-0
223 | dependencies:
224 | '@babel/core': 7.19.0
225 | '@babel/helper-plugin-utils': 7.19.0
226 | dev: true
227 |
228 | /@babel/plugin-transform-react-jsx-development/7.18.6_@babel+core@7.19.0:
229 | resolution: {integrity: sha512-SA6HEjwYFKF7WDjWcMcMGUimmw/nhNRDWxr+KaLSCrkD/LMDBvWRmHAYgE1HDeF8KUuI8OAu+RT6EOtKxSW2qA==}
230 | engines: {node: '>=6.9.0'}
231 | peerDependencies:
232 | '@babel/core': ^7.0.0-0
233 | dependencies:
234 | '@babel/core': 7.19.0
235 | '@babel/plugin-transform-react-jsx': 7.19.0_@babel+core@7.19.0
236 | dev: true
237 |
238 | /@babel/plugin-transform-react-jsx-self/7.18.6_@babel+core@7.19.0:
239 | resolution: {integrity: sha512-A0LQGx4+4Jv7u/tWzoJF7alZwnBDQd6cGLh9P+Ttk4dpiL+J5p7NSNv/9tlEFFJDq3kjxOavWmbm6t0Gk+A3Ig==}
240 | engines: {node: '>=6.9.0'}
241 | peerDependencies:
242 | '@babel/core': ^7.0.0-0
243 | dependencies:
244 | '@babel/core': 7.19.0
245 | '@babel/helper-plugin-utils': 7.19.0
246 | dev: true
247 |
248 | /@babel/plugin-transform-react-jsx-source/7.18.6_@babel+core@7.19.0:
249 | resolution: {integrity: sha512-utZmlASneDfdaMh0m/WausbjUjEdGrQJz0vFK93d7wD3xf5wBtX219+q6IlCNZeguIcxS2f/CvLZrlLSvSHQXw==}
250 | engines: {node: '>=6.9.0'}
251 | peerDependencies:
252 | '@babel/core': ^7.0.0-0
253 | dependencies:
254 | '@babel/core': 7.19.0
255 | '@babel/helper-plugin-utils': 7.19.0
256 | dev: true
257 |
258 | /@babel/plugin-transform-react-jsx/7.19.0_@babel+core@7.19.0:
259 | resolution: {integrity: sha512-UVEvX3tXie3Szm3emi1+G63jyw1w5IcMY0FSKM+CRnKRI5Mr1YbCNgsSTwoTwKphQEG9P+QqmuRFneJPZuHNhg==}
260 | engines: {node: '>=6.9.0'}
261 | peerDependencies:
262 | '@babel/core': ^7.0.0-0
263 | dependencies:
264 | '@babel/core': 7.19.0
265 | '@babel/helper-annotate-as-pure': 7.18.6
266 | '@babel/helper-module-imports': 7.18.6
267 | '@babel/helper-plugin-utils': 7.19.0
268 | '@babel/plugin-syntax-jsx': 7.18.6_@babel+core@7.19.0
269 | '@babel/types': 7.19.0
270 | dev: true
271 |
272 | /@babel/runtime/7.19.0:
273 | resolution: {integrity: sha512-eR8Lo9hnDS7tqkO7NsV+mKvCmv5boaXFSZ70DnfhcgiEne8hv9oCEd36Klw74EtizEqLsy4YnW8UWwpBVolHZA==}
274 | engines: {node: '>=6.9.0'}
275 | dependencies:
276 | regenerator-runtime: 0.13.9
277 | dev: false
278 |
279 | /@babel/template/7.18.10:
280 | resolution: {integrity: sha512-TI+rCtooWHr3QJ27kJxfjutghu44DLnasDMwpDqCXVTal9RLp3RSYNh4NdBrRP2cQAoG9A8juOQl6P6oZG4JxA==}
281 | engines: {node: '>=6.9.0'}
282 | dependencies:
283 | '@babel/code-frame': 7.18.6
284 | '@babel/parser': 7.19.0
285 | '@babel/types': 7.19.0
286 | dev: true
287 |
288 | /@babel/traverse/7.19.0:
289 | resolution: {integrity: sha512-4pKpFRDh+utd2mbRC8JLnlsMUii3PMHjpL6a0SZ4NMZy7YFP9aXORxEhdMVOc9CpWtDF09IkciQLEhK7Ml7gRA==}
290 | engines: {node: '>=6.9.0'}
291 | dependencies:
292 | '@babel/code-frame': 7.18.6
293 | '@babel/generator': 7.19.0
294 | '@babel/helper-environment-visitor': 7.18.9
295 | '@babel/helper-function-name': 7.19.0
296 | '@babel/helper-hoist-variables': 7.18.6
297 | '@babel/helper-split-export-declaration': 7.18.6
298 | '@babel/parser': 7.19.0
299 | '@babel/types': 7.19.0
300 | debug: 4.3.4
301 | globals: 11.12.0
302 | transitivePeerDependencies:
303 | - supports-color
304 | dev: true
305 |
306 | /@babel/types/7.19.0:
307 | resolution: {integrity: sha512-YuGopBq3ke25BVSiS6fgF49Ul9gH1x70Bcr6bqRLjWCkcX8Hre1/5+z+IiWOIerRMSSEfGZVB9z9kyq7wVs9YA==}
308 | engines: {node: '>=6.9.0'}
309 | dependencies:
310 | '@babel/helper-string-parser': 7.18.10
311 | '@babel/helper-validator-identifier': 7.18.6
312 | to-fast-properties: 2.0.0
313 | dev: true
314 |
315 | /@chevrotain/cst-dts-gen/10.3.0:
316 | resolution: {integrity: sha512-7DJPfCtfK1SU1/F3ZmmVv5IsTTcP/iiKFqU1m0H4VzJNvG3/GNxJFQjy4t/veWTAFSPWSj1WCNyq+sc5XKq9yA==}
317 | dependencies:
318 | '@chevrotain/gast': 10.3.0
319 | '@chevrotain/types': 10.3.0
320 | lodash: 4.17.21
321 | dev: false
322 |
323 | /@chevrotain/gast/10.3.0:
324 | resolution: {integrity: sha512-kLbGubyLprlyFZ1/c5pkpciCi6WTcRcnKhkfflSdKsZuoy0OmVTEXzrmFCQWzJ+QtmQNtPZTKwIBXJ6Zixp6nA==}
325 | dependencies:
326 | '@chevrotain/types': 10.3.0
327 | lodash: 4.17.21
328 | dev: false
329 |
330 | /@chevrotain/types/10.3.0:
331 | resolution: {integrity: sha512-LGesL4c5+FyweDsmFukcxmsowpagj1iC4iqkQSIDG3Y7krV2rIOmCDDq4kZff51Asr6yQHEJsWTyvGVHeWQLkw==}
332 | dev: false
333 |
334 | /@chevrotain/utils/10.3.0:
335 | resolution: {integrity: sha512-KCpFcX+kNyKlVZQW60ZUGRW5Nsg5u0F2CIgHiDQyg282ouHS9xap2ZEKqhwGE/0nYP46nAPnGPdb/IYh7ZHOsA==}
336 | dev: false
337 |
338 | /@esbuild/linux-loong64/0.15.7:
339 | resolution: {integrity: sha512-IKznSJOsVUuyt7cDzzSZyqBEcZe+7WlBqTVXiF1OXP/4Nm387ToaXZ0fyLwI1iBlI/bzpxVq411QE2/Bt2XWWw==}
340 | engines: {node: '>=12'}
341 | cpu: [loong64]
342 | os: [linux]
343 | requiresBuild: true
344 | dev: true
345 | optional: true
346 |
347 | /@jridgewell/gen-mapping/0.1.1:
348 | resolution: {integrity: sha512-sQXCasFk+U8lWYEe66WxRDOE9PjVz4vSM51fTu3Hw+ClTpUSQb718772vH3pyS5pShp6lvQM7SxgIDXXXmOX7w==}
349 | engines: {node: '>=6.0.0'}
350 | dependencies:
351 | '@jridgewell/set-array': 1.1.2
352 | '@jridgewell/sourcemap-codec': 1.4.14
353 | dev: true
354 |
355 | /@jridgewell/gen-mapping/0.3.2:
356 | resolution: {integrity: sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A==}
357 | engines: {node: '>=6.0.0'}
358 | dependencies:
359 | '@jridgewell/set-array': 1.1.2
360 | '@jridgewell/sourcemap-codec': 1.4.14
361 | '@jridgewell/trace-mapping': 0.3.15
362 | dev: true
363 |
364 | /@jridgewell/resolve-uri/3.1.0:
365 | resolution: {integrity: sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==}
366 | engines: {node: '>=6.0.0'}
367 | dev: true
368 |
369 | /@jridgewell/set-array/1.1.2:
370 | resolution: {integrity: sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==}
371 | engines: {node: '>=6.0.0'}
372 | dev: true
373 |
374 | /@jridgewell/sourcemap-codec/1.4.14:
375 | resolution: {integrity: sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==}
376 | dev: true
377 |
378 | /@jridgewell/trace-mapping/0.3.15:
379 | resolution: {integrity: sha512-oWZNOULl+UbhsgB51uuZzglikfIKSUBO/M9W2OfEjn7cmqoAiCgmv9lyACTUacZwBz0ITnJ2NqjU8Tx0DHL88g==}
380 | dependencies:
381 | '@jridgewell/resolve-uri': 3.1.0
382 | '@jridgewell/sourcemap-codec': 1.4.14
383 | dev: true
384 |
385 | /@radix-ui/popper/0.1.0:
386 | resolution: {integrity: sha512-uzYeElL3w7SeNMuQpXiFlBhTT+JyaNMCwDfjKkrzugEcYrf5n52PHqncNdQPUtR42hJh8V9FsqyEDbDxkeNjJQ==}
387 | dependencies:
388 | '@babel/runtime': 7.19.0
389 | csstype: 3.1.0
390 | dev: false
391 |
392 | /@radix-ui/primitive/0.1.0:
393 | resolution: {integrity: sha512-tqxZKybwN5Fa3VzZry4G6mXAAb9aAqKmPtnVbZpL0vsBwvOHTBwsjHVPXylocYLwEtBY9SCe665bYnNB515uoA==}
394 | dependencies:
395 | '@babel/runtime': 7.19.0
396 | dev: false
397 |
398 | /@radix-ui/react-arrow/0.1.3_react@18.2.0:
399 | resolution: {integrity: sha512-9x1gRYdlUD5OUwY7L+M+4FY/YltDSsrNSj8QXGPbxZxL5ghWXB/4lhyIGccCwk/e8ggfmQYv9SRNmn3LavPo3A==}
400 | peerDependencies:
401 | react: ^16.8 || ^17.0
402 | dependencies:
403 | '@babel/runtime': 7.19.0
404 | '@radix-ui/react-primitive': 0.1.3_react@18.2.0
405 | react: 18.2.0
406 | dev: false
407 |
408 | /@radix-ui/react-compose-refs/0.1.0_react@18.2.0:
409 | resolution: {integrity: sha512-eyclbh+b77k+69Dk72q3694OHrn9B3QsoIRx7ywX341U9RK1ThgQjMFZoPtmZNQTksXHLNEiefR8hGVeFyInGg==}
410 | peerDependencies:
411 | react: ^16.8 || ^17.0
412 | dependencies:
413 | '@babel/runtime': 7.19.0
414 | react: 18.2.0
415 | dev: false
416 |
417 | /@radix-ui/react-context/0.1.1_react@18.2.0:
418 | resolution: {integrity: sha512-PkyVX1JsLBioeu0jB9WvRpDBBLtLZohVDT3BB5CTSJqActma8S8030P57mWZb4baZifMvN7KKWPAA40UmWKkQg==}
419 | peerDependencies:
420 | react: ^16.8 || ^17.0
421 | dependencies:
422 | '@babel/runtime': 7.19.0
423 | react: 18.2.0
424 | dev: false
425 |
426 | /@radix-ui/react-id/0.1.4_react@18.2.0:
427 | resolution: {integrity: sha512-/hq5m/D0ZfJWOS7TLF+G0l08KDRs87LBE46JkAvgKkg1fW4jkucx9At9D9vauIPSbdNmww5kXEp566hMlA8eXA==}
428 | peerDependencies:
429 | react: ^16.8 || ^17.0
430 | dependencies:
431 | '@babel/runtime': 7.19.0
432 | '@radix-ui/react-use-layout-effect': 0.1.0_react@18.2.0
433 | react: 18.2.0
434 | dev: false
435 |
436 | /@radix-ui/react-popper/0.1.3_react@18.2.0:
437 | resolution: {integrity: sha512-2OV2YaJv7iTZexJY3HJ7B6Fs1A/3JXd3fRGU4JY0guACfGMD1C/jSgds505MKQOTiHE/quI6j3/q8yfzFjJR9g==}
438 | peerDependencies:
439 | react: ^16.8 || ^17.0
440 | dependencies:
441 | '@babel/runtime': 7.19.0
442 | '@radix-ui/popper': 0.1.0
443 | '@radix-ui/react-arrow': 0.1.3_react@18.2.0
444 | '@radix-ui/react-compose-refs': 0.1.0_react@18.2.0
445 | '@radix-ui/react-context': 0.1.1_react@18.2.0
446 | '@radix-ui/react-primitive': 0.1.3_react@18.2.0
447 | '@radix-ui/react-use-rect': 0.1.1_react@18.2.0
448 | '@radix-ui/react-use-size': 0.1.0_react@18.2.0
449 | '@radix-ui/rect': 0.1.1
450 | react: 18.2.0
451 | dev: false
452 |
453 | /@radix-ui/react-portal/0.1.3_biqbaboplfbrettd7655fr4n2y:
454 | resolution: {integrity: sha512-DrV+sPYLs0HhmX5/b7yRT6nLM9Nl6FtQe2KUG+46kiCOKQ+0XzNMO5hmeQtyq0mRf/qlC02rFu6OMsWpIqVsJg==}
455 | peerDependencies:
456 | react: ^16.8 || ^17.0
457 | react-dom: ^16.8 || ^17.0
458 | dependencies:
459 | '@babel/runtime': 7.19.0
460 | '@radix-ui/react-primitive': 0.1.3_react@18.2.0
461 | '@radix-ui/react-use-layout-effect': 0.1.0_react@18.2.0
462 | react: 18.2.0
463 | react-dom: 18.2.0_react@18.2.0
464 | dev: false
465 |
466 | /@radix-ui/react-portal/0.1.4_biqbaboplfbrettd7655fr4n2y:
467 | resolution: {integrity: sha512-MO0wRy2eYRTZ/CyOri9NANCAtAtq89DEtg90gicaTlkCfdqCLEBsLb+/q66BZQTr3xX/Vq01nnVfc/TkCqoqvw==}
468 | peerDependencies:
469 | react: ^16.8 || ^17.0
470 | react-dom: ^16.8 || ^17.0
471 | dependencies:
472 | '@babel/runtime': 7.19.0
473 | '@radix-ui/react-primitive': 0.1.4_react@18.2.0
474 | '@radix-ui/react-use-layout-effect': 0.1.0_react@18.2.0
475 | react: 18.2.0
476 | react-dom: 18.2.0_react@18.2.0
477 | dev: false
478 |
479 | /@radix-ui/react-presence/0.1.1_react@18.2.0:
480 | resolution: {integrity: sha512-LsL+NcWDpFUAYCmXeH02o4pgqcSLpwxP84UIjCtpIKrsPe2vLuhcp79KC/jZJeXz+of2lUpMAxpM+eCpxFZtlg==}
481 | peerDependencies:
482 | react: '>=16.8'
483 | dependencies:
484 | '@babel/runtime': 7.19.0
485 | '@radix-ui/react-compose-refs': 0.1.0_react@18.2.0
486 | '@radix-ui/react-use-layout-effect': 0.1.0_react@18.2.0
487 | react: 18.2.0
488 | dev: false
489 |
490 | /@radix-ui/react-primitive/0.1.3_react@18.2.0:
491 | resolution: {integrity: sha512-fcyADaaAx2jdqEDLsTs6aX50S3L1c9K9CC6XMpJpuXFJCU4n9PGTFDZRtY2gAoXXoRCPIBsklCopSmGb6SsDjQ==}
492 | peerDependencies:
493 | react: ^16.8 || ^17.0
494 | dependencies:
495 | '@babel/runtime': 7.19.0
496 | '@radix-ui/react-slot': 0.1.2_react@18.2.0
497 | react: 18.2.0
498 | dev: false
499 |
500 | /@radix-ui/react-primitive/0.1.4_react@18.2.0:
501 | resolution: {integrity: sha512-6gSl2IidySupIMJFjYnDIkIWRyQdbu/AHK7rbICPani+LW4b0XdxBXc46og/iZvuwW8pjCS8I2SadIerv84xYA==}
502 | peerDependencies:
503 | react: ^16.8 || ^17.0
504 | dependencies:
505 | '@babel/runtime': 7.19.0
506 | '@radix-ui/react-slot': 0.1.2_react@18.2.0
507 | react: 18.2.0
508 | dev: false
509 |
510 | /@radix-ui/react-slot/0.1.2_react@18.2.0:
511 | resolution: {integrity: sha512-ADkqfL+agEzEguU3yS26jfB50hRrwf7U4VTwAOZEmi/g+ITcBWe12yM46ueS/UCIMI9Py+gFUaAdxgxafFvY2Q==}
512 | peerDependencies:
513 | react: ^16.8 || ^17.0
514 | dependencies:
515 | '@babel/runtime': 7.19.0
516 | '@radix-ui/react-compose-refs': 0.1.0_react@18.2.0
517 | react: 18.2.0
518 | dev: false
519 |
520 | /@radix-ui/react-tooltip/0.1.6_biqbaboplfbrettd7655fr4n2y:
521 | resolution: {integrity: sha512-0uaRpRmTCQo5yMUkDpv4LEDnaQDoeLXcNNhZonCZdbZBQ7ntvjURIWIigq1/pXZp0UX7oPpFzsXD9jUp8JT0WA==}
522 | peerDependencies:
523 | react: ^16.8 || ^17.0
524 | react-dom: ^16.8 || ^17.0
525 | dependencies:
526 | '@babel/runtime': 7.19.0
527 | '@radix-ui/primitive': 0.1.0
528 | '@radix-ui/react-compose-refs': 0.1.0_react@18.2.0
529 | '@radix-ui/react-context': 0.1.1_react@18.2.0
530 | '@radix-ui/react-id': 0.1.4_react@18.2.0
531 | '@radix-ui/react-popper': 0.1.3_react@18.2.0
532 | '@radix-ui/react-portal': 0.1.3_biqbaboplfbrettd7655fr4n2y
533 | '@radix-ui/react-presence': 0.1.1_react@18.2.0
534 | '@radix-ui/react-primitive': 0.1.3_react@18.2.0
535 | '@radix-ui/react-slot': 0.1.2_react@18.2.0
536 | '@radix-ui/react-use-controllable-state': 0.1.0_react@18.2.0
537 | '@radix-ui/react-use-escape-keydown': 0.1.0_react@18.2.0
538 | '@radix-ui/react-use-previous': 0.1.0_react@18.2.0
539 | '@radix-ui/react-use-rect': 0.1.1_react@18.2.0
540 | '@radix-ui/react-visually-hidden': 0.1.3_react@18.2.0
541 | react: 18.2.0
542 | react-dom: 18.2.0_react@18.2.0
543 | dev: false
544 |
545 | /@radix-ui/react-use-callback-ref/0.1.0_react@18.2.0:
546 | resolution: {integrity: sha512-Va041McOFFl+aV+sejvl0BS2aeHx86ND9X/rVFmEFQKTXCp6xgUK0NGUAGcgBlIjnJSbMYPGEk1xKSSlVcN2Aw==}
547 | peerDependencies:
548 | react: ^16.8 || ^17.0
549 | dependencies:
550 | '@babel/runtime': 7.19.0
551 | react: 18.2.0
552 | dev: false
553 |
554 | /@radix-ui/react-use-controllable-state/0.1.0_react@18.2.0:
555 | resolution: {integrity: sha512-zv7CX/PgsRl46a52Tl45TwqwVJdmqnlQEQhaYMz/yBOD2sx2gCkCFSoF/z9mpnYWmS6DTLNTg5lIps3fV6EnXg==}
556 | peerDependencies:
557 | react: ^16.8 || ^17.0
558 | dependencies:
559 | '@babel/runtime': 7.19.0
560 | '@radix-ui/react-use-callback-ref': 0.1.0_react@18.2.0
561 | react: 18.2.0
562 | dev: false
563 |
564 | /@radix-ui/react-use-escape-keydown/0.1.0_react@18.2.0:
565 | resolution: {integrity: sha512-tDLZbTGFmvXaazUXXv8kYbiCcbAE8yKgng9s95d8fCO+Eundv0Jngbn/hKPhDDs4jj9ChwRX5cDDnlaN+ugYYQ==}
566 | peerDependencies:
567 | react: ^16.8 || ^17.0
568 | dependencies:
569 | '@babel/runtime': 7.19.0
570 | '@radix-ui/react-use-callback-ref': 0.1.0_react@18.2.0
571 | react: 18.2.0
572 | dev: false
573 |
574 | /@radix-ui/react-use-layout-effect/0.1.0_react@18.2.0:
575 | resolution: {integrity: sha512-+wdeS51Y+E1q1Wmd+1xSSbesZkpVj4jsg0BojCbopWvgq5iBvixw5vgemscdh58ep98BwUbsFYnrywFhV9yrVg==}
576 | peerDependencies:
577 | react: ^16.8 || ^17.0
578 | dependencies:
579 | '@babel/runtime': 7.19.0
580 | react: 18.2.0
581 | dev: false
582 |
583 | /@radix-ui/react-use-previous/0.1.0_react@18.2.0:
584 | resolution: {integrity: sha512-0fxNc33rYnCzDMPSiSnfS8YklnxQo8WqbAQXPAgIaaA1jRu2qFB916PL4qCIW+avcAAqFD38vWhqDqcVmBharA==}
585 | peerDependencies:
586 | react: ^16.8 || ^17.0
587 | dependencies:
588 | '@babel/runtime': 7.19.0
589 | react: 18.2.0
590 | dev: false
591 |
592 | /@radix-ui/react-use-rect/0.1.1_react@18.2.0:
593 | resolution: {integrity: sha512-kHNNXAsP3/PeszEmM/nxBBS9Jbo93sO+xuMTcRfwzXsmxT5gDXQzAiKbZQ0EecCPtJIzqvr7dlaQi/aP1PKYqQ==}
594 | peerDependencies:
595 | react: ^16.8 || ^17.0
596 | dependencies:
597 | '@babel/runtime': 7.19.0
598 | '@radix-ui/rect': 0.1.1
599 | react: 18.2.0
600 | dev: false
601 |
602 | /@radix-ui/react-use-size/0.1.0_react@18.2.0:
603 | resolution: {integrity: sha512-TcZAsR+BYI46w/RbaSFCRACl+Jh6mDqhu6GS2r0iuJpIVrj8atff7qtTjmMmfGtEDNEjhl7DxN3pr1nTS/oruQ==}
604 | peerDependencies:
605 | react: ^16.8 || ^17.0
606 | dependencies:
607 | '@babel/runtime': 7.19.0
608 | react: 18.2.0
609 | dev: false
610 |
611 | /@radix-ui/react-visually-hidden/0.1.3_react@18.2.0:
612 | resolution: {integrity: sha512-dPU6ZR2WQ/W9qv7E1Y8/I8ymqG+8sViU6dQQ6sfr2/8yGr0I4mmI7ywTnqXaE+YS9gHLEZHdQcEqTNESg6YfdQ==}
613 | peerDependencies:
614 | react: ^16.8 || ^17.0
615 | dependencies:
616 | '@babel/runtime': 7.19.0
617 | '@radix-ui/react-primitive': 0.1.3_react@18.2.0
618 | react: 18.2.0
619 | dev: false
620 |
621 | /@radix-ui/rect/0.1.1:
622 | resolution: {integrity: sha512-g3hnE/UcOg7REdewduRPAK88EPuLZtaq7sA9ouu8S+YEtnyFRI16jgv6GZYe3VMoQLL1T171ebmEPtDjyxWLzw==}
623 | dependencies:
624 | '@babel/runtime': 7.19.0
625 | dev: false
626 |
627 | /@react-spring/animated/9.5.2_react@18.2.0:
628 | resolution: {integrity: sha512-oRlX+MmYLbK8IuUZR7SQUnRjXxJ4PMIZeBkBd1SUWVgVJAHMTfJzPltzm+I6p59qX+qLlklYHfnWaonQKDqLuQ==}
629 | peerDependencies:
630 | react: ^16.8.0 || >=17.0.0 || >=18.0.0
631 | dependencies:
632 | '@react-spring/shared': 9.5.2_react@18.2.0
633 | '@react-spring/types': 9.5.2
634 | react: 18.2.0
635 | dev: false
636 |
637 | /@react-spring/core/9.5.2_react@18.2.0:
638 | resolution: {integrity: sha512-UMRtFH6EfebMp/NMDGCUY5+hZFXsg9iT9hzt/iPzJSz2WMXKBjLoFZHJXcmiVOrIhzHmg1O0pFECn1Wp6pZ5Gw==}
639 | peerDependencies:
640 | react: ^16.8.0 || >=17.0.0 || >=18.0.0
641 | dependencies:
642 | '@react-spring/animated': 9.5.2_react@18.2.0
643 | '@react-spring/rafz': 9.5.2
644 | '@react-spring/shared': 9.5.2_react@18.2.0
645 | '@react-spring/types': 9.5.2
646 | react: 18.2.0
647 | dev: false
648 |
649 | /@react-spring/rafz/9.5.2:
650 | resolution: {integrity: sha512-xHSRXKKBI/wDUkZGrspkOm4VlgN6lZi8Tw9Jzibp9QKf3neoof+U2mDNgklvnLaasymtUwAq9o4ZfFvQIVNgPQ==}
651 | dev: false
652 |
653 | /@react-spring/shared/9.5.2_react@18.2.0:
654 | resolution: {integrity: sha512-/OSf2sjwY4BUnjZL6xMC+H3WxOOhMUCk+yZwgdj40XuyUpk6E6tYyiPeD9Yq5GLsZHodkvE1syVMRVReL4ndAg==}
655 | peerDependencies:
656 | react: ^16.8.0 || >=17.0.0 || >=18.0.0
657 | dependencies:
658 | '@react-spring/rafz': 9.5.2
659 | '@react-spring/types': 9.5.2
660 | react: 18.2.0
661 | dev: false
662 |
663 | /@react-spring/three/9.5.2_2a6gtlagoszca3momc2bks73vi:
664 | resolution: {integrity: sha512-3H7Lv8BJZ3dajh0yJA3m9rEbqz5ZNrTCAkhVOeLqgvBlcWU5qVs4luYA1Z7H4vZnLqVtzv+kHAyg3XIpuTOXhQ==}
665 | peerDependencies:
666 | '@react-three/fiber': '>=6.0'
667 | react: ^16.11.0 || >=17.0.0 || >=18.0.0
668 | three: '>=0.126'
669 | dependencies:
670 | '@react-spring/animated': 9.5.2_react@18.2.0
671 | '@react-spring/core': 9.5.2_react@18.2.0
672 | '@react-spring/shared': 9.5.2_react@18.2.0
673 | '@react-spring/types': 9.5.2
674 | '@react-three/fiber': 8.7.2_ww22p6cticflcq7fk2rysgxj34
675 | react: 18.2.0
676 | three: 0.144.0
677 | dev: false
678 |
679 | /@react-spring/types/9.5.2:
680 | resolution: {integrity: sha512-n/wBRSHPqTmEd4BFWY6TeR1o/UY+3ujoqMxLjqy90CcY/ozJzDRuREL3c+pxMeTF2+B7dX33dTPCtFMX51nbxg==}
681 | dev: false
682 |
683 | /@react-three/drei/9.29.1_gjrj76muidflkn6okfckfwmak4:
684 | resolution: {integrity: sha512-mT1r8pko66Ws8KC9oszuwpym7fiklfewqACZ+eX3oyTsSeUc2FtmbaJB4KZdV2lyrph9+A4Ex9b1JCfQLKqGlA==}
685 | peerDependencies:
686 | '@react-three/fiber': '>=8.0'
687 | react: '>=18.0'
688 | react-dom: '>=18.0'
689 | three: '>=0.137'
690 | peerDependenciesMeta:
691 | react-dom:
692 | optional: true
693 | dependencies:
694 | '@babel/runtime': 7.19.0
695 | '@react-spring/three': 9.5.2_2a6gtlagoszca3momc2bks73vi
696 | '@react-three/fiber': 8.7.2_ww22p6cticflcq7fk2rysgxj34
697 | '@use-gesture/react': 10.2.19_react@18.2.0
698 | detect-gpu: 4.0.38
699 | glsl-noise: 0.0.0
700 | lodash.clamp: 4.0.3
701 | lodash.omit: 4.5.0
702 | lodash.pick: 4.4.0
703 | meshline: 2.0.4_three@0.144.0
704 | react: 18.2.0
705 | react-composer: 5.0.3_react@18.2.0
706 | react-dom: 18.2.0_react@18.2.0
707 | react-merge-refs: 1.1.0
708 | stats.js: 0.17.0
709 | suspend-react: 0.0.8_react@18.2.0
710 | three: 0.144.0
711 | three-mesh-bvh: 0.5.16_three@0.144.0
712 | three-stdlib: 2.15.0_three@0.144.0
713 | troika-three-text: 0.46.4_three@0.144.0
714 | utility-types: 3.10.0
715 | zustand: 3.7.2_react@18.2.0
716 | dev: false
717 |
718 | /@react-three/fiber/8.7.2_ww22p6cticflcq7fk2rysgxj34:
719 | resolution: {integrity: sha512-tV9XjVUhCE+yZgY5dPHoEJi9+LmPZemJfVC9oVItT+sGm/uVMC7pEMUzmfo3Igax7KiL7lyQHM7sJOJKFtbuNg==}
720 | peerDependencies:
721 | expo: '>=43.0'
722 | expo-asset: '>=8.4'
723 | expo-gl: '>=11.0'
724 | react: '>=18.0'
725 | react-dom: '>=18.0'
726 | react-native: '>=0.64'
727 | three: '>=0.133'
728 | peerDependenciesMeta:
729 | expo:
730 | optional: true
731 | expo-asset:
732 | optional: true
733 | expo-gl:
734 | optional: true
735 | react-dom:
736 | optional: true
737 | react-native:
738 | optional: true
739 | dependencies:
740 | '@babel/runtime': 7.19.0
741 | '@types/react-reconciler': 0.26.7
742 | react: 18.2.0
743 | react-dom: 18.2.0_react@18.2.0
744 | react-reconciler: 0.27.0_react@18.2.0
745 | react-use-measure: 2.1.1_biqbaboplfbrettd7655fr4n2y
746 | scheduler: 0.21.0
747 | suspend-react: 0.0.8_react@18.2.0
748 | three: 0.144.0
749 | zustand: 3.7.2_react@18.2.0
750 | dev: false
751 |
752 | /@stitches/react/1.2.8_react@18.2.0:
753 | resolution: {integrity: sha512-9g9dWI4gsSVe8bNLlb+lMkBYsnIKCZTmvqvDG+Avnn69XfmHZKiaMrx7cgTaddq7aTPPmXiTsbFcUy0xgI4+wA==}
754 | peerDependencies:
755 | react: '>= 16.3.0'
756 | dependencies:
757 | react: 18.2.0
758 | dev: false
759 |
760 | /@types/offscreencanvas/2019.7.0:
761 | resolution: {integrity: sha512-PGcyveRIpL1XIqK8eBsmRBt76eFgtzuPiSTyKHZxnGemp2yzGzWpjYKAfK3wIMiU7eH+851yEpiuP8JZerTmWg==}
762 | dev: false
763 |
764 | /@types/prop-types/15.7.5:
765 | resolution: {integrity: sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w==}
766 |
767 | /@types/react-dom/18.0.6:
768 | resolution: {integrity: sha512-/5OFZgfIPSwy+YuIBP/FgJnQnsxhZhjjrnxudMddeblOouIodEQ75X14Rr4wGSG/bknL+Omy9iWlLo1u/9GzAA==}
769 | dependencies:
770 | '@types/react': 18.0.18
771 | dev: true
772 |
773 | /@types/react-reconciler/0.26.7:
774 | resolution: {integrity: sha512-mBDYl8x+oyPX/VBb3E638N0B7xG+SPk/EAMcVPeexqus/5aTpTphQi0curhhshOqRrc9t6OPoJfEUkbymse/lQ==}
775 | dependencies:
776 | '@types/react': 18.0.18
777 | dev: false
778 |
779 | /@types/react/18.0.17:
780 | resolution: {integrity: sha512-38ETy4tL+rn4uQQi7mB81G7V1g0u2ryquNmsVIOKUAEIDK+3CUjZ6rSRpdvS99dNBnkLFL83qfmtLacGOTIhwQ==}
781 | dependencies:
782 | '@types/prop-types': 15.7.5
783 | '@types/scheduler': 0.16.2
784 | csstype: 3.1.0
785 | dev: true
786 |
787 | /@types/react/18.0.18:
788 | resolution: {integrity: sha512-6hI08umYs6NaiHFEEGioXnxJ+oEhY3eRz8VCUaudZmGdtvPviCJB8mgaMxaDWAdPSYd4eFavrPk2QIolwbLYrg==}
789 | dependencies:
790 | '@types/prop-types': 15.7.5
791 | '@types/scheduler': 0.16.2
792 | csstype: 3.1.0
793 |
794 | /@types/scheduler/0.16.2:
795 | resolution: {integrity: sha512-hppQEBDmlwhFAXKJX2KnWLYu5yMfi91yazPb2l+lbJiwW+wdo1gNeRA+3RgNSO39WYX2euey41KEwnqesU2Jew==}
796 |
797 | /@types/three/0.144.0:
798 | resolution: {integrity: sha512-psvEs6q5rLN50jUYZ3D4pZMfxTbdt3A243blt0my7/NcL6chaCZpHe2csbCtx0SOD9fI/XnF3wnVUAYZGqCSYg==}
799 | dependencies:
800 | '@types/webxr': 0.5.0
801 | dev: true
802 |
803 | /@types/webxr/0.5.0:
804 | resolution: {integrity: sha512-IUMDPSXnYIbEO2IereEFcgcqfDREOgmbGqtrMpVPpACTU6pltYLwHgVkrnYv0XhWEcjio9sYEfIEzgn3c7nDqA==}
805 | dev: true
806 |
807 | /@use-gesture/core/10.2.19:
808 | resolution: {integrity: sha512-fsvuWmEfDDVgCEChLZuJFO8ZgBQLsEsL40ncv+HWYbkF90SwrLo2lkCu+O9TZa9ipqWC2KBXl27pRODY5ogr4w==}
809 | dev: false
810 |
811 | /@use-gesture/react/10.2.19_react@18.2.0:
812 | resolution: {integrity: sha512-pzRBEHehKKaM0T1bRlvLACfUlFetfaTrNH3mduJlRTsWvgKV+SNhoGxZzIavqyZW1kcIacYeXPr3XfvutpoN2w==}
813 | peerDependencies:
814 | react: '>= 16.8.0'
815 | dependencies:
816 | '@use-gesture/core': 10.2.19
817 | react: 18.2.0
818 | dev: false
819 |
820 | /@vitejs/plugin-react/2.1.0_vite@3.1.0:
821 | resolution: {integrity: sha512-am6rPyyU3LzUYne3Gd9oj9c4Rzbq5hQnuGXSMT6Gujq45Il/+bunwq3lrB7wghLkiF45ygMwft37vgJ/NE8IAA==}
822 | engines: {node: ^14.18.0 || >=16.0.0}
823 | peerDependencies:
824 | vite: ^3.0.0
825 | dependencies:
826 | '@babel/core': 7.19.0
827 | '@babel/plugin-transform-react-jsx': 7.19.0_@babel+core@7.19.0
828 | '@babel/plugin-transform-react-jsx-development': 7.18.6_@babel+core@7.19.0
829 | '@babel/plugin-transform-react-jsx-self': 7.18.6_@babel+core@7.19.0
830 | '@babel/plugin-transform-react-jsx-source': 7.18.6_@babel+core@7.19.0
831 | magic-string: 0.26.3
832 | react-refresh: 0.14.0
833 | vite: 3.1.0
834 | transitivePeerDependencies:
835 | - supports-color
836 | dev: true
837 |
838 | /@webgpu/glslang/0.0.15:
839 | resolution: {integrity: sha512-niT+Prh3Aff8Uf1MVBVUsaNjFj9rJAKDXuoHIKiQbB+6IUP/3J3JIhBNyZ7lDhytvXxw6ppgnwKZdDJ08UMj4Q==}
840 | dev: false
841 |
842 | /@welldone-software/why-did-you-render/6.2.3_react@18.2.0:
843 | resolution: {integrity: sha512-FQgi90jvC9uw2aALlonJfqaWOvU5UUBBVvdAnS2iryXwCc4YJkKsPJY5Y/LzaND3OIyk8XGUn1vTRn6hcem28Q==}
844 | peerDependencies:
845 | react: ^16 || ^17
846 | dependencies:
847 | lodash: 4.17.21
848 | react: 18.2.0
849 | dev: false
850 |
851 | /ansi-regex/5.0.1:
852 | resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==}
853 | engines: {node: '>=8'}
854 | dev: true
855 |
856 | /ansi-styles/3.2.1:
857 | resolution: {integrity: sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==}
858 | engines: {node: '>=4'}
859 | dependencies:
860 | color-convert: 1.9.3
861 | dev: true
862 |
863 | /ansi-styles/4.3.0:
864 | resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==}
865 | engines: {node: '>=8'}
866 | dependencies:
867 | color-convert: 2.0.1
868 | dev: true
869 |
870 | /assign-symbols/1.0.0:
871 | resolution: {integrity: sha512-Q+JC7Whu8HhmTdBph/Tq59IoRtoy6KAm5zzPv00WdujX82lbAL8K7WVjne7vdCsAmbF4AYaDOPyO3k0kl8qIrw==}
872 | engines: {node: '>=0.10.0'}
873 | dev: false
874 |
875 | /attr-accept/2.2.2:
876 | resolution: {integrity: sha512-7prDjvt9HmqiZ0cl5CRjtS84sEyhsHP2coDkaZKRKVfCDo9s7iw7ChVmar78Gu9pC4SoR/28wFu/G5JJhTnqEg==}
877 | engines: {node: '>=4'}
878 | dev: false
879 |
880 | /bidi-js/1.0.2:
881 | resolution: {integrity: sha512-rzSy/k7WdX5zOyeHHCOixGXbCHkyogkxPKL2r8QtzHmVQDiWCXUWa18bLdMWT9CYMLOYTjWpTHawuev2ouYJVw==}
882 | dependencies:
883 | require-from-string: 2.0.2
884 | dev: false
885 |
886 | /browserslist/4.21.3:
887 | resolution: {integrity: sha512-898rgRXLAyRkM1GryrrBHGkqA5hlpkV5MhtZwg9QXeiyLUYs2k00Un05aX5l2/yJIOObYKOpS2JNo8nJDE7fWQ==}
888 | engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7}
889 | hasBin: true
890 | dependencies:
891 | caniuse-lite: 1.0.30001393
892 | electron-to-chromium: 1.4.244
893 | node-releases: 2.0.6
894 | update-browserslist-db: 1.0.7_browserslist@4.21.3
895 | dev: true
896 |
897 | /caniuse-lite/1.0.30001393:
898 | resolution: {integrity: sha512-N/od11RX+Gsk+1qY/jbPa0R6zJupEa0lxeBG598EbrtblxVCTJsQwbRBm6+V+rxpc5lHKdsXb9RY83cZIPLseA==}
899 | dev: true
900 |
901 | /chalk/2.4.2:
902 | resolution: {integrity: sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==}
903 | engines: {node: '>=4'}
904 | dependencies:
905 | ansi-styles: 3.2.1
906 | escape-string-regexp: 1.0.5
907 | supports-color: 5.5.0
908 | dev: true
909 |
910 | /chevrotain/10.3.0:
911 | resolution: {integrity: sha512-sy3yTBfvNJmxzYOGWaDStZFuA7va5/MXwzBU+XBIol0bR0aYlfGqTjzgedeu32Ki/j7IVyvYAZO2PInBjmmMjg==}
912 | dependencies:
913 | '@chevrotain/cst-dts-gen': 10.3.0
914 | '@chevrotain/gast': 10.3.0
915 | '@chevrotain/types': 10.3.0
916 | '@chevrotain/utils': 10.3.0
917 | lodash: 4.17.21
918 | regexp-to-ast: 0.5.0
919 | dev: false
920 |
921 | /cliui/7.0.4:
922 | resolution: {integrity: sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==}
923 | dependencies:
924 | string-width: 4.2.3
925 | strip-ansi: 6.0.1
926 | wrap-ansi: 7.0.0
927 | dev: true
928 |
929 | /color-convert/1.9.3:
930 | resolution: {integrity: sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==}
931 | dependencies:
932 | color-name: 1.1.3
933 | dev: true
934 |
935 | /color-convert/2.0.1:
936 | resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==}
937 | engines: {node: '>=7.0.0'}
938 | dependencies:
939 | color-name: 1.1.4
940 | dev: true
941 |
942 | /color-name/1.1.3:
943 | resolution: {integrity: sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==}
944 | dev: true
945 |
946 | /color-name/1.1.4:
947 | resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==}
948 | dev: true
949 |
950 | /colord/2.9.3:
951 | resolution: {integrity: sha512-jeC1axXpnb0/2nn/Y1LPuLdgXBLH7aDcHu4KEKfqw3CUhX7ZpfBSlPKyqXE6btIgEzfWtrX3/tyBCaCvXvMkOw==}
952 | dev: false
953 |
954 | /convert-source-map/1.8.0:
955 | resolution: {integrity: sha512-+OQdjP49zViI/6i7nIJpA8rAl4sV/JdPfU9nZs3VqOwGIgizICvuN2ru6fMd+4llL0tar18UYJXfZ/TWtmhUjA==}
956 | dependencies:
957 | safe-buffer: 5.1.2
958 | dev: true
959 |
960 | /csstype/3.1.0:
961 | resolution: {integrity: sha512-uX1KG+x9h5hIJsaKR9xHUeUraxf8IODOwq9JLNPq6BwB04a/xgpq3rcx47l5BZu5zBPlgD342tdke3Hom/nJRA==}
962 |
963 | /debounce/1.2.1:
964 | resolution: {integrity: sha512-XRRe6Glud4rd/ZGQfiV1ruXSfbvfJedlV9Y6zOlP+2K04vBYiJEte6stfFkCP03aMnY5tsipamumUjL14fofug==}
965 | dev: false
966 |
967 | /debug/4.3.4:
968 | resolution: {integrity: sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==}
969 | engines: {node: '>=6.0'}
970 | peerDependencies:
971 | supports-color: '*'
972 | peerDependenciesMeta:
973 | supports-color:
974 | optional: true
975 | dependencies:
976 | ms: 2.1.2
977 | dev: true
978 |
979 | /define-lazy-prop/2.0.0:
980 | resolution: {integrity: sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og==}
981 | engines: {node: '>=8'}
982 | dev: true
983 |
984 | /dequal/2.0.3:
985 | resolution: {integrity: sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==}
986 | engines: {node: '>=6'}
987 | dev: false
988 |
989 | /detect-gpu/4.0.38:
990 | resolution: {integrity: sha512-rcUSndkHBA6jXq3yKolPHHyur7ypJkjwLQzrv3ONGays6/CPYBLA8fSWqRnNlGaT2J0bGrB5pPYcm5Oyz+xPoQ==}
991 | dependencies:
992 | webgl-constants: 1.1.1
993 | dev: false
994 |
995 | /draco3d/1.5.3:
996 | resolution: {integrity: sha512-Ahum6SewAd1oVMm6Fk8T/zCE0qbzjohhO5pl1Xp5Outl4JKv7jYicfd5vNtkzImx94XE35fhNXVqHk9ajt+6Tg==}
997 | dev: false
998 |
999 | /electron-to-chromium/1.4.244:
1000 | resolution: {integrity: sha512-E21saXLt2eTDaTxgUtiJtBUqanF9A32wZasAwDZ8gvrqXoxrBrbwtDCx7c/PQTLp81wj4X0OLDeoGQg7eMo3+w==}
1001 | dev: true
1002 |
1003 | /emoji-regex/8.0.0:
1004 | resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==}
1005 | dev: true
1006 |
1007 | /esbuild-android-64/0.15.7:
1008 | resolution: {integrity: sha512-p7rCvdsldhxQr3YHxptf1Jcd86dlhvc3EQmQJaZzzuAxefO9PvcI0GLOa5nCWem1AJ8iMRu9w0r5TG8pHmbi9w==}
1009 | engines: {node: '>=12'}
1010 | cpu: [x64]
1011 | os: [android]
1012 | requiresBuild: true
1013 | dev: true
1014 | optional: true
1015 |
1016 | /esbuild-android-arm64/0.15.7:
1017 | resolution: {integrity: sha512-L775l9ynJT7rVqRM5vo+9w5g2ysbOCfsdLV4CWanTZ1k/9Jb3IYlQ06VCI1edhcosTYJRECQFJa3eAvkx72eyQ==}
1018 | engines: {node: '>=12'}
1019 | cpu: [arm64]
1020 | os: [android]
1021 | requiresBuild: true
1022 | dev: true
1023 | optional: true
1024 |
1025 | /esbuild-darwin-64/0.15.7:
1026 | resolution: {integrity: sha512-KGPt3r1c9ww009t2xLB6Vk0YyNOXh7hbjZ3EecHoVDxgtbUlYstMPDaReimKe6eOEfyY4hBEEeTvKwPsiH5WZg==}
1027 | engines: {node: '>=12'}
1028 | cpu: [x64]
1029 | os: [darwin]
1030 | requiresBuild: true
1031 | dev: true
1032 | optional: true
1033 |
1034 | /esbuild-darwin-arm64/0.15.7:
1035 | resolution: {integrity: sha512-kBIHvtVqbSGajN88lYMnR3aIleH3ABZLLFLxwL2stiuIGAjGlQW741NxVTpUHQXUmPzxi6POqc9npkXa8AcSZQ==}
1036 | engines: {node: '>=12'}
1037 | cpu: [arm64]
1038 | os: [darwin]
1039 | requiresBuild: true
1040 | dev: true
1041 | optional: true
1042 |
1043 | /esbuild-freebsd-64/0.15.7:
1044 | resolution: {integrity: sha512-hESZB91qDLV5MEwNxzMxPfbjAhOmtfsr9Wnuci7pY6TtEh4UDuevmGmkUIjX/b+e/k4tcNBMf7SRQ2mdNuK/HQ==}
1045 | engines: {node: '>=12'}
1046 | cpu: [x64]
1047 | os: [freebsd]
1048 | requiresBuild: true
1049 | dev: true
1050 | optional: true
1051 |
1052 | /esbuild-freebsd-arm64/0.15.7:
1053 | resolution: {integrity: sha512-dLFR0ChH5t+b3J8w0fVKGvtwSLWCv7GYT2Y2jFGulF1L5HftQLzVGN+6pi1SivuiVSmTh28FwUhi9PwQicXI6Q==}
1054 | engines: {node: '>=12'}
1055 | cpu: [arm64]
1056 | os: [freebsd]
1057 | requiresBuild: true
1058 | dev: true
1059 | optional: true
1060 |
1061 | /esbuild-linux-32/0.15.7:
1062 | resolution: {integrity: sha512-v3gT/LsONGUZcjbt2swrMjwxo32NJzk+7sAgtxhGx1+ZmOFaTRXBAi1PPfgpeo/J//Un2jIKm/I+qqeo4caJvg==}
1063 | engines: {node: '>=12'}
1064 | cpu: [ia32]
1065 | os: [linux]
1066 | requiresBuild: true
1067 | dev: true
1068 | optional: true
1069 |
1070 | /esbuild-linux-64/0.15.7:
1071 | resolution: {integrity: sha512-LxXEfLAKwOVmm1yecpMmWERBshl+Kv5YJ/1KnyAr6HRHFW8cxOEsEfisD3sVl/RvHyW//lhYUVSuy9jGEfIRAQ==}
1072 | engines: {node: '>=12'}
1073 | cpu: [x64]
1074 | os: [linux]
1075 | requiresBuild: true
1076 | dev: true
1077 | optional: true
1078 |
1079 | /esbuild-linux-arm/0.15.7:
1080 | resolution: {integrity: sha512-JKgAHtMR5f75wJTeuNQbyznZZa+pjiUHV7sRZp42UNdyXC6TiUYMW/8z8yIBAr2Fpad8hM1royZKQisqPABPvQ==}
1081 | engines: {node: '>=12'}
1082 | cpu: [arm]
1083 | os: [linux]
1084 | requiresBuild: true
1085 | dev: true
1086 | optional: true
1087 |
1088 | /esbuild-linux-arm64/0.15.7:
1089 | resolution: {integrity: sha512-P3cfhudpzWDkglutWgXcT2S7Ft7o2e3YDMrP1n0z2dlbUZghUkKCyaWw0zhp4KxEEzt/E7lmrtRu/pGWnwb9vw==}
1090 | engines: {node: '>=12'}
1091 | cpu: [arm64]
1092 | os: [linux]
1093 | requiresBuild: true
1094 | dev: true
1095 | optional: true
1096 |
1097 | /esbuild-linux-mips64le/0.15.7:
1098 | resolution: {integrity: sha512-T7XKuxl0VpeFLCJXub6U+iybiqh0kM/bWOTb4qcPyDDwNVhLUiPcGdG2/0S7F93czUZOKP57YiLV8YQewgLHKw==}
1099 | engines: {node: '>=12'}
1100 | cpu: [mips64el]
1101 | os: [linux]
1102 | requiresBuild: true
1103 | dev: true
1104 | optional: true
1105 |
1106 | /esbuild-linux-ppc64le/0.15.7:
1107 | resolution: {integrity: sha512-6mGuC19WpFN7NYbecMIJjeQgvDb5aMuvyk0PDYBJrqAEMkTwg3Z98kEKuCm6THHRnrgsdr7bp4SruSAxEM4eJw==}
1108 | engines: {node: '>=12'}
1109 | cpu: [ppc64]
1110 | os: [linux]
1111 | requiresBuild: true
1112 | dev: true
1113 | optional: true
1114 |
1115 | /esbuild-linux-riscv64/0.15.7:
1116 | resolution: {integrity: sha512-uUJsezbswAYo/X7OU/P+PuL/EI9WzxsEQXDekfwpQ23uGiooxqoLFAPmXPcRAt941vjlY9jtITEEikWMBr+F/g==}
1117 | engines: {node: '>=12'}
1118 | cpu: [riscv64]
1119 | os: [linux]
1120 | requiresBuild: true
1121 | dev: true
1122 | optional: true
1123 |
1124 | /esbuild-linux-s390x/0.15.7:
1125 | resolution: {integrity: sha512-+tO+xOyTNMc34rXlSxK7aCwJgvQyffqEM5MMdNDEeMU3ss0S6wKvbBOQfgd5jRPblfwJ6b+bKiz0g5nABpY0QQ==}
1126 | engines: {node: '>=12'}
1127 | cpu: [s390x]
1128 | os: [linux]
1129 | requiresBuild: true
1130 | dev: true
1131 | optional: true
1132 |
1133 | /esbuild-netbsd-64/0.15.7:
1134 | resolution: {integrity: sha512-yVc4Wz+Pu3cP5hzm5kIygNPrjar/v5WCSoRmIjCPWfBVJkZNb5brEGKUlf+0Y759D48BCWa0WHrWXaNy0DULTQ==}
1135 | engines: {node: '>=12'}
1136 | cpu: [x64]
1137 | os: [netbsd]
1138 | requiresBuild: true
1139 | dev: true
1140 | optional: true
1141 |
1142 | /esbuild-openbsd-64/0.15.7:
1143 | resolution: {integrity: sha512-GsimbwC4FSR4lN3wf8XmTQ+r8/0YSQo21rWDL0XFFhLHKlzEA4SsT1Tl8bPYu00IU6UWSJ+b3fG/8SB69rcuEQ==}
1144 | engines: {node: '>=12'}
1145 | cpu: [x64]
1146 | os: [openbsd]
1147 | requiresBuild: true
1148 | dev: true
1149 | optional: true
1150 |
1151 | /esbuild-sunos-64/0.15.7:
1152 | resolution: {integrity: sha512-8CDI1aL/ts0mDGbWzjEOGKXnU7p3rDzggHSBtVryQzkSOsjCHRVe0iFYUuhczlxU1R3LN/E7HgUO4NXzGGP/Ag==}
1153 | engines: {node: '>=12'}
1154 | cpu: [x64]
1155 | os: [sunos]
1156 | requiresBuild: true
1157 | dev: true
1158 | optional: true
1159 |
1160 | /esbuild-windows-32/0.15.7:
1161 | resolution: {integrity: sha512-cOnKXUEPS8EGCzRSFa1x6NQjGhGsFlVgjhqGEbLTPsA7x4RRYiy2RKoArNUU4iR2vHmzqS5Gr84MEumO/wxYKA==}
1162 | engines: {node: '>=12'}
1163 | cpu: [ia32]
1164 | os: [win32]
1165 | requiresBuild: true
1166 | dev: true
1167 | optional: true
1168 |
1169 | /esbuild-windows-64/0.15.7:
1170 | resolution: {integrity: sha512-7MI08Ec2sTIDv+zH6StNBKO+2hGUYIT42GmFyW6MBBWWtJhTcQLinKS6ldIN1d52MXIbiJ6nXyCJ+LpL4jBm3Q==}
1171 | engines: {node: '>=12'}
1172 | cpu: [x64]
1173 | os: [win32]
1174 | requiresBuild: true
1175 | dev: true
1176 | optional: true
1177 |
1178 | /esbuild-windows-arm64/0.15.7:
1179 | resolution: {integrity: sha512-R06nmqBlWjKHddhRJYlqDd3Fabx9LFdKcjoOy08YLimwmsswlFBJV4rXzZCxz/b7ZJXvrZgj8DDv1ewE9+StMw==}
1180 | engines: {node: '>=12'}
1181 | cpu: [arm64]
1182 | os: [win32]
1183 | requiresBuild: true
1184 | dev: true
1185 | optional: true
1186 |
1187 | /esbuild/0.15.7:
1188 | resolution: {integrity: sha512-7V8tzllIbAQV1M4QoE52ImKu8hT/NLGlGXkiDsbEU5PS6K8Mn09ZnYoS+dcmHxOS9CRsV4IRAMdT3I67IyUNXw==}
1189 | engines: {node: '>=12'}
1190 | hasBin: true
1191 | requiresBuild: true
1192 | optionalDependencies:
1193 | '@esbuild/linux-loong64': 0.15.7
1194 | esbuild-android-64: 0.15.7
1195 | esbuild-android-arm64: 0.15.7
1196 | esbuild-darwin-64: 0.15.7
1197 | esbuild-darwin-arm64: 0.15.7
1198 | esbuild-freebsd-64: 0.15.7
1199 | esbuild-freebsd-arm64: 0.15.7
1200 | esbuild-linux-32: 0.15.7
1201 | esbuild-linux-64: 0.15.7
1202 | esbuild-linux-arm: 0.15.7
1203 | esbuild-linux-arm64: 0.15.7
1204 | esbuild-linux-mips64le: 0.15.7
1205 | esbuild-linux-ppc64le: 0.15.7
1206 | esbuild-linux-riscv64: 0.15.7
1207 | esbuild-linux-s390x: 0.15.7
1208 | esbuild-netbsd-64: 0.15.7
1209 | esbuild-openbsd-64: 0.15.7
1210 | esbuild-sunos-64: 0.15.7
1211 | esbuild-windows-32: 0.15.7
1212 | esbuild-windows-64: 0.15.7
1213 | esbuild-windows-arm64: 0.15.7
1214 | dev: true
1215 |
1216 | /escalade/3.1.1:
1217 | resolution: {integrity: sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==}
1218 | engines: {node: '>=6'}
1219 | dev: true
1220 |
1221 | /escape-string-regexp/1.0.5:
1222 | resolution: {integrity: sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==}
1223 | engines: {node: '>=0.8.0'}
1224 | dev: true
1225 |
1226 | /extend-shallow/2.0.1:
1227 | resolution: {integrity: sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==}
1228 | engines: {node: '>=0.10.0'}
1229 | dependencies:
1230 | is-extendable: 0.1.1
1231 | dev: false
1232 |
1233 | /extend-shallow/3.0.2:
1234 | resolution: {integrity: sha512-BwY5b5Ql4+qZoefgMj2NUmx+tehVTH/Kf4k1ZEtOHNFcm2wSxMRo992l6X3TIgni2eZVTZ85xMOjF31fwZAj6Q==}
1235 | engines: {node: '>=0.10.0'}
1236 | dependencies:
1237 | assign-symbols: 1.0.0
1238 | is-extendable: 1.0.1
1239 | dev: false
1240 |
1241 | /fflate/0.6.10:
1242 | resolution: {integrity: sha512-IQrh3lEPM93wVCEczc9SaAOvkmcoQn/G8Bo1e8ZPlY3X3bnAxWaBdvTdvM1hP62iZp0BXWDy4vTAy4fF0+Dlpg==}
1243 | dev: false
1244 |
1245 | /file-selector/0.5.0:
1246 | resolution: {integrity: sha512-s8KNnmIDTBoD0p9uJ9uD0XY38SCeBOtj0UMXyQSLg1Ypfrfj8+dAvwsLjYQkQ2GjhVtp2HrnF5cJzMhBjfD8HA==}
1247 | engines: {node: '>= 10'}
1248 | dependencies:
1249 | tslib: 2.4.0
1250 | dev: false
1251 |
1252 | /for-in/1.0.2:
1253 | resolution: {integrity: sha512-7EwmXrOjyL+ChxMhmG5lnW9MPt1aIeZEwKhQzoBUdTV0N3zuwWDZYVJatDvZ2OyzPUvdIAZDsCetk3coyMfcnQ==}
1254 | engines: {node: '>=0.10.0'}
1255 | dev: false
1256 |
1257 | /fsevents/2.3.2:
1258 | resolution: {integrity: sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==}
1259 | engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0}
1260 | os: [darwin]
1261 | requiresBuild: true
1262 | dev: true
1263 | optional: true
1264 |
1265 | /function-bind/1.1.1:
1266 | resolution: {integrity: sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==}
1267 | dev: true
1268 |
1269 | /gensync/1.0.0-beta.2:
1270 | resolution: {integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==}
1271 | engines: {node: '>=6.9.0'}
1272 | dev: true
1273 |
1274 | /get-caller-file/2.0.5:
1275 | resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==}
1276 | engines: {node: 6.* || 8.* || >= 10.*}
1277 | dev: true
1278 |
1279 | /get-value/2.0.6:
1280 | resolution: {integrity: sha512-Ln0UQDlxH1BapMu3GPtf7CuYNwRZf2gwCuPqbyG6pB8WfmFpzqcy4xtAaAMUhnNqjMKTiCPZG2oMT3YSx8U2NA==}
1281 | engines: {node: '>=0.10.0'}
1282 | dev: false
1283 |
1284 | /globals/11.12.0:
1285 | resolution: {integrity: sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==}
1286 | engines: {node: '>=4'}
1287 | dev: true
1288 |
1289 | /glsl-noise/0.0.0:
1290 | resolution: {integrity: sha512-b/ZCF6amfAUb7dJM/MxRs7AetQEahYzJ8PtgfrmEdtw6uyGOr+ZSGtgjFm6mfsBkxJ4d2W7kg+Nlqzqvn3Bc0w==}
1291 | dev: false
1292 |
1293 | /has-flag/3.0.0:
1294 | resolution: {integrity: sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==}
1295 | engines: {node: '>=4'}
1296 | dev: true
1297 |
1298 | /has/1.0.3:
1299 | resolution: {integrity: sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==}
1300 | engines: {node: '>= 0.4.0'}
1301 | dependencies:
1302 | function-bind: 1.1.1
1303 | dev: true
1304 |
1305 | /immer/9.0.15:
1306 | resolution: {integrity: sha512-2eB/sswms9AEUSkOm4SbV5Y7Vmt/bKRwByd52jfLkW4OLYeaTP3EEiJ9agqU0O/tq6Dk62Zfj+TJSqfm1rLVGQ==}
1307 | dev: false
1308 |
1309 | /is-core-module/2.10.0:
1310 | resolution: {integrity: sha512-Erxj2n/LDAZ7H8WNJXd9tw38GYM3dv8rk8Zcs+jJuxYTW7sozH+SS8NtrSjVL1/vpLvWi1hxy96IzjJ3EHTJJg==}
1311 | dependencies:
1312 | has: 1.0.3
1313 | dev: true
1314 |
1315 | /is-docker/2.2.1:
1316 | resolution: {integrity: sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==}
1317 | engines: {node: '>=8'}
1318 | hasBin: true
1319 | dev: true
1320 |
1321 | /is-extendable/0.1.1:
1322 | resolution: {integrity: sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==}
1323 | engines: {node: '>=0.10.0'}
1324 | dev: false
1325 |
1326 | /is-extendable/1.0.1:
1327 | resolution: {integrity: sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==}
1328 | engines: {node: '>=0.10.0'}
1329 | dependencies:
1330 | is-plain-object: 2.0.4
1331 | dev: false
1332 |
1333 | /is-fullwidth-code-point/3.0.0:
1334 | resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==}
1335 | engines: {node: '>=8'}
1336 | dev: true
1337 |
1338 | /is-plain-object/2.0.4:
1339 | resolution: {integrity: sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==}
1340 | engines: {node: '>=0.10.0'}
1341 | dependencies:
1342 | isobject: 3.0.1
1343 | dev: false
1344 |
1345 | /is-wsl/2.2.0:
1346 | resolution: {integrity: sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==}
1347 | engines: {node: '>=8'}
1348 | dependencies:
1349 | is-docker: 2.2.1
1350 | dev: true
1351 |
1352 | /isobject/3.0.1:
1353 | resolution: {integrity: sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==}
1354 | engines: {node: '>=0.10.0'}
1355 | dev: false
1356 |
1357 | /js-tokens/4.0.0:
1358 | resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==}
1359 |
1360 | /jsesc/2.5.2:
1361 | resolution: {integrity: sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==}
1362 | engines: {node: '>=4'}
1363 | hasBin: true
1364 | dev: true
1365 |
1366 | /json5/2.2.1:
1367 | resolution: {integrity: sha512-1hqLFMSrGHRHxav9q9gNjJ5EXznIxGVO09xQRrwplcS8qs28pZ8s8hupZAmqDwZUmVZ2Qb2jnyPOWcDH8m8dlA==}
1368 | engines: {node: '>=6'}
1369 | hasBin: true
1370 | dev: true
1371 |
1372 | /ktx-parse/0.4.5:
1373 | resolution: {integrity: sha512-MK3FOody4TXbFf8Yqv7EBbySw7aPvEcPX++Ipt6Sox+/YMFvR5xaTyhfNSk1AEmMy+RYIw81ctN4IMxCB8OAlg==}
1374 | dev: false
1375 |
1376 | /leva/0.9.31_biqbaboplfbrettd7655fr4n2y:
1377 | resolution: {integrity: sha512-qQGz35mKM9BXTFcG9qeB+89lkdvguDriiNWoGU9U8BU8r57Ve+6rFF+X5EPKJKwhmFQSbHIRj3mBZKjCjHor2g==}
1378 | peerDependencies:
1379 | react: '>=16.8.0'
1380 | react-dom: '>=16.8.0'
1381 | dependencies:
1382 | '@radix-ui/react-portal': 0.1.4_biqbaboplfbrettd7655fr4n2y
1383 | '@radix-ui/react-tooltip': 0.1.6_biqbaboplfbrettd7655fr4n2y
1384 | '@stitches/react': 1.2.8_react@18.2.0
1385 | '@use-gesture/react': 10.2.19_react@18.2.0
1386 | '@welldone-software/why-did-you-render': 6.2.3_react@18.2.0
1387 | colord: 2.9.3
1388 | dequal: 2.0.3
1389 | merge-value: 1.0.0
1390 | react: 18.2.0
1391 | react-colorful: 5.6.1_biqbaboplfbrettd7655fr4n2y
1392 | react-dom: 18.2.0_react@18.2.0
1393 | react-dropzone: 12.1.0_react@18.2.0
1394 | v8n: 1.5.1
1395 | zustand: 3.7.2_react@18.2.0
1396 | dev: false
1397 |
1398 | /lodash.clamp/4.0.3:
1399 | resolution: {integrity: sha512-HvzRFWjtcguTW7yd8NJBshuNaCa8aqNFtnswdT7f/cMd/1YKy5Zzoq4W/Oxvnx9l7aeY258uSdDfM793+eLsVg==}
1400 | dev: false
1401 |
1402 | /lodash.omit/4.5.0:
1403 | resolution: {integrity: sha512-XeqSp49hNGmlkj2EJlfrQFIzQ6lXdNro9sddtQzcJY8QaoC2GO0DT7xaIokHeyM+mIT0mPMlPvkYzg2xCuHdZg==}
1404 | dev: false
1405 |
1406 | /lodash.pick/4.4.0:
1407 | resolution: {integrity: sha512-hXt6Ul/5yWjfklSGvLQl8vM//l3FtyHZeuelpzK6mm99pNvN9yTDruNZPEJZD1oWrqo+izBmB7oUfWgcCX7s4Q==}
1408 | dev: false
1409 |
1410 | /lodash/4.17.21:
1411 | resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==}
1412 | dev: false
1413 |
1414 | /loose-envify/1.4.0:
1415 | resolution: {integrity: sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==}
1416 | hasBin: true
1417 | dependencies:
1418 | js-tokens: 4.0.0
1419 | dev: false
1420 |
1421 | /magic-string/0.26.3:
1422 | resolution: {integrity: sha512-u1Po0NDyFcwdg2nzHT88wSK0+Rih0N1M+Ph1Sp08k8yvFFU3KR72wryS7e1qMPJypt99WB7fIFVCA92mQrMjrg==}
1423 | engines: {node: '>=12'}
1424 | dependencies:
1425 | sourcemap-codec: 1.4.8
1426 | dev: true
1427 |
1428 | /merge-value/1.0.0:
1429 | resolution: {integrity: sha512-fJMmvat4NeKz63Uv9iHWcPDjCWcCkoiRoajRTEO8hlhUC6rwaHg0QCF9hBOTjZmm4JuglPckPSTtcuJL5kp0TQ==}
1430 | engines: {node: '>=0.10.0'}
1431 | dependencies:
1432 | get-value: 2.0.6
1433 | is-extendable: 1.0.1
1434 | mixin-deep: 1.3.2
1435 | set-value: 2.0.1
1436 | dev: false
1437 |
1438 | /meshline/2.0.4_three@0.144.0:
1439 | resolution: {integrity: sha512-Jh6DJl/zLqA4xsKvGv5950jr2ukyXQE1wgxs8u94cImHrvL6soVIggqjP+2hVHZXGYaKnWszhtjuCbKNeQyYiw==}
1440 | peerDependencies:
1441 | three: '>=0.137'
1442 | dependencies:
1443 | three: 0.144.0
1444 | dev: false
1445 |
1446 | /mixin-deep/1.3.2:
1447 | resolution: {integrity: sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA==}
1448 | engines: {node: '>=0.10.0'}
1449 | dependencies:
1450 | for-in: 1.0.2
1451 | is-extendable: 1.0.1
1452 | dev: false
1453 |
1454 | /mmd-parser/1.0.4:
1455 | resolution: {integrity: sha512-Qi0VCU46t2IwfGv5KF0+D/t9cizcDug7qnNoy9Ggk7aucp0tssV8IwTMkBlDbm+VqAf3cdQHTCARKSsuS2MYFg==}
1456 | dev: false
1457 |
1458 | /ms/2.1.2:
1459 | resolution: {integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==}
1460 | dev: true
1461 |
1462 | /nanoid/3.3.4:
1463 | resolution: {integrity: sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw==}
1464 | engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1}
1465 | hasBin: true
1466 | dev: true
1467 |
1468 | /node-releases/2.0.6:
1469 | resolution: {integrity: sha512-PiVXnNuFm5+iYkLBNeq5211hvO38y63T0i2KKh2KnUs3RpzJ+JtODFjkD8yjLwnDkTYF1eKXheUwdssR+NRZdg==}
1470 | dev: true
1471 |
1472 | /object-assign/4.1.1:
1473 | resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==}
1474 | engines: {node: '>=0.10.0'}
1475 | dev: false
1476 |
1477 | /open/8.4.0:
1478 | resolution: {integrity: sha512-XgFPPM+B28FtCCgSb9I+s9szOC1vZRSwgWsRUA5ylIxRTgKozqjOCrVOqGsYABPYK5qnfqClxZTFBa8PKt2v6Q==}
1479 | engines: {node: '>=12'}
1480 | dependencies:
1481 | define-lazy-prop: 2.0.0
1482 | is-docker: 2.2.1
1483 | is-wsl: 2.2.0
1484 | dev: true
1485 |
1486 | /opentype.js/1.3.4:
1487 | resolution: {integrity: sha512-d2JE9RP/6uagpQAVtJoF0pJJA/fgai89Cc50Yp0EJHk+eLp6QQ7gBoblsnubRULNY132I0J1QKMJ+JTbMqz4sw==}
1488 | engines: {node: '>= 8.0.0'}
1489 | hasBin: true
1490 | dependencies:
1491 | string.prototype.codepointat: 0.2.1
1492 | tiny-inflate: 1.0.3
1493 | dev: false
1494 |
1495 | /path-parse/1.0.7:
1496 | resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==}
1497 | dev: true
1498 |
1499 | /picocolors/1.0.0:
1500 | resolution: {integrity: sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==}
1501 | dev: true
1502 |
1503 | /postcss/8.4.16:
1504 | resolution: {integrity: sha512-ipHE1XBvKzm5xI7hiHCZJCSugxvsdq2mPnsq5+UF+VHCjiBvtDrlxJfMBToWaP9D5XlgNmcFGqoHmUn0EYEaRQ==}
1505 | engines: {node: ^10 || ^12 || >=14}
1506 | dependencies:
1507 | nanoid: 3.3.4
1508 | picocolors: 1.0.0
1509 | source-map-js: 1.0.2
1510 | dev: true
1511 |
1512 | /potpack/1.0.2:
1513 | resolution: {integrity: sha512-choctRBIV9EMT9WGAZHn3V7t0Z2pMQyl0EZE6pFc/6ml3ssw7Dlf/oAOvFwjm1HVsqfQN8GfeFyJ+d8tRzqueQ==}
1514 | dev: false
1515 |
1516 | /prop-types/15.8.1:
1517 | resolution: {integrity: sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==}
1518 | dependencies:
1519 | loose-envify: 1.4.0
1520 | object-assign: 4.1.1
1521 | react-is: 16.13.1
1522 | dev: false
1523 |
1524 | /react-colorful/5.6.1_biqbaboplfbrettd7655fr4n2y:
1525 | resolution: {integrity: sha512-1exovf0uGTGyq5mXQT0zgQ80uvj2PCwvF8zY1RN9/vbJVSjSo3fsB/4L3ObbF7u70NduSiK4xu4Y6q1MHoUGEw==}
1526 | peerDependencies:
1527 | react: '>=16.8.0'
1528 | react-dom: '>=16.8.0'
1529 | dependencies:
1530 | react: 18.2.0
1531 | react-dom: 18.2.0_react@18.2.0
1532 | dev: false
1533 |
1534 | /react-composer/5.0.3_react@18.2.0:
1535 | resolution: {integrity: sha512-1uWd07EME6XZvMfapwZmc7NgCZqDemcvicRi3wMJzXsQLvZ3L7fTHVyPy1bZdnWXM4iPjYuNE+uJ41MLKeTtnA==}
1536 | peerDependencies:
1537 | react: ^15.0.0 || ^16.0.0 || ^17.0.0 || ^18.0.0
1538 | dependencies:
1539 | prop-types: 15.8.1
1540 | react: 18.2.0
1541 | dev: false
1542 |
1543 | /react-dom/18.2.0_react@18.2.0:
1544 | resolution: {integrity: sha512-6IMTriUmvsjHUjNtEDudZfuDQUoWXVxKHhlEGSk81n4YFS+r/Kl99wXiwlVXtPBtJenozv2P+hxDsw9eA7Xo6g==}
1545 | peerDependencies:
1546 | react: ^18.2.0
1547 | dependencies:
1548 | loose-envify: 1.4.0
1549 | react: 18.2.0
1550 | scheduler: 0.23.0
1551 | dev: false
1552 |
1553 | /react-dropzone/12.1.0_react@18.2.0:
1554 | resolution: {integrity: sha512-iBYHA1rbopIvtzokEX4QubO6qk5IF/x3BtKGu74rF2JkQDXnwC4uO/lHKpaw4PJIV6iIAYOlwLv2FpiGyqHNog==}
1555 | engines: {node: '>= 10.13'}
1556 | peerDependencies:
1557 | react: '>= 16.8'
1558 | dependencies:
1559 | attr-accept: 2.2.2
1560 | file-selector: 0.5.0
1561 | prop-types: 15.8.1
1562 | react: 18.2.0
1563 | dev: false
1564 |
1565 | /react-is/16.13.1:
1566 | resolution: {integrity: sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==}
1567 | dev: false
1568 |
1569 | /react-merge-refs/1.1.0:
1570 | resolution: {integrity: sha512-alTKsjEL0dKH/ru1Iyn7vliS2QRcBp9zZPGoWxUOvRGWPUYgjo+V01is7p04It6KhgrzhJGnIj9GgX8W4bZoCQ==}
1571 | dev: false
1572 |
1573 | /react-reconciler/0.27.0_react@18.2.0:
1574 | resolution: {integrity: sha512-HmMDKciQjYmBRGuuhIaKA1ba/7a+UsM5FzOZsMO2JYHt9Jh8reCb7j1eDC95NOyUlKM9KRyvdx0flBuDvYSBoA==}
1575 | engines: {node: '>=0.10.0'}
1576 | peerDependencies:
1577 | react: ^18.0.0
1578 | dependencies:
1579 | loose-envify: 1.4.0
1580 | react: 18.2.0
1581 | scheduler: 0.21.0
1582 | dev: false
1583 |
1584 | /react-refresh/0.14.0:
1585 | resolution: {integrity: sha512-wViHqhAd8OHeLS/IRMJjTSDHF3U9eWi62F/MledQGPdJGDhodXJ9PBLNGr6WWL7qlH12Mt3TyTpbS+hGXMjCzQ==}
1586 | engines: {node: '>=0.10.0'}
1587 | dev: true
1588 |
1589 | /react-use-measure/2.1.1_biqbaboplfbrettd7655fr4n2y:
1590 | resolution: {integrity: sha512-nocZhN26cproIiIduswYpV5y5lQpSQS1y/4KuvUCjSKmw7ZWIS/+g3aFnX3WdBkyuGUtTLif3UTqnLLhbDoQig==}
1591 | peerDependencies:
1592 | react: '>=16.13'
1593 | react-dom: '>=16.13'
1594 | dependencies:
1595 | debounce: 1.2.1
1596 | react: 18.2.0
1597 | react-dom: 18.2.0_react@18.2.0
1598 | dev: false
1599 |
1600 | /react/18.2.0:
1601 | resolution: {integrity: sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ==}
1602 | engines: {node: '>=0.10.0'}
1603 | dependencies:
1604 | loose-envify: 1.4.0
1605 | dev: false
1606 |
1607 | /regenerator-runtime/0.13.9:
1608 | resolution: {integrity: sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA==}
1609 | dev: false
1610 |
1611 | /regexp-to-ast/0.5.0:
1612 | resolution: {integrity: sha512-tlbJqcMHnPKI9zSrystikWKwHkBqu2a/Sgw01h3zFjvYrMxEDYHzzoMZnUrbIfpTFEsoRnnviOXNCzFiSc54Qw==}
1613 | dev: false
1614 |
1615 | /require-directory/2.1.1:
1616 | resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==}
1617 | engines: {node: '>=0.10.0'}
1618 | dev: true
1619 |
1620 | /require-from-string/2.0.2:
1621 | resolution: {integrity: sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==}
1622 | engines: {node: '>=0.10.0'}
1623 | dev: false
1624 |
1625 | /resolve/1.22.1:
1626 | resolution: {integrity: sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==}
1627 | hasBin: true
1628 | dependencies:
1629 | is-core-module: 2.10.0
1630 | path-parse: 1.0.7
1631 | supports-preserve-symlinks-flag: 1.0.0
1632 | dev: true
1633 |
1634 | /rollup-plugin-visualizer/5.8.1:
1635 | resolution: {integrity: sha512-NBT/xN/LWCwDM2/j5vYmjzpEAKHyclo/8Cv8AfTCwgADAG+tLJDy1vzxMw6NO0dSDjmTeRELD9UU3FwknLv0GQ==}
1636 | engines: {node: '>=14'}
1637 | hasBin: true
1638 | peerDependencies:
1639 | rollup: ^2.0.0
1640 | peerDependenciesMeta:
1641 | rollup:
1642 | optional: true
1643 | dependencies:
1644 | nanoid: 3.3.4
1645 | open: 8.4.0
1646 | source-map: 0.7.4
1647 | yargs: 17.5.1
1648 | dev: true
1649 |
1650 | /rollup/2.78.1:
1651 | resolution: {integrity: sha512-VeeCgtGi4P+o9hIg+xz4qQpRl6R401LWEXBmxYKOV4zlF82lyhgh2hTZnheFUbANE8l2A41F458iwj2vEYaXJg==}
1652 | engines: {node: '>=10.0.0'}
1653 | hasBin: true
1654 | optionalDependencies:
1655 | fsevents: 2.3.2
1656 | dev: true
1657 |
1658 | /safe-buffer/5.1.2:
1659 | resolution: {integrity: sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==}
1660 | dev: true
1661 |
1662 | /scheduler/0.21.0:
1663 | resolution: {integrity: sha512-1r87x5fz9MXqswA2ERLo0EbOAU74DpIUO090gIasYTqlVoJeMcl+Z1Rg7WHz+qtPujhS/hGIt9kxZOYBV3faRQ==}
1664 | dependencies:
1665 | loose-envify: 1.4.0
1666 | dev: false
1667 |
1668 | /scheduler/0.23.0:
1669 | resolution: {integrity: sha512-CtuThmgHNg7zIZWAXi3AsyIzA3n4xx7aNyjwC2VJldO2LMVDhFK+63xGqq6CsJH4rTAt6/M+N4GhZiDYPx9eUw==}
1670 | dependencies:
1671 | loose-envify: 1.4.0
1672 | dev: false
1673 |
1674 | /semver/6.3.0:
1675 | resolution: {integrity: sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==}
1676 | hasBin: true
1677 | dev: true
1678 |
1679 | /set-value/2.0.1:
1680 | resolution: {integrity: sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==}
1681 | engines: {node: '>=0.10.0'}
1682 | dependencies:
1683 | extend-shallow: 2.0.1
1684 | is-extendable: 0.1.1
1685 | is-plain-object: 2.0.4
1686 | split-string: 3.1.0
1687 | dev: false
1688 |
1689 | /source-map-js/1.0.2:
1690 | resolution: {integrity: sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==}
1691 | engines: {node: '>=0.10.0'}
1692 | dev: true
1693 |
1694 | /source-map/0.7.4:
1695 | resolution: {integrity: sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==}
1696 | engines: {node: '>= 8'}
1697 | dev: true
1698 |
1699 | /sourcemap-codec/1.4.8:
1700 | resolution: {integrity: sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==}
1701 | dev: true
1702 |
1703 | /split-string/3.1.0:
1704 | resolution: {integrity: sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==}
1705 | engines: {node: '>=0.10.0'}
1706 | dependencies:
1707 | extend-shallow: 3.0.2
1708 | dev: false
1709 |
1710 | /stats.js/0.17.0:
1711 | resolution: {integrity: sha512-hNKz8phvYLPEcRkeG1rsGmV5ChMjKDAWU7/OJJdDErPBNChQXxCo3WZurGpnWc6gZhAzEPFad1aVgyOANH1sMw==}
1712 | dev: false
1713 |
1714 | /string-width/4.2.3:
1715 | resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==}
1716 | engines: {node: '>=8'}
1717 | dependencies:
1718 | emoji-regex: 8.0.0
1719 | is-fullwidth-code-point: 3.0.0
1720 | strip-ansi: 6.0.1
1721 | dev: true
1722 |
1723 | /string.prototype.codepointat/0.2.1:
1724 | resolution: {integrity: sha512-2cBVCj6I4IOvEnjgO/hWqXjqBGsY+zwPmHl12Srk9IXSZ56Jwwmy+66XO5Iut/oQVR7t5ihYdLB0GMa4alEUcg==}
1725 | dev: false
1726 |
1727 | /strip-ansi/6.0.1:
1728 | resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==}
1729 | engines: {node: '>=8'}
1730 | dependencies:
1731 | ansi-regex: 5.0.1
1732 | dev: true
1733 |
1734 | /supports-color/5.5.0:
1735 | resolution: {integrity: sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==}
1736 | engines: {node: '>=4'}
1737 | dependencies:
1738 | has-flag: 3.0.0
1739 | dev: true
1740 |
1741 | /supports-preserve-symlinks-flag/1.0.0:
1742 | resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==}
1743 | engines: {node: '>= 0.4'}
1744 | dev: true
1745 |
1746 | /suspend-react/0.0.8_react@18.2.0:
1747 | resolution: {integrity: sha512-ZC3r8Hu1y0dIThzsGw0RLZplnX9yXwfItcvaIzJc2VQVi8TGyGDlu92syMB5ulybfvGLHAI5Ghzlk23UBPF8xg==}
1748 | peerDependencies:
1749 | react: '>=17.0'
1750 | dependencies:
1751 | react: 18.2.0
1752 | dev: false
1753 |
1754 | /three-mesh-bvh/0.5.16_three@0.144.0:
1755 | resolution: {integrity: sha512-kN3QGKJNiQQcuiOsjVIkjtPnV3PJa+0Orih2E52afa+kQfs3zfoYt6Kxn6b6RNiAfaQ+7ckwPK0mTVFVl2F2LA==}
1756 | peerDependencies:
1757 | three: '>= 0.123.0'
1758 | dependencies:
1759 | three: 0.144.0
1760 | dev: false
1761 |
1762 | /three-stdlib/2.15.0_three@0.144.0:
1763 | resolution: {integrity: sha512-81jgpEajYB1HczIKAqcG8oEgRPbKJr/8KfxMY3xIHe9kDNw426PckStLt+GVmV15ezOS+QlUFVSuyjSRPpSLsg==}
1764 | peerDependencies:
1765 | three: '>=0.122.0'
1766 | dependencies:
1767 | '@babel/runtime': 7.19.0
1768 | '@types/offscreencanvas': 2019.7.0
1769 | '@webgpu/glslang': 0.0.15
1770 | chevrotain: 10.3.0
1771 | draco3d: 1.5.3
1772 | fflate: 0.6.10
1773 | ktx-parse: 0.4.5
1774 | mmd-parser: 1.0.4
1775 | opentype.js: 1.3.4
1776 | potpack: 1.0.2
1777 | three: 0.144.0
1778 | zstddec: 0.0.2
1779 | dev: false
1780 |
1781 | /three/0.144.0:
1782 | resolution: {integrity: sha512-R8AXPuqfjfRJKkYoTQcTK7A6i3AdO9++2n8ubya/GTU+fEHhYKu1ZooRSCPkx69jbnzT7dD/xEo6eROQTt2lJw==}
1783 | dev: false
1784 |
1785 | /tiny-inflate/1.0.3:
1786 | resolution: {integrity: sha512-pkY1fj1cKHb2seWDy0B16HeWyczlJA9/WW3u3c4z/NiWDsO3DOU5D7nhTLE9CF0yXv/QZFY7sEJmj24dK+Rrqw==}
1787 | dev: false
1788 |
1789 | /to-fast-properties/2.0.0:
1790 | resolution: {integrity: sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==}
1791 | engines: {node: '>=4'}
1792 | dev: true
1793 |
1794 | /troika-three-text/0.46.4_three@0.144.0:
1795 | resolution: {integrity: sha512-Qsv0HhUKTZgSmAJs5wvO7YlBoJSP9TGPLmrg+K9pbQq4lseQdcevbno/WI38bwJBZ/qS56hvfqEzY0zUEFzDIw==}
1796 | peerDependencies:
1797 | three: '>=0.103.0'
1798 | dependencies:
1799 | bidi-js: 1.0.2
1800 | three: 0.144.0
1801 | troika-three-utils: 0.46.0_three@0.144.0
1802 | troika-worker-utils: 0.46.0
1803 | webgl-sdf-generator: 1.1.1
1804 | dev: false
1805 |
1806 | /troika-three-utils/0.46.0_three@0.144.0:
1807 | resolution: {integrity: sha512-llHyrXAcwzr0bpg80GxsIp73N7FuImm4WCrKDJkAqcAsWmE5pfP9+Qzw+oMWK1P/AdHQ79eOrOl9NjyW4aOw0w==}
1808 | peerDependencies:
1809 | three: '>=0.103.0'
1810 | dependencies:
1811 | three: 0.144.0
1812 | dev: false
1813 |
1814 | /troika-worker-utils/0.46.0:
1815 | resolution: {integrity: sha512-bzOx5f2ZBxkFhXtIvDJlLn2AI3bzCkGVbCndl/2dL5QZrwHEKl45OEIilCxYQQWJG1rEbOD9O80tMjoYjw19OA==}
1816 | dev: false
1817 |
1818 | /tslib/2.4.0:
1819 | resolution: {integrity: sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==}
1820 | dev: false
1821 |
1822 | /typescript/4.6.4:
1823 | resolution: {integrity: sha512-9ia/jWHIEbo49HfjrLGfKbZSuWo9iTMwXO+Ca3pRsSpbsMbc7/IU8NKdCZVRRBafVPGnoJeFL76ZOAA84I9fEg==}
1824 | engines: {node: '>=4.2.0'}
1825 | hasBin: true
1826 | dev: true
1827 |
1828 | /update-browserslist-db/1.0.7_browserslist@4.21.3:
1829 | resolution: {integrity: sha512-iN/XYesmZ2RmmWAiI4Z5rq0YqSiv0brj9Ce9CfhNE4xIW2h+MFxcgkxIzZ+ShkFPUkjU3gQ+3oypadD3RAMtrg==}
1830 | hasBin: true
1831 | peerDependencies:
1832 | browserslist: '>= 4.21.0'
1833 | dependencies:
1834 | browserslist: 4.21.3
1835 | escalade: 3.1.1
1836 | picocolors: 1.0.0
1837 | dev: true
1838 |
1839 | /use-sync-external-store/1.2.0_react@18.2.0:
1840 | resolution: {integrity: sha512-eEgnFxGQ1Ife9bzYs6VLi8/4X6CObHMw9Qr9tPY43iKwsPw8xE8+EFsf/2cFZ5S3esXgpWgtSCtLNS41F+sKPA==}
1841 | peerDependencies:
1842 | react: ^16.8.0 || ^17.0.0 || ^18.0.0
1843 | dependencies:
1844 | react: 18.2.0
1845 | dev: false
1846 |
1847 | /utility-types/3.10.0:
1848 | resolution: {integrity: sha512-O11mqxmi7wMKCo6HKFt5AhO4BwY3VV68YU07tgxfz8zJTIxr4BpsezN49Ffwy9j3ZpwwJp4fkRwjRzq3uWE6Rg==}
1849 | engines: {node: '>= 4'}
1850 | dev: false
1851 |
1852 | /v8n/1.5.1:
1853 | resolution: {integrity: sha512-LdabyT4OffkyXFCe9UT+uMkxNBs5rcTVuZClvxQr08D5TUgo1OFKkoT65qYRCsiKBl/usHjpXvP4hHMzzDRj3A==}
1854 | dev: false
1855 |
1856 | /vite/3.1.0:
1857 | resolution: {integrity: sha512-YBg3dUicDpDWFCGttmvMbVyS9ydjntwEjwXRj2KBFwSB8SxmGcudo1yb8FW5+M/G86aS8x828ujnzUVdsLjs9g==}
1858 | engines: {node: ^14.18.0 || >=16.0.0}
1859 | hasBin: true
1860 | peerDependencies:
1861 | less: '*'
1862 | sass: '*'
1863 | stylus: '*'
1864 | terser: ^5.4.0
1865 | peerDependenciesMeta:
1866 | less:
1867 | optional: true
1868 | sass:
1869 | optional: true
1870 | stylus:
1871 | optional: true
1872 | terser:
1873 | optional: true
1874 | dependencies:
1875 | esbuild: 0.15.7
1876 | postcss: 8.4.16
1877 | resolve: 1.22.1
1878 | rollup: 2.78.1
1879 | optionalDependencies:
1880 | fsevents: 2.3.2
1881 | dev: true
1882 |
1883 | /webgl-constants/1.1.1:
1884 | resolution: {integrity: sha512-LkBXKjU5r9vAW7Gcu3T5u+5cvSvh5WwINdr0C+9jpzVB41cjQAP5ePArDtk/WHYdVj0GefCgM73BA7FlIiNtdg==}
1885 | dev: false
1886 |
1887 | /webgl-sdf-generator/1.1.1:
1888 | resolution: {integrity: sha512-9Z0JcMTFxeE+b2x1LJTdnaT8rT8aEp7MVxkNwoycNmJWwPdzoXzMh0BjJSh/AEFP+KPYZUli814h8bJZFIZ2jA==}
1889 | dev: false
1890 |
1891 | /wrap-ansi/7.0.0:
1892 | resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==}
1893 | engines: {node: '>=10'}
1894 | dependencies:
1895 | ansi-styles: 4.3.0
1896 | string-width: 4.2.3
1897 | strip-ansi: 6.0.1
1898 | dev: true
1899 |
1900 | /y18n/5.0.8:
1901 | resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==}
1902 | engines: {node: '>=10'}
1903 | dev: true
1904 |
1905 | /yargs-parser/21.1.1:
1906 | resolution: {integrity: sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==}
1907 | engines: {node: '>=12'}
1908 | dev: true
1909 |
1910 | /yargs/17.5.1:
1911 | resolution: {integrity: sha512-t6YAJcxDkNX7NFYiVtKvWUz8l+PaKTLiL63mJYWR2GnHq2gjEWISzsLp9wg3aY36dY1j+gfIEL3pIF+XlJJfbA==}
1912 | engines: {node: '>=12'}
1913 | dependencies:
1914 | cliui: 7.0.4
1915 | escalade: 3.1.1
1916 | get-caller-file: 2.0.5
1917 | require-directory: 2.1.1
1918 | string-width: 4.2.3
1919 | y18n: 5.0.8
1920 | yargs-parser: 21.1.1
1921 | dev: true
1922 |
1923 | /zstddec/0.0.2:
1924 | resolution: {integrity: sha512-DCo0oxvcvOTGP/f5FA6tz2Z6wF+FIcEApSTu0zV5sQgn9hoT5lZ9YRAKUraxt9oP7l4e8TnNdi8IZTCX6WCkwA==}
1925 | dev: false
1926 |
1927 | /zustand/3.7.2_react@18.2.0:
1928 | resolution: {integrity: sha512-PIJDIZKtokhof+9+60cpockVOq05sJzHCriyvaLBmEJixseQ1a5Kdov6fWZfWOu5SK9c+FhH1jU0tntLxRJYMA==}
1929 | engines: {node: '>=12.7.0'}
1930 | peerDependencies:
1931 | react: '>=16.8'
1932 | peerDependenciesMeta:
1933 | react:
1934 | optional: true
1935 | dependencies:
1936 | react: 18.2.0
1937 | dev: false
1938 |
1939 | /zustand/4.1.1_immer@9.0.15+react@18.2.0:
1940 | resolution: {integrity: sha512-h4F3WMqsZgvvaE0n3lThx4MM81Ls9xebjvrABNzf5+jb3/03YjNTSgZXeyrvXDArMeV9untvWXRw1tY+ntPYbA==}
1941 | engines: {node: '>=12.7.0'}
1942 | peerDependencies:
1943 | immer: '>=9.0'
1944 | react: '>=16.8'
1945 | peerDependenciesMeta:
1946 | immer:
1947 | optional: true
1948 | react:
1949 | optional: true
1950 | dependencies:
1951 | immer: 9.0.15
1952 | react: 18.2.0
1953 | use-sync-external-store: 1.2.0_react@18.2.0
1954 | dev: false
1955 |
--------------------------------------------------------------------------------
/public/vite.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/screenshot.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jsulpis/3d-terrain-r3f/e3f77989676f56eb16b5411dfb5f2b348c241bab/screenshot.jpg
--------------------------------------------------------------------------------
/src/App.css:
--------------------------------------------------------------------------------
1 | * {
2 | box-sizing: border-box;
3 | margin: 0;
4 | padding: 0;
5 | }
6 |
7 | html,
8 | body,
9 | #root {
10 | width: 100%;
11 | height: 100%;
12 | }
13 |
14 | body {
15 | background: #141414;
16 | font-family: -apple-system, BlinkMacSystemFont, avenir next, avenir, helvetica neue,
17 | helvetica, ubuntu, roboto, noto, segoe ui, arial, sans-serif;
18 | }
19 |
20 | canvas {
21 | cursor: grab;
22 | }
23 |
24 | canvas:active {
25 | cursor: grabbing;
26 | }
27 |
--------------------------------------------------------------------------------
/src/App.tsx:
--------------------------------------------------------------------------------
1 | import { Canvas } from "@react-three/fiber";
2 | import { OrbitControls } from "@react-three/drei";
3 | import "./App.css";
4 | import { Lights } from "./components/Lights";
5 | import { Gizmo } from "./components/Gizmo";
6 | import { GUI } from "./components/GUI";
7 | import { Terrain } from "./components/Terrain";
8 |
9 | export default function App() {
10 | return (
11 | <>
12 |
13 |
29 | >
30 | );
31 | }
32 |
--------------------------------------------------------------------------------
/src/colors/useDisplay.ts:
--------------------------------------------------------------------------------
1 | import { useSettings } from "../state/useSettings";
2 | import { useHeightMap } from "./useHeightMap";
3 | import { useNaturalColor } from "./useNaturalColor";
4 |
5 | export function useDisplay() {
6 | const getNaturalColor = useNaturalColor();
7 | const getHeightMapColor = useHeightMap();
8 | const display = useSettings((s) => s.display);
9 |
10 | return display === "color" ? getNaturalColor : getHeightMapColor;
11 | }
12 |
--------------------------------------------------------------------------------
/src/colors/useHeightMap.ts:
--------------------------------------------------------------------------------
1 | import { Color } from "three";
2 |
3 | export function useHeightMap() {
4 | const floorColor = new Color().setHSL(0.75, 1, 0.5);
5 | const ceilingColor = new Color().setHSL(0, 1, 0.5);
6 | const zmin = 0.05;
7 | const zmax = 0.5;
8 |
9 | return (height: number): Color => {
10 | const percent = (height - zmin) / (zmax - zmin);
11 | return floorColor.clone().lerpHSL(ceilingColor, percent);
12 | };
13 | }
14 |
--------------------------------------------------------------------------------
/src/colors/useNaturalColor.ts:
--------------------------------------------------------------------------------
1 | import { Color, MathUtils } from "three";
2 | import { useSettings } from "../state/useSettings";
3 |
4 | export function useNaturalColor() {
5 | const colors = useSettings((s) => s.colors);
6 |
7 | return (height: number): Color => {
8 | const assetType = (() => {
9 | if (height <= colors.Water.value) {
10 | return "Water";
11 | } else if (height <= colors.Water.value + colors.Shore.value) {
12 | return "Shore";
13 | } else if (height <= colors.Water.value + colors.Beach.value) {
14 | return "Beach";
15 | } else if (height <= colors.Water.value + colors.Shrub.value) {
16 | return "Shrub";
17 | } else if (height <= colors.Water.value + colors.Forest.value) {
18 | return "Forest";
19 | } else if (height <= colors.Water.value + colors.Stone.value) {
20 | return "Stone";
21 | } else {
22 | return "Snow";
23 | }
24 | })();
25 | const color = new Color(colors[assetType].color);
26 | const hsl = color.getHSL({ h: 0, s: 1, l: 1 });
27 |
28 | color.setHSL(
29 | hsl.h,
30 | hsl.s * 1.7,
31 | hsl.l *
32 | (height <= colors.Water.value
33 | ? MathUtils.mapLinear(
34 | Math.pow(1 - (colors.Water.value - height) * 1.3, 6),
35 | 0,
36 | 1,
37 | 0,
38 | 1.4
39 | )
40 | : 1)
41 | );
42 |
43 | return color;
44 | };
45 | }
46 |
--------------------------------------------------------------------------------
/src/components/GUI.tsx:
--------------------------------------------------------------------------------
1 | import { button, Leva, useControls } from "leva";
2 | import { useSettings, Settings } from "../state/useSettings";
3 |
4 | export function GUI() {
5 | const colors = useSettings((s) => s.colors);
6 | const generation = useSettings((s) => s.generation);
7 | const display = useSettings((s) => s.display);
8 | const setColorValue = useSettings((s) => s.setColorValue);
9 | const setColor = useSettings((s) => s.setColor);
10 | const setGeneration = useSettings((s) => s.setGeneration);
11 | const setDisplay = useSettings((s) => s.setDisplay);
12 |
13 | useControls("Colors", () => {
14 | const res = {} as any;
15 | Object.keys(colors).forEach((color) => {
16 | res[color] = {
17 | value: colors[color].value,
18 | min: 0,
19 | max: 1,
20 | onChange: (v: number) => setColorValue(color, v)
21 | };
22 |
23 | res[color] = {
24 | value: colors[color].color,
25 | onChange: (v: string) => setColor(color, v)
26 | };
27 | });
28 |
29 | return res;
30 | });
31 |
32 | useControls("Display", () => ({
33 | HeightMap: {
34 | value: display === "height",
35 | onChange: (v: boolean) => setDisplay(v ? "height" : "color")
36 | }
37 | }));
38 |
39 | const [_, set] = useControls("Generation", () => {
40 | const res = {} as any;
41 | (Object.keys(generation) as Array).forEach((param) => {
42 | res[param] = {
43 | value: generation[param],
44 | min: 0.01,
45 | max: 1,
46 | onChange: (v: number) => setGeneration(param, v)
47 | };
48 | });
49 | res["Sea Level"] = {
50 | value: colors.Water.value,
51 | min: 0,
52 | max: 1,
53 | onChange: (v: number) => setColorValue("Water", v / 2)
54 | };
55 |
56 | return res;
57 | });
58 |
59 | useControls({
60 | Regenerate: button(() => set({ Seed: Math.random() }))
61 | });
62 |
63 | return ;
64 | }
65 |
--------------------------------------------------------------------------------
/src/components/Gizmo.tsx:
--------------------------------------------------------------------------------
1 | import { GizmoHelper, GizmoViewport } from "@react-three/drei";
2 |
3 | export const Gizmo = () => {
4 | return (
5 | {}}>
6 |
11 |
12 | );
13 | };
14 |
--------------------------------------------------------------------------------
/src/components/Lights.tsx:
--------------------------------------------------------------------------------
1 | import { useRef } from "react";
2 | import { useHelper } from "@react-three/drei";
3 | import { DirectionalLight, DirectionalLightHelper } from "three";
4 |
5 | export function Lights() {
6 | const ref = useRef(null);
7 |
8 | // useHelper(ref, DirectionalLightHelper);
9 |
10 | return (
11 |
12 |
13 |
21 |
22 |
23 | );
24 | }
25 |
--------------------------------------------------------------------------------
/src/components/Terrain.tsx:
--------------------------------------------------------------------------------
1 | import { useEffect, useRef } from "react";
2 | import { Object3D, InstancedMesh } from "three";
3 | import { useProceduralTerrain } from "../geometry/useProceduralTerrain";
4 | import { TerrainStats } from "./TerrainStats";
5 | import { useDisplay } from "../colors/useDisplay";
6 |
7 | const emptyObject = new Object3D();
8 |
9 | export function Terrain() {
10 | const ref = useRef(null);
11 |
12 | const { dataBlocks, scale } = useProceduralTerrain();
13 | const getColor = useDisplay();
14 |
15 | useEffect(() => {
16 | const mesh = ref.current;
17 | if (!mesh) return;
18 |
19 | dataBlocks.forEach(({ x, y, z, height }, i) => {
20 | const color = getColor(height);
21 |
22 | emptyObject.position.set(x, y, z);
23 | emptyObject.updateMatrix();
24 |
25 | mesh.setMatrixAt?.(i, emptyObject.matrix);
26 | mesh.setColorAt?.(i, color);
27 | });
28 |
29 | mesh.instanceMatrix.needsUpdate = true;
30 | mesh.instanceColor!.needsUpdate = true;
31 | }, [dataBlocks, getColor]);
32 |
33 | return (
34 | <>
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 | >
44 | );
45 | }
46 |
--------------------------------------------------------------------------------
/src/components/TerrainStats.tsx:
--------------------------------------------------------------------------------
1 | import { Html } from "@react-three/drei";
2 | import type { FC } from "react";
3 |
4 | const numberFormatter = new Intl.NumberFormat();
5 |
6 | export const TerrainStats: FC<{ blockCount: number }> = ({ blockCount }) => (
7 | [40, 40, 0]} style={{ color: "white" }}>
8 | {numberFormatter.format(blockCount)}
9 | blocks
10 |
11 |
12 | ({Math.sqrt(blockCount)}x{Math.sqrt(blockCount)})
13 |
14 |
15 | );
16 |
--------------------------------------------------------------------------------
/src/geometry/useFbmNoise.ts:
--------------------------------------------------------------------------------
1 | import { useCallback, useMemo } from "react";
2 | import { MathUtils, Vector2 } from "three";
3 | import { FBM } from "../lib/three-noise.module";
4 | import { useSettings } from "../state/useSettings";
5 |
6 | export function useFbmNoise() {
7 | const generation = useSettings((s) => s.generation);
8 |
9 | const fbm = useMemo(
10 | () =>
11 | new FBM({
12 | seed: generation.Seed,
13 | lacunarity: generation.Detail * 4,
14 | persistance: generation.Fuzzyness * 2
15 | }),
16 | [generation]
17 | );
18 |
19 | return useCallback(
20 | (vector: Vector2) =>
21 | Math.pow(
22 | MathUtils.mapLinear(
23 | fbm.get2(vector),
24 | -1, //
25 | 1,
26 | 0,
27 | 1
28 | ),
29 | 2
30 | ),
31 | [fbm]
32 | );
33 | }
34 |
--------------------------------------------------------------------------------
/src/geometry/useProceduralTerrain.ts:
--------------------------------------------------------------------------------
1 | import { useMemo } from "react";
2 | import { useSettings } from "../state/useSettings";
3 | import { useFbmNoise } from "./useFbmNoise";
4 | import { useSquareSurface } from "./useSquareSurface";
5 |
6 | /**
7 | * Generate a square procedural terrain using a noise function for the relief
8 | */
9 | export function useProceduralTerrain() {
10 | const { surface, scale } = useSquareSurface();
11 |
12 | const waterLevel = useSettings((s) => s.colors.Water.value);
13 | const generationScale = useSettings((s) => s.generation.Scale);
14 | const generationHeight = useSettings((s) => s.generation.Height);
15 | const display = useSettings((s) => s.display);
16 |
17 | const getNoiseValue = useFbmNoise();
18 |
19 | const dataBlocks = useMemo(
20 | () =>
21 | surface.map((point) => {
22 | const scaledVector = point.clone().multiplyScalar(scale * generationScale);
23 | const realHeight = getNoiseValue(scaledVector) * generationHeight;
24 | let visibleHeight = realHeight;
25 |
26 | if (display === "color" && realHeight < waterLevel) {
27 | visibleHeight = waterLevel;
28 | }
29 |
30 | return {
31 | x: point.x,
32 | y: point.y,
33 | z: (visibleHeight / scale) * 3,
34 | height: realHeight
35 | };
36 | }),
37 | [
38 | surface,
39 | scale,
40 | generationScale,
41 | generationHeight,
42 | waterLevel,
43 | getNoiseValue,
44 | display
45 | ]
46 | );
47 |
48 | return { dataBlocks, scale };
49 | }
50 |
--------------------------------------------------------------------------------
/src/geometry/useSquareSurface.ts:
--------------------------------------------------------------------------------
1 | import { useMemo } from "react";
2 | import { Vector2 } from "three";
3 | import { useSettings } from "../state/useSettings";
4 |
5 | const INTRINSIC_TERRAIN_MAX_SIZE = 500;
6 | const VISIBLE_MAP_SIZE = 8;
7 |
8 | export function useSquareSurface() {
9 | const resolution = useSettings((s) => s.generation.Resolution);
10 | const terrainSize = Math.max(INTRINSIC_TERRAIN_MAX_SIZE * resolution, 20);
11 |
12 | return useMemo(() => {
13 | const surface = [];
14 | const scale = VISIBLE_MAP_SIZE / terrainSize;
15 |
16 | for (let x = -terrainSize / 2; x < terrainSize / 2; x++) {
17 | for (let y = -terrainSize / 2; y < terrainSize / 2; y++) {
18 | surface.push(new Vector2(x, y));
19 | }
20 | }
21 | return { surface, scale };
22 | }, [terrainSize]);
23 | }
24 |
--------------------------------------------------------------------------------
/src/lib/three-noise.module.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * This file has been borrowed from the 'three-noise' package by Faraz Shaikh (@CantBeFaraz):
3 | * https://github.com/FarazzShaikh/three-noise/blob/master/build/three-noise.module.js
4 | *
5 | * because at the time of writing there are a couple of issues with said package:
6 | * https://github.com/FarazzShaikh/three-noise/issues
7 | */
8 | // @ts-nocheck
9 |
10 | import { Vector2, Vector3 } from "three";
11 |
12 | var definitions_perlin =
13 | '#define GLSLIFY 1\n// From https://github.com/hughsk/glsl-noise/blob/master/periodic/2d.glsl\n\n//\n// GLSL textureless classic 2D noise "cnoise",\n// with an RSL-style periodic variant "pnoise".\n// Author: Stefan Gustavson (stefan.gustavson@liu.se)\n// Version: 2011-08-22\n//\n// Many thanks to Ian McEwan of Ashima Arts for the\n// ideas for permutation and gradient selection.\n//\n// Copyright (c) 2011 Stefan Gustavson. All rights reserved.\n// Distributed under the MIT license. See LICENSE file.\n// https://github.com/ashima/webgl-noise\n//\n\nvec4 mod289(vec4 x) { return x - floor(x * (1.0 / 289.0)) * 289.0; }\n\nvec4 permute(vec4 x) { return mod289(((x * 34.0) + 1.0) * x); }\n\nvec4 taylorInvSqrt(vec4 r) { return 1.79284291400159 - 0.85373472095314 * r; }\n\nvec2 fade(vec2 t) { return t * t * t * (t * (t * 6.0 - 15.0) + 10.0); }\n\nfloat map(float value, float min1, float max1, float min2, float max2) {\n return min2 + (value - min1) * (max2 - min2) / (max1 - min1);\n}\n\n// Classic Perlin noise, periodic variant\nfloat perlin(vec2 P) {\n\n vec2 rep = vec2(255.0, 255.0);\n\n vec4 Pi = floor(P.xyxy) + vec4(0.0, 0.0, 1.0, 1.0);\n vec4 Pf = fract(P.xyxy) - vec4(0.0, 0.0, 1.0, 1.0);\n Pi = mod(Pi, rep.xyxy); // To create noise with explicit period\n Pi = mod289(Pi); // To avoid truncation effects in permutation\n vec4 ix = Pi.xzxz;\n vec4 iy = Pi.yyww;\n vec4 fx = Pf.xzxz;\n vec4 fy = Pf.yyww;\n\n vec4 i = permute(permute(ix) + iy);\n\n vec4 gx = fract(i * (1.0 / 41.0)) * 2.0 - 1.0;\n vec4 gy = abs(gx) - 0.5;\n vec4 tx = floor(gx + 0.5);\n gx = gx - tx;\n\n vec2 g00 = vec2(gx.x, gy.x);\n vec2 g10 = vec2(gx.y, gy.y);\n vec2 g01 = vec2(gx.z, gy.z);\n vec2 g11 = vec2(gx.w, gy.w);\n\n vec4 norm = taylorInvSqrt(\n vec4(dot(g00, g00), dot(g01, g01), dot(g10, g10), dot(g11, g11)));\n g00 *= norm.x;\n g01 *= norm.y;\n g10 *= norm.z;\n g11 *= norm.w;\n\n float n00 = dot(g00, vec2(fx.x, fy.x));\n float n10 = dot(g10, vec2(fx.y, fy.y));\n float n01 = dot(g01, vec2(fx.z, fy.z));\n float n11 = dot(g11, vec2(fx.w, fy.w));\n\n vec2 fade_xy = fade(Pf.xy);\n vec2 n_x = mix(vec2(n00, n01), vec2(n10, n11), fade_xy.x);\n float n_xy = mix(n_x.x, n_x.y, fade_xy.y);\n return map(2.3 * n_xy, -1.0, 1.0, 0.0, 1.0);\n}\n\nfloat fbm(vec2 pos, vec4 props) {\n float persistance = props.x;\n float lacunarity = props.y;\n float redistribution = props.z;\n int octaves = int(props.w);\n\n float result = 0.0;\n float amplitude = 1.0;\n float frequency = 1.0;\n float maximum = amplitude;\n\n for (int i = 0; i < 2; i++) {\n\n vec2 p = pos.xy * frequency;\n\n float noiseVal = perlin(p);\n result += noiseVal * amplitude;\n\n frequency *= lacunarity;\n amplitude *= persistance;\n maximum += amplitude;\n }\n\n float redistributed = pow(result, redistribution);\n return redistributed / maximum;\n}\n'; // eslint-disable-line
14 |
15 | var p = [
16 | 151, 160, 137, 91, 90, 15, 131, 13, 201, 95, 96, 53, 194, 233, 7, 225, 140, 36, 103, 30,
17 | 69, 142, 8, 99, 37, 240, 21, 10, 23, 190, 6, 148, 247, 120, 234, 75, 0, 26, 197, 62, 94,
18 | 252, 219, 203, 117, 35, 11, 32, 57, 177, 33, 88, 237, 149, 56, 87, 174, 20, 125, 136,
19 | 171, 168, 68, 175, 74, 165, 71, 134, 139, 48, 27, 166, 77, 146, 158, 231, 83, 111, 229,
20 | 122, 60, 211, 133, 230, 220, 105, 92, 41, 55, 46, 245, 40, 244, 102, 143, 54, 65, 25,
21 | 63, 161, 1, 216, 80, 73, 209, 76, 132, 187, 208, 89, 18, 169, 200, 196, 135, 130, 116,
22 | 188, 159, 86, 164, 100, 109, 198, 173, 186, 3, 64, 52, 217, 226, 250, 124, 123, 5, 202,
23 | 38, 147, 118, 126, 255, 82, 85, 212, 207, 206, 59, 227, 47, 16, 58, 17, 182, 189, 28,
24 | 42, 223, 183, 170, 213, 119, 248, 152, 2, 44, 154, 163, 70, 221, 153, 101, 155, 167, 43,
25 | 172, 9, 129, 22, 39, 253, 19, 98, 108, 110, 79, 113, 224, 232, 178, 185, 112, 104, 218,
26 | 246, 97, 228, 251, 34, 242, 193, 238, 210, 144, 12, 191, 179, 162, 241, 81, 51, 145,
27 | 235, 249, 14, 239, 107, 49, 192, 214, 31, 181, 199, 106, 157, 184, 84, 204, 176, 115,
28 | 121, 50, 45, 127, 4, 150, 254, 138, 236, 205, 93, 222, 114, 67, 29, 24, 72, 243, 141,
29 | 128, 195, 78, 66, 215, 61, 156, 180
30 | ];
31 |
32 | /**
33 | * An implimentation of Perlin Noise by Ken Perlin.
34 | */
35 | class Perlin {
36 | /**
37 | *
38 | * @param {number} seed Seed Value for PRNG.
39 | */
40 | constructor(seed) {
41 | const _gradientVecs = [
42 | // 2D Vecs
43 | new Vector3(1, 1, 0),
44 | new Vector3(-1, 1, 0),
45 | new Vector3(1, -1, 0),
46 | new Vector3(-1, -1, 0),
47 | // + 3D Vecs
48 | new Vector3(1, 0, 1),
49 | new Vector3(-1, 0, 1),
50 | new Vector3(1, 0, -1),
51 | new Vector3(-1, 0, -1),
52 | new Vector3(0, 1, 1),
53 | new Vector3(0, -1, 1),
54 | new Vector3(0, 1, -1),
55 | new Vector3(0, -1, -1)
56 | ];
57 |
58 | var perm = new Array(512);
59 | var gradP = new Array(512);
60 |
61 | if (!seed) seed = 1;
62 | seed *= 65536;
63 |
64 | seed = Math.floor(seed);
65 | if (seed < 256) {
66 | seed |= seed << 8;
67 | }
68 |
69 | for (var i = 0; i < 256; i++) {
70 | var v;
71 | if (i & 1) {
72 | v = p[i] ^ (seed & 255);
73 | } else {
74 | v = p[i] ^ ((seed >> 8) & 255);
75 | }
76 |
77 | perm[i] = perm[i + 256] = v;
78 | gradP[i] = gradP[i + 256] = _gradientVecs[v % 12];
79 | }
80 |
81 | this._seed = seed;
82 |
83 | this._offsetMatrix = [
84 | new Vector3(0, 0, 0),
85 | new Vector3(0, 0, 1),
86 | new Vector3(0, 1, 0),
87 | new Vector3(0, 1, 1),
88 | new Vector3(1, 0, 0),
89 | new Vector3(1, 0, 1),
90 | new Vector3(1, 1, 0),
91 | new Vector3(1, 1, 1)
92 | ];
93 |
94 | /**
95 | * GLSL Shader Chunk for 2D Perlin Noise. Can be used with
96 | * three-CustomShaderMaterial.
97 | * See: three-CustomShaderMaterial
98 | */
99 | this.shaderChunk = {
100 | defines: "",
101 | header: definitions_perlin,
102 | main: "",
103 | uniforms: [{ three_noise_seed: this._seed }]
104 | };
105 |
106 | this.perm = perm;
107 | this.gradP = gradP;
108 | }
109 |
110 | _fade(t) {
111 | return t * t * t * (t * (t * 6 - 15) + 10);
112 | }
113 |
114 | _lerp(a, b, t) {
115 | return (1 - t) * a + t * b;
116 | }
117 |
118 | _gradient(posInCell) {
119 | if (posInCell instanceof Vector3) {
120 | return posInCell.x + this.perm[posInCell.y + this.perm[posInCell.z]];
121 | } else {
122 | return posInCell.x + this.perm[posInCell.y];
123 | }
124 | }
125 |
126 | /**
127 | * Maps a number from one range to another.
128 | * @param {number} x Input Number
129 | * @param {number} in_min Current range minimum
130 | * @param {number} in_max Current range maximum
131 | * @param {number} out_min New range minimum
132 | * @param {number} out_max New range maximum
133 | * @returns {number} Input Mapped to range [out_min, out_max]
134 | */
135 | static map(x, in_min, in_max, out_min, out_max) {
136 | return ((x - in_min) * (out_max - out_min)) / (in_max - in_min) + out_min;
137 | }
138 |
139 | /**
140 | * Samples 2D Perlin Nosie at given coordinates.
141 | * @param {Vector2 | Vector3} input Coordincates to sample at
142 | * @returns {number} Value of Perlin Noise at that coordinate.
143 | */
144 | get2(input) {
145 | if (input.z !== undefined) input = new Vector2(input.x, input.y);
146 |
147 | const cell = new Vector2(Math.floor(input.x), Math.floor(input.y));
148 | input.sub(cell);
149 |
150 | cell.x &= 255;
151 | cell.y &= 255;
152 |
153 | const gradiantDot = [];
154 | for (let i = 0; i < 4; i++) {
155 | const s3 = this._offsetMatrix[i * 2];
156 | const s = new Vector2(s3.x, s3.y);
157 |
158 | const grad3 = this.gradP[this._gradient(new Vector2().addVectors(cell, s))];
159 | const grad2 = new Vector2(grad3.x, grad3.y);
160 | const dist2 = new Vector2().subVectors(input, s);
161 |
162 | gradiantDot.push(grad2.dot(dist2));
163 | }
164 |
165 | const u = this._fade(input.x);
166 | const v = this._fade(input.y);
167 |
168 | const value = this._lerp(
169 | this._lerp(gradiantDot[0], gradiantDot[2], u),
170 | this._lerp(gradiantDot[1], gradiantDot[3], u),
171 | v
172 | );
173 |
174 | return value;
175 | }
176 |
177 | /**
178 | * Samples 3D Perlin Nosie at given coordinates.
179 | * @param {Vector}3 input Coordincates to sample at
180 | * @returns {number} Value of Perlin Noise at that coordinate.
181 | */
182 | get3(input) {
183 | if (input.z === undefined) throw "Input to Perlin::get3() must be of type Vector3";
184 |
185 | const cell = new Vector3(
186 | Math.floor(input.x),
187 | Math.floor(input.y),
188 | Math.floor(input.z)
189 | );
190 | input.sub(cell);
191 |
192 | cell.x &= 255;
193 | cell.y &= 255;
194 | cell.z &= 255;
195 |
196 | const gradiantDot = [];
197 | for (let i = 0; i < 8; i++) {
198 | const s = this._offsetMatrix[i];
199 |
200 | const grad3 = this.gradP[this._gradient(new Vector3().addVectors(cell, s))];
201 | const dist2 = new Vector3().subVectors(input, s);
202 |
203 | gradiantDot.push(grad3.dot(dist2));
204 | }
205 |
206 | const u = this._fade(input.x);
207 | const v = this._fade(input.y);
208 | const w = this._fade(input.z);
209 |
210 | const value = this._lerp(
211 | this._lerp(
212 | this._lerp(gradiantDot[0], gradiantDot[4], u),
213 | this._lerp(gradiantDot[1], gradiantDot[5], u),
214 | w
215 | ),
216 | this._lerp(
217 | this._lerp(gradiantDot[2], gradiantDot[6], u),
218 | this._lerp(gradiantDot[3], gradiantDot[7], u),
219 | w
220 | ),
221 | v
222 | );
223 |
224 | return value;
225 | }
226 | }
227 |
228 | /**
229 | * This class is an implimentaiton of a Fractal Brownian Motion
230 | * function using Perlin Nosie.
231 | */
232 | class FBM {
233 | /**
234 | * Create an instance of the FBM class.
235 | * Use this instance to generate fBm noise.
236 | *
237 | * @param {Object} options Options for fBm generaiton.
238 | * @param {number} options.seed Seed for Perlin Noise
239 | * @param {number} options.scale What distance to view the noisemap
240 | * @param {number} options.persistance How much each octave contributes to the overall shape
241 | * @param {number} options.lacunarity How much detail is added or removed at each octave
242 | * @param {number} options.octaves Levels of detail you want you perlin noise to have
243 | * @param {number} options.redistribution Level of flatness within the valleys
244 | */
245 | constructor(options) {
246 | const { seed, scale, persistance, lacunarity, octaves, redistribution } = options;
247 | this._noise = new Perlin(seed);
248 | this._scale = scale || 1;
249 | this._persistance = persistance || 0.5;
250 | this._lacunarity = lacunarity || 2;
251 | this._octaves = octaves || 6;
252 | this._redistribution = redistribution || 1;
253 | }
254 |
255 | /**
256 | * Sample 2D Perlin Noise with fBm at given
257 | * coordinates. The function will use Perlin_get2
or Perlin_get3
258 | * depending on the input vector's type.
259 | *
260 | * @param {(Vector2 | Vector3)} input Coordinates to sample noise at.
261 | * @returns {number} Normalized noise in the range [0, 1]
262 | */
263 | get2(input) {
264 | let result = 0;
265 | let amplitude = 1;
266 | let frequency = 1;
267 | let max = amplitude;
268 |
269 | let noiseFunction = this._noise.get2.bind(this._noise);
270 |
271 | for (let i = 0; i < this._octaves; i++) {
272 | const position = new Vector2(
273 | input.x * this._scale * frequency,
274 | input.y * this._scale * frequency
275 | );
276 |
277 | const noiseVal = noiseFunction(position);
278 | result += noiseVal * amplitude;
279 |
280 | frequency *= this._lacunarity;
281 | amplitude *= this._persistance;
282 | max += amplitude;
283 | }
284 |
285 | const redistributed = Math.pow(result, this._redistribution);
286 | return redistributed / max;
287 | }
288 |
289 | /**
290 | * Sample 3D Perlin Noise with fBm at given
291 | * coordinates. The function will use Perlin_get2
or Perlin_get3
292 | * depending on the input vector's type.
293 | *
294 | * @param {Vector3} input Coordinates to sample noise at.
295 | * @returns {number} Normalized noise in the range [0, 1]
296 | */
297 | get3(input) {
298 | let result = 0;
299 | let amplitude = 1;
300 | let frequency = 1;
301 | let max = amplitude;
302 |
303 | let noiseFunction = this._noise.get3.bind(this._noise);
304 |
305 | for (let i = 0; i < this._octaves; i++) {
306 | const position = new Vector3(
307 | input.x * this._scale * frequency,
308 | input.y * this._scale * frequency,
309 | input.z * this._scale * frequency
310 | );
311 |
312 | const noiseVal = noiseFunction(position);
313 | result += noiseVal * amplitude;
314 |
315 | frequency *= this._lacunarity;
316 | amplitude *= this._persistance;
317 | max += amplitude;
318 | }
319 |
320 | const redistributed = Math.pow(result, this._redistribution);
321 | return redistributed / max;
322 | }
323 | }
324 |
325 | export { FBM, Perlin };
326 |
--------------------------------------------------------------------------------
/src/main.tsx:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import ReactDOM from "react-dom/client";
3 | import App from "./App";
4 |
5 | ReactDOM.createRoot(document.getElementById("root") as HTMLElement).render(
6 |
7 |
8 |
9 | );
10 |
--------------------------------------------------------------------------------
/src/state/useSettings.ts:
--------------------------------------------------------------------------------
1 | import create from "zustand";
2 | import { immer } from "zustand/middleware/immer";
3 |
4 | export type SettingsState = {
5 | colors: {
6 | [key: string]: {
7 | value: number;
8 | color: string;
9 | };
10 | };
11 | display: "color" | "height";
12 | generation: {
13 | Seed: number;
14 | Height: number;
15 | Scale: number;
16 | Detail: number;
17 | Fuzzyness: number;
18 | Resolution: number;
19 | };
20 | };
21 |
22 | export type SettingsActions = {
23 | setColorValue: (key: string, value: number) => void;
24 | setColor: (key: string, color: string) => void;
25 | setDisplay: (value: SettingsState["display"]) => void;
26 | setGeneration: (key: keyof SettingsState["generation"], value: number) => void;
27 | };
28 |
29 | export type Settings = SettingsState & SettingsActions;
30 |
31 | const initialState: SettingsState = {
32 | colors: {
33 | Snow: {
34 | value: 0.6,
35 | color: "#9aa7ad"
36 | },
37 | Stone: {
38 | value: 0.36,
39 | color: "#656565"
40 | },
41 | Forest: {
42 | value: 0.29,
43 | color: "#586647"
44 | },
45 | Shrub: {
46 | value: 0.1,
47 | color: "#9ea667"
48 | },
49 | Beach: {
50 | value: 0.04,
51 | color: "#efb28f"
52 | },
53 | Shore: {
54 | value: 0.01,
55 | color: "#ffd68f"
56 | },
57 | Water: {
58 | value: 0.42,
59 | color: "#00a9ff"
60 | }
61 | },
62 | display: "color",
63 | generation: {
64 | Seed: Math.random(),
65 | Height: 1,
66 | Scale: 0.3,
67 | Detail: 0.5,
68 | Fuzzyness: 0.2,
69 | Resolution: 0.3
70 | }
71 | };
72 |
73 | export const useSettings = create(
74 | immer((set) => ({
75 | ...initialState,
76 | setColorValue: (key, value) =>
77 | set((state) => {
78 | state.colors[key].value = value;
79 | }),
80 | setColor: (key, color) =>
81 | set((state) => {
82 | state.colors[key].color = color;
83 | }),
84 | setDisplay: (value) =>
85 | set((state) => {
86 | state.display = value;
87 | }),
88 | setGeneration: (key, value) =>
89 | set((state) => {
90 | state.generation[key] = value;
91 | })
92 | }))
93 | );
94 |
--------------------------------------------------------------------------------
/src/vite-env.d.ts:
--------------------------------------------------------------------------------
1 | ///
2 |
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "ESNext",
4 | "useDefineForClassFields": true,
5 | "lib": ["DOM", "DOM.Iterable", "ESNext"],
6 | "allowJs": false,
7 | "skipLibCheck": true,
8 | "esModuleInterop": false,
9 | "allowSyntheticDefaultImports": true,
10 | "strict": true,
11 | "forceConsistentCasingInFileNames": true,
12 | "module": "ESNext",
13 | "moduleResolution": "Node",
14 | "resolveJsonModule": true,
15 | "isolatedModules": true,
16 | "noEmit": true,
17 | "jsx": "react-jsx"
18 | },
19 | "include": ["src"],
20 | "references": [{ "path": "./tsconfig.node.json" }]
21 | }
22 |
--------------------------------------------------------------------------------
/tsconfig.node.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "composite": true,
4 | "module": "ESNext",
5 | "moduleResolution": "Node",
6 | "allowSyntheticDefaultImports": true
7 | },
8 | "include": ["vite.config.ts"]
9 | }
10 |
--------------------------------------------------------------------------------
/vite.config.ts:
--------------------------------------------------------------------------------
1 | import { defineConfig } from "vite";
2 | import react from "@vitejs/plugin-react";
3 | import { visualizer } from "rollup-plugin-visualizer";
4 |
5 | // https://vitejs.dev/config/
6 | export default defineConfig({
7 | plugins: [react(), visualizer()]
8 | });
9 |
--------------------------------------------------------------------------------