Integrate browser geolocation API (#9)

* Add GPS service and nautical base city data

- Implement `GpsService` with methods for position updates and enabling/disabling GPS.
- Introduce test data for nautical base cities with key attributes like population, coordinates, and images.
- Update dependencies in `bun.lock` with required packages such as `geojson`.

* give map a custom style

* shift towards rust exclusivity

* `build.rs` streamlines map build. Added an axum server with the map assets embedded.

* update readmes

* base-map api retrieves geolocation from the navigator of the browser

* make map standalone wry that pulls assets from the server to simulate behavior in bevy

* wip wasm

* wasm build fixed

* fix path ref to assets

---------

Co-authored-by: geoffsee <>
This commit is contained in:
Geoff Seemueller
2025-07-16 17:44:25 -04:00
committed by GitHub
parent 4b3dd2a1c3
commit 602bc5d4b8
49 changed files with 7748 additions and 1279 deletions

589
Cargo.lock generated

File diff suppressed because it is too large Load Diff

View File

@@ -1,5 +1,5 @@
[workspace]
members = ["crates/yachtpit", "crates/yachtpit/mobile", "crates/systems", "crates/components", "crates/datalink", "crates/datalink-provider"]
members = ["crates/yachtpit", "crates/yachtpit/mobile", "crates/systems", "crates/components", "crates/datalink", "crates/datalink-provider", "crates/base-map"]
resolver = "2"
default-members = [
@@ -8,4 +8,4 @@ default-members = [
[workspace.dependencies]
bevy = { version = "0.16", default-features = false }
wasm-bindgen = "=0.2.100"
wasm-bindgen = "=0.2.100"

874
bun.lock
View File

@@ -1,874 +0,0 @@
{
"lockfileVersion": 1,
"workspaces": {
"": {
"name": "yachtpit",
"devDependencies": {
"@types/bun": "latest",
},
"peerDependencies": {
"typescript": "^5",
},
},
"packages/base-map": {
"name": "base-map",
"version": "0.0.0",
"dependencies": {
"next-themes": "^0.4.6",
"react": "^19.1.0",
"react-dom": "^19.1.0",
"react-icons": "^5.5.0",
},
"devDependencies": {
"@chakra-ui/react": "^3.21.1",
"@emotion/react": "^11.14.0",
"@eslint/js": "^9.29.0",
"@types/js-cookie": "^3.0.6",
"@types/react": "^19.1.8",
"@types/react-dom": "^19.1.6",
"@vitejs/plugin-react-swc": "^3.10.2",
"bevy_flurx_api": "^0.1.0",
"eslint": "^9.29.0",
"eslint-plugin-react-hooks": "^5.2.0",
"eslint-plugin-react-refresh": "^0.4.20",
"globals": "^16.2.0",
"js-cookie": "^3.0.5",
"mapbox-gl": "^3.13.0",
"react-map-gl": "^8.0.4",
"typescript": "~5.8.3",
"typescript-eslint": "^8.34.1",
"vite": "^7.0.0",
"vite-tsconfig-paths": "^5.1.4",
},
},
},
"packages": {
"@ark-ui/react": ["@ark-ui/react@5.15.4", "", { "dependencies": { "@internationalized/date": "3.8.2", "@zag-js/accordion": "1.17.4", "@zag-js/anatomy": "1.17.4", "@zag-js/angle-slider": "1.17.4", "@zag-js/auto-resize": "1.17.4", "@zag-js/avatar": "1.17.4", "@zag-js/carousel": "1.17.4", "@zag-js/checkbox": "1.17.4", "@zag-js/clipboard": "1.17.4", "@zag-js/collapsible": "1.17.4", "@zag-js/collection": "1.17.4", "@zag-js/color-picker": "1.17.4", "@zag-js/color-utils": "1.17.4", "@zag-js/combobox": "1.17.4", "@zag-js/core": "1.17.4", "@zag-js/date-picker": "1.17.4", "@zag-js/date-utils": "1.17.4", "@zag-js/dialog": "1.17.4", "@zag-js/dom-query": "1.17.4", "@zag-js/editable": "1.17.4", "@zag-js/file-upload": "1.17.4", "@zag-js/file-utils": "1.17.4", "@zag-js/floating-panel": "1.17.4", "@zag-js/focus-trap": "1.17.4", "@zag-js/highlight-word": "1.17.4", "@zag-js/hover-card": "1.17.4", "@zag-js/i18n-utils": "1.17.4", "@zag-js/listbox": "1.17.4", "@zag-js/menu": "1.17.4", "@zag-js/number-input": "1.17.4", "@zag-js/pagination": "1.17.4", "@zag-js/password-input": "1.17.4", "@zag-js/pin-input": "1.17.4", "@zag-js/popover": "1.17.4", "@zag-js/presence": "1.17.4", "@zag-js/progress": "1.17.4", "@zag-js/qr-code": "1.17.4", "@zag-js/radio-group": "1.17.4", "@zag-js/rating-group": "1.17.4", "@zag-js/react": "1.17.4", "@zag-js/select": "1.17.4", "@zag-js/signature-pad": "1.17.4", "@zag-js/slider": "1.17.4", "@zag-js/splitter": "1.17.4", "@zag-js/steps": "1.17.4", "@zag-js/switch": "1.17.4", "@zag-js/tabs": "1.17.4", "@zag-js/tags-input": "1.17.4", "@zag-js/time-picker": "1.17.4", "@zag-js/timer": "1.17.4", "@zag-js/toast": "1.17.4", "@zag-js/toggle": "1.17.4", "@zag-js/toggle-group": "1.17.4", "@zag-js/tooltip": "1.17.4", "@zag-js/tour": "1.17.4", "@zag-js/tree-view": "1.17.4", "@zag-js/types": "1.17.4", "@zag-js/utils": "1.17.4" }, "peerDependencies": { "react": ">=18.0.0", "react-dom": ">=18.0.0" } }, "sha512-+xBKqxmt0JHewOsYsHXtedcdPsPZirAwd9y80JpyYfp8bSpIhmombLTjh0Ue9ktKPr7LdoZhV7qcX1TNrX4grg=="],
"@babel/code-frame": ["@babel/code-frame@7.27.1", "", { "dependencies": { "@babel/helper-validator-identifier": "^7.27.1", "js-tokens": "^4.0.0", "picocolors": "^1.1.1" } }, "sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg=="],
"@babel/generator": ["@babel/generator@7.28.0", "", { "dependencies": { "@babel/parser": "^7.28.0", "@babel/types": "^7.28.0", "@jridgewell/gen-mapping": "^0.3.12", "@jridgewell/trace-mapping": "^0.3.28", "jsesc": "^3.0.2" } }, "sha512-lJjzvrbEeWrhB4P3QBsH7tey117PjLZnDbLiQEKjQ/fNJTjuq4HSqgFA+UNSwZT8D7dxxbnuSBMsa1lrWzKlQg=="],
"@babel/helper-globals": ["@babel/helper-globals@7.28.0", "", {}, "sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw=="],
"@babel/helper-module-imports": ["@babel/helper-module-imports@7.27.1", "", { "dependencies": { "@babel/traverse": "^7.27.1", "@babel/types": "^7.27.1" } }, "sha512-0gSFWUPNXNopqtIPQvlD5WgXYI5GY2kP2cCvoT8kczjbfcfuIljTbcWrulD1CIPIX2gt1wghbDy08yE1p+/r3w=="],
"@babel/helper-string-parser": ["@babel/helper-string-parser@7.27.1", "", {}, "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA=="],
"@babel/helper-validator-identifier": ["@babel/helper-validator-identifier@7.27.1", "", {}, "sha512-D2hP9eA+Sqx1kBZgzxZh0y1trbuU+JoDkiEwqhQ36nodYqJwyEIhPSdMNd7lOm/4io72luTPWH20Yda0xOuUow=="],
"@babel/parser": ["@babel/parser@7.28.0", "", { "dependencies": { "@babel/types": "^7.28.0" }, "bin": "./bin/babel-parser.js" }, "sha512-jVZGvOxOuNSsuQuLRTh13nU0AogFlw32w/MT+LV6D3sP5WdbW61E77RnkbaO2dUvmPAYrBDJXGn5gGS6tH4j8g=="],
"@babel/runtime": ["@babel/runtime@7.27.6", "", {}, "sha512-vbavdySgbTTrmFE+EsiqUTzlOr5bzlnJtUv9PynGCAKvfQqjIXbvFdumPM/GxMDfyuGMJaJAU6TO4zc1Jf1i8Q=="],
"@babel/template": ["@babel/template@7.27.2", "", { "dependencies": { "@babel/code-frame": "^7.27.1", "@babel/parser": "^7.27.2", "@babel/types": "^7.27.1" } }, "sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw=="],
"@babel/traverse": ["@babel/traverse@7.28.0", "", { "dependencies": { "@babel/code-frame": "^7.27.1", "@babel/generator": "^7.28.0", "@babel/helper-globals": "^7.28.0", "@babel/parser": "^7.28.0", "@babel/template": "^7.27.2", "@babel/types": "^7.28.0", "debug": "^4.3.1" } }, "sha512-mGe7UK5wWyh0bKRfupsUchrQGqvDbZDbKJw+kcRGSmdHVYrv+ltd0pnpDTVpiTqnaBru9iEvA8pz8W46v0Amwg=="],
"@babel/types": ["@babel/types@7.28.0", "", { "dependencies": { "@babel/helper-string-parser": "^7.27.1", "@babel/helper-validator-identifier": "^7.27.1" } }, "sha512-jYnje+JyZG5YThjHiF28oT4SIZLnYOcSBb6+SDaFIyzDVSkXQmQQYclJ2R+YxcdmK0AX6x1E5OQNtuh3jHDrUg=="],
"@chakra-ui/react": ["@chakra-ui/react@3.21.1", "", { "dependencies": { "@ark-ui/react": "5.15.4", "@emotion/is-prop-valid": "1.3.1", "@emotion/serialize": "1.3.3", "@emotion/use-insertion-effect-with-fallbacks": "1.2.0", "@emotion/utils": "1.4.2", "@pandacss/is-valid-prop": "0.54.0", "csstype": "3.1.3", "fast-safe-stringify": "2.1.1" }, "peerDependencies": { "@emotion/react": ">=11", "react": ">=18", "react-dom": ">=18" } }, "sha512-tc8SAeOZbOeOSY+BROE6o1FyzoS8sAuC6TAwlfUCZWhv9CMsxBisC88D4WI/puwnZVfUbzzhdVEQmWkCbJK6ag=="],
"@emotion/babel-plugin": ["@emotion/babel-plugin@11.13.5", "", { "dependencies": { "@babel/helper-module-imports": "^7.16.7", "@babel/runtime": "^7.18.3", "@emotion/hash": "^0.9.2", "@emotion/memoize": "^0.9.0", "@emotion/serialize": "^1.3.3", "babel-plugin-macros": "^3.1.0", "convert-source-map": "^1.5.0", "escape-string-regexp": "^4.0.0", "find-root": "^1.1.0", "source-map": "^0.5.7", "stylis": "4.2.0" } }, "sha512-pxHCpT2ex+0q+HH91/zsdHkw/lXd468DIN2zvfvLtPKLLMo6gQj7oLObq8PhkrxOZb/gGCq03S3Z7PDhS8pduQ=="],
"@emotion/cache": ["@emotion/cache@11.14.0", "", { "dependencies": { "@emotion/memoize": "^0.9.0", "@emotion/sheet": "^1.4.0", "@emotion/utils": "^1.4.2", "@emotion/weak-memoize": "^0.4.0", "stylis": "4.2.0" } }, "sha512-L/B1lc/TViYk4DcpGxtAVbx0ZyiKM5ktoIyafGkH6zg/tj+mA+NE//aPYKG0k8kCHSHVJrpLpcAlOBEXQ3SavA=="],
"@emotion/hash": ["@emotion/hash@0.9.2", "", {}, "sha512-MyqliTZGuOm3+5ZRSaaBGP3USLw6+EGykkwZns2EPC5g8jJ4z9OrdZY9apkl3+UP9+sdz76YYkwCKP5gh8iY3g=="],
"@emotion/is-prop-valid": ["@emotion/is-prop-valid@1.3.1", "", { "dependencies": { "@emotion/memoize": "^0.9.0" } }, "sha512-/ACwoqx7XQi9knQs/G0qKvv5teDMhD7bXYns9N/wM8ah8iNb8jZ2uNO0YOgiq2o2poIvVtJS2YALasQuMSQ7Kw=="],
"@emotion/memoize": ["@emotion/memoize@0.9.0", "", {}, "sha512-30FAj7/EoJ5mwVPOWhAyCX+FPfMDrVecJAM+Iw9NRoSl4BBAQeqj4cApHHUXOVvIPgLVDsCFoz/hGD+5QQD1GQ=="],
"@emotion/react": ["@emotion/react@11.14.0", "", { "dependencies": { "@babel/runtime": "^7.18.3", "@emotion/babel-plugin": "^11.13.5", "@emotion/cache": "^11.14.0", "@emotion/serialize": "^1.3.3", "@emotion/use-insertion-effect-with-fallbacks": "^1.2.0", "@emotion/utils": "^1.4.2", "@emotion/weak-memoize": "^0.4.0", "hoist-non-react-statics": "^3.3.1" }, "peerDependencies": { "react": ">=16.8.0" } }, "sha512-O000MLDBDdk/EohJPFUqvnp4qnHeYkVP5B0xEG0D/L7cOKP9kefu2DXn8dj74cQfsEzUqh+sr1RzFqiL1o+PpA=="],
"@emotion/serialize": ["@emotion/serialize@1.3.3", "", { "dependencies": { "@emotion/hash": "^0.9.2", "@emotion/memoize": "^0.9.0", "@emotion/unitless": "^0.10.0", "@emotion/utils": "^1.4.2", "csstype": "^3.0.2" } }, "sha512-EISGqt7sSNWHGI76hC7x1CksiXPahbxEOrC5RjmFRJTqLyEK9/9hZvBbiYn70dw4wuwMKiEMCUlR6ZXTSWQqxA=="],
"@emotion/sheet": ["@emotion/sheet@1.4.0", "", {}, "sha512-fTBW9/8r2w3dXWYM4HCB1Rdp8NLibOw2+XELH5m5+AkWiL/KqYX6dc0kKYlaYyKjrQ6ds33MCdMPEwgs2z1rqg=="],
"@emotion/unitless": ["@emotion/unitless@0.10.0", "", {}, "sha512-dFoMUuQA20zvtVTuxZww6OHoJYgrzfKM1t52mVySDJnMSEa08ruEvdYQbhvyu6soU+NeLVd3yKfTfT0NeV6qGg=="],
"@emotion/use-insertion-effect-with-fallbacks": ["@emotion/use-insertion-effect-with-fallbacks@1.2.0", "", { "peerDependencies": { "react": ">=16.8.0" } }, "sha512-yJMtVdH59sxi/aVJBpk9FQq+OR8ll5GT8oWd57UpeaKEVGab41JWaCFA7FRLoMLloOZF/c/wsPoe+bfGmRKgDg=="],
"@emotion/utils": ["@emotion/utils@1.4.2", "", {}, "sha512-3vLclRofFziIa3J2wDh9jjbkUz9qk5Vi3IZ/FSTKViB0k+ef0fPV7dYrUIugbgupYDx7v9ud/SjrtEP8Y4xLoA=="],
"@emotion/weak-memoize": ["@emotion/weak-memoize@0.4.0", "", {}, "sha512-snKqtPW01tN0ui7yu9rGv69aJXr/a/Ywvl11sUjNtEcRc+ng/mQriFL0wLXMef74iHa/EkftbDzU9F8iFbH+zg=="],
"@esbuild/aix-ppc64": ["@esbuild/aix-ppc64@0.25.5", "", { "os": "aix", "cpu": "ppc64" }, "sha512-9o3TMmpmftaCMepOdA5k/yDw8SfInyzWWTjYTFCX3kPSDJMROQTb8jg+h9Cnwnmm1vOzvxN7gIfB5V2ewpjtGA=="],
"@esbuild/android-arm": ["@esbuild/android-arm@0.25.5", "", { "os": "android", "cpu": "arm" }, "sha512-AdJKSPeEHgi7/ZhuIPtcQKr5RQdo6OO2IL87JkianiMYMPbCtot9fxPbrMiBADOWWm3T2si9stAiVsGbTQFkbA=="],
"@esbuild/android-arm64": ["@esbuild/android-arm64@0.25.5", "", { "os": "android", "cpu": "arm64" }, "sha512-VGzGhj4lJO+TVGV1v8ntCZWJktV7SGCs3Pn1GRWI1SBFtRALoomm8k5E9Pmwg3HOAal2VDc2F9+PM/rEY6oIDg=="],
"@esbuild/android-x64": ["@esbuild/android-x64@0.25.5", "", { "os": "android", "cpu": "x64" }, "sha512-D2GyJT1kjvO//drbRT3Hib9XPwQeWd9vZoBJn+bu/lVsOZ13cqNdDeqIF/xQ5/VmWvMduP6AmXvylO/PIc2isw=="],
"@esbuild/darwin-arm64": ["@esbuild/darwin-arm64@0.25.5", "", { "os": "darwin", "cpu": "arm64" }, "sha512-GtaBgammVvdF7aPIgH2jxMDdivezgFu6iKpmT+48+F8Hhg5J/sfnDieg0aeG/jfSvkYQU2/pceFPDKlqZzwnfQ=="],
"@esbuild/darwin-x64": ["@esbuild/darwin-x64@0.25.5", "", { "os": "darwin", "cpu": "x64" }, "sha512-1iT4FVL0dJ76/q1wd7XDsXrSW+oLoquptvh4CLR4kITDtqi2e/xwXwdCVH8hVHU43wgJdsq7Gxuzcs6Iq/7bxQ=="],
"@esbuild/freebsd-arm64": ["@esbuild/freebsd-arm64@0.25.5", "", { "os": "freebsd", "cpu": "arm64" }, "sha512-nk4tGP3JThz4La38Uy/gzyXtpkPW8zSAmoUhK9xKKXdBCzKODMc2adkB2+8om9BDYugz+uGV7sLmpTYzvmz6Sw=="],
"@esbuild/freebsd-x64": ["@esbuild/freebsd-x64@0.25.5", "", { "os": "freebsd", "cpu": "x64" }, "sha512-PrikaNjiXdR2laW6OIjlbeuCPrPaAl0IwPIaRv+SMV8CiM8i2LqVUHFC1+8eORgWyY7yhQY+2U2fA55mBzReaw=="],
"@esbuild/linux-arm": ["@esbuild/linux-arm@0.25.5", "", { "os": "linux", "cpu": "arm" }, "sha512-cPzojwW2okgh7ZlRpcBEtsX7WBuqbLrNXqLU89GxWbNt6uIg78ET82qifUy3W6OVww6ZWobWub5oqZOVtwolfw=="],
"@esbuild/linux-arm64": ["@esbuild/linux-arm64@0.25.5", "", { "os": "linux", "cpu": "arm64" }, "sha512-Z9kfb1v6ZlGbWj8EJk9T6czVEjjq2ntSYLY2cw6pAZl4oKtfgQuS4HOq41M/BcoLPzrUbNd+R4BXFyH//nHxVg=="],
"@esbuild/linux-ia32": ["@esbuild/linux-ia32@0.25.5", "", { "os": "linux", "cpu": "ia32" }, "sha512-sQ7l00M8bSv36GLV95BVAdhJ2QsIbCuCjh/uYrWiMQSUuV+LpXwIqhgJDcvMTj+VsQmqAHL2yYaasENvJ7CDKA=="],
"@esbuild/linux-loong64": ["@esbuild/linux-loong64@0.25.5", "", { "os": "linux", "cpu": "none" }, "sha512-0ur7ae16hDUC4OL5iEnDb0tZHDxYmuQyhKhsPBV8f99f6Z9KQM02g33f93rNH5A30agMS46u2HP6qTdEt6Q1kg=="],
"@esbuild/linux-mips64el": ["@esbuild/linux-mips64el@0.25.5", "", { "os": "linux", "cpu": "none" }, "sha512-kB/66P1OsHO5zLz0i6X0RxlQ+3cu0mkxS3TKFvkb5lin6uwZ/ttOkP3Z8lfR9mJOBk14ZwZ9182SIIWFGNmqmg=="],
"@esbuild/linux-ppc64": ["@esbuild/linux-ppc64@0.25.5", "", { "os": "linux", "cpu": "ppc64" }, "sha512-UZCmJ7r9X2fe2D6jBmkLBMQetXPXIsZjQJCjgwpVDz+YMcS6oFR27alkgGv3Oqkv07bxdvw7fyB71/olceJhkQ=="],
"@esbuild/linux-riscv64": ["@esbuild/linux-riscv64@0.25.5", "", { "os": "linux", "cpu": "none" }, "sha512-kTxwu4mLyeOlsVIFPfQo+fQJAV9mh24xL+y+Bm6ej067sYANjyEw1dNHmvoqxJUCMnkBdKpvOn0Ahql6+4VyeA=="],
"@esbuild/linux-s390x": ["@esbuild/linux-s390x@0.25.5", "", { "os": "linux", "cpu": "s390x" }, "sha512-K2dSKTKfmdh78uJ3NcWFiqyRrimfdinS5ErLSn3vluHNeHVnBAFWC8a4X5N+7FgVE1EjXS1QDZbpqZBjfrqMTQ=="],
"@esbuild/linux-x64": ["@esbuild/linux-x64@0.25.5", "", { "os": "linux", "cpu": "x64" }, "sha512-uhj8N2obKTE6pSZ+aMUbqq+1nXxNjZIIjCjGLfsWvVpy7gKCOL6rsY1MhRh9zLtUtAI7vpgLMK6DxjO8Qm9lJw=="],
"@esbuild/netbsd-arm64": ["@esbuild/netbsd-arm64@0.25.5", "", { "os": "none", "cpu": "arm64" }, "sha512-pwHtMP9viAy1oHPvgxtOv+OkduK5ugofNTVDilIzBLpoWAM16r7b/mxBvfpuQDpRQFMfuVr5aLcn4yveGvBZvw=="],
"@esbuild/netbsd-x64": ["@esbuild/netbsd-x64@0.25.5", "", { "os": "none", "cpu": "x64" }, "sha512-WOb5fKrvVTRMfWFNCroYWWklbnXH0Q5rZppjq0vQIdlsQKuw6mdSihwSo4RV/YdQ5UCKKvBy7/0ZZYLBZKIbwQ=="],
"@esbuild/openbsd-arm64": ["@esbuild/openbsd-arm64@0.25.5", "", { "os": "openbsd", "cpu": "arm64" }, "sha512-7A208+uQKgTxHd0G0uqZO8UjK2R0DDb4fDmERtARjSHWxqMTye4Erz4zZafx7Di9Cv+lNHYuncAkiGFySoD+Mw=="],
"@esbuild/openbsd-x64": ["@esbuild/openbsd-x64@0.25.5", "", { "os": "openbsd", "cpu": "x64" }, "sha512-G4hE405ErTWraiZ8UiSoesH8DaCsMm0Cay4fsFWOOUcz8b8rC6uCvnagr+gnioEjWn0wC+o1/TAHt+It+MpIMg=="],
"@esbuild/sunos-x64": ["@esbuild/sunos-x64@0.25.5", "", { "os": "sunos", "cpu": "x64" }, "sha512-l+azKShMy7FxzY0Rj4RCt5VD/q8mG/e+mDivgspo+yL8zW7qEwctQ6YqKX34DTEleFAvCIUviCFX1SDZRSyMQA=="],
"@esbuild/win32-arm64": ["@esbuild/win32-arm64@0.25.5", "", { "os": "win32", "cpu": "arm64" }, "sha512-O2S7SNZzdcFG7eFKgvwUEZ2VG9D/sn/eIiz8XRZ1Q/DO5a3s76Xv0mdBzVM5j5R639lXQmPmSo0iRpHqUUrsxw=="],
"@esbuild/win32-ia32": ["@esbuild/win32-ia32@0.25.5", "", { "os": "win32", "cpu": "ia32" }, "sha512-onOJ02pqs9h1iMJ1PQphR+VZv8qBMQ77Klcsqv9CNW2w6yLqoURLcgERAIurY6QE63bbLuqgP9ATqajFLK5AMQ=="],
"@esbuild/win32-x64": ["@esbuild/win32-x64@0.25.5", "", { "os": "win32", "cpu": "x64" }, "sha512-TXv6YnJ8ZMVdX+SXWVBo/0p8LTcrUYngpWjvm91TMjjBQii7Oz11Lw5lbDV5Y0TzuhSJHwiH4hEtC1I42mMS0g=="],
"@eslint-community/eslint-utils": ["@eslint-community/eslint-utils@4.7.0", "", { "dependencies": { "eslint-visitor-keys": "^3.4.3" }, "peerDependencies": { "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" } }, "sha512-dyybb3AcajC7uha6CvhdVRJqaKyn7w2YKqKyAN37NKYgZT36w+iRb0Dymmc5qEJ549c/S31cMMSFd75bteCpCw=="],
"@eslint-community/regexpp": ["@eslint-community/regexpp@4.12.1", "", {}, "sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ=="],
"@eslint/config-array": ["@eslint/config-array@0.21.0", "", { "dependencies": { "@eslint/object-schema": "^2.1.6", "debug": "^4.3.1", "minimatch": "^3.1.2" } }, "sha512-ENIdc4iLu0d93HeYirvKmrzshzofPw6VkZRKQGe9Nv46ZnWUzcF1xV01dcvEg/1wXUR61OmmlSfyeyO7EvjLxQ=="],
"@eslint/config-helpers": ["@eslint/config-helpers@0.3.0", "", {}, "sha512-ViuymvFmcJi04qdZeDc2whTHryouGcDlaxPqarTD0ZE10ISpxGUVZGZDx4w01upyIynL3iu6IXH2bS1NhclQMw=="],
"@eslint/core": ["@eslint/core@0.14.0", "", { "dependencies": { "@types/json-schema": "^7.0.15" } }, "sha512-qIbV0/JZr7iSDjqAc60IqbLdsj9GDt16xQtWD+B78d/HAlvysGdZZ6rpJHGAc2T0FQx1X6thsSPdnoiGKdNtdg=="],
"@eslint/eslintrc": ["@eslint/eslintrc@3.3.1", "", { "dependencies": { "ajv": "^6.12.4", "debug": "^4.3.2", "espree": "^10.0.1", "globals": "^14.0.0", "ignore": "^5.2.0", "import-fresh": "^3.2.1", "js-yaml": "^4.1.0", "minimatch": "^3.1.2", "strip-json-comments": "^3.1.1" } }, "sha512-gtF186CXhIl1p4pJNGZw8Yc6RlshoePRvE0X91oPGb3vZ8pM3qOS9W9NGPat9LziaBV7XrJWGylNQXkGcnM3IQ=="],
"@eslint/js": ["@eslint/js@9.30.1", "", {}, "sha512-zXhuECFlyep42KZUhWjfvsmXGX39W8K8LFb8AWXM9gSV9dQB+MrJGLKvW6Zw0Ggnbpw0VHTtrhFXYe3Gym18jg=="],
"@eslint/object-schema": ["@eslint/object-schema@2.1.6", "", {}, "sha512-RBMg5FRL0I0gs51M/guSAj5/e14VQ4tpZnQNWwuDT66P14I43ItmPfIZRhO9fUVIPOAQXU47atlywZ/czoqFPA=="],
"@eslint/plugin-kit": ["@eslint/plugin-kit@0.3.3", "", { "dependencies": { "@eslint/core": "^0.15.1", "levn": "^0.4.1" } }, "sha512-1+WqvgNMhmlAambTvT3KPtCl/Ibr68VldY2XY40SL1CE0ZXiakFR/cbTspaF5HsnpDMvcYYoJHfl4980NBjGag=="],
"@floating-ui/core": ["@floating-ui/core@1.7.2", "", { "dependencies": { "@floating-ui/utils": "^0.2.10" } }, "sha512-wNB5ooIKHQc+Kui96jE/n69rHFWAVoxn5CAzL1Xdd8FG03cgY3MLO+GF9U3W737fYDSgPWA6MReKhBQBop6Pcw=="],
"@floating-ui/dom": ["@floating-ui/dom@1.7.1", "", { "dependencies": { "@floating-ui/core": "^1.7.1", "@floating-ui/utils": "^0.2.9" } }, "sha512-cwsmW/zyw5ltYTUeeYJ60CnQuPqmGwuGVhG9w0PRaRKkAyi38BT5CKrpIbb+jtahSwUl04cWzSx9ZOIxeS6RsQ=="],
"@floating-ui/utils": ["@floating-ui/utils@0.2.10", "", {}, "sha512-aGTxbpbg8/b5JfU1HXSrbH3wXZuLPJcNEcZQFMxLs3oSzgtVu6nFPkbbGGUvBcUjKV2YyB9Wxxabo+HEH9tcRQ=="],
"@humanfs/core": ["@humanfs/core@0.19.1", "", {}, "sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA=="],
"@humanfs/node": ["@humanfs/node@0.16.6", "", { "dependencies": { "@humanfs/core": "^0.19.1", "@humanwhocodes/retry": "^0.3.0" } }, "sha512-YuI2ZHQL78Q5HbhDiBA1X4LmYdXCKCMQIfw0pw7piHJwyREFebJUvrQN4cMssyES6x+vfUbx1CIpaQUKYdQZOw=="],
"@humanwhocodes/module-importer": ["@humanwhocodes/module-importer@1.0.1", "", {}, "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA=="],
"@humanwhocodes/retry": ["@humanwhocodes/retry@0.4.3", "", {}, "sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ=="],
"@internationalized/date": ["@internationalized/date@3.8.2", "", { "dependencies": { "@swc/helpers": "^0.5.0" } }, "sha512-/wENk7CbvLbkUvX1tu0mwq49CVkkWpkXubGel6birjRPyo6uQ4nQpnq5xZu823zRCwwn82zgHrvgF1vZyvmVgA=="],
"@internationalized/number": ["@internationalized/number@3.6.3", "", { "dependencies": { "@swc/helpers": "^0.5.0" } }, "sha512-p+Zh1sb6EfrfVaS86jlHGQ9HA66fJhV9x5LiE5vCbZtXEHAuhcmUZUdZ4WrFpUBfNalr2OkAJI5AcKEQF+Lebw=="],
"@jridgewell/gen-mapping": ["@jridgewell/gen-mapping@0.3.12", "", { "dependencies": { "@jridgewell/sourcemap-codec": "^1.5.0", "@jridgewell/trace-mapping": "^0.3.24" } }, "sha512-OuLGC46TjB5BbN1dH8JULVVZY4WTdkF7tV9Ys6wLL1rubZnCMstOhNHueU5bLCrnRuDhKPDM4g6sw4Bel5Gzqg=="],
"@jridgewell/resolve-uri": ["@jridgewell/resolve-uri@3.1.2", "", {}, "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw=="],
"@jridgewell/sourcemap-codec": ["@jridgewell/sourcemap-codec@1.5.4", "", {}, "sha512-VT2+G1VQs/9oz078bLrYbecdZKs912zQlkelYpuf+SXF+QvZDYJlbx/LSx+meSAwdDFnF8FVXW92AVjjkVmgFw=="],
"@jridgewell/trace-mapping": ["@jridgewell/trace-mapping@0.3.29", "", { "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", "@jridgewell/sourcemap-codec": "^1.4.14" } }, "sha512-uw6guiW/gcAGPDhLmd77/6lW8QLeiV5RUTsAX46Db6oLhGaVj4lhnPwb184s1bkc8kdVg/+h988dro8GRDpmYQ=="],
"@mapbox/jsonlint-lines-primitives": ["@mapbox/jsonlint-lines-primitives@2.0.2", "", {}, "sha512-rY0o9A5ECsTQRVhv7tL/OyDpGAoUB4tTvLiW1DSzQGq4bvTPhNw1VpSNjDJc5GFZ2XuyOtSWSVN05qOtcD71qQ=="],
"@mapbox/mapbox-gl-supported": ["@mapbox/mapbox-gl-supported@3.0.0", "", {}, "sha512-2XghOwu16ZwPJLOFVuIOaLbN0iKMn867evzXFyf0P22dqugezfJwLmdanAgU25ITvz1TvOfVP4jsDImlDJzcWg=="],
"@mapbox/point-geometry": ["@mapbox/point-geometry@0.1.0", "", {}, "sha512-6j56HdLTwWGO0fJPlrZtdU/B13q8Uwmo18Ck2GnGgN9PCFyKTZ3UbXeEdRFh18i9XQ92eH2VdtpJHpBD3aripQ=="],
"@mapbox/tiny-sdf": ["@mapbox/tiny-sdf@2.0.6", "", {}, "sha512-qMqa27TLw+ZQz5Jk+RcwZGH7BQf5G/TrutJhspsca/3SHwmgKQ1iq+d3Jxz5oysPVYTGP6aXxCo5Lk9Er6YBAA=="],
"@mapbox/unitbezier": ["@mapbox/unitbezier@0.0.1", "", {}, "sha512-nMkuDXFv60aBr9soUG5q+GvZYL+2KZHVvsqFCzqnkGEf46U2fvmytHaEVc1/YZbiLn8X+eR3QzX1+dwDO1lxlw=="],
"@mapbox/vector-tile": ["@mapbox/vector-tile@1.3.1", "", { "dependencies": { "@mapbox/point-geometry": "~0.1.0" } }, "sha512-MCEddb8u44/xfQ3oD+Srl/tNcQoqTw3goGk2oLsrFxOTc3dUp+kAnby3PvAeeBYSMSjSPD1nd1AJA6W49WnoUw=="],
"@mapbox/whoots-js": ["@mapbox/whoots-js@3.1.0", "", {}, "sha512-Es6WcD0nO5l+2BOQS4uLfNPYQaNDfbot3X1XUoloz+x0mPDS3eeORZJl06HXjwBG1fOGwCRnzK88LMdxKRrd6Q=="],
"@maplibre/maplibre-gl-style-spec": ["@maplibre/maplibre-gl-style-spec@19.3.3", "", { "dependencies": { "@mapbox/jsonlint-lines-primitives": "~2.0.2", "@mapbox/unitbezier": "^0.0.1", "json-stringify-pretty-compact": "^3.0.0", "minimist": "^1.2.8", "rw": "^1.3.3", "sort-object": "^3.0.3" }, "bin": { "gl-style-format": "dist/gl-style-format.mjs", "gl-style-migrate": "dist/gl-style-migrate.mjs", "gl-style-validate": "dist/gl-style-validate.mjs" } }, "sha512-cOZZOVhDSulgK0meTsTkmNXb1ahVvmTmWmfx9gRBwc6hq98wS9JP35ESIoNq3xqEan+UN+gn8187Z6E4NKhLsw=="],
"@nodelib/fs.scandir": ["@nodelib/fs.scandir@2.1.5", "", { "dependencies": { "@nodelib/fs.stat": "2.0.5", "run-parallel": "^1.1.9" } }, "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g=="],
"@nodelib/fs.stat": ["@nodelib/fs.stat@2.0.5", "", {}, "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A=="],
"@nodelib/fs.walk": ["@nodelib/fs.walk@1.2.8", "", { "dependencies": { "@nodelib/fs.scandir": "2.1.5", "fastq": "^1.6.0" } }, "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg=="],
"@pandacss/is-valid-prop": ["@pandacss/is-valid-prop@0.54.0", "", {}, "sha512-UhRgg1k9VKRCBAHl+XUK3lvN0k9bYifzYGZOqajDid4L1DyU813A1L0ZwN4iV9WX5TX3PfUugqtgG9LnIeFGBQ=="],
"@rolldown/pluginutils": ["@rolldown/pluginutils@1.0.0-beta.11", "", {}, "sha512-L/gAA/hyCSuzTF1ftlzUSI/IKr2POHsv1Dd78GfqkR83KMNuswWD61JxGV2L7nRwBBBSDr6R1gCkdTmoN7W4ag=="],
"@rollup/rollup-android-arm-eabi": ["@rollup/rollup-android-arm-eabi@4.44.2", "", { "os": "android", "cpu": "arm" }, "sha512-g0dF8P1e2QYPOj1gu7s/3LVP6kze9A7m6x0BZ9iTdXK8N5c2V7cpBKHV3/9A4Zd8xxavdhK0t4PnqjkqVmUc9Q=="],
"@rollup/rollup-android-arm64": ["@rollup/rollup-android-arm64@4.44.2", "", { "os": "android", "cpu": "arm64" }, "sha512-Yt5MKrOosSbSaAK5Y4J+vSiID57sOvpBNBR6K7xAaQvk3MkcNVV0f9fE20T+41WYN8hDn6SGFlFrKudtx4EoxA=="],
"@rollup/rollup-darwin-arm64": ["@rollup/rollup-darwin-arm64@4.44.2", "", { "os": "darwin", "cpu": "arm64" }, "sha512-EsnFot9ZieM35YNA26nhbLTJBHD0jTwWpPwmRVDzjylQT6gkar+zenfb8mHxWpRrbn+WytRRjE0WKsfaxBkVUA=="],
"@rollup/rollup-darwin-x64": ["@rollup/rollup-darwin-x64@4.44.2", "", { "os": "darwin", "cpu": "x64" }, "sha512-dv/t1t1RkCvJdWWxQ2lWOO+b7cMsVw5YFaS04oHpZRWehI1h0fV1gF4wgGCTyQHHjJDfbNpwOi6PXEafRBBezw=="],
"@rollup/rollup-freebsd-arm64": ["@rollup/rollup-freebsd-arm64@4.44.2", "", { "os": "freebsd", "cpu": "arm64" }, "sha512-W4tt4BLorKND4qeHElxDoim0+BsprFTwb+vriVQnFFtT/P6v/xO5I99xvYnVzKWrK6j7Hb0yp3x7V5LUbaeOMg=="],
"@rollup/rollup-freebsd-x64": ["@rollup/rollup-freebsd-x64@4.44.2", "", { "os": "freebsd", "cpu": "x64" }, "sha512-tdT1PHopokkuBVyHjvYehnIe20fxibxFCEhQP/96MDSOcyjM/shlTkZZLOufV3qO6/FQOSiJTBebhVc12JyPTA=="],
"@rollup/rollup-linux-arm-gnueabihf": ["@rollup/rollup-linux-arm-gnueabihf@4.44.2", "", { "os": "linux", "cpu": "arm" }, "sha512-+xmiDGGaSfIIOXMzkhJ++Oa0Gwvl9oXUeIiwarsdRXSe27HUIvjbSIpPxvnNsRebsNdUo7uAiQVgBD1hVriwSQ=="],
"@rollup/rollup-linux-arm-musleabihf": ["@rollup/rollup-linux-arm-musleabihf@4.44.2", "", { "os": "linux", "cpu": "arm" }, "sha512-bDHvhzOfORk3wt8yxIra8N4k/N0MnKInCW5OGZaeDYa/hMrdPaJzo7CSkjKZqX4JFUWjUGm88lI6QJLCM7lDrA=="],
"@rollup/rollup-linux-arm64-gnu": ["@rollup/rollup-linux-arm64-gnu@4.44.2", "", { "os": "linux", "cpu": "arm64" }, "sha512-NMsDEsDiYghTbeZWEGnNi4F0hSbGnsuOG+VnNvxkKg0IGDvFh7UVpM/14mnMwxRxUf9AdAVJgHPvKXf6FpMB7A=="],
"@rollup/rollup-linux-arm64-musl": ["@rollup/rollup-linux-arm64-musl@4.44.2", "", { "os": "linux", "cpu": "arm64" }, "sha512-lb5bxXnxXglVq+7imxykIp5xMq+idehfl+wOgiiix0191av84OqbjUED+PRC5OA8eFJYj5xAGcpAZ0pF2MnW+A=="],
"@rollup/rollup-linux-loongarch64-gnu": ["@rollup/rollup-linux-loongarch64-gnu@4.44.2", "", { "os": "linux", "cpu": "none" }, "sha512-Yl5Rdpf9pIc4GW1PmkUGHdMtbx0fBLE1//SxDmuf3X0dUC57+zMepow2LK0V21661cjXdTn8hO2tXDdAWAqE5g=="],
"@rollup/rollup-linux-powerpc64le-gnu": ["@rollup/rollup-linux-powerpc64le-gnu@4.44.2", "", { "os": "linux", "cpu": "ppc64" }, "sha512-03vUDH+w55s680YYryyr78jsO1RWU9ocRMaeV2vMniJJW/6HhoTBwyyiiTPVHNWLnhsnwcQ0oH3S9JSBEKuyqw=="],
"@rollup/rollup-linux-riscv64-gnu": ["@rollup/rollup-linux-riscv64-gnu@4.44.2", "", { "os": "linux", "cpu": "none" }, "sha512-iYtAqBg5eEMG4dEfVlkqo05xMOk6y/JXIToRca2bAWuqjrJYJlx/I7+Z+4hSrsWU8GdJDFPL4ktV3dy4yBSrzg=="],
"@rollup/rollup-linux-riscv64-musl": ["@rollup/rollup-linux-riscv64-musl@4.44.2", "", { "os": "linux", "cpu": "none" }, "sha512-e6vEbgaaqz2yEHqtkPXa28fFuBGmUJ0N2dOJK8YUfijejInt9gfCSA7YDdJ4nYlv67JfP3+PSWFX4IVw/xRIPg=="],
"@rollup/rollup-linux-s390x-gnu": ["@rollup/rollup-linux-s390x-gnu@4.44.2", "", { "os": "linux", "cpu": "s390x" }, "sha512-evFOtkmVdY3udE+0QKrV5wBx7bKI0iHz5yEVx5WqDJkxp9YQefy4Mpx3RajIVcM6o7jxTvVd/qpC1IXUhGc1Mw=="],
"@rollup/rollup-linux-x64-gnu": ["@rollup/rollup-linux-x64-gnu@4.44.2", "", { "os": "linux", "cpu": "x64" }, "sha512-/bXb0bEsWMyEkIsUL2Yt5nFB5naLAwyOWMEviQfQY1x3l5WsLKgvZf66TM7UTfED6erckUVUJQ/jJ1FSpm3pRQ=="],
"@rollup/rollup-linux-x64-musl": ["@rollup/rollup-linux-x64-musl@4.44.2", "", { "os": "linux", "cpu": "x64" }, "sha512-3D3OB1vSSBXmkGEZR27uiMRNiwN08/RVAcBKwhUYPaiZ8bcvdeEwWPvbnXvvXHY+A/7xluzcN+kaiOFNiOZwWg=="],
"@rollup/rollup-win32-arm64-msvc": ["@rollup/rollup-win32-arm64-msvc@4.44.2", "", { "os": "win32", "cpu": "arm64" }, "sha512-VfU0fsMK+rwdK8mwODqYeM2hDrF2WiHaSmCBrS7gColkQft95/8tphyzv2EupVxn3iE0FI78wzffoULH1G+dkw=="],
"@rollup/rollup-win32-ia32-msvc": ["@rollup/rollup-win32-ia32-msvc@4.44.2", "", { "os": "win32", "cpu": "ia32" }, "sha512-+qMUrkbUurpE6DVRjiJCNGZBGo9xM4Y0FXU5cjgudWqIBWbcLkjE3XprJUsOFgC6xjBClwVa9k6O3A7K3vxb5Q=="],
"@rollup/rollup-win32-x64-msvc": ["@rollup/rollup-win32-x64-msvc@4.44.2", "", { "os": "win32", "cpu": "x64" }, "sha512-3+QZROYfJ25PDcxFF66UEk8jGWigHJeecZILvkPkyQN7oc5BvFo4YEXFkOs154j3FTMp9mn9Ky8RCOwastduEA=="],
"@swc/core": ["@swc/core@1.12.9", "", { "dependencies": { "@swc/counter": "^0.1.3", "@swc/types": "^0.1.23" }, "optionalDependencies": { "@swc/core-darwin-arm64": "1.12.9", "@swc/core-darwin-x64": "1.12.9", "@swc/core-linux-arm-gnueabihf": "1.12.9", "@swc/core-linux-arm64-gnu": "1.12.9", "@swc/core-linux-arm64-musl": "1.12.9", "@swc/core-linux-x64-gnu": "1.12.9", "@swc/core-linux-x64-musl": "1.12.9", "@swc/core-win32-arm64-msvc": "1.12.9", "@swc/core-win32-ia32-msvc": "1.12.9", "@swc/core-win32-x64-msvc": "1.12.9" }, "peerDependencies": { "@swc/helpers": ">=0.5.17" }, "optionalPeers": ["@swc/helpers"] }, "sha512-O+LfT2JlVMsIMWG9x+rdxg8GzpzeGtCZQfXV7cKc1PjIKUkLFf1QJ7okuseA4f/9vncu37dQ2ZcRrPKy0Ndd5g=="],
"@swc/core-darwin-arm64": ["@swc/core-darwin-arm64@1.12.9", "", { "os": "darwin", "cpu": "arm64" }, "sha512-GACFEp4nD6V+TZNR2JwbMZRHB+Yyvp14FrcmB6UCUYmhuNWjkxi+CLnEvdbuiKyQYv0zA+TRpCHZ+whEs6gwfA=="],
"@swc/core-darwin-x64": ["@swc/core-darwin-x64@1.12.9", "", { "os": "darwin", "cpu": "x64" }, "sha512-hv2kls7Ilkm2EpeJz+I9MCil7pGS3z55ZAgZfxklEuYsxpICycxeH+RNRv4EraggN44ms+FWCjtZFu0LGg2V3g=="],
"@swc/core-linux-arm-gnueabihf": ["@swc/core-linux-arm-gnueabihf@1.12.9", "", { "os": "linux", "cpu": "arm" }, "sha512-od9tDPiG+wMU9wKtd6y3nYJdNqgDOyLdgRRcrj1/hrbHoUPOM8wZQZdwQYGarw63iLXGgsw7t5HAF9Yc51ilFA=="],
"@swc/core-linux-arm64-gnu": ["@swc/core-linux-arm64-gnu@1.12.9", "", { "os": "linux", "cpu": "arm64" }, "sha512-6qx1ka9LHcLzxIgn2Mros+CZLkHK2TawlXzi/h7DJeNnzi8F1Hw0Yzjp8WimxNCg6s2n+o3jnmin1oXB7gg8rw=="],
"@swc/core-linux-arm64-musl": ["@swc/core-linux-arm64-musl@1.12.9", "", { "os": "linux", "cpu": "arm64" }, "sha512-yghFZWKPVVGbUdqiD7ft23G0JX6YFGDJPz9YbLLAwGuKZ9th3/jlWoQDAw1Naci31LQhVC+oIji6ozihSuwB2A=="],
"@swc/core-linux-x64-gnu": ["@swc/core-linux-x64-gnu@1.12.9", "", { "os": "linux", "cpu": "x64" }, "sha512-SFUxyhWLZRNL8QmgGNqdi2Q43PNyFVkRZ2zIif30SOGFSxnxcf2JNeSeBgKIGVgaLSuk6xFVVCtJ3KIeaStgRg=="],
"@swc/core-linux-x64-musl": ["@swc/core-linux-x64-musl@1.12.9", "", { "os": "linux", "cpu": "x64" }, "sha512-9FB0wM+6idCGTI20YsBNBg9xSWtkDBymnpaTCsZM3qDc0l4uOpJMqbfWhQvp17x7r/ulZfb2QY8RDvQmCL6AcQ=="],
"@swc/core-win32-arm64-msvc": ["@swc/core-win32-arm64-msvc@1.12.9", "", { "os": "win32", "cpu": "arm64" }, "sha512-zHOusMVbOH9ik5RtRrMiGzLpKwxrPXgXkBm3SbUCa65HAdjV33NZ0/R9Rv1uPESALtEl2tzMYLUxYA5ECFDFhA=="],
"@swc/core-win32-ia32-msvc": ["@swc/core-win32-ia32-msvc@1.12.9", "", { "os": "win32", "cpu": "ia32" }, "sha512-aWZf0PqE0ot7tCuhAjRkDFf41AzzSQO0x2xRfTbnhpROp57BRJ/N5eee1VULO/UA2PIJRG7GKQky5bSGBYlFug=="],
"@swc/core-win32-x64-msvc": ["@swc/core-win32-x64-msvc@1.12.9", "", { "os": "win32", "cpu": "x64" }, "sha512-C25fYftXOras3P3anSUeXXIpxmEkdAcsIL9yrr0j1xepTZ/yKwpnQ6g3coj8UXdeJy4GTVlR6+Ow/QiBgZQNOg=="],
"@swc/counter": ["@swc/counter@0.1.3", "", {}, "sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ=="],
"@swc/helpers": ["@swc/helpers@0.5.17", "", { "dependencies": { "tslib": "^2.8.0" } }, "sha512-5IKx/Y13RsYd+sauPb2x+U/xZikHjolzfuDgTAl/Tdf3Q8rslRvC19NKDLgAJQ6wsqADk10ntlv08nPFw/gO/A=="],
"@swc/types": ["@swc/types@0.1.23", "", { "dependencies": { "@swc/counter": "^0.1.3" } }, "sha512-u1iIVZV9Q0jxY+yM2vw/hZGDNudsN85bBpTqzAQ9rzkxW9D+e3aEM4Han+ow518gSewkXgjmEK0BD79ZcNVgPw=="],
"@types/bun": ["@types/bun@1.2.18", "", { "dependencies": { "bun-types": "1.2.18" } }, "sha512-Xf6RaWVheyemaThV0kUfaAUvCNokFr+bH8Jxp+tTZfx7dAPA8z9ePnP9S9+Vspzuxxx9JRAXhnyccRj3GyCMdQ=="],
"@types/estree": ["@types/estree@1.0.8", "", {}, "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w=="],
"@types/geojson": ["@types/geojson@7946.0.16", "", {}, "sha512-6C8nqWur3j98U6+lXDfTUWIfgvZU+EumvpHKcYjujKH7woYyLj2sUmff0tRhrqM7BohUw7Pz3ZB1jj2gW9Fvmg=="],
"@types/geojson-vt": ["@types/geojson-vt@3.2.5", "", { "dependencies": { "@types/geojson": "*" } }, "sha512-qDO7wqtprzlpe8FfQ//ClPV9xiuoh2nkIgiouIptON9w5jvD/fA4szvP9GBlDVdJ5dldAl0kX/sy3URbWwLx0g=="],
"@types/js-cookie": ["@types/js-cookie@3.0.6", "", {}, "sha512-wkw9yd1kEXOPnvEeEV1Go1MmxtBJL0RR79aOTAApecWFVu7w0NNXNqhcWgvw2YgZDYadliXkl14pa3WXw5jlCQ=="],
"@types/json-schema": ["@types/json-schema@7.0.15", "", {}, "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA=="],
"@types/mapbox__point-geometry": ["@types/mapbox__point-geometry@0.1.4", "", {}, "sha512-mUWlSxAmYLfwnRBmgYV86tgYmMIICX4kza8YnE/eIlywGe2XoOxlpVnXWwir92xRLjwyarqwpu2EJKD2pk0IUA=="],
"@types/mapbox__vector-tile": ["@types/mapbox__vector-tile@1.3.4", "", { "dependencies": { "@types/geojson": "*", "@types/mapbox__point-geometry": "*", "@types/pbf": "*" } }, "sha512-bpd8dRn9pr6xKvuEBQup8pwQfD4VUyqO/2deGjfpe6AwC8YRlyEipvefyRJUSiCJTZuCb8Pl1ciVV5ekqJ96Bg=="],
"@types/node": ["@types/node@24.0.10", "", { "dependencies": { "undici-types": "~7.8.0" } }, "sha512-ENHwaH+JIRTDIEEbDK6QSQntAYGtbvdDXnMXnZaZ6k13Du1dPMmprkEHIL7ok2Wl2aZevetwTAb5S+7yIF+enA=="],
"@types/parse-json": ["@types/parse-json@4.0.2", "", {}, "sha512-dISoDXWWQwUquiKsyZ4Ng+HX2KsPL7LyHKHQwgGFEA3IaKac4Obd+h2a/a6waisAoepJlBcx9paWqjA8/HVjCw=="],
"@types/pbf": ["@types/pbf@3.0.5", "", {}, "sha512-j3pOPiEcWZ34R6a6mN07mUkM4o4Lwf6hPNt8eilOeZhTFbxFXmKhvXl9Y28jotFPaI1bpPDJsbCprUoNke6OrA=="],
"@types/react": ["@types/react@19.1.8", "", { "dependencies": { "csstype": "^3.0.2" } }, "sha512-AwAfQ2Wa5bCx9WP8nZL2uMZWod7J7/JSplxbTmBQ5ms6QpqNYm672H0Vu9ZVKVngQ+ii4R/byguVEUZQyeg44g=="],
"@types/react-dom": ["@types/react-dom@19.1.6", "", { "peerDependencies": { "@types/react": "^19.0.0" } }, "sha512-4hOiT/dwO8Ko0gV1m/TJZYk3y0KBnY9vzDh7W+DH17b2HFSOGgdj33dhihPeuy3l0q23+4e+hoXHV6hCC4dCXw=="],
"@types/supercluster": ["@types/supercluster@7.1.3", "", { "dependencies": { "@types/geojson": "*" } }, "sha512-Z0pOY34GDFl3Q6hUFYf3HkTwKEE02e7QgtJppBt+beEAxnyOpJua+voGFvxINBHa06GwLFFym7gRPY2SiKIfIA=="],
"@typescript-eslint/eslint-plugin": ["@typescript-eslint/eslint-plugin@8.35.1", "", { "dependencies": { "@eslint-community/regexpp": "^4.10.0", "@typescript-eslint/scope-manager": "8.35.1", "@typescript-eslint/type-utils": "8.35.1", "@typescript-eslint/utils": "8.35.1", "@typescript-eslint/visitor-keys": "8.35.1", "graphemer": "^1.4.0", "ignore": "^7.0.0", "natural-compare": "^1.4.0", "ts-api-utils": "^2.1.0" }, "peerDependencies": { "@typescript-eslint/parser": "^8.35.1", "eslint": "^8.57.0 || ^9.0.0", "typescript": ">=4.8.4 <5.9.0" } }, "sha512-9XNTlo7P7RJxbVeICaIIIEipqxLKguyh+3UbXuT2XQuFp6d8VOeDEGuz5IiX0dgZo8CiI6aOFLg4e8cF71SFVg=="],
"@typescript-eslint/parser": ["@typescript-eslint/parser@8.35.1", "", { "dependencies": { "@typescript-eslint/scope-manager": "8.35.1", "@typescript-eslint/types": "8.35.1", "@typescript-eslint/typescript-estree": "8.35.1", "@typescript-eslint/visitor-keys": "8.35.1", "debug": "^4.3.4" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0", "typescript": ">=4.8.4 <5.9.0" } }, "sha512-3MyiDfrfLeK06bi/g9DqJxP5pV74LNv4rFTyvGDmT3x2p1yp1lOd+qYZfiRPIOf/oON+WRZR5wxxuF85qOar+w=="],
"@typescript-eslint/project-service": ["@typescript-eslint/project-service@8.35.1", "", { "dependencies": { "@typescript-eslint/tsconfig-utils": "^8.35.1", "@typescript-eslint/types": "^8.35.1", "debug": "^4.3.4" }, "peerDependencies": { "typescript": ">=4.8.4 <5.9.0" } }, "sha512-VYxn/5LOpVxADAuP3NrnxxHYfzVtQzLKeldIhDhzC8UHaiQvYlXvKuVho1qLduFbJjjy5U5bkGwa3rUGUb1Q6Q=="],
"@typescript-eslint/scope-manager": ["@typescript-eslint/scope-manager@8.35.1", "", { "dependencies": { "@typescript-eslint/types": "8.35.1", "@typescript-eslint/visitor-keys": "8.35.1" } }, "sha512-s/Bpd4i7ht2934nG+UoSPlYXd08KYz3bmjLEb7Ye1UVob0d1ENiT3lY8bsCmik4RqfSbPw9xJJHbugpPpP5JUg=="],
"@typescript-eslint/tsconfig-utils": ["@typescript-eslint/tsconfig-utils@8.35.1", "", { "peerDependencies": { "typescript": ">=4.8.4 <5.9.0" } }, "sha512-K5/U9VmT9dTHoNowWZpz+/TObS3xqC5h0xAIjXPw+MNcKV9qg6eSatEnmeAwkjHijhACH0/N7bkhKvbt1+DXWQ=="],
"@typescript-eslint/type-utils": ["@typescript-eslint/type-utils@8.35.1", "", { "dependencies": { "@typescript-eslint/typescript-estree": "8.35.1", "@typescript-eslint/utils": "8.35.1", "debug": "^4.3.4", "ts-api-utils": "^2.1.0" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0", "typescript": ">=4.8.4 <5.9.0" } }, "sha512-HOrUBlfVRz5W2LIKpXzZoy6VTZzMu2n8q9C2V/cFngIC5U1nStJgv0tMV4sZPzdf4wQm9/ToWUFPMN9Vq9VJQQ=="],
"@typescript-eslint/types": ["@typescript-eslint/types@8.35.1", "", {}, "sha512-q/O04vVnKHfrrhNAscndAn1tuQhIkwqnaW+eu5waD5IPts2eX1dgJxgqcPx5BX109/qAz7IG6VrEPTOYKCNfRQ=="],
"@typescript-eslint/typescript-estree": ["@typescript-eslint/typescript-estree@8.35.1", "", { "dependencies": { "@typescript-eslint/project-service": "8.35.1", "@typescript-eslint/tsconfig-utils": "8.35.1", "@typescript-eslint/types": "8.35.1", "@typescript-eslint/visitor-keys": "8.35.1", "debug": "^4.3.4", "fast-glob": "^3.3.2", "is-glob": "^4.0.3", "minimatch": "^9.0.4", "semver": "^7.6.0", "ts-api-utils": "^2.1.0" }, "peerDependencies": { "typescript": ">=4.8.4 <5.9.0" } }, "sha512-Vvpuvj4tBxIka7cPs6Y1uvM7gJgdF5Uu9F+mBJBPY4MhvjrjWGK4H0lVgLJd/8PWZ23FTqsaJaLEkBCFUk8Y9g=="],
"@typescript-eslint/utils": ["@typescript-eslint/utils@8.35.1", "", { "dependencies": { "@eslint-community/eslint-utils": "^4.7.0", "@typescript-eslint/scope-manager": "8.35.1", "@typescript-eslint/types": "8.35.1", "@typescript-eslint/typescript-estree": "8.35.1" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0", "typescript": ">=4.8.4 <5.9.0" } }, "sha512-lhnwatFmOFcazAsUm3ZnZFpXSxiwoa1Lj50HphnDe1Et01NF4+hrdXONSUHIcbVu2eFb1bAf+5yjXkGVkXBKAQ=="],
"@typescript-eslint/visitor-keys": ["@typescript-eslint/visitor-keys@8.35.1", "", { "dependencies": { "@typescript-eslint/types": "8.35.1", "eslint-visitor-keys": "^4.2.1" } }, "sha512-VRwixir4zBWCSTP/ljEo091lbpypz57PoeAQ9imjG+vbeof9LplljsL1mos4ccG6H9IjfrVGM359RozUnuFhpw=="],
"@vis.gl/react-mapbox": ["@vis.gl/react-mapbox@8.0.4", "", { "peerDependencies": { "mapbox-gl": ">=3.5.0", "react": ">=16.3.0", "react-dom": ">=16.3.0" }, "optionalPeers": ["mapbox-gl"] }, "sha512-NFk0vsWcNzSs0YCsVdt2100Zli9QWR+pje8DacpLkkGEAXFaJsFtI1oKD0Hatiate4/iAIW39SQHhgfhbeEPfQ=="],
"@vis.gl/react-maplibre": ["@vis.gl/react-maplibre@8.0.4", "", { "dependencies": { "@maplibre/maplibre-gl-style-spec": "^19.2.1" }, "peerDependencies": { "maplibre-gl": ">=4.0.0", "react": ">=16.3.0", "react-dom": ">=16.3.0" }, "optionalPeers": ["maplibre-gl"] }, "sha512-HwZyfLjEu+y1mUFvwDAkVxinGm8fEegaWN+O8np/WZ2Sqe5Lv6OXFpV6GWz9LOEvBYMbGuGk1FQdejo+4HCJ5w=="],
"@vitejs/plugin-react-swc": ["@vitejs/plugin-react-swc@3.10.2", "", { "dependencies": { "@rolldown/pluginutils": "1.0.0-beta.11", "@swc/core": "^1.11.31" }, "peerDependencies": { "vite": "^4 || ^5 || ^6 || ^7.0.0-beta.0" } }, "sha512-xD3Rdvrt5LgANug7WekBn1KhcvLn1H3jNBfJRL3reeOIua/WnZOEV5qi5qIBq5T8R0jUDmRtxuvk4bPhzGHDWw=="],
"@zag-js/accordion": ["@zag-js/accordion@1.17.4", "", { "dependencies": { "@zag-js/anatomy": "1.17.4", "@zag-js/core": "1.17.4", "@zag-js/dom-query": "1.17.4", "@zag-js/types": "1.17.4", "@zag-js/utils": "1.17.4" } }, "sha512-WkzoksfxJjuSdq+hIHCINc6hQtoYo5Nf0SfuInBiehRnoJtVjmpqk8VLxhLWhwFD/KMqz0wtWcM0itUGNpOyiw=="],
"@zag-js/anatomy": ["@zag-js/anatomy@1.17.4", "", {}, "sha512-EDc7dD5nnr5T3kujMc+EvWIAACZ45cyeKKiPDUCAsmrOAYxIpD+Efh5lvKum6XLIUyUNnkpEVTazVNOeaoZBtQ=="],
"@zag-js/angle-slider": ["@zag-js/angle-slider@1.17.4", "", { "dependencies": { "@zag-js/anatomy": "1.17.4", "@zag-js/core": "1.17.4", "@zag-js/dom-query": "1.17.4", "@zag-js/rect-utils": "1.17.4", "@zag-js/types": "1.17.4", "@zag-js/utils": "1.17.4" } }, "sha512-atke7qq2dd2f4Om4T6k9GYi5bvUdBWDuwDIaBC39Kygyrj8IjShlcyv+QETbX0MaghIhbLBJQuvc+7G3eIMF1A=="],
"@zag-js/aria-hidden": ["@zag-js/aria-hidden@1.17.4", "", {}, "sha512-P7aSTINxBwGbDUxhemto10JsajbE+kIzKrPMOWAbIipfFSwPtaN4XJRg2aQHZFBuHNm1n2x87n2TJBwjAlPiNQ=="],
"@zag-js/auto-resize": ["@zag-js/auto-resize@1.17.4", "", { "dependencies": { "@zag-js/dom-query": "1.17.4" } }, "sha512-kCC0cvuxG/yf28P52waRlz7FaliPrOyPXH+XM+GrznLkC8/TpMeR092G9+oHiYauNESTb+yyQzGgKqW6xFd/Rw=="],
"@zag-js/avatar": ["@zag-js/avatar@1.17.4", "", { "dependencies": { "@zag-js/anatomy": "1.17.4", "@zag-js/core": "1.17.4", "@zag-js/dom-query": "1.17.4", "@zag-js/types": "1.17.4", "@zag-js/utils": "1.17.4" } }, "sha512-+B4esXErOoiYNmHarg9aZWAhUhx6bzoIp31zCMkb6lNUKCDb8hBpFIWYpkgOrPmMaMka2zSYSvpfx6+4zA1Lcg=="],
"@zag-js/carousel": ["@zag-js/carousel@1.17.4", "", { "dependencies": { "@zag-js/anatomy": "1.17.4", "@zag-js/core": "1.17.4", "@zag-js/dom-query": "1.17.4", "@zag-js/scroll-snap": "1.17.4", "@zag-js/types": "1.17.4", "@zag-js/utils": "1.17.4" } }, "sha512-/n6nK5N9d+j3C+Q5GFnkeX4pMzZY/spKKhAbEMk2MPIHcbX50Ozdn+2MIGz0opAWtVwMXPhbl+WFeoNr8jbiSw=="],
"@zag-js/checkbox": ["@zag-js/checkbox@1.17.4", "", { "dependencies": { "@zag-js/anatomy": "1.17.4", "@zag-js/core": "1.17.4", "@zag-js/dom-query": "1.17.4", "@zag-js/focus-visible": "1.17.4", "@zag-js/types": "1.17.4", "@zag-js/utils": "1.17.4" } }, "sha512-nHrbGhHHUdtvkaJ4jAeCzAG5ioEm719a815oxji2rM1Ei+tCD0mrHCntIeuFejVCGnvR2wFnNJaWaZlES85Vqw=="],
"@zag-js/clipboard": ["@zag-js/clipboard@1.17.4", "", { "dependencies": { "@zag-js/anatomy": "1.17.4", "@zag-js/core": "1.17.4", "@zag-js/dom-query": "1.17.4", "@zag-js/types": "1.17.4", "@zag-js/utils": "1.17.4" } }, "sha512-WieXgxRCbBayngNSSMMj2zVcR0QO0cT5cZZuYLSn1eTbglo9J4sAX1QyEvHwbZWVt/rEokj3Gdp/Pme6rAQpwQ=="],
"@zag-js/collapsible": ["@zag-js/collapsible@1.17.4", "", { "dependencies": { "@zag-js/anatomy": "1.17.4", "@zag-js/core": "1.17.4", "@zag-js/dom-query": "1.17.4", "@zag-js/types": "1.17.4", "@zag-js/utils": "1.17.4" } }, "sha512-2bDQYGYoiHWECQPQNeC8ekCshXoXb1i3yY9U3siSyKxMZdBL4VdW5+0UOQoleperbN9NONeEcHW0H10cPofEIA=="],
"@zag-js/collection": ["@zag-js/collection@1.17.4", "", { "dependencies": { "@zag-js/utils": "1.17.4" } }, "sha512-N4FUhh6avw146IAUKxMj57clXOoN1XjY45ETWJMfahlmmmnttaCKuiiUj57/XIgmt3Vpg2bYIthcyTxeI+K4QQ=="],
"@zag-js/color-picker": ["@zag-js/color-picker@1.17.4", "", { "dependencies": { "@zag-js/anatomy": "1.17.4", "@zag-js/color-utils": "1.17.4", "@zag-js/core": "1.17.4", "@zag-js/dismissable": "1.17.4", "@zag-js/dom-query": "1.17.4", "@zag-js/popper": "1.17.4", "@zag-js/types": "1.17.4", "@zag-js/utils": "1.17.4" } }, "sha512-Zue+eoBeTyKNiHW8lSN+GMWHWsPdl0yZozuRmtuxpKYnI30SSr6GIs88GCY9Inosxz9RqKx7t7TMxsyJlLiJVA=="],
"@zag-js/color-utils": ["@zag-js/color-utils@1.17.4", "", { "dependencies": { "@zag-js/utils": "1.17.4" } }, "sha512-gasEa7yNMRW3dyJPtSVgZkXB5yrDF21XEaT+x8QLzj7WDutXeCOVPpc1GzBD+DupCcb6mTMUbhYdaf52WQxmWA=="],
"@zag-js/combobox": ["@zag-js/combobox@1.17.4", "", { "dependencies": { "@zag-js/anatomy": "1.17.4", "@zag-js/aria-hidden": "1.17.4", "@zag-js/collection": "1.17.4", "@zag-js/core": "1.17.4", "@zag-js/dismissable": "1.17.4", "@zag-js/dom-query": "1.17.4", "@zag-js/popper": "1.17.4", "@zag-js/types": "1.17.4", "@zag-js/utils": "1.17.4" } }, "sha512-E7mDsVEcIVbRUUIzsI8+OfXyTdPCih60/g7SRd5Mu8cLnzOxdC4tmeoIY+42otPr0e1bieVMjUXTEKR7wvQuAA=="],
"@zag-js/core": ["@zag-js/core@1.17.4", "", { "dependencies": { "@zag-js/dom-query": "1.17.4", "@zag-js/utils": "1.17.4" } }, "sha512-DIL2MXMLBYKR3pnjGGodiEUkY+ST/J81gtIJ32bLYxWWiMeX0SoPIvDZ9tqDHub9Kkd5CF07onXHkdAmB9Djrg=="],
"@zag-js/date-picker": ["@zag-js/date-picker@1.17.4", "", { "dependencies": { "@zag-js/anatomy": "1.17.4", "@zag-js/core": "1.17.4", "@zag-js/date-utils": "1.17.4", "@zag-js/dismissable": "1.17.4", "@zag-js/dom-query": "1.17.4", "@zag-js/live-region": "1.17.4", "@zag-js/popper": "1.17.4", "@zag-js/types": "1.17.4", "@zag-js/utils": "1.17.4" }, "peerDependencies": { "@internationalized/date": ">=3.0.0" } }, "sha512-yNYLFlNnmBI+9gzHmrGrDsGSeHa8cj6+pWhNutIVAT9pyEmg/6AciFndL5+P9bolKo59qtXLpX8libxZ4wLr2g=="],
"@zag-js/date-utils": ["@zag-js/date-utils@1.17.4", "", { "peerDependencies": { "@internationalized/date": ">=3.0.0" } }, "sha512-kPw7GLnj560NdUpXJ1SeoJkNSIddZBa+Sd2fPlyDwqxB5lptqNeRK9FcascRL12PgI7EeM7/R9MVTkTPGdQNjg=="],
"@zag-js/dialog": ["@zag-js/dialog@1.17.4", "", { "dependencies": { "@zag-js/anatomy": "1.17.4", "@zag-js/aria-hidden": "1.17.4", "@zag-js/core": "1.17.4", "@zag-js/dismissable": "1.17.4", "@zag-js/dom-query": "1.17.4", "@zag-js/focus-trap": "1.17.4", "@zag-js/remove-scroll": "1.17.4", "@zag-js/types": "1.17.4", "@zag-js/utils": "1.17.4" } }, "sha512-UCTcGlAlbTSS2Po5XvOOl7FiLba5+kh0Vltz8NAZUNn4e87LeitQVTW68k/pxa2nnnaKfPN6CsAWYQ21aZOcwA=="],
"@zag-js/dismissable": ["@zag-js/dismissable@1.17.4", "", { "dependencies": { "@zag-js/dom-query": "1.17.4", "@zag-js/interact-outside": "1.17.4", "@zag-js/utils": "1.17.4" } }, "sha512-LkFdUz2Ay3D/CsSjQSVjxQwzH6U5rU6cvEcUTOM90RUSozuV2pAK5NnI3JH3jAy1USlpTbjxHL+2bdep2jkAEg=="],
"@zag-js/dom-query": ["@zag-js/dom-query@1.17.4", "", { "dependencies": { "@zag-js/types": "1.17.4" } }, "sha512-1fNDCWkHRZXB4dD2hoiyMy0cSkrB/u4fur3To5sOKteka5e9om1/YdbYxXNLmVfeTiC/SJtWNelXP7c/8uDwOw=="],
"@zag-js/editable": ["@zag-js/editable@1.17.4", "", { "dependencies": { "@zag-js/anatomy": "1.17.4", "@zag-js/core": "1.17.4", "@zag-js/dom-query": "1.17.4", "@zag-js/interact-outside": "1.17.4", "@zag-js/types": "1.17.4", "@zag-js/utils": "1.17.4" } }, "sha512-qTfvrhbHtfvFZv3l+qAlweOpWyzDwYRQ1xrI+Sc8pCHhml6QiZ1UFUpYbiQWPn7dqdzBEVUIhjzDX4lzjsWGSA=="],
"@zag-js/file-upload": ["@zag-js/file-upload@1.17.4", "", { "dependencies": { "@zag-js/anatomy": "1.17.4", "@zag-js/core": "1.17.4", "@zag-js/dom-query": "1.17.4", "@zag-js/file-utils": "1.17.4", "@zag-js/i18n-utils": "1.17.4", "@zag-js/types": "1.17.4", "@zag-js/utils": "1.17.4" } }, "sha512-onV7jN2l9oXcKAuO/KY0TNcqyaFroQ8JjY+QxOOrZEmhvo48h/Lbi0FwBfk3syNWCRK3ihpRQbKOa1lthupGjg=="],
"@zag-js/file-utils": ["@zag-js/file-utils@1.17.4", "", { "dependencies": { "@zag-js/i18n-utils": "1.17.4" } }, "sha512-eg+ywy2qJn+rXz7wBsJc0N0H6qmKEMvxaWtsynBZ+XDbyrEec/aHNRDaM+l5xdFjDKb5/R151nEDXgnBAT8miA=="],
"@zag-js/floating-panel": ["@zag-js/floating-panel@1.17.4", "", { "dependencies": { "@zag-js/anatomy": "1.17.4", "@zag-js/core": "1.17.4", "@zag-js/dismissable": "1.17.4", "@zag-js/dom-query": "1.17.4", "@zag-js/popper": "1.17.4", "@zag-js/rect-utils": "1.17.4", "@zag-js/store": "1.17.4", "@zag-js/types": "1.17.4", "@zag-js/utils": "1.17.4" } }, "sha512-YgGP0PybQ0adlW6aOkFaho1tOzSk0rIVhCzsCQmln9mhSYgSCgwMoJIqfsFTLVpKB7TO155okOh5kwelH75Jfw=="],
"@zag-js/focus-trap": ["@zag-js/focus-trap@1.17.4", "", { "dependencies": { "@zag-js/dom-query": "1.17.4" } }, "sha512-6exU3DOkyqE2LSRydhgQIho/XhNOvQ35AEbYN81I6yniJPARbkGmDcQaKHZXSL7+tAe0ynX09yfVo4Cskio8Ow=="],
"@zag-js/focus-visible": ["@zag-js/focus-visible@1.17.4", "", { "dependencies": { "@zag-js/dom-query": "1.17.4" } }, "sha512-9P1GtsFqbuLcplwK/Y7MdnQz9NipYUjef8PS2/duQzRf3UM99/zu1ZbRqwNIW/Tf5ztvet3+dMBAN5HEyYW0Rw=="],
"@zag-js/highlight-word": ["@zag-js/highlight-word@1.17.4", "", {}, "sha512-uBK/5OsopYE5qBjkIoQuqvgd6CTnKpttt4+ODFjPV0NPImgcDuqBT1KlFZZZEPZ58fu1TtNU6hNVKHmZ4EzUnw=="],
"@zag-js/hover-card": ["@zag-js/hover-card@1.17.4", "", { "dependencies": { "@zag-js/anatomy": "1.17.4", "@zag-js/core": "1.17.4", "@zag-js/dismissable": "1.17.4", "@zag-js/dom-query": "1.17.4", "@zag-js/popper": "1.17.4", "@zag-js/types": "1.17.4", "@zag-js/utils": "1.17.4" } }, "sha512-yOVqj2KUxcMZx6B0LpkMRa1q736eVUXTzQD6Keh4cKxtnCFE+ydYVv70xHL4CLWFqz6+PFRYApgzd05IIbff7w=="],
"@zag-js/i18n-utils": ["@zag-js/i18n-utils@1.17.4", "", { "dependencies": { "@zag-js/dom-query": "1.17.4" } }, "sha512-HiRKMQGaZUpjqekq1h1UlMqquIBnQYSiGpW9vWCUbKs5hr7z3VIgJtKoxdCsBkno7vBEejl316DIIDh3N2qbeA=="],
"@zag-js/interact-outside": ["@zag-js/interact-outside@1.17.4", "", { "dependencies": { "@zag-js/dom-query": "1.17.4", "@zag-js/utils": "1.17.4" } }, "sha512-jd7/4V7ESS6FJILPWIm5CmXVR+maZ4fQmQUPV56WOURKdl2LZ2bPgfjvEaVI9BTm7qPTML6O55xgB87rS/sXlw=="],
"@zag-js/listbox": ["@zag-js/listbox@1.17.4", "", { "dependencies": { "@zag-js/anatomy": "1.17.4", "@zag-js/collection": "1.17.4", "@zag-js/core": "1.17.4", "@zag-js/dom-query": "1.17.4", "@zag-js/focus-visible": "1.17.4", "@zag-js/types": "1.17.4", "@zag-js/utils": "1.17.4" } }, "sha512-14OReAbUZNEYjy2eBPqI7FUxts0kTjQS268aukfzLvHcJHAHTcP9ru7XMftZlPbQBofPGr/lSLhIa4NZJF3vrw=="],
"@zag-js/live-region": ["@zag-js/live-region@1.17.4", "", {}, "sha512-fP2f6C6vEcWydvhYKMYWaVu8tqyiCnKJx8auJ2zL/yZGLz/W3xDdRRqHJCfneilN7m8C6tJhWBBZm5Th22bGmQ=="],
"@zag-js/menu": ["@zag-js/menu@1.17.4", "", { "dependencies": { "@zag-js/anatomy": "1.17.4", "@zag-js/core": "1.17.4", "@zag-js/dismissable": "1.17.4", "@zag-js/dom-query": "1.17.4", "@zag-js/popper": "1.17.4", "@zag-js/rect-utils": "1.17.4", "@zag-js/types": "1.17.4", "@zag-js/utils": "1.17.4" } }, "sha512-KzpvU/rPiPFDexcD+RmcLhPOII5SPgGSSdidpz3pTBy8yEwnwOSoN0PGHm8WnOD4US2wZOHvOqR+Rov8IbmKWw=="],
"@zag-js/number-input": ["@zag-js/number-input@1.17.4", "", { "dependencies": { "@internationalized/number": "3.6.3", "@zag-js/anatomy": "1.17.4", "@zag-js/core": "1.17.4", "@zag-js/dom-query": "1.17.4", "@zag-js/types": "1.17.4", "@zag-js/utils": "1.17.4" } }, "sha512-lyrZwr3X1wicL8MThZvu4JH5pwldYO2gKQ+CVgMTx6H2epQNVJJ9i8v/+buUNB9/2ufjUV0MaxQ2fuGTXyjAKw=="],
"@zag-js/pagination": ["@zag-js/pagination@1.17.4", "", { "dependencies": { "@zag-js/anatomy": "1.17.4", "@zag-js/core": "1.17.4", "@zag-js/dom-query": "1.17.4", "@zag-js/types": "1.17.4", "@zag-js/utils": "1.17.4" } }, "sha512-yTOcwRdJ0CozEzw0Q+lAUkpWUERFVCCSx9qqIAGqF5jEZSWefUWMQVcPRqupLQ51mhCXdt+wDDh2mTY6Mr+L3A=="],
"@zag-js/password-input": ["@zag-js/password-input@1.17.4", "", { "dependencies": { "@zag-js/anatomy": "1.17.4", "@zag-js/core": "1.17.4", "@zag-js/dom-query": "1.17.4", "@zag-js/types": "1.17.4", "@zag-js/utils": "1.17.4" } }, "sha512-h77V18+KBvZHUcARnr+Qw+P5vGvvSC9UMzjnE2SpMIpyvOIr1Fp+4TCGKVEIIsWR0LzWnK79UNExVj1Th3t1TQ=="],
"@zag-js/pin-input": ["@zag-js/pin-input@1.17.4", "", { "dependencies": { "@zag-js/anatomy": "1.17.4", "@zag-js/core": "1.17.4", "@zag-js/dom-query": "1.17.4", "@zag-js/types": "1.17.4", "@zag-js/utils": "1.17.4" } }, "sha512-k2rhmS0oAPUE93DgdHtV7HkpBvTj3iGvUusVwmifE42ct1VnuuedXHKlicGbJ2ZXWelXmKd5675LHfwmF68h2A=="],
"@zag-js/popover": ["@zag-js/popover@1.17.4", "", { "dependencies": { "@zag-js/anatomy": "1.17.4", "@zag-js/aria-hidden": "1.17.4", "@zag-js/core": "1.17.4", "@zag-js/dismissable": "1.17.4", "@zag-js/dom-query": "1.17.4", "@zag-js/focus-trap": "1.17.4", "@zag-js/popper": "1.17.4", "@zag-js/remove-scroll": "1.17.4", "@zag-js/types": "1.17.4", "@zag-js/utils": "1.17.4" } }, "sha512-uDRfw5/F3FPeanOJbXnVmk5c+RFFkQozZ6dn3qdnynWn1sLh56Kf5Ys4X+MQInxqUKdtDCb7cO2tfkAZXE5ZOA=="],
"@zag-js/popper": ["@zag-js/popper@1.17.4", "", { "dependencies": { "@floating-ui/dom": "1.7.1", "@zag-js/dom-query": "1.17.4", "@zag-js/utils": "1.17.4" } }, "sha512-ZdlDcaBzDx4XUzicTviaCP0Q6W1AXwRzdPVO2TzosqQyyn/tYqEfcJePYu9XVsr1Y6bkume4Pt0ucuRN+kUeYQ=="],
"@zag-js/presence": ["@zag-js/presence@1.17.4", "", { "dependencies": { "@zag-js/core": "1.17.4", "@zag-js/dom-query": "1.17.4", "@zag-js/types": "1.17.4" } }, "sha512-xFEITSvZjoNYh3Ea+48tFqwwsOtSeEa27c3GOa1ToCTs0J+7SrP19bj5w7Hnbk5cGY/4P5OD8OiMKvkPughjEw=="],
"@zag-js/progress": ["@zag-js/progress@1.17.4", "", { "dependencies": { "@zag-js/anatomy": "1.17.4", "@zag-js/core": "1.17.4", "@zag-js/dom-query": "1.17.4", "@zag-js/types": "1.17.4", "@zag-js/utils": "1.17.4" } }, "sha512-1FWUIizd8OMcK+0uUA/6ly3VJd5eHeOZkXC4lIWDGGwLhfEv2Lm+pgF5Ix5u1mtcmawBbhpkSlYjc1CbsjUTQQ=="],
"@zag-js/qr-code": ["@zag-js/qr-code@1.17.4", "", { "dependencies": { "@zag-js/anatomy": "1.17.4", "@zag-js/core": "1.17.4", "@zag-js/dom-query": "1.17.4", "@zag-js/types": "1.17.4", "@zag-js/utils": "1.17.4", "proxy-memoize": "3.0.1", "uqr": "0.1.2" } }, "sha512-z2FLUlGCLmKcNyXCdeWJkovLo4NvFdRAe43psn0M8rhd470rYCzol1/86s2G72DjqUT0ZwadkfgRjLfaLHkYdQ=="],
"@zag-js/radio-group": ["@zag-js/radio-group@1.17.4", "", { "dependencies": { "@zag-js/anatomy": "1.17.4", "@zag-js/core": "1.17.4", "@zag-js/dom-query": "1.17.4", "@zag-js/focus-visible": "1.17.4", "@zag-js/types": "1.17.4", "@zag-js/utils": "1.17.4" } }, "sha512-/u9ugWth+FPu3W1VUTuBIVq3TbJZMLYF8cFPhvTgIjBvbQw9Oe+TW+WywyH1z7Oaz03e4IYhW445sWGoC9TNvw=="],
"@zag-js/rating-group": ["@zag-js/rating-group@1.17.4", "", { "dependencies": { "@zag-js/anatomy": "1.17.4", "@zag-js/core": "1.17.4", "@zag-js/dom-query": "1.17.4", "@zag-js/types": "1.17.4", "@zag-js/utils": "1.17.4" } }, "sha512-5KQdf+CLX3RzCu7Bj8Xn7AKeDU+sxCjxCcbjs8VviLl6Rj/OaFUoUomZFf/wLsJLY1tqk6PD7dX4NczY7YC2YQ=="],
"@zag-js/react": ["@zag-js/react@1.17.4", "", { "dependencies": { "@zag-js/core": "1.17.4", "@zag-js/store": "1.17.4", "@zag-js/types": "1.17.4", "@zag-js/utils": "1.17.4" }, "peerDependencies": { "react": ">=18.0.0", "react-dom": ">=18.0.0" } }, "sha512-43TEe1Afjh1RR3Byxib/jZ2Wn4UVdZY5Irx5v3tnp8NY8BFeswPhP28e6W2NT4c/UZoWeRxYlXDdrRS2p8L8Wg=="],
"@zag-js/rect-utils": ["@zag-js/rect-utils@1.17.4", "", {}, "sha512-DiYNOwtVek9qwtbV906zjNpM8dmJL4sp131rPRgRStTg8MHpfW2PUOaxFklKh9/ykFwPDu6rx7kQ9Y2P4ez/xg=="],
"@zag-js/remove-scroll": ["@zag-js/remove-scroll@1.17.4", "", { "dependencies": { "@zag-js/dom-query": "1.17.4" } }, "sha512-EY+N1UodKfu2omYknbWfv+33pljfVW5ZX01iuSlTng3Vx5Zn6xlQCTxpVWvDidACEN6jjBn00QFbGWEhDDBpdw=="],
"@zag-js/scroll-snap": ["@zag-js/scroll-snap@1.17.4", "", { "dependencies": { "@zag-js/dom-query": "1.17.4" } }, "sha512-bdYtDdJjXcupjoTs5n3Z310wEDrsykgWIKVOy5r4daNp+aH99YHBvINt0BUzjfyCpoEH0KvM9KwKlwOhq7XUNA=="],
"@zag-js/select": ["@zag-js/select@1.17.4", "", { "dependencies": { "@zag-js/anatomy": "1.17.4", "@zag-js/collection": "1.17.4", "@zag-js/core": "1.17.4", "@zag-js/dismissable": "1.17.4", "@zag-js/dom-query": "1.17.4", "@zag-js/popper": "1.17.4", "@zag-js/types": "1.17.4", "@zag-js/utils": "1.17.4" } }, "sha512-Yy/83xydKl/Qz3BoeNCwu964lLRDqoF4fsOWPeOFEN6HHftLD7NNNO7eIqe2Qe84ZBwAeQeZ8cNNI2oYHFc/ag=="],
"@zag-js/signature-pad": ["@zag-js/signature-pad@1.17.4", "", { "dependencies": { "@zag-js/anatomy": "1.17.4", "@zag-js/core": "1.17.4", "@zag-js/dom-query": "1.17.4", "@zag-js/types": "1.17.4", "@zag-js/utils": "1.17.4", "perfect-freehand": "^1.2.2" } }, "sha512-nGv9uBNkq+jrLfdN+wuINA+ch0jZs/m1UUDcyUvpRfQa/AlkNdv9oC8p6KUJwNhunTQN6E2RCZqO43q49ioEtg=="],
"@zag-js/slider": ["@zag-js/slider@1.17.4", "", { "dependencies": { "@zag-js/anatomy": "1.17.4", "@zag-js/core": "1.17.4", "@zag-js/dom-query": "1.17.4", "@zag-js/types": "1.17.4", "@zag-js/utils": "1.17.4" } }, "sha512-Iq3pgLmJIvmQXaUm/+Xt1/s1IV1p73E7ySbThdZ8EADDn60m5ESVTwEymK9jnH10hpXuxDvI1GcbWPOTrIxwYQ=="],
"@zag-js/splitter": ["@zag-js/splitter@1.17.4", "", { "dependencies": { "@zag-js/anatomy": "1.17.4", "@zag-js/core": "1.17.4", "@zag-js/dom-query": "1.17.4", "@zag-js/types": "1.17.4", "@zag-js/utils": "1.17.4" } }, "sha512-6uThEf+gD0z6Nf6CYvp28I2zjfGW0JOdFAJDpwyqyngvGbO4oPkWPozn8uUmbovQrzhiyUx1C6o5UPDsLgFWhw=="],
"@zag-js/steps": ["@zag-js/steps@1.17.4", "", { "dependencies": { "@zag-js/anatomy": "1.17.4", "@zag-js/core": "1.17.4", "@zag-js/dom-query": "1.17.4", "@zag-js/types": "1.17.4", "@zag-js/utils": "1.17.4" } }, "sha512-MSPtDEkPpQTQ/LTsTRhSeG/P4TCl9b0/nKf/cMT/KlmrK7pTonjkDvux/AQHLxkqZ+tMZYl7qYd/ocdARe1mtA=="],
"@zag-js/store": ["@zag-js/store@1.17.4", "", { "dependencies": { "proxy-compare": "3.0.1" } }, "sha512-80i4/ggb2OrZ9+l1EJgYcp8uBy5oJwwae/kzy2/r93P+gotct5/qiyZYrybE8+YhU0u5zPiyjTxH0SILfP9Ofg=="],
"@zag-js/switch": ["@zag-js/switch@1.17.4", "", { "dependencies": { "@zag-js/anatomy": "1.17.4", "@zag-js/core": "1.17.4", "@zag-js/dom-query": "1.17.4", "@zag-js/focus-visible": "1.17.4", "@zag-js/types": "1.17.4", "@zag-js/utils": "1.17.4" } }, "sha512-d5kBKe+q7V87V6K3BcsfJ1jU2qiJvPLjBumUDFkrzU0E5jweVOOwYrqDzLX8X4cBXk9A2R6U8rYdgGwWDctmWQ=="],
"@zag-js/tabs": ["@zag-js/tabs@1.17.4", "", { "dependencies": { "@zag-js/anatomy": "1.17.4", "@zag-js/core": "1.17.4", "@zag-js/dom-query": "1.17.4", "@zag-js/types": "1.17.4", "@zag-js/utils": "1.17.4" } }, "sha512-jvchw7erb8ryQTR92QQyP64nmJPJHCeOr6s09ghYqyNIVI5xgVy5hcfgrE4iMXODJ9CSAMsZHqY7QN5Xq10l3Q=="],
"@zag-js/tags-input": ["@zag-js/tags-input@1.17.4", "", { "dependencies": { "@zag-js/anatomy": "1.17.4", "@zag-js/auto-resize": "1.17.4", "@zag-js/core": "1.17.4", "@zag-js/dom-query": "1.17.4", "@zag-js/interact-outside": "1.17.4", "@zag-js/live-region": "1.17.4", "@zag-js/types": "1.17.4", "@zag-js/utils": "1.17.4" } }, "sha512-BYzvgIdqjv2LZSf5tfRECklCEt9u/uyc4gaGOiEseNIzcyQ9xrg9fq2Yk6Wt8mhWujdCbC/zJS2RB3LdcVePng=="],
"@zag-js/time-picker": ["@zag-js/time-picker@1.17.4", "", { "dependencies": { "@zag-js/anatomy": "1.17.4", "@zag-js/core": "1.17.4", "@zag-js/dismissable": "1.17.4", "@zag-js/dom-query": "1.17.4", "@zag-js/popper": "1.17.4", "@zag-js/types": "1.17.4", "@zag-js/utils": "1.17.4" }, "peerDependencies": { "@internationalized/date": ">=3.0.0" } }, "sha512-HGMIWqmpo2/cybCLNaPuMfRZx/wjkNAJKm33oZJXqwpc6rxWvh8bpEtpEOp7WDwWifthc/6VBUI5Smc+aO6oVA=="],
"@zag-js/timer": ["@zag-js/timer@1.17.4", "", { "dependencies": { "@zag-js/anatomy": "1.17.4", "@zag-js/core": "1.17.4", "@zag-js/dom-query": "1.17.4", "@zag-js/types": "1.17.4", "@zag-js/utils": "1.17.4" } }, "sha512-jDUIz4jgZAFqAOra/9Ng3mraMMnh1fTHtUAzFgolzwY6V8l2eAMGX0DrXtoEVqxlh4IGE00xN6Kus9j3NfcUOA=="],
"@zag-js/toast": ["@zag-js/toast@1.17.4", "", { "dependencies": { "@zag-js/anatomy": "1.17.4", "@zag-js/core": "1.17.4", "@zag-js/dismissable": "1.17.4", "@zag-js/dom-query": "1.17.4", "@zag-js/types": "1.17.4", "@zag-js/utils": "1.17.4" } }, "sha512-lhu0mhHLpT2DaI9d6BjlE2vJEL9/jFmyPGJ9QG9kkQAxDNtEJLiCJEe12mKs5S9LoxDHJGWGYkF2O/7XwLkDnA=="],
"@zag-js/toggle": ["@zag-js/toggle@1.17.4", "", { "dependencies": { "@zag-js/anatomy": "1.17.4", "@zag-js/core": "1.17.4", "@zag-js/dom-query": "1.17.4", "@zag-js/types": "1.17.4", "@zag-js/utils": "1.17.4" } }, "sha512-cKggg0TaGErAZmYXWGMHH81Gti+AXLMqT29V7EM2qI2tWQzzsmbDbUVoEQ7iZf8Ng6d/JfsZsLq6biZZHg6KsA=="],
"@zag-js/toggle-group": ["@zag-js/toggle-group@1.17.4", "", { "dependencies": { "@zag-js/anatomy": "1.17.4", "@zag-js/core": "1.17.4", "@zag-js/dom-query": "1.17.4", "@zag-js/types": "1.17.4", "@zag-js/utils": "1.17.4" } }, "sha512-cegFuo8X66MX7b06n6rIJlf4hFDPejmZeq1eSu7co4hVKAfqazBFh6SGsnKdIXhOUo162tFchNuKMkhZU3sWBQ=="],
"@zag-js/tooltip": ["@zag-js/tooltip@1.17.4", "", { "dependencies": { "@zag-js/anatomy": "1.17.4", "@zag-js/core": "1.17.4", "@zag-js/dom-query": "1.17.4", "@zag-js/focus-visible": "1.17.4", "@zag-js/popper": "1.17.4", "@zag-js/store": "1.17.4", "@zag-js/types": "1.17.4", "@zag-js/utils": "1.17.4" } }, "sha512-lDRXZjd7anVb4h2ZvDCYYZ+puJZZwry5xi72jY6xhz3vVWX5qfkYjZ/MHuuDk/S+fEY+luWJXJ+cPh+v1zie0g=="],
"@zag-js/tour": ["@zag-js/tour@1.17.4", "", { "dependencies": { "@zag-js/anatomy": "1.17.4", "@zag-js/core": "1.17.4", "@zag-js/dismissable": "1.17.4", "@zag-js/dom-query": "1.17.4", "@zag-js/focus-trap": "1.17.4", "@zag-js/interact-outside": "1.17.4", "@zag-js/popper": "1.17.4", "@zag-js/types": "1.17.4", "@zag-js/utils": "1.17.4" } }, "sha512-RSnzJLTygsMPUXcMuYY0GWTskfwDsSeyM5Jbn5iMUUphnj/3nCtZttbsA22jnXCYE8bK+/+6PnfdcD0Elysf7Q=="],
"@zag-js/tree-view": ["@zag-js/tree-view@1.17.4", "", { "dependencies": { "@zag-js/anatomy": "1.17.4", "@zag-js/collection": "1.17.4", "@zag-js/core": "1.17.4", "@zag-js/dom-query": "1.17.4", "@zag-js/types": "1.17.4", "@zag-js/utils": "1.17.4" } }, "sha512-XRc2DxB/gVrkmS7+ZTJBC8p0G1J+mqtFb5zzRxyNitp+VW7yMsRtAUJ7m5gT5bD71zOkk4fPhwuB+ZZtpPAaMQ=="],
"@zag-js/types": ["@zag-js/types@1.17.4", "", { "dependencies": { "csstype": "3.1.3" } }, "sha512-GHE1ykkMeHuIPHkkU1JNcIWMoFH322Yq65S4dhhsEgqMRX3BUHW8ids5e+7WOu9ZSH3PGJdpUXe8+jg3USpwaw=="],
"@zag-js/utils": ["@zag-js/utils@1.17.4", "", {}, "sha512-FXici9HJG1ZBLCmbHO/ed4iurDriDjdx8XOfSD052bu22ViWl5jnO2K77OwagexbXGGAJNhswvDeQg5CSqYbvA=="],
"acorn": ["acorn@8.15.0", "", { "bin": { "acorn": "bin/acorn" } }, "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg=="],
"acorn-jsx": ["acorn-jsx@5.3.2", "", { "peerDependencies": { "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" } }, "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ=="],
"ajv": ["ajv@6.12.6", "", { "dependencies": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", "json-schema-traverse": "^0.4.1", "uri-js": "^4.2.2" } }, "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g=="],
"ansi-styles": ["ansi-styles@4.3.0", "", { "dependencies": { "color-convert": "^2.0.1" } }, "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg=="],
"argparse": ["argparse@2.0.1", "", {}, "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q=="],
"arr-union": ["arr-union@3.1.0", "", {}, "sha512-sKpyeERZ02v1FeCZT8lrfJq5u6goHCtpTAzPwJYe7c8SPFOboNjNg1vz2L4VTn9T4PQxEx13TbXLmYUcS6Ug7Q=="],
"assign-symbols": ["assign-symbols@1.0.0", "", {}, "sha512-Q+JC7Whu8HhmTdBph/Tq59IoRtoy6KAm5zzPv00WdujX82lbAL8K7WVjne7vdCsAmbF4AYaDOPyO3k0kl8qIrw=="],
"babel-plugin-macros": ["babel-plugin-macros@3.1.0", "", { "dependencies": { "@babel/runtime": "^7.12.5", "cosmiconfig": "^7.0.0", "resolve": "^1.19.0" } }, "sha512-Cg7TFGpIr01vOQNODXOOaGz2NpCU5gl8x1qJFbb6hbZxR7XrcE2vtbAsTAbJ7/xwJtUuJEw8K8Zr/AE0LHlesg=="],
"balanced-match": ["balanced-match@1.0.2", "", {}, "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="],
"base-map": ["base-map@workspace:packages/base-map"],
"bevy_flurx_api": ["bevy_flurx_api@0.1.0", "", { "dependencies": { "global": "^4.4.0", "pnpm": "^9.15.0" } }, "sha512-h74CxORqMa7iwTGTPe5ItkABEf7ZQIRlUSbeYPSBkF1SXnFCAaeF7FE4FklFmpRCKTYhryqVez02h75QACr45g=="],
"brace-expansion": ["brace-expansion@1.1.12", "", { "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" } }, "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg=="],
"braces": ["braces@3.0.3", "", { "dependencies": { "fill-range": "^7.1.1" } }, "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA=="],
"bun-types": ["bun-types@1.2.18", "", { "dependencies": { "@types/node": "*" }, "peerDependencies": { "@types/react": "^19" } }, "sha512-04+Eha5NP7Z0A9YgDAzMk5PHR16ZuLVa83b26kH5+cp1qZW4F6FmAURngE7INf4tKOvCE69vYvDEwoNl1tGiWw=="],
"bytewise": ["bytewise@1.1.0", "", { "dependencies": { "bytewise-core": "^1.2.2", "typewise": "^1.0.3" } }, "sha512-rHuuseJ9iQ0na6UDhnrRVDh8YnWVlU6xM3VH6q/+yHDeUH2zIhUzP+2/h3LIrhLDBtTqzWpE3p3tP/boefskKQ=="],
"bytewise-core": ["bytewise-core@1.2.3", "", { "dependencies": { "typewise-core": "^1.2" } }, "sha512-nZD//kc78OOxeYtRlVk8/zXqTB4gf/nlguL1ggWA8FuchMyOxcyHR4QPQZMUmA7czC+YnaBrPUCubqAWe50DaA=="],
"callsites": ["callsites@3.1.0", "", {}, "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ=="],
"chalk": ["chalk@4.1.2", "", { "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" } }, "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA=="],
"cheap-ruler": ["cheap-ruler@4.0.0", "", {}, "sha512-0BJa8f4t141BYKQyn9NSQt1PguFQXMXwZiA5shfoaBYHAb2fFk2RAX+tiWMoQU+Agtzt3mdt0JtuyshAXqZ+Vw=="],
"color-convert": ["color-convert@2.0.1", "", { "dependencies": { "color-name": "~1.1.4" } }, "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ=="],
"color-name": ["color-name@1.1.4", "", {}, "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="],
"concat-map": ["concat-map@0.0.1", "", {}, "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg=="],
"convert-source-map": ["convert-source-map@1.9.0", "", {}, "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A=="],
"cosmiconfig": ["cosmiconfig@7.1.0", "", { "dependencies": { "@types/parse-json": "^4.0.0", "import-fresh": "^3.2.1", "parse-json": "^5.0.0", "path-type": "^4.0.0", "yaml": "^1.10.0" } }, "sha512-AdmX6xUzdNASswsFtmwSt7Vj8po9IuqXm0UXz7QKPuEUmPB4XyjGfaAr2PSuELMwkRMVH1EpIkX5bTZGRB3eCA=="],
"cross-spawn": ["cross-spawn@7.0.6", "", { "dependencies": { "path-key": "^3.1.0", "shebang-command": "^2.0.0", "which": "^2.0.1" } }, "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA=="],
"csscolorparser": ["csscolorparser@1.0.3", "", {}, "sha512-umPSgYwZkdFoUrH5hIq5kf0wPSXiro51nPw0j2K/c83KflkPSTBGMz6NJvMB+07VlL0y7VPo6QJcDjcgKTTm3w=="],
"csstype": ["csstype@3.1.3", "", {}, "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw=="],
"debug": ["debug@4.4.1", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ=="],
"deep-is": ["deep-is@0.1.4", "", {}, "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ=="],
"dom-walk": ["dom-walk@0.1.2", "", {}, "sha512-6QvTW9mrGeIegrFXdtQi9pk7O/nSK6lSdXW2eqUspN5LWD7UTji2Fqw5V2YLjBpHEoU9Xl/eUWNpDeZvoyOv2w=="],
"earcut": ["earcut@3.0.1", "", {}, "sha512-0l1/0gOjESMeQyYaK5IDiPNvFeu93Z/cO0TjZh9eZ1vyCtZnA7KMZ8rQggpsJHIbGSdrqYq9OhuveadOVHCshw=="],
"error-ex": ["error-ex@1.3.2", "", { "dependencies": { "is-arrayish": "^0.2.1" } }, "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g=="],
"esbuild": ["esbuild@0.25.5", "", { "optionalDependencies": { "@esbuild/aix-ppc64": "0.25.5", "@esbuild/android-arm": "0.25.5", "@esbuild/android-arm64": "0.25.5", "@esbuild/android-x64": "0.25.5", "@esbuild/darwin-arm64": "0.25.5", "@esbuild/darwin-x64": "0.25.5", "@esbuild/freebsd-arm64": "0.25.5", "@esbuild/freebsd-x64": "0.25.5", "@esbuild/linux-arm": "0.25.5", "@esbuild/linux-arm64": "0.25.5", "@esbuild/linux-ia32": "0.25.5", "@esbuild/linux-loong64": "0.25.5", "@esbuild/linux-mips64el": "0.25.5", "@esbuild/linux-ppc64": "0.25.5", "@esbuild/linux-riscv64": "0.25.5", "@esbuild/linux-s390x": "0.25.5", "@esbuild/linux-x64": "0.25.5", "@esbuild/netbsd-arm64": "0.25.5", "@esbuild/netbsd-x64": "0.25.5", "@esbuild/openbsd-arm64": "0.25.5", "@esbuild/openbsd-x64": "0.25.5", "@esbuild/sunos-x64": "0.25.5", "@esbuild/win32-arm64": "0.25.5", "@esbuild/win32-ia32": "0.25.5", "@esbuild/win32-x64": "0.25.5" }, "bin": { "esbuild": "bin/esbuild" } }, "sha512-P8OtKZRv/5J5hhz0cUAdu/cLuPIKXpQl1R9pZtvmHWQvrAUVd0UNIPT4IB4W3rNOqVO0rlqHmCIbSwxh/c9yUQ=="],
"escape-string-regexp": ["escape-string-regexp@4.0.0", "", {}, "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA=="],
"eslint": ["eslint@9.30.1", "", { "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", "@eslint-community/regexpp": "^4.12.1", "@eslint/config-array": "^0.21.0", "@eslint/config-helpers": "^0.3.0", "@eslint/core": "^0.14.0", "@eslint/eslintrc": "^3.3.1", "@eslint/js": "9.30.1", "@eslint/plugin-kit": "^0.3.1", "@humanfs/node": "^0.16.6", "@humanwhocodes/module-importer": "^1.0.1", "@humanwhocodes/retry": "^0.4.2", "@types/estree": "^1.0.6", "@types/json-schema": "^7.0.15", "ajv": "^6.12.4", "chalk": "^4.0.0", "cross-spawn": "^7.0.6", "debug": "^4.3.2", "escape-string-regexp": "^4.0.0", "eslint-scope": "^8.4.0", "eslint-visitor-keys": "^4.2.1", "espree": "^10.4.0", "esquery": "^1.5.0", "esutils": "^2.0.2", "fast-deep-equal": "^3.1.3", "file-entry-cache": "^8.0.0", "find-up": "^5.0.0", "glob-parent": "^6.0.2", "ignore": "^5.2.0", "imurmurhash": "^0.1.4", "is-glob": "^4.0.0", "json-stable-stringify-without-jsonify": "^1.0.1", "lodash.merge": "^4.6.2", "minimatch": "^3.1.2", "natural-compare": "^1.4.0", "optionator": "^0.9.3" }, "peerDependencies": { "jiti": "*" }, "optionalPeers": ["jiti"], "bin": { "eslint": "bin/eslint.js" } }, "sha512-zmxXPNMOXmwm9E0yQLi5uqXHs7uq2UIiqEKo3Gq+3fwo1XrJ+hijAZImyF7hclW3E6oHz43Yk3RP8at6OTKflQ=="],
"eslint-plugin-react-hooks": ["eslint-plugin-react-hooks@5.2.0", "", { "peerDependencies": { "eslint": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0 || ^9.0.0" } }, "sha512-+f15FfK64YQwZdJNELETdn5ibXEUQmW1DZL6KXhNnc2heoy/sg9VJJeT7n8TlMWouzWqSWavFkIhHyIbIAEapg=="],
"eslint-plugin-react-refresh": ["eslint-plugin-react-refresh@0.4.20", "", { "peerDependencies": { "eslint": ">=8.40" } }, "sha512-XpbHQ2q5gUF8BGOX4dHe+71qoirYMhApEPZ7sfhF/dNnOF1UXnCMGZf79SFTBO7Bz5YEIT4TMieSlJBWhP9WBA=="],
"eslint-scope": ["eslint-scope@8.4.0", "", { "dependencies": { "esrecurse": "^4.3.0", "estraverse": "^5.2.0" } }, "sha512-sNXOfKCn74rt8RICKMvJS7XKV/Xk9kA7DyJr8mJik3S7Cwgy3qlkkmyS2uQB3jiJg6VNdZd/pDBJu0nvG2NlTg=="],
"eslint-visitor-keys": ["eslint-visitor-keys@4.2.1", "", {}, "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ=="],
"espree": ["espree@10.4.0", "", { "dependencies": { "acorn": "^8.15.0", "acorn-jsx": "^5.3.2", "eslint-visitor-keys": "^4.2.1" } }, "sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ=="],
"esquery": ["esquery@1.6.0", "", { "dependencies": { "estraverse": "^5.1.0" } }, "sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg=="],
"esrecurse": ["esrecurse@4.3.0", "", { "dependencies": { "estraverse": "^5.2.0" } }, "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag=="],
"estraverse": ["estraverse@5.3.0", "", {}, "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA=="],
"esutils": ["esutils@2.0.3", "", {}, "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g=="],
"extend-shallow": ["extend-shallow@2.0.1", "", { "dependencies": { "is-extendable": "^0.1.0" } }, "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug=="],
"fast-deep-equal": ["fast-deep-equal@3.1.3", "", {}, "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q=="],
"fast-glob": ["fast-glob@3.3.3", "", { "dependencies": { "@nodelib/fs.stat": "^2.0.2", "@nodelib/fs.walk": "^1.2.3", "glob-parent": "^5.1.2", "merge2": "^1.3.0", "micromatch": "^4.0.8" } }, "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg=="],
"fast-json-stable-stringify": ["fast-json-stable-stringify@2.1.0", "", {}, "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw=="],
"fast-levenshtein": ["fast-levenshtein@2.0.6", "", {}, "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw=="],
"fast-safe-stringify": ["fast-safe-stringify@2.1.1", "", {}, "sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA=="],
"fastq": ["fastq@1.19.1", "", { "dependencies": { "reusify": "^1.0.4" } }, "sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ=="],
"fdir": ["fdir@6.4.6", "", { "peerDependencies": { "picomatch": "^3 || ^4" }, "optionalPeers": ["picomatch"] }, "sha512-hiFoqpyZcfNm1yc4u8oWCf9A2c4D3QjCrks3zmoVKVxpQRzmPNar1hUJcBG2RQHvEVGDN+Jm81ZheVLAQMK6+w=="],
"file-entry-cache": ["file-entry-cache@8.0.0", "", { "dependencies": { "flat-cache": "^4.0.0" } }, "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ=="],
"fill-range": ["fill-range@7.1.1", "", { "dependencies": { "to-regex-range": "^5.0.1" } }, "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg=="],
"find-root": ["find-root@1.1.0", "", {}, "sha512-NKfW6bec6GfKc0SGx1e07QZY9PE99u0Bft/0rzSD5k3sO/vwkVUpDUKVm5Gpp5Ue3YfShPFTX2070tDs5kB9Ng=="],
"find-up": ["find-up@5.0.0", "", { "dependencies": { "locate-path": "^6.0.0", "path-exists": "^4.0.0" } }, "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng=="],
"flat-cache": ["flat-cache@4.0.1", "", { "dependencies": { "flatted": "^3.2.9", "keyv": "^4.5.4" } }, "sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw=="],
"flatted": ["flatted@3.3.3", "", {}, "sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg=="],
"fsevents": ["fsevents@2.3.3", "", { "os": "darwin" }, "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw=="],
"function-bind": ["function-bind@1.1.2", "", {}, "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA=="],
"geojson-vt": ["geojson-vt@4.0.2", "", {}, "sha512-AV9ROqlNqoZEIJGfm1ncNjEXfkz2hdFlZf0qkVfmkwdKa8vj7H16YUOT81rJw1rdFhyEDlN2Tds91p/glzbl5A=="],
"get-value": ["get-value@2.0.6", "", {}, "sha512-Ln0UQDlxH1BapMu3GPtf7CuYNwRZf2gwCuPqbyG6pB8WfmFpzqcy4xtAaAMUhnNqjMKTiCPZG2oMT3YSx8U2NA=="],
"gl-matrix": ["gl-matrix@3.4.3", "", {}, "sha512-wcCp8vu8FT22BnvKVPjXa/ICBWRq/zjFfdofZy1WSpQZpphblv12/bOQLBC1rMM7SGOFS9ltVmKOHil5+Ml7gA=="],
"glob-parent": ["glob-parent@6.0.2", "", { "dependencies": { "is-glob": "^4.0.3" } }, "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A=="],
"global": ["global@4.4.0", "", { "dependencies": { "min-document": "^2.19.0", "process": "^0.11.10" } }, "sha512-wv/LAoHdRE3BeTGz53FAamhGlPLhlssK45usmGFThIi4XqnBmjKQ16u+RNbP7WvigRZDxUsM0J3gcQ5yicaL0w=="],
"globals": ["globals@16.3.0", "", {}, "sha512-bqWEnJ1Nt3neqx2q5SFfGS8r/ahumIakg3HcwtNlrVlwXIeNumWn/c7Pn/wKzGhf6SaW6H6uWXLqC30STCMchQ=="],
"globrex": ["globrex@0.1.2", "", {}, "sha512-uHJgbwAMwNFf5mLst7IWLNg14x1CkeqglJb/K3doi4dw6q2IvAAmM/Y81kevy83wP+Sst+nutFTYOGg3d1lsxg=="],
"graphemer": ["graphemer@1.4.0", "", {}, "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag=="],
"grid-index": ["grid-index@1.1.0", "", {}, "sha512-HZRwumpOGUrHyxO5bqKZL0B0GlUpwtCAzZ42sgxUPniu33R1LSFH5yrIcBCHjkctCAh3mtWKcKd9J4vDDdeVHA=="],
"has-flag": ["has-flag@4.0.0", "", {}, "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ=="],
"hasown": ["hasown@2.0.2", "", { "dependencies": { "function-bind": "^1.1.2" } }, "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ=="],
"hoist-non-react-statics": ["hoist-non-react-statics@3.3.2", "", { "dependencies": { "react-is": "^16.7.0" } }, "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw=="],
"ieee754": ["ieee754@1.2.1", "", {}, "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA=="],
"ignore": ["ignore@5.3.2", "", {}, "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g=="],
"import-fresh": ["import-fresh@3.3.1", "", { "dependencies": { "parent-module": "^1.0.0", "resolve-from": "^4.0.0" } }, "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ=="],
"imurmurhash": ["imurmurhash@0.1.4", "", {}, "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA=="],
"is-arrayish": ["is-arrayish@0.2.1", "", {}, "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg=="],
"is-core-module": ["is-core-module@2.16.1", "", { "dependencies": { "hasown": "^2.0.2" } }, "sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w=="],
"is-extendable": ["is-extendable@0.1.1", "", {}, "sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw=="],
"is-extglob": ["is-extglob@2.1.1", "", {}, "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ=="],
"is-glob": ["is-glob@4.0.3", "", { "dependencies": { "is-extglob": "^2.1.1" } }, "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg=="],
"is-number": ["is-number@7.0.0", "", {}, "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng=="],
"is-plain-object": ["is-plain-object@2.0.4", "", { "dependencies": { "isobject": "^3.0.1" } }, "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og=="],
"isexe": ["isexe@2.0.0", "", {}, "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw=="],
"isobject": ["isobject@3.0.1", "", {}, "sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg=="],
"js-cookie": ["js-cookie@3.0.5", "", {}, "sha512-cEiJEAEoIbWfCZYKWhVwFuvPX1gETRYPw6LlaTKoxD3s2AkXzkCjnp6h0V77ozyqj0jakteJ4YqDJT830+lVGw=="],
"js-tokens": ["js-tokens@4.0.0", "", {}, "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ=="],
"js-yaml": ["js-yaml@4.1.0", "", { "dependencies": { "argparse": "^2.0.1" }, "bin": { "js-yaml": "bin/js-yaml.js" } }, "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA=="],
"jsesc": ["jsesc@3.1.0", "", { "bin": { "jsesc": "bin/jsesc" } }, "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA=="],
"json-buffer": ["json-buffer@3.0.1", "", {}, "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ=="],
"json-parse-even-better-errors": ["json-parse-even-better-errors@2.3.1", "", {}, "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w=="],
"json-schema-traverse": ["json-schema-traverse@0.4.1", "", {}, "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg=="],
"json-stable-stringify-without-jsonify": ["json-stable-stringify-without-jsonify@1.0.1", "", {}, "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw=="],
"json-stringify-pretty-compact": ["json-stringify-pretty-compact@3.0.0", "", {}, "sha512-Rc2suX5meI0S3bfdZuA7JMFBGkJ875ApfVyq2WHELjBiiG22My/l7/8zPpH/CfFVQHuVLd8NLR0nv6vi0BYYKA=="],
"kdbush": ["kdbush@4.0.2", "", {}, "sha512-WbCVYJ27Sz8zi9Q7Q0xHC+05iwkm3Znipc2XTlrnJbsHMYktW4hPhXUE8Ys1engBrvffoSCqbil1JQAa7clRpA=="],
"keyv": ["keyv@4.5.4", "", { "dependencies": { "json-buffer": "3.0.1" } }, "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw=="],
"levn": ["levn@0.4.1", "", { "dependencies": { "prelude-ls": "^1.2.1", "type-check": "~0.4.0" } }, "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ=="],
"lines-and-columns": ["lines-and-columns@1.2.4", "", {}, "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg=="],
"locate-path": ["locate-path@6.0.0", "", { "dependencies": { "p-locate": "^5.0.0" } }, "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw=="],
"lodash.merge": ["lodash.merge@4.6.2", "", {}, "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ=="],
"mapbox-gl": ["mapbox-gl@3.13.0", "", { "dependencies": { "@mapbox/jsonlint-lines-primitives": "^2.0.2", "@mapbox/mapbox-gl-supported": "^3.0.0", "@mapbox/point-geometry": "^0.1.0", "@mapbox/tiny-sdf": "^2.0.6", "@mapbox/unitbezier": "^0.0.1", "@mapbox/vector-tile": "^1.3.1", "@mapbox/whoots-js": "^3.1.0", "@types/geojson": "^7946.0.16", "@types/geojson-vt": "^3.2.5", "@types/mapbox__point-geometry": "^0.1.4", "@types/mapbox__vector-tile": "^1.3.4", "@types/pbf": "^3.0.5", "@types/supercluster": "^7.1.3", "cheap-ruler": "^4.0.0", "csscolorparser": "~1.0.3", "earcut": "^3.0.1", "geojson-vt": "^4.0.2", "gl-matrix": "^3.4.3", "grid-index": "^1.1.0", "kdbush": "^4.0.2", "martinez-polygon-clipping": "^0.7.4", "murmurhash-js": "^1.0.0", "pbf": "^3.2.1", "potpack": "^2.0.0", "quickselect": "^3.0.0", "serialize-to-js": "^3.1.2", "supercluster": "^8.0.1", "tinyqueue": "^3.0.0", "vt-pbf": "^3.1.3" } }, "sha512-TSSJIvDKsiSPk22889FWk9V4mmjljbizUf8Y2Jhho2j0Mj4zonC6kKwoVLf3oGqYWTZ+oQrd0Cxg6LCmZmPPbQ=="],
"martinez-polygon-clipping": ["martinez-polygon-clipping@0.7.4", "", { "dependencies": { "robust-predicates": "^2.0.4", "splaytree": "^0.1.4", "tinyqueue": "^1.2.0" } }, "sha512-jBEwrKtA0jTagUZj2bnmb4Yg2s4KnJGRePStgI7bAVjtcipKiF39R4LZ2V/UT61jMYWrTcBhPazexeqd6JAVtw=="],
"merge2": ["merge2@1.4.1", "", {}, "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg=="],
"micromatch": ["micromatch@4.0.8", "", { "dependencies": { "braces": "^3.0.3", "picomatch": "^2.3.1" } }, "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA=="],
"min-document": ["min-document@2.19.0", "", { "dependencies": { "dom-walk": "^0.1.0" } }, "sha512-9Wy1B3m3f66bPPmU5hdA4DR4PB2OfDU/+GS3yAB7IQozE3tqXaVv2zOjgla7MEGSRv95+ILmOuvhLkOK6wJtCQ=="],
"minimatch": ["minimatch@3.1.2", "", { "dependencies": { "brace-expansion": "^1.1.7" } }, "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw=="],
"minimist": ["minimist@1.2.8", "", {}, "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA=="],
"ms": ["ms@2.1.3", "", {}, "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="],
"murmurhash-js": ["murmurhash-js@1.0.0", "", {}, "sha512-TvmkNhkv8yct0SVBSy+o8wYzXjE4Zz3PCesbfs8HiCXXdcTuocApFv11UWlNFWKYsP2okqrhb7JNlSm9InBhIw=="],
"nanoid": ["nanoid@3.3.11", "", { "bin": { "nanoid": "bin/nanoid.cjs" } }, "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w=="],
"natural-compare": ["natural-compare@1.4.0", "", {}, "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw=="],
"next-themes": ["next-themes@0.4.6", "", { "peerDependencies": { "react": "^16.8 || ^17 || ^18 || ^19 || ^19.0.0-rc", "react-dom": "^16.8 || ^17 || ^18 || ^19 || ^19.0.0-rc" } }, "sha512-pZvgD5L0IEvX5/9GWyHMf3m8BKiVQwsCMHfoFosXtXBMnaS0ZnIJ9ST4b4NqLVKDEm8QBxoNNGNaBv2JNF6XNA=="],
"optionator": ["optionator@0.9.4", "", { "dependencies": { "deep-is": "^0.1.3", "fast-levenshtein": "^2.0.6", "levn": "^0.4.1", "prelude-ls": "^1.2.1", "type-check": "^0.4.0", "word-wrap": "^1.2.5" } }, "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g=="],
"p-limit": ["p-limit@3.1.0", "", { "dependencies": { "yocto-queue": "^0.1.0" } }, "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ=="],
"p-locate": ["p-locate@5.0.0", "", { "dependencies": { "p-limit": "^3.0.2" } }, "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw=="],
"parent-module": ["parent-module@1.0.1", "", { "dependencies": { "callsites": "^3.0.0" } }, "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g=="],
"parse-json": ["parse-json@5.2.0", "", { "dependencies": { "@babel/code-frame": "^7.0.0", "error-ex": "^1.3.1", "json-parse-even-better-errors": "^2.3.0", "lines-and-columns": "^1.1.6" } }, "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg=="],
"path-exists": ["path-exists@4.0.0", "", {}, "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w=="],
"path-key": ["path-key@3.1.1", "", {}, "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q=="],
"path-parse": ["path-parse@1.0.7", "", {}, "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw=="],
"path-type": ["path-type@4.0.0", "", {}, "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw=="],
"pbf": ["pbf@3.3.0", "", { "dependencies": { "ieee754": "^1.1.12", "resolve-protobuf-schema": "^2.1.0" }, "bin": { "pbf": "bin/pbf" } }, "sha512-XDF38WCH3z5OV/OVa8GKUNtLAyneuzbCisx7QUCF8Q6Nutx0WnJrQe5O+kOtBlLfRNUws98Y58Lblp+NJG5T4Q=="],
"perfect-freehand": ["perfect-freehand@1.2.2", "", {}, "sha512-eh31l019WICQ03pkF3FSzHxB8n07ItqIQ++G5UV8JX0zVOXzgTGCqnRR0jJ2h9U8/2uW4W4mtGJELt9kEV0CFQ=="],
"picocolors": ["picocolors@1.1.1", "", {}, "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA=="],
"picomatch": ["picomatch@4.0.2", "", {}, "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg=="],
"pnpm": ["pnpm@9.15.9", "", { "bin": { "pnpm": "bin/pnpm.cjs", "pnpx": "bin/pnpx.cjs" } }, "sha512-aARhQYk8ZvrQHAeSMRKOmvuJ74fiaR1p5NQO7iKJiClf1GghgbrlW1hBjDolO95lpQXsfF+UA+zlzDzTfc8lMQ=="],
"postcss": ["postcss@8.5.6", "", { "dependencies": { "nanoid": "^3.3.11", "picocolors": "^1.1.1", "source-map-js": "^1.2.1" } }, "sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg=="],
"potpack": ["potpack@2.0.0", "", {}, "sha512-Q+/tYsFU9r7xoOJ+y/ZTtdVQwTWfzjbiXBDMM/JKUux3+QPP02iUuIoeBQ+Ot6oEDlC+/PGjB/5A3K7KKb7hcw=="],
"prelude-ls": ["prelude-ls@1.2.1", "", {}, "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g=="],
"process": ["process@0.11.10", "", {}, "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A=="],
"protocol-buffers-schema": ["protocol-buffers-schema@3.6.0", "", {}, "sha512-TdDRD+/QNdrCGCE7v8340QyuXd4kIWIgapsE2+n/SaGiSSbomYl4TjHlvIoCWRpE7wFt02EpB35VVA2ImcBVqw=="],
"proxy-compare": ["proxy-compare@3.0.1", "", {}, "sha512-V9plBAt3qjMlS1+nC8771KNf6oJ12gExvaxnNzN/9yVRLdTv/lc+oJlnSzrdYDAvBfTStPCoiaCOTmTs0adv7Q=="],
"proxy-memoize": ["proxy-memoize@3.0.1", "", { "dependencies": { "proxy-compare": "^3.0.0" } }, "sha512-VDdG/VYtOgdGkWJx7y0o7p+zArSf2383Isci8C+BP3YXgMYDoPd3cCBjw0JdWb6YBb9sFiOPbAADDVTPJnh+9g=="],
"punycode": ["punycode@2.3.1", "", {}, "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg=="],
"queue-microtask": ["queue-microtask@1.2.3", "", {}, "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A=="],
"quickselect": ["quickselect@3.0.0", "", {}, "sha512-XdjUArbK4Bm5fLLvlm5KpTFOiOThgfWWI4axAZDWg4E/0mKdZyI9tNEfds27qCi1ze/vwTR16kvmmGhRra3c2g=="],
"react": ["react@19.1.0", "", {}, "sha512-FS+XFBNvn3GTAWq26joslQgWNoFu08F4kl0J4CgdNKADkdSGXQyTCnKteIAJy96Br6YbpEU1LSzV5dYtjMkMDg=="],
"react-dom": ["react-dom@19.1.0", "", { "dependencies": { "scheduler": "^0.26.0" }, "peerDependencies": { "react": "^19.1.0" } }, "sha512-Xs1hdnE+DyKgeHJeJznQmYMIBG3TKIHJJT95Q58nHLSrElKlGQqDTR2HQ9fx5CN/Gk6Vh/kupBTDLU11/nDk/g=="],
"react-icons": ["react-icons@5.5.0", "", { "peerDependencies": { "react": "*" } }, "sha512-MEFcXdkP3dLo8uumGI5xN3lDFNsRtrjbOEKDLD7yv76v4wpnEq2Lt2qeHaQOr34I/wPN3s3+N08WkQ+CW37Xiw=="],
"react-is": ["react-is@16.13.1", "", {}, "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ=="],
"react-map-gl": ["react-map-gl@8.0.4", "", { "dependencies": { "@vis.gl/react-mapbox": "8.0.4", "@vis.gl/react-maplibre": "8.0.4" }, "peerDependencies": { "mapbox-gl": ">=1.13.0", "maplibre-gl": ">=1.13.0", "react": ">=16.3.0", "react-dom": ">=16.3.0" }, "optionalPeers": ["mapbox-gl", "maplibre-gl"] }, "sha512-SHdpvFIvswsZBg6BCPcwY/nbKuCo3sJM1Cj7Sd+gA3gFRFOixD+KtZ2XSuUWq2WySL2emYEXEgrLZoXsV4Ut4Q=="],
"resolve": ["resolve@1.22.10", "", { "dependencies": { "is-core-module": "^2.16.0", "path-parse": "^1.0.7", "supports-preserve-symlinks-flag": "^1.0.0" }, "bin": { "resolve": "bin/resolve" } }, "sha512-NPRy+/ncIMeDlTAsuqwKIiferiawhefFJtkNSW0qZJEqMEb+qBt/77B/jGeeek+F0uOeN05CDa6HXbbIgtVX4w=="],
"resolve-from": ["resolve-from@4.0.0", "", {}, "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g=="],
"resolve-protobuf-schema": ["resolve-protobuf-schema@2.1.0", "", { "dependencies": { "protocol-buffers-schema": "^3.3.1" } }, "sha512-kI5ffTiZWmJaS/huM8wZfEMer1eRd7oJQhDuxeCLe3t7N7mX3z94CN0xPxBQxFYQTSNz9T0i+v6inKqSdK8xrQ=="],
"reusify": ["reusify@1.1.0", "", {}, "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw=="],
"robust-predicates": ["robust-predicates@2.0.4", "", {}, "sha512-l4NwboJM74Ilm4VKfbAtFeGq7aEjWL+5kVFcmgFA2MrdnQWx9iE/tUGvxY5HyMI7o/WpSIUFLbC5fbeaHgSCYg=="],
"rollup": ["rollup@4.44.2", "", { "dependencies": { "@types/estree": "1.0.8" }, "optionalDependencies": { "@rollup/rollup-android-arm-eabi": "4.44.2", "@rollup/rollup-android-arm64": "4.44.2", "@rollup/rollup-darwin-arm64": "4.44.2", "@rollup/rollup-darwin-x64": "4.44.2", "@rollup/rollup-freebsd-arm64": "4.44.2", "@rollup/rollup-freebsd-x64": "4.44.2", "@rollup/rollup-linux-arm-gnueabihf": "4.44.2", "@rollup/rollup-linux-arm-musleabihf": "4.44.2", "@rollup/rollup-linux-arm64-gnu": "4.44.2", "@rollup/rollup-linux-arm64-musl": "4.44.2", "@rollup/rollup-linux-loongarch64-gnu": "4.44.2", "@rollup/rollup-linux-powerpc64le-gnu": "4.44.2", "@rollup/rollup-linux-riscv64-gnu": "4.44.2", "@rollup/rollup-linux-riscv64-musl": "4.44.2", "@rollup/rollup-linux-s390x-gnu": "4.44.2", "@rollup/rollup-linux-x64-gnu": "4.44.2", "@rollup/rollup-linux-x64-musl": "4.44.2", "@rollup/rollup-win32-arm64-msvc": "4.44.2", "@rollup/rollup-win32-ia32-msvc": "4.44.2", "@rollup/rollup-win32-x64-msvc": "4.44.2", "fsevents": "~2.3.2" }, "bin": { "rollup": "dist/bin/rollup" } }, "sha512-PVoapzTwSEcelaWGth3uR66u7ZRo6qhPHc0f2uRO9fX6XDVNrIiGYS0Pj9+R8yIIYSD/mCx2b16Ws9itljKSPg=="],
"run-parallel": ["run-parallel@1.2.0", "", { "dependencies": { "queue-microtask": "^1.2.2" } }, "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA=="],
"rw": ["rw@1.3.3", "", {}, "sha512-PdhdWy89SiZogBLaw42zdeqtRJ//zFd2PgQavcICDUgJT5oW10QCRKbJ6bg4r0/UY2M6BWd5tkxuGFRvCkgfHQ=="],
"scheduler": ["scheduler@0.26.0", "", {}, "sha512-NlHwttCI/l5gCPR3D1nNXtWABUmBwvZpEQiD4IXSbIDq8BzLIK/7Ir5gTFSGZDUu37K5cMNp0hFtzO38sC7gWA=="],
"semver": ["semver@7.7.2", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA=="],
"serialize-to-js": ["serialize-to-js@3.1.2", "", {}, "sha512-owllqNuDDEimQat7EPG0tH7JjO090xKNzUtYz6X+Sk2BXDnOCilDdNLwjWeFywG9xkJul1ULvtUQa9O4pUaY0w=="],
"set-value": ["set-value@2.0.1", "", { "dependencies": { "extend-shallow": "^2.0.1", "is-extendable": "^0.1.1", "is-plain-object": "^2.0.3", "split-string": "^3.0.1" } }, "sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw=="],
"shebang-command": ["shebang-command@2.0.0", "", { "dependencies": { "shebang-regex": "^3.0.0" } }, "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA=="],
"shebang-regex": ["shebang-regex@3.0.0", "", {}, "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A=="],
"sort-asc": ["sort-asc@0.2.0", "", {}, "sha512-umMGhjPeHAI6YjABoSTrFp2zaBtXBej1a0yKkuMUyjjqu6FJsTF+JYwCswWDg+zJfk/5npWUUbd33HH/WLzpaA=="],
"sort-desc": ["sort-desc@0.2.0", "", {}, "sha512-NqZqyvL4VPW+RAxxXnB8gvE1kyikh8+pR+T+CXLksVRN9eiQqkQlPwqWYU0mF9Jm7UnctShlxLyAt1CaBOTL1w=="],
"sort-object": ["sort-object@3.0.3", "", { "dependencies": { "bytewise": "^1.1.0", "get-value": "^2.0.2", "is-extendable": "^0.1.1", "sort-asc": "^0.2.0", "sort-desc": "^0.2.0", "union-value": "^1.0.1" } }, "sha512-nK7WOY8jik6zaG9CRwZTaD5O7ETWDLZYMM12pqY8htll+7dYeqGfEUPcUBHOpSJg2vJOrvFIY2Dl5cX2ih1hAQ=="],
"source-map": ["source-map@0.5.7", "", {}, "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ=="],
"source-map-js": ["source-map-js@1.2.1", "", {}, "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA=="],
"splaytree": ["splaytree@0.1.4", "", {}, "sha512-D50hKrjZgBzqD3FT2Ek53f2dcDLAQT8SSGrzj3vidNH5ISRgceeGVJ2dQIthKOuayqFXfFjXheHNo4bbt9LhRQ=="],
"split-string": ["split-string@3.1.0", "", { "dependencies": { "extend-shallow": "^3.0.0" } }, "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw=="],
"strip-json-comments": ["strip-json-comments@3.1.1", "", {}, "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig=="],
"stylis": ["stylis@4.2.0", "", {}, "sha512-Orov6g6BB1sDfYgzWfTHDOxamtX1bE/zo104Dh9e6fqJ3PooipYyfJ0pUmrZO2wAvO8YbEyeFrkV91XTsGMSrw=="],
"supercluster": ["supercluster@8.0.1", "", { "dependencies": { "kdbush": "^4.0.2" } }, "sha512-IiOea5kJ9iqzD2t7QJq/cREyLHTtSmUT6gQsweojg9WH2sYJqZK9SswTu6jrscO6D1G5v5vYZ9ru/eq85lXeZQ=="],
"supports-color": ["supports-color@7.2.0", "", { "dependencies": { "has-flag": "^4.0.0" } }, "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw=="],
"supports-preserve-symlinks-flag": ["supports-preserve-symlinks-flag@1.0.0", "", {}, "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w=="],
"tinyglobby": ["tinyglobby@0.2.14", "", { "dependencies": { "fdir": "^6.4.4", "picomatch": "^4.0.2" } }, "sha512-tX5e7OM1HnYr2+a2C/4V0htOcSQcoSTH9KgJnVvNm5zm/cyEWKJ7j7YutsH9CxMdtOkkLFy2AHrMci9IM8IPZQ=="],
"tinyqueue": ["tinyqueue@3.0.0", "", {}, "sha512-gRa9gwYU3ECmQYv3lslts5hxuIa90veaEcxDYuu3QGOIAEM2mOZkVHp48ANJuu1CURtRdHKUBY5Lm1tHV+sD4g=="],
"to-regex-range": ["to-regex-range@5.0.1", "", { "dependencies": { "is-number": "^7.0.0" } }, "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ=="],
"ts-api-utils": ["ts-api-utils@2.1.0", "", { "peerDependencies": { "typescript": ">=4.8.4" } }, "sha512-CUgTZL1irw8u29bzrOD/nH85jqyc74D6SshFgujOIA7osm2Rz7dYH77agkx7H4FBNxDq7Cjf+IjaX/8zwFW+ZQ=="],
"tsconfck": ["tsconfck@3.1.6", "", { "peerDependencies": { "typescript": "^5.0.0" }, "optionalPeers": ["typescript"], "bin": { "tsconfck": "bin/tsconfck.js" } }, "sha512-ks6Vjr/jEw0P1gmOVwutM3B7fWxoWBL2KRDb1JfqGVawBmO5UsvmWOQFGHBPl5yxYz4eERr19E6L7NMv+Fej4w=="],
"tslib": ["tslib@2.8.1", "", {}, "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="],
"type-check": ["type-check@0.4.0", "", { "dependencies": { "prelude-ls": "^1.2.1" } }, "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew=="],
"typescript": ["typescript@5.8.3", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ=="],
"typescript-eslint": ["typescript-eslint@8.35.1", "", { "dependencies": { "@typescript-eslint/eslint-plugin": "8.35.1", "@typescript-eslint/parser": "8.35.1", "@typescript-eslint/utils": "8.35.1" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0", "typescript": ">=4.8.4 <5.9.0" } }, "sha512-xslJjFzhOmHYQzSB/QTeASAHbjmxOGEP6Coh93TXmUBFQoJ1VU35UHIDmG06Jd6taf3wqqC1ntBnCMeymy5Ovw=="],
"typewise": ["typewise@1.0.3", "", { "dependencies": { "typewise-core": "^1.2.0" } }, "sha512-aXofE06xGhaQSPzt8hlTY+/YWQhm9P0jYUp1f2XtmW/3Bk0qzXcyFWAtPoo2uTGQj1ZwbDuSyuxicq+aDo8lCQ=="],
"typewise-core": ["typewise-core@1.2.0", "", {}, "sha512-2SCC/WLzj2SbUwzFOzqMCkz5amXLlxtJqDKTICqg30x+2DZxcfZN2MvQZmGfXWKNWaKK9pBPsvkcwv8bF/gxKg=="],
"undici-types": ["undici-types@7.8.0", "", {}, "sha512-9UJ2xGDvQ43tYyVMpuHlsgApydB8ZKfVYTsLDhXkFL/6gfkp+U8xTGdh8pMJv1SpZna0zxG1DwsKZsreLbXBxw=="],
"union-value": ["union-value@1.0.1", "", { "dependencies": { "arr-union": "^3.1.0", "get-value": "^2.0.6", "is-extendable": "^0.1.1", "set-value": "^2.0.1" } }, "sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg=="],
"uqr": ["uqr@0.1.2", "", {}, "sha512-MJu7ypHq6QasgF5YRTjqscSzQp/W11zoUk6kvmlH+fmWEs63Y0Eib13hYFwAzagRJcVY8WVnlV+eBDUGMJ5IbA=="],
"uri-js": ["uri-js@4.4.1", "", { "dependencies": { "punycode": "^2.1.0" } }, "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg=="],
"vite": ["vite@7.0.2", "", { "dependencies": { "esbuild": "^0.25.0", "fdir": "^6.4.6", "picomatch": "^4.0.2", "postcss": "^8.5.6", "rollup": "^4.40.0", "tinyglobby": "^0.2.14" }, "optionalDependencies": { "fsevents": "~2.3.3" }, "peerDependencies": { "@types/node": "^20.19.0 || >=22.12.0", "jiti": ">=1.21.0", "less": "^4.0.0", "lightningcss": "^1.21.0", "sass": "^1.70.0", "sass-embedded": "^1.70.0", "stylus": ">=0.54.8", "sugarss": "^5.0.0", "terser": "^5.16.0", "tsx": "^4.8.1", "yaml": "^2.4.2" }, "optionalPeers": ["@types/node", "jiti", "less", "lightningcss", "sass", "sass-embedded", "stylus", "sugarss", "terser", "tsx", "yaml"], "bin": { "vite": "bin/vite.js" } }, "sha512-hxdyZDY1CM6SNpKI4w4lcUc3Mtkd9ej4ECWVHSMrOdSinVc2zYOAppHeGc/hzmRo3pxM5blMzkuWHOJA/3NiFw=="],
"vite-tsconfig-paths": ["vite-tsconfig-paths@5.1.4", "", { "dependencies": { "debug": "^4.1.1", "globrex": "^0.1.2", "tsconfck": "^3.0.3" }, "peerDependencies": { "vite": "*" }, "optionalPeers": ["vite"] }, "sha512-cYj0LRuLV2c2sMqhqhGpaO3LretdtMn/BVX4cPLanIZuwwrkVl+lK84E/miEXkCHWXuq65rhNN4rXsBcOB3S4w=="],
"vt-pbf": ["vt-pbf@3.1.3", "", { "dependencies": { "@mapbox/point-geometry": "0.1.0", "@mapbox/vector-tile": "^1.3.1", "pbf": "^3.2.1" } }, "sha512-2LzDFzt0mZKZ9IpVF2r69G9bXaP2Q2sArJCmcCgvfTdCCZzSyz4aCLoQyUilu37Ll56tCblIZrXFIjNUpGIlmA=="],
"which": ["which@2.0.2", "", { "dependencies": { "isexe": "^2.0.0" }, "bin": { "node-which": "./bin/node-which" } }, "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA=="],
"word-wrap": ["word-wrap@1.2.5", "", {}, "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA=="],
"yaml": ["yaml@1.10.2", "", {}, "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg=="],
"yocto-queue": ["yocto-queue@0.1.0", "", {}, "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q=="],
"@eslint-community/eslint-utils/eslint-visitor-keys": ["eslint-visitor-keys@3.4.3", "", {}, "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag=="],
"@eslint/eslintrc/globals": ["globals@14.0.0", "", {}, "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ=="],
"@eslint/plugin-kit/@eslint/core": ["@eslint/core@0.15.1", "", { "dependencies": { "@types/json-schema": "^7.0.15" } }, "sha512-bkOp+iumZCCbt1K1CmWf0R9pM5yKpDv+ZXtvSyQpudrI9kuFLp+bM2WOPXImuD/ceQuaa8f5pj93Y7zyECIGNA=="],
"@humanfs/node/@humanwhocodes/retry": ["@humanwhocodes/retry@0.3.1", "", {}, "sha512-JBxkERygn7Bv/GbN5Rv8Ul6LVknS+5Bp6RgDC/O8gEBU/yeH5Ui5C/OlWrTb6qct7LjjfT6Re2NxB0ln0yYybA=="],
"@typescript-eslint/eslint-plugin/ignore": ["ignore@7.0.5", "", {}, "sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg=="],
"@typescript-eslint/typescript-estree/minimatch": ["minimatch@9.0.5", "", { "dependencies": { "brace-expansion": "^2.0.1" } }, "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow=="],
"fast-glob/glob-parent": ["glob-parent@5.1.2", "", { "dependencies": { "is-glob": "^4.0.1" } }, "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow=="],
"martinez-polygon-clipping/tinyqueue": ["tinyqueue@1.2.3", "", {}, "sha512-Qz9RgWuO9l8lT+Y9xvbzhPT2efIUIFd69N7eF7tJ9lnQl0iLj1M7peK7IoUGZL9DJHw9XftqLreccfxcQgYLxA=="],
"micromatch/picomatch": ["picomatch@2.3.1", "", {}, "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA=="],
"split-string/extend-shallow": ["extend-shallow@3.0.2", "", { "dependencies": { "assign-symbols": "^1.0.0", "is-extendable": "^1.0.1" } }, "sha512-BwY5b5Ql4+qZoefgMj2NUmx+tehVTH/Kf4k1ZEtOHNFcm2wSxMRo992l6X3TIgni2eZVTZ85xMOjF31fwZAj6Q=="],
"@typescript-eslint/typescript-estree/minimatch/brace-expansion": ["brace-expansion@2.0.2", "", { "dependencies": { "balanced-match": "^1.0.0" } }, "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ=="],
"split-string/extend-shallow/is-extendable": ["is-extendable@1.0.1", "", { "dependencies": { "is-plain-object": "^2.0.4" } }, "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA=="],
}
}

View File

@@ -0,0 +1,93 @@
[package]
name = "base-map"
version = "0.1.0"
edition = "2021"
description = "Rust backend + Vite frontend"
license = "MIT OR Apache-2.0"
# Tell Cargo to run our build script
build = "build.rs"
# ────────────────────────────────────────────────
# Dependencies you actually need in Rust code
# (pick only the ones you want)
# ────────────────────────────────────────────────
[dependencies]
# Web server framework (swap for actixweb, warp, etc.)
axum = { version = "0.7", optional = true, default-features = false, features = ["macros", "tokio", "http1", "json"] }
tokio = { version = "1.46.0", features = ["full"], optional = true}
tower-http = { version = "0.6", features = ["full"] }
tracing = "0.1.37"
tracing-subscriber = "0.3.16"
anyhow = "1"
axum-embed = "0.1.0"
wry = { version = "=0.51.2", features = ["protocol", "os-webview"] }
tao = { version = "0.34"}
web-sys = { version = "0.3.77", features = [
"console",
"Geolocation",
"Navigator",
"Window",
"Document",
"Element",
"Position",
"PositionOptions",
"PositionError",
"Coordinates"
] }
# Staticfile embedding helper (compile assets straight into the binary).
# If you prefer reading from disk at runtime, delete this.
rust-embed = { version = "8", optional = true }
serde = { version = "1.0.219", features = ["derive"] }
# ────────────────────────────────────────────────
# Devonly dependencies (examples, tests, benches)
# ────────────────────────────────────────────────
[dev-dependencies]
serde_json = "1"
# ────────────────────────────────────────────────
# Features let you strip out things you dont want
# by disabling default features in your workspace
# ────────────────────────────────────────────────
[features]
default = ["server", "embed-assets"]
# Feature that pulls in the server stack
server = ["axum", "tokio"]
# Feature that embeds Vites dist/ into the binary
embed-assets = ["rust-embed"]
# ────────────────────────────────────────────────
# Tell Cargo what NOT to publish to crates.io
# ────────────────────────────────────────────────
[package.metadata]
# Keep your node_modules and dist/ out of the crate
# published to crates.io (theyre huge and useless there)
exclude = [
"map/node_modules/**",
"map/dist/**"
]
# ────────────────────────────────────────────────
# Optional: workspace setup
# ────────────────────────────────────────────────
# If this lives inside a workspace, remove [workspace] here
# and put these paths in the root Cargo.toml instead.
[lib]
# Default name is fine; no need to set anything unless you want cdylib, etc.
path = "src/lib.rs"
# Optional: multiple binaries live in src/bin/
[[bin]]
name = "server" # produces target/release/server
path = "src/main.rs"
# Optional: multiple binaries live in src/bin/
[[bin]]
name = "app" # produces target/release/server
path = "src/app.rs"

22
crates/base-map/README.md Normal file
View File

@@ -0,0 +1,22 @@
# YachtPit Base Map Crate
This crate is intended to provide a production build system and independent rust development environment for geospatial maps within yachtpit.
## Overview
// TODO
## Features
// TODO
## Usage
// TODO
```shell
cargo run --bin server
cargo run --bin app
#Error: User denied Geolocation
```
## Dependencies
// TODO
## Architecture
// TODO

120
crates/base-map/build.rs Normal file
View File

@@ -0,0 +1,120 @@
// build.rs
use std::{
env,
fs,
path::{Path, PathBuf},
process::Command,
};
///
/// {
/// "name": "yachtpit",
/// "private": true,
/// "workspaces": ["packages/*"],
/// "scripts": {
/// "build-and-deploy-map": "cd crates/base-map && npm run build && cd ../.. && mkdir -p crates/yachtpit/assets/ui/packages/base-map/dist && cp -r packages/base-map/dist/* crates/yachtpit/assets/ui/packages/base-map/dist/ && cp -r packages/base-map/dist/assets crates/yachtpit/assets/ui/",
/// "postinstall": "npm run build-and-deploy-map"
/// },
/// "devDependencies": {
/// "@types/bun": "latest"
/// },
/// "peerDependencies": {
/// "typescript": "^5"
/// }
/// }
///
fn main() {
// ---------- 0. Locate the map frontend ----------
let map_dir = Path::new("map");
assert!(
map_dir.join("package.json").exists(),
"Expected `map/package.json` is your map frontend in `map/`?"
);
// ---------- 1. Tell Cargo when to rerun ----------
println!("cargo:rerun-if-changed={}", map_dir.join("package.json").display());
println!("cargo:rerun-if-changed={}", map_dir.join("vite.config.ts").display());
println!("cargo:rerun-if-changed={}", map_dir.join("vite.config.js").display());
println!("cargo:rerun-if-changed={}", map_dir.join("src").display());
// ---------- 2. Install & build ----------
run("npm", &["install"], map_dir);
run("npm", &["run", "build"], map_dir); // assumes "build": "tsc -b && vite build" in package.json
// ---------- 3. Copy artefacts following build-and-deploy-map script ----------
let dist = map_dir.join("dist");
let crate_asset_output = out_static_dir();
// Create target directory: crates/yachtpit/assets/ui/packages/base-map/dist
let base_map_dest = Path::new("../yachtpit/assets/ui/packages/base-map/dist");
if base_map_dest.exists() {
fs::remove_dir_all(&base_map_dest).expect("clearing old base-map dist failed");
}
if crate_asset_output.exists() {
fs::remove_dir_all(&crate_asset_output).expect("clearing old base-map dist failed");
}
fs::create_dir_all(&base_map_dest).unwrap();
fs::create_dir_all(&crate_asset_output).unwrap();
// Copy dist/* to crates/yachtpit/assets/ui/packages/base-map/dist/
copy_dir(&dist, &base_map_dest).expect("copying base-map dist/ failed");
copy_dir(&dist, &crate_asset_output).expect("crate asset output failed");
// Copy dist/assets to crates/yachtpit/assets/ui/assets (if assets exist)
let dist_assets = dist.join("assets");
if dist_assets.exists() {
let ui_assets_dest = Path::new("../yachtpit/assets/ui/assets");
if ui_assets_dest.exists() {
fs::remove_dir_all(&ui_assets_dest).expect("clearing old ui assets failed");
}
fs::create_dir_all(&ui_assets_dest).unwrap();
copy_dir(&dist_assets, &ui_assets_dest).expect("copying assets to ui/ failed");
}
}
// -----------------------------------------------------------------------------
// Helpers
// -----------------------------------------------------------------------------
fn run(cmd: &str, args: &[&str], cwd: &Path) {
let ok = Command::new(cmd)
.args(args)
.current_dir(cwd)
.status()
.unwrap_or_else(|_| panic!("failed to spawn `{cmd}`; is it on PATH?"))
.success();
if !ok {
panic!("command `{cmd} {}` failed", args.join(" "));
}
}
/// `$OUT_DIR/../../../static` → a sibling of your crate root inside `target/*/static`.
fn out_static_dir() -> PathBuf {
let out_dir = env::var("OUT_DIR").expect("OUT_DIR env var is set by Cargo");
PathBuf::from(out_dir)
.parent() // build/
.and_then(|p| p.parent()) // <hash>/
.and_then(|p| p.parent()) // release/
.map(|p| p.join("static"))
.expect("could not compute static dir")
}
/// Recursively copy a directory.
fn copy_dir(src: &Path, dst: &Path) -> std::io::Result<()> {
for entry in fs::read_dir(src)? {
let entry = entry?;
let ty = entry.file_type()?;
let dst_path = dst.join(entry.file_name());
if ty.is_dir() {
fs::create_dir_all(&dst_path)?;
copy_dir(&entry.path(), &dst_path)?;
} else {
fs::copy(entry.path(), dst_path)?;
}
}
Ok(())
}

5585
crates/base-map/map/package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -6,8 +6,9 @@
"scripts": {
"dev": "vite",
"build": "tsc -b && vite build",
"lint": "eslint .",
"preview": "vite preview"
"lint": "eslint ",
"preview": "vite preview",
"background-server": "(cd ../ && cargo run &)"
},
"dependencies": {
"next-themes": "^0.4.6",
@@ -33,7 +34,9 @@
"typescript": "~5.8.3",
"typescript-eslint": "^8.34.1",
"vite": "^7.0.0",
"@tauri-apps/plugin-geolocation": "^2.3.0",
"vite-tsconfig-paths": "^5.1.4",
"bevy_flurx_api": "^0.1.0"
"bevy_flurx_api": "^0.1.0",
"geojson": "^0.5.0"
}
}

View File

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

View File

@@ -0,0 +1,238 @@
// import Map from 'react-map-gl/mapbox';
// import {Source, Layer} from 'react-map-gl/maplibre';
import 'mapbox-gl/dist/mapbox-gl.css';
import {Box, Button, HStack, Input} from '@chakra-ui/react';
import {useCallback, useEffect, useState} from "react";
import MapNext from "@/MapNext.tsx";
// import type {FeatureCollection} from 'geojson';
// import type {CircleLayerSpecification} from "mapbox-gl";
// public key
const key =
'cGsuZXlKMUlqb2laMlZ2Wm1aelpXVWlMQ0poSWpvaVkycDFOalo0YkdWNk1EUTRjRE41YjJnNFp6VjNNelp6YXlKOS56LUtzS1l0X3VGUGdCSDYwQUFBNFNn';
// const vesselLayerStyle: CircleLayerSpecification = {
// id: 'vessel',
// type: 'circle',
// paint: {
// 'circle-radius': 8,
// 'circle-color': '#ff4444',
// 'circle-stroke-width': 2,
// 'circle-stroke-color': '#ffffff'
// },
// source: ''
// };
// Types for bevy_flurx_ipc communication
interface GpsPosition {
latitude: number;
longitude: number;
zoom: number;
}
interface VesselStatus {
latitude: number;
longitude: number;
heading: number;
speed: number;
}
// interface MapViewParams {
// latitude: number;
// longitude: number;
// zoom: number;
// }
// interface AuthParams {
// authenticated: boolean;
// token: string | null;
// }
function App() {
const [isSearchOpen, setIsSearchOpen] = useState(false);
// Map state that can be updated from Rust
// const [mapView, setMapView] = useState({
// longitude: -122.4,
// latitude: 37.8,
// zoom: 14
// });
// Vessel position state
// const [vesselPosition, setVesselPosition] = useState<VesselStatus | null>(null);
// Create vessel geojson data
// const vesselGeojson: FeatureCollection = {
// type: 'FeatureCollection',
// features: vesselPosition ? [
// {
// type: 'Feature',
// geometry: {
// type: 'Point',
// coordinates: [vesselPosition.longitude, vesselPosition.latitude]
// },
// properties: {
// title: 'Vessel Position',
// heading: vesselPosition.heading,
// speed: vesselPosition.speed
// }
// }
// ] : []
// };
// Button click handlers
const handleNavigationClick = useCallback(async () => {
if (typeof window !== 'undefined' && (window as any).__FLURX__) {
try {
await (window as any).__FLURX__.invoke("navigation_clicked");
console.log('Navigation clicked');
} catch (error) {
console.error('Failed to invoke navigation_clicked:', error);
}
}
}, []);
const handleSearchClick = useCallback(async () => {
setIsSearchOpen(!isSearchOpen);
if (typeof window !== 'undefined' && (window as any).__FLURX__) {
try {
await (window as any).__FLURX__.invoke("search_clicked");
console.log('Search clicked');
} catch (error) {
console.error('Failed to invoke search_clicked:', error);
}
}
}, []);
// const handleMapViewChange = useCallback(async (evt: any) => {
// const { longitude, latitude, zoom } = evt.viewState;
// setMapView({ longitude, latitude, zoom });
//
// if (typeof window !== 'undefined' && (window as any).__FLURX__) {
// try {
// const mapViewParams: MapViewParams = {
// latitude,
// longitude,
// zoom
// };
// await (window as any).__FLURX__.invoke("map_view_changed", mapViewParams);
// console.log('Map view changed:', mapViewParams);
// } catch (error) {
// console.error('Failed to invoke map_view_changed:', error);
// }
// }
// }, []);
// Poll for vessel status updates
useEffect(() => {
const pollVesselStatus = async () => {
if (typeof window !== 'undefined' && (window as any).__FLURX__) {
try {
const vesselStatus: VesselStatus = await (window as any).__FLURX__.invoke("get_vessel_status");
console.log('Vessel status:', vesselStatus);
// setVesselPosition(vesselStatus);
} catch (error) {
console.error('Failed to get vessel status:', error);
}
}
};
// Poll every 5 seconds
const interval = setInterval(pollVesselStatus, 5000);
// Also poll immediately
pollVesselStatus();
return () => clearInterval(interval);
}, []);
// Initialize map with data from Rust
useEffect(() => {
const initializeMap = async () => {
if (typeof window !== 'undefined' && (window as any).__FLURX__) {
try {
const mapInit: GpsPosition = await (window as any).__FLURX__.invoke("get_map_init");
console.log('Map initialization data:', mapInit);
// setMapView({
// latitude: mapInit.latitude,
// longitude: mapInit.longitude,
// zoom: mapInit.zoom
// });
} catch (error) {
console.error('Failed to get map initialization data:', error);
}
}
};
initializeMap();
}, []);
return (
/* Full-screen wrapper — fills the viewport and becomes the positioning context */
<Box w="100vw" h="100vh" position="relative" overflow="hidden">
{/* Button bar — absolutely positioned inside the wrapper */}
<HStack position="absolute" top={4} right={4} zIndex={1}>
<Box
display="flex"
alignItems="center"
>
<Button
colorScheme="teal"
size="sm"
variant="solid"
onClick={handleSearchClick}
mr={2}
>
Search
</Button>
{isSearchOpen && <Box
w="200px"
transition="all 0.3s"
transform={`translateX(${isSearchOpen ? "0" : "100%"})`}
opacity={isSearchOpen ? 1 : 0}
color="white"
>
<Input
placeholder="Search..."
size="sm"
_placeholder={{
color: "#d1cfcf"
}}
/>
</Box>}
</Box>
<Button
colorScheme="blue"
size="sm"
variant="solid"
onClick={handleNavigationClick}
>
Layer
</Button>
</HStack>
<MapNext mapboxPublicKey={atob(key)}/>
{/*<Map*/}
{/* mapboxAccessToken={atob(key)}*/}
{/* initialViewState={mapView}*/}
{/* onMove={handleMapViewChange}*/}
{/* mapStyle="mapbox://styles/mapbox/dark-v11"*/}
{/* reuseMaps*/}
{/* attributionControl={false}*/}
{/* style={{width: '100%', height: '100%'}} // let the wrapper dictate size*/}
{/*>*/}
{/* /!*{vesselPosition && (*!/*/}
{/* /!* <Source id="vessel-data" type="geojson" data={vesselGeojson}>*!/*/}
{/* /!* <Layer {...vesselLayerStyle} />*!/*/}
{/* /!* </Source>*!/*/}
{/* /!*)}*!/*/}
{/*</Map>*/}
</Box>
);
}
export default App;

View File

@@ -0,0 +1,115 @@
import {useState, useMemo} from 'react';
import Map, {
Marker,
Popup,
NavigationControl,
FullscreenControl,
ScaleControl,
GeolocateControl
} from 'react-map-gl/mapbox';
import ControlPanel from './control-panel.tsx';
import Pin from './pin.tsx';
import PORTS from './test_data/nautical-base-data.json';
import {Box} from "@chakra-ui/react";
export default function MapNext(props: any = {mapboxPublicKey: ""} as any) {
const [popupInfo, setPopupInfo] = useState(null);
const pins = useMemo(
() =>
PORTS.map((city, index) => (
<Marker
key={`marker-${index}`}
longitude={city.longitude}
latitude={city.latitude}
anchor="bottom"
onClick={e => {
// If we let the click event propagates to the map, it will immediately close the popup
// with `closeOnClick: true`
e.originalEvent.stopPropagation();
/*
src/MapNext.tsx:34:38 - error TS2345: Argument of type '{ city: string; population: string; image: string; state: string; latitude: number; longitude: number; }' is not assignable to parameter of type 'SetStateAction<null>'.
Type '{ city: string; population: string; image: string; state: string; latitude: number; longitude: number; }' provides no match for the signature '(prevState: null): null'.
*/
// @ts-ignore
setPopupInfo(city);
}}
>
<Pin />
</Marker>
)),
[]
);
return (
<Box>
<Map
initialViewState={{
latitude: 40,
longitude: -100,
zoom: 3.5,
bearing: 0,
pitch: 0
}}
mapStyle="mapbox://styles/geoffsee/cmd1qz39x01ga01qv5acea02y"
mapboxAccessToken={props.mapboxPublicKey}
style={{position: "fixed", width: '100%', height: '100%', bottom: 0, top: 0, left: 0, right: 0}}
>
<GeolocateControl showUserHeading={true} showUserLocation={true} position="top-left" />
<FullscreenControl position="top-left" />
<NavigationControl position="top-left" />
<ScaleControl />
{pins}
{popupInfo && (
<Popup
anchor="top"
/*
src/MapNext.tsx:66:53 - error TS2339: Property 'longitude' does not exist on type 'never'.
66 longitude={Number(popupInfo.longitude)}
*/
// @ts-ignore
longitude={Number(popupInfo.longitude)}
/*
src/MapNext.tsx:67:52 - error TS2339: Property 'latitude' does not exist on type 'never'.
67 latitude={Number(popupInfo.latitude)}
~~~~~~~~
*/
// @ts-ignore
latitude={Number(popupInfo.latitude)}
onClose={() => setPopupInfo(null)}
>
<div>
{/*src/MapNext.tsx:71:40 - error TS2339: Property 'city' does not exist on type 'never'.
71 {popupInfo.city}, {popupInfo.state} |{' '}
~~~~*/}
{/*@ts-ignore*/}{/*@ts-ignore*/}
{popupInfo.city},{popupInfo.state}
{/*@ts-ignore*/}
<a
target="_new"
href={`http://en.wikipedia.org/w/index.php?title=Special:Search&search=${(popupInfo as any).city}, ${(popupInfo as any).state}`}
>
Wikipedia
</a>
</div>
{/*@ts-ignore*/}
<img width="100%" src={popupInfo.image} />
</Popup>
)}
</Map>
<ControlPanel />
</Box>
);
}

View File

Before

Width:  |  Height:  |  Size: 4.0 KiB

After

Width:  |  Height:  |  Size: 4.0 KiB

View File

@@ -4,7 +4,7 @@ import { ChakraProvider, defaultSystem } from "@chakra-ui/react"
import {
ColorModeProvider,
type ColorModeProviderProps,
} from "./color-mode"
} from "./color-mode.tsx"
export function Provider(props: ColorModeProviderProps) {
return (

View File

@@ -0,0 +1,29 @@
import * as React from 'react';
function ControlPanel() {
return (
<div className="control-panel">
<h3>Marker, Popup, NavigationControl and FullscreenControl </h3>
<p>
Map showing top 20 most populated cities of the United States. Click on a marker to learn
more.
</p>
<p>
Data source:{' '}
<a href="https://en.wikipedia.org/wiki/List_of_United_States_cities_by_population">
Wikipedia
</a>
</p>
<div className="source-link">
<a
href="https://github.com/visgl/react-map-gl/tree/8.0-release/examples/mapbox/controls"
target="_new"
>
View Code
</a>
</div>
</div>
);
}
export default React.memo(ControlPanel);

View File

@@ -1,7 +1,7 @@
import {StrictMode} from 'react'
import {createRoot} from 'react-dom/client'
import App from './App.tsx'
import {Provider} from "@/components/ui/provider"
import {Provider} from "@/components/ui/provider.tsx"
createRoot(document.getElementById('root')!).render(
<StrictMode>

View File

@@ -0,0 +1,21 @@
import * as React from 'react';
const ICON = `M20.2,15.7L20.2,15.7c1.1-1.6,1.8-3.6,1.8-5.7c0-5.6-4.5-10-10-10S2,4.5,2,10c0,2,0.6,3.9,1.6,5.4c0,0.1,0.1,0.2,0.2,0.3
c0,0,0.1,0.1,0.1,0.2c0.2,0.3,0.4,0.6,0.7,0.9c2.6,3.1,7.4,7.6,7.4,7.6s4.8-4.5,7.4-7.5c0.2-0.3,0.5-0.6,0.7-0.9
C20.1,15.8,20.2,15.8,20.2,15.7z`;
const pinStyle = {
cursor: 'pointer',
fill: '#d00',
stroke: 'none'
};
function Pin({size = 20}) {
return (
<svg height={size} viewBox="0 0 24 24" style={pinStyle}>
<path d={ICON} />
</svg>
);
}
export default React.memo(Pin);

View File

@@ -0,0 +1,22 @@
[
{"city":"New York","population":"8,175,133","image":"http://upload.wikimedia.org/wikipedia/commons/thumb/b/b9/Above_Gotham.jpg/240px-Above_Gotham.jpg","state":"New York","latitude":40.6643,"longitude":-73.9385},
{"city":"Los Angeles","population":"3,792,621","image":"http://upload.wikimedia.org/wikipedia/commons/thumb/5/57/LA_Skyline_Mountains2.jpg/240px-LA_Skyline_Mountains2.jpg","state":"California","latitude":34.0194,"longitude":-118.4108},
{"city":"Chicago","population":"2,695,598","image":"http://upload.wikimedia.org/wikipedia/commons/thumb/8/85/2008-06-10_3000x1000_chicago_skyline.jpg/240px-2008-06-10_3000x1000_chicago_skyline.jpg","state":"Illinois","latitude":41.8376,"longitude":-87.6818},
{"city":"Houston","population":"2,100,263","image":"http://upload.wikimedia.org/wikipedia/commons/thumb/6/60/Aerial_views_of_the_Houston%2C_Texas%2C_28005u.jpg/240px-Aerial_views_of_the_Houston%2C_Texas%2C_28005u.jpg","state":"Texas","latitude":29.7805,"longitude":-95.3863},
{"city":"Phoenix","population":"1,445,632","image":"http://upload.wikimedia.org/wikipedia/commons/thumb/b/b9/Downtown_Phoenix_Aerial_Looking_Northeast.jpg/207px-Downtown_Phoenix_Aerial_Looking_Northeast.jpg","state":"Arizona","latitude":33.5722,"longitude":-112.0880},
{"city":"Philadelphia","population":"1,526,006","image":"http://upload.wikimedia.org/wikipedia/commons/thumb/4/4d/Philly_skyline.jpg/240px-Philly_skyline.jpg","state":"Pennsylvania","latitude":40.0094,"longitude":-75.1333},
{"city":"San Antonio","population":"1,327,407","image":"http://upload.wikimedia.org/wikipedia/commons/thumb/f/ff/Downtown_San_Antonio_View.JPG/240px-Downtown_San_Antonio_View.JPG","state":"Texas","latitude":29.4724,"longitude":-98.5251},
{"city":"San Diego","population":"1,307,402","image":"http://upload.wikimedia.org/wikipedia/commons/thumb/5/53/US_Navy_110604-N-NS602-574_Navy_and_Marine_Corps_personnel%2C_along_with_community_leaders_from_the_greater_San_Diego_area_come_together_to_commemora.jpg/240px-US_Navy_110604-N-NS602-574_Navy_and_Marine_Corps_personnel%2C_along_with_community_leaders_from_the_greater_San_Diego_area_come_together_to_commemora.jpg","state":"California","latitude":32.8153,"longitude":-117.1350},
{"city":"Dallas","population":"1,197,816","image":"http://upload.wikimedia.org/wikipedia/commons/thumb/a/ab/Dallas_skyline_daytime.jpg/240px-Dallas_skyline_daytime.jpg","state":"Texas","latitude":32.7757,"longitude":-96.7967},
{"city":"San Jose","population":"945,942","image":"http://upload.wikimedia.org/wikipedia/commons/thumb/1/1e/Downtown_San_Jose_skyline.PNG/240px-Downtown_San_Jose_skyline.PNG","state":"California","latitude":37.2969,"longitude":-121.8193},
{"city":"Austin","population":"790,390","image":"http://upload.wikimedia.org/wikipedia/commons/thumb/9/97/Austin2012-12-01.JPG/240px-Austin2012-12-01.JPG","state":"Texas","latitude":30.3072,"longitude":-97.7560},
{"city":"Jacksonville","population":"821,784","image":"http://upload.wikimedia.org/wikipedia/commons/thumb/f/f3/Skyline_of_Jacksonville_FL%2C_South_view_20160706_1.jpg/240px-Skyline_of_Jacksonville_FL%2C_South_view_20160706_1.jpg","state":"Florida","latitude":30.3370,"longitude":-81.6613},
{"city":"San Francisco","population":"805,235","image":"http://upload.wikimedia.org/wikipedia/commons/thumb/6/6a/San_Francisco_skyline_from_Coit_Tower.jpg/240px-San_Francisco_skyline_from_Coit_Tower.jpg","state":"California","latitude":37.7751,"longitude":-122.4193},
{"city":"Columbus","population":"787,033","image":"http://upload.wikimedia.org/wikipedia/commons/thumb/f/fc/Columbus-ohio-skyline-panorama.jpg/240px-Columbus-ohio-skyline-panorama.jpg","state":"Ohio","latitude":39.9848,"longitude":-82.9850},
{"city":"Indianapolis","population":"820,445","image":"http://upload.wikimedia.org/wikipedia/commons/thumb/1/16/Downtown_indy_from_parking_garage_zoom.JPG/213px-Downtown_indy_from_parking_garage_zoom.JPG","state":"Indiana","latitude":39.7767,"longitude":-86.1459},
{"city":"Fort Worth","population":"741,206","image":"http://upload.wikimedia.org/wikipedia/commons/thumb/d/db/FortWorthTexasSkylineW.jpg/240px-FortWorthTexasSkylineW.jpg","state":"Texas","latitude":32.7795,"longitude":-97.3463},
{"city":"Charlotte","population":"731,424","image":"http://upload.wikimedia.org/wikipedia/commons/thumb/7/7d/Charlotte_skyline45647.jpg/222px-Charlotte_skyline45647.jpg","state":"North Carolina","latitude":35.2087,"longitude":-80.8307},
{"city":"Seattle","population":"608,660","image":"http://upload.wikimedia.org/wikipedia/commons/thumb/3/36/SeattleI5Skyline.jpg/240px-SeattleI5Skyline.jpg","state":"Washington","latitude":47.6205,"longitude":-122.3509},
{"city":"Denver","population":"600,158","image":"http://upload.wikimedia.org/wikipedia/commons/thumb/0/0b/DenverCP.JPG/240px-DenverCP.JPG","state":"Colorado","latitude":39.7618,"longitude":-104.8806},
{"city":"El Paso","population":"649,121","image":"http://upload.wikimedia.org/wikipedia/commons/thumb/6/6d/Downtown_El_Paso_at_sunset.jpeg/240px-Downtown_El_Paso_at_sunset.jpeg","state":"Texas","latitude":31.8484,"longitude":-106.4270}
]

View File

@@ -0,0 +1,22 @@
[
{"city":"New York","population":"8,335,897","image":"https://upload.wikimedia.org/wikipedia/commons/thumb/b/b9/Above_Gotham.jpg/240px-Above_Gotham.jpg","state":"New York","latitude":40.7128,"longitude":-74.0060},
{"city":"Los Angeles","population":"3,822,238","image":"https://upload.wikimedia.org/wikipedia/commons/thumb/5/57/LA_Skyline_Mountains2.jpg/240px-LA_Skyline_Mountains2.jpg","state":"California","latitude":34.0522,"longitude":-118.2437},
{"city":"Long Beach","population":"456,062","image":"https://upload.wikimedia.org/wikipedia/commons/thumb/d/d9/Long_Beach_skyline_from_Shoreline_Village.jpg/240px-Long_Beach_skyline_from_Shoreline_Village.jpg","state":"California","latitude":33.7701,"longitude":-118.1937},
{"city":"Seattle","population":"749,256","image":"https://upload.wikimedia.org/wikipedia/commons/thumb/3/36/SeattleI5Skyline.jpg/240px-SeattleI5Skyline.jpg","state":"Washington","latitude":47.6062,"longitude":-122.3321},
{"city":"San Francisco","population":"808,437","image":"https://upload.wikimedia.org/wikipedia/commons/thumb/6/6a/San_Francisco_skyline_from_Coit_Tower.jpg/240px-San_Francisco_skyline_from_Coit_Tower.jpg","state":"California","latitude":37.7749,"longitude":-122.4194},
{"city":"San Diego","population":"1,386,932","image":"https://upload.wikimedia.org/wikipedia/commons/thumb/5/53/US_Navy_110604-N-NS602-574_Navy_and_Marine_Corps_personnel%2C_along_with_community_leaders_from_the_greater_San_Diego_area_come_together_to_commemora.jpg/240px-US_Navy_110604-N-NS602-574_Navy_and_Marine_Corps_personnel%2C_along_with_community_leaders_from_the_greater_San_Diego_area_come_together_to_commemora.jpg","state":"California","latitude":32.7157,"longitude":-117.1611},
{"city":"Norfolk","population":"235,089","image":"https://upload.wikimedia.org/wikipedia/commons/thumb/6/6e/Norfolk_Skyline_from_Portsmouth.jpg/240px-Norfolk_Skyline_from_Portsmouth.jpg","state":"Virginia","latitude":36.8508,"longitude":-76.2859},
{"city":"Miami","population":"449,514","image":"https://upload.wikimedia.org/wikipedia/commons/thumb/4/4b/Miami_skyline_201807_cat.jpg/240px-Miami_skyline_201807_cat.jpg","state":"Florida","latitude":25.7617,"longitude":-80.1918},
{"city":"Boston","population":"675,647","image":"https://upload.wikimedia.org/wikipedia/commons/thumb/1/1b/Boston_skyline_and_Boston_Harbor.jpg/240px-Boston_skyline_and_Boston_Harbor.jpg","state":"Massachusetts","latitude":42.3601,"longitude":-71.0589},
{"city":"Baltimore","population":"585,708","image":"https://upload.wikimedia.org/wikipedia/commons/thumb/3/3b/Baltimore_Skyline.jpg/240px-Baltimore_Skyline.jpg","state":"Maryland","latitude":39.2904,"longitude":-76.6122},
{"city":"Charleston","population":"151,612","image":"https://upload.wikimedia.org/wikipedia/commons/thumb/a/a7/Charleston_SC_Skyline.jpg/240px-Charleston_SC_Skyline.jpg","state":"South Carolina","latitude":32.7765,"longitude":-79.9311},
{"city":"Savannah","population":"147,780","image":"https://upload.wikimedia.org/wikipedia/commons/thumb/4/40/Savannah_GA%2C_River_Street.jpg/240px-Savannah_GA%2C_River_Street.jpg","state":"Georgia","latitude":32.0809,"longitude":-81.0912},
{"city":"Tampa","population":"403,364","image":"https://upload.wikimedia.org/wikipedia/commons/thumb/4/4d/Tampa_skyline_from_South%2C_2022.jpg/240px-Tampa_skyline_from_South%2C_2022.jpg","state":"Florida","latitude":27.9506,"longitude":-82.4572},
{"city":"Mobile","population":"187,041","image":"https://upload.wikimedia.org/wikipedia/commons/thumb/7/70/Mobile_skyline_from_Mobile_River.jpg/240px-Mobile_skyline_from_Mobile_River.jpg","state":"Alabama","latitude":30.6954,"longitude":-88.0399},
{"city":"Anchorage","population":"288,121","image":"https://upload.wikimedia.org/wikipedia/commons/thumb/5/55/Anchorage_skyline_and_susitna.jpg/240px-Anchorage_skyline_and_susitna.jpg","state":"Alaska","latitude":61.2181,"longitude":-149.9003},
{"city":"Portland","population":"68,408","image":"https://upload.wikimedia.org/wikipedia/commons/thumb/4/48/Portland_Maine_skyline.jpg/240px-Portland_Maine_skyline.jpg","state":"Maine","latitude":43.6591,"longitude":-70.2568},
{"city":"Honolulu","population":"349,547","image":"https://upload.wikimedia.org/wikipedia/commons/thumb/1/10/Honolulu_and_Diamond_Head.jpg/240px-Honolulu_and_Diamond_Head.jpg","state":"Hawaii","latitude":21.3069,"longitude":-157.8583},
{"city":"New Orleans","population":"376,971","image":"https://upload.wikimedia.org/wikipedia/commons/thumb/f/fb/New_Orleans_skyline_sunset_Dec_28_2021_PANO_DSC07177-07179.jpg/240px-New_Orleans_skyline_sunset_Dec_28_2021_PANO_DSC07177-07179.jpg","state":"Louisiana","latitude":29.9511,"longitude":-90.0715},
{"city":"Jacksonville","population":"971,319","image":"https://upload.wikimedia.org/wikipedia/commons/thumb/f/f3/Skyline_of_Jacksonville_FL%2C_South_view_20160706_1.jpg/240px-Skyline_of_Jacksonville_FL%2C_South_view_20160706_1.jpg","state":"Florida","latitude":30.3322,"longitude":-81.6557},
{"city":"Houston","population":"2,302,878","image":"https://upload.wikimedia.org/wikipedia/commons/thumb/6/60/Aerial_views_of_the_Houston%2C_Texas%2C_28005u.jpg/240px-Aerial_views_of_the_Houston%2C_Texas%2C_28005u.jpg","state":"Texas","latitude":29.7604,"longitude":-95.3698}
]

View File

@@ -25,5 +25,7 @@
"noFallthroughCasesInSwitch": true,
"noUncheckedSideEffectImports": true
},
"include": ["src"]
"include": [
"src"
]
}

View File

@@ -0,0 +1,7 @@
{
"files": [],
"references": [
{ "path": "./tsconfig.app.json"},
{ "path": "./tsconfig.node.json"}
],
}

View File

@@ -21,5 +21,7 @@
"noFallthroughCasesInSwitch": true,
"noUncheckedSideEffectImports": true
},
"include": ["vite.config.ts"]
"include": [
"vite.config.ts"
]
}

View File

@@ -0,0 +1,73 @@
use tao::{
event::{Event, WindowEvent},
event_loop::{ControlFlow, EventLoop},
window::WindowBuilder,
};
use tao::platform::macos::WindowBuilderExtMacOS;
use tower_http::follow_redirect::policy::PolicyExt;
use tower_http::ServiceExt;
use wry::WebViewBuilder;
fn main() -> wry::Result<()> {
let event_loop = EventLoop::new();
let window = WindowBuilder::new()
.with_title("YachtPit Map")
.build(&event_loop).unwrap();
let builder = WebViewBuilder::new()
.with_url("http://localhost:8080/geolocate")
.with_new_window_req_handler(|e| {
println!("NewWindow: {e:?}");
true
})
.with_ipc_handler(|e| {
println!("IPC: {e:?}");
})
.with_drag_drop_handler(|e| {
match e {
wry::DragDropEvent::Enter { paths, position } => {
println!("DragEnter: {position:?} {paths:?} ")
}
wry::DragDropEvent::Over { position } => println!("DragOver: {position:?} "),
wry::DragDropEvent::Drop { paths, position } => {
println!("DragDrop: {position:?} {paths:?} ")
}
wry::DragDropEvent::Leave => println!("DragLeave"),
_ => {}
}
true
});
#[cfg(any(
target_os = "windows",
target_os = "macos",
target_os = "ios",
target_os = "android"
))]
let _webview = builder.build(&window)?;
#[cfg(not(any(
target_os = "windows",
target_os = "macos",
target_os = "ios",
target_os = "android"
)))]
let _webview = {
use tao::platform::unix::WindowExtUnix;
use wry::WebViewBuilderExtUnix;
let vbox = window.default_vbox().unwrap();
builder.build_gtk(vbox)?
};
event_loop.run(move |event, _, control_flow| {
*control_flow = ControlFlow::Wait;
if let Event::WindowEvent {
event: WindowEvent::CloseRequested,
..
} = event
{
*control_flow = ControlFlow::Exit;
}
});
}

View File

@@ -0,0 +1,216 @@
use axum::response::{Html, IntoResponse};
pub async fn geolocate() -> impl IntoResponse {
Html(
r#"
<!doctype html>
<html lang="en">
<head><meta charset="utf-8"><title>Geo Demo</title></head>
<body>
<div style="font-family: Arial, sans-serif; padding: 20px;">
<h2>Location Service</h2>
<div id="status"></div>
<pre id="out"></pre>
</div>
<script type="module">
const out = document.getElementById('out');
const status = document.getElementById('status');
// Persist / reuse a perbrowser UUID
let id = localStorage.getItem('browser_id');
if (!id) {
id = crypto.randomUUID();
localStorage.setItem('browser_id', id);
}
async function checkLocationPermission() {
if (!navigator.geolocation) {
status.innerHTML = '<p style="color: red;">Geolocation is not supported by this browser.</p>';
return false;
}
if (!navigator.permissions) {
// Fallback for browsers without Permissions API
return requestLocationDirectly();
}
try {
const permission = await navigator.permissions.query({name: 'geolocation'});
switch(permission.state) {
case 'granted':
status.innerHTML = '<p style="color: green;">Location permission granted. Getting location...</p>';
return getCurrentLocation();
case 'denied':
status.innerHTML = '<p style="color: red;">Location permission denied. Please enable location access in your browser settings and refresh the page.</p>';
return false;
case 'prompt':
status.innerHTML = '<p style="color: orange;">Requesting location permission...</p>';
return requestLocationDirectly();
default:
return requestLocationDirectly();
}
} catch (error) {
console.error('Error checking permission:', error);
return requestLocationDirectly();
}
}
function requestLocationDirectly() {
status.innerHTML = '<p>Requesting location access...</p>';
return getCurrentLocation();
}
function getCurrentLocation() {
return new Promise((resolve, reject) => {
navigator.geolocation.getCurrentPosition(
async pos => {
const payload = {
id,
lat: pos.coords.latitude,
lon: pos.coords.longitude,
accuracy: pos.coords.accuracy,
timestamp: pos.timestamp
};
out.textContent = JSON.stringify(payload, null, 2);
status.innerHTML = '<p style="color: green;">Location obtained successfully!</p>';
try {
await fetch('/geolocate', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(payload)
});
status.innerHTML += '<p style="color: green;">Location sent to server.</p>';
} catch (fetchError) {
status.innerHTML += `<p style="color: orange;">Warning: Could not send location to server: ${fetchError.message}</p>`;
}
resolve(true);
},
err => {
handleLocationError(err);
reject(err);
},
{
enableHighAccuracy: true,
timeout: 15000,
maximumAge: 60000
}
);
});
}
function handleLocationError(err) {
let errorMessage = '';
let color = 'red';
switch(err.code) {
case err.PERMISSION_DENIED:
errorMessage = 'Location access denied. Please enable location access in your browser settings and refresh the page.';
break;
case err.POSITION_UNAVAILABLE:
errorMessage = 'Location information is unavailable. Please check your GPS/location services.';
color = 'orange';
break;
case err.TIMEOUT:
errorMessage = 'Location request timed out. Please refresh the page to try again.';
color = 'orange';
break;
default:
errorMessage = `Unknown error occurred: ${err.message}`;
break;
}
status.innerHTML = `<p style="color: ${color};">Error: ${errorMessage}</p>`;
out.textContent = `Error: ${errorMessage}`;
}
// Start the location check when page loads
checkLocationPermission();
</script>
</body>
</html>
"#,
)
}
// v2
// pub async fn geolocate() -> impl IntoResponse {
// Html(
// r#"
// <!doctype html>
// <html lang="en">
// <head><meta charset="utf-8"><title>Geo Demo</title></head>
// <body>
// <pre id="out"></pre>
//
// <script type="module">
// let position_var = undefined;
// const out = document.getElementById('out');
//
// // Persist / reuse a perbrowser UUID
// let id = localStorage.getItem('browser_id');
// if (!id) {
// id = crypto.randomUUID();
// localStorage.setItem('browser_id', id);
// }
//
// if (!navigator.geolocation) {
// out.textContent = 'Geolocation not supported';
// } else {
//
// navigator.geolocation.getCurrentPosition(
// async pos => {
// const payload = {
// id,
// lat: pos.coords.latitude,
// lon: pos.coords.longitude
// };
// position_var = JSON.stringify(payload, null, 2);
// out.textContent = JSON.stringify(payload, null, 2);
// await fetch('/geolocate', { // <-- new route
// method: 'POST',
// headers: { 'Content-Type': 'application/json' },
// body: JSON.stringify(payload)
// });
// },
// err => out.textContent = `Error: ${err.message}`
// );
// }
// </script>
// </body>
// </html>
// "#,
// )
// }
// v1
// pub async fn geolocate() -> impl IntoResponse {
// // A minimal page that asks only after the user clicks.
// Html(r#"
// <!doctype html>
// <html lang="en">
// <head><meta charset="utf-8"><title>Geo Demo</title></head>
// <body>
// <pre id="out"></pre>
//
// <script>
// console.log('Hello from the browser');
// const out = document.getElementById('out');
// if (!navigator.geolocation) {
// out.textContent = 'Geolocation not supported';
// } else {
// navigator.geolocation.getCurrentPosition(
// pos => out.textContent =
// `Lat${pos.coords.latitude}, Lon${pos.coords.longitude}`,
// err => out.textContent = `Error: ${err.message}`
// );
// }
// </script>
// </body>
// </html>
// "#)
// }

View File

@@ -0,0 +1,33 @@
mod geolocate;
mod app;
use axum::response::IntoResponse;
use axum::routing::post;
// src/lib.rs
use axum::{routing::get, Json, Router};
use serde::Deserialize;
use tower_http::trace::TraceLayer;
// ===== JSON coming back from the browser =====
#[derive(Deserialize, Debug)]
struct LocationPayload {
id: String,
lat: f64,
lon: f64,
}
// ===== POST /api/location handler =====
async fn receive_location(axum::Json(p): Json<LocationPayload>) -> impl IntoResponse {
println!("Got location: {p:?}");
axum::http::StatusCode::OK
}
// a helper for integration tests or other binaries
pub fn build_router() -> Router {
Router::new()
.route("/status", get(|| async { "OK" }))
.route("/geolocate", get(geolocate::geolocate))
.route("/geolocate", post(receive_location))
.layer(TraceLayer::new_for_http())
}

View File

@@ -0,0 +1,32 @@
use axum_embed::ServeEmbed;
use base_map::build_router;
use rust_embed::RustEmbed;
use tokio::net::TcpListener;
#[derive(RustEmbed, Clone)]
#[folder = "map/dist/"]
struct Assets;
#[tokio::main]
async fn main() -> anyhow::Result<()> {
tracing_subscriber::fmt()
.with_max_level(tracing::Level::INFO)
.init();
let listener = TcpListener::bind("127.0.0.1:8080").await?;
let local_address = listener.local_addr()?;
tracing::info!("Server listening on http://{}", local_address);
async fn fallback(uri: axum::http::Uri) -> (axum::http::StatusCode, String) {
(axum::http::StatusCode::NOT_FOUND, format!("No route for {uri}"))
}
let serve_assets = ServeEmbed::<Assets>::new();
let router = build_router();
let app = router
.nest_service("/", serve_assets)
.fallback(fallback);
axum::serve(listener, app).await?;
Ok(())
}

View File

@@ -21,3 +21,18 @@ datalink = { path = "../datalink" }
[target.'cfg(not(target_arch = "wasm32"))'.dependencies]
datalink-provider = { path = "../datalink-provider" }
[target.'cfg(target_arch = "wasm32")'.dependencies]
wasm-bindgen = { workspace = true }
web-sys = { version = "0.3.77", features = [
"console",
"Geolocation",
"Navigator",
"Window",
"Document",
"Element",
"Position",
"PositionOptions",
"PositionError",
"Coordinates"
] }

View File

@@ -0,0 +1,115 @@
// src/geo_plugin.rs
use bevy::prelude::*;
use std::sync::{Arc, Mutex};
#[cfg(target_arch = "wasm32")]
use wasm_bindgen::{closure::Closure, JsCast};
#[cfg(target_arch = "wasm32")]
use web_sys::window;
#[derive(Resource, Default)]
pub struct UserLocation {
pub lat: f64,
pub lon: f64,
pub accuracy: f64,
pub fresh: bool,
}
#[derive(Resource)]
pub struct LocationData {
pub data: Arc<Mutex<Option<(f64, f64, f64)>>>,
}
impl Default for LocationData {
fn default() -> Self {
Self {
data: Arc::new(Mutex::new(None)),
}
}
}
pub struct GeoPlugin;
impl Plugin for GeoPlugin {
fn build(&self, app: &mut App) {
app.init_resource::<UserLocation>()
.init_resource::<LocationData>();
#[cfg(target_arch = "wasm32")]
{
app.add_systems(Startup, request_location)
.add_systems(Update, update_location);
}
}
}
#[cfg(target_arch = "wasm32")]
fn request_location(location_data: Res<LocationData>) {
let window = match window() {
Some(w) => w,
None => {
warn!("No window object available");
return;
}
};
let geo = match window.navigator().geolocation() {
Ok(g) => g,
Err(_) => {
warn!("Geolocation not available");
return;
}
};
let data_clone = location_data.data.clone();
let success = Closure::<dyn FnMut(web_sys::Position)>::new(move |pos: web_sys::Position| {
let c: web_sys::Coordinates = pos.coords();
if let Ok(mut data) = data_clone.lock() {
*data = Some((c.latitude(), c.longitude(), c.accuracy()));
}
});
let error = Closure::<dyn FnMut(web_sys::PositionError)>::new(move |err: web_sys::PositionError| {
match err.code() {
1 => {
warn!("Geolocation permission denied. This may be due to:");
warn!(" - User denied location access");
warn!(" - Insecure connection (HTTP instead of HTTPS)");
warn!(" - Browser security settings");
warn!(" Consider serving over HTTPS for geolocation access");
},
2 => {
warn!("Geolocation position unavailable: {}", err.message());
},
3 => {
warn!("Geolocation timeout: {}", err.message());
},
_ => {
warn!("Geolocation error: {} (code: {})", err.message(), err.code());
}
}
});
// watch_position keeps updating; get_current_position is oneshot
match geo.watch_position_with_error_callback(success.as_ref().unchecked_ref(), Some(error.as_ref().unchecked_ref())) {
Ok(_) => {
success.forget(); // leak the closure so it lives forever
error.forget(); // leak the error closure too
}
Err(e) => {
warn!("Failed to start watching position: {:?}", e);
}
}
}
#[cfg(target_arch = "wasm32")]
fn update_location(mut loc: ResMut<UserLocation>, location_data: Res<LocationData>) {
if let Ok(mut data) = location_data.data.lock() {
if let Some((lat, lon, accuracy)) = data.take() {
loc.lat = lat;
loc.lon = lon;
loc.accuracy = accuracy;
loc.fresh = true;
}
}
}

View File

@@ -5,6 +5,7 @@ mod vessel;
mod ais;
mod gps;
mod radar;
mod geo_plugin;
// Re-export components from the components crate
pub use components::{
@@ -16,3 +17,5 @@ pub use components::{
pub use world::player::{get_vessel_systems, setup_instrument_cluster_system, PlayerPlugin};
pub use vessel::vessel_systems::{create_vessel_systems, AisSystem, GpsSystem, RadarSystem, SystemInteraction, SystemStatus, VesselSystem};
pub use geo_plugin::GeoPlugin;

View File

@@ -59,8 +59,19 @@ rand = { version = "0.8.3" }
webbrowser = { version = "1", features = ["hardened"] }
systems = { path = "../systems" }
components = { path = "../components" }
wasm-bindgen = "0.2"
web-sys = { version = "0.3.53", features = ["Document", "Element", "HtmlElement", "Window"] }
wasm-bindgen = { workspace = true }
web-sys = { version = "0.3", features = [
"console",
"Geolocation",
"Navigator",
"Window",
"Document",
"Element",
"Position",
"PositionOptions",
"PositionError",
"Coordinates"
] }
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
@@ -78,9 +89,12 @@ winit = "0.30"
bevy_webview_wry = { version = "0.4", default-features = false, features = ["api"] }
bevy_flurx = "0.11"
bevy_flurx_ipc = "0.4.0"
# (run `cargo tree | grep wry` and use the version you see for bevy_webview_wry)
wry = { version = "=0.51.2", optional = true, features = ["os-webview"] } # GPS support for native platforms - placeholder for future real GPS implementation
[target.'cfg(target_arch = "wasm32")'.dependencies]
tokio = { version = "1.0", features = ["rt"] }
console_error_panic_hook = "0.1"
[build-dependencies]
embed-resource = "1"

View File

@@ -51,3 +51,9 @@ body {
#bevy {
z-index: 2;
}
#yachtpit-canvas {
width: 100%;
height: 100%;
display: block;
}

View File

@@ -3,6 +3,7 @@
mod core;
mod ui;
mod services;
use bevy::app::App;
#[cfg(debug_assertions)]
@@ -11,7 +12,10 @@ use bevy::prelude::*;
use crate::core::{ActionsPlugin, SystemManagerPlugin};
use crate::core::system_manager::SystemManager;
use crate::ui::{LoadingPlugin, MenuPlugin, GpsMapPlugin};
use crate::services::GpsServicePlugin;
use systems::{PlayerPlugin, setup_instrument_cluster, get_vessel_systems};
#[cfg(target_arch = "wasm32")]
use systems::GeoPlugin;
// See https://bevy-cheatbook.github.io/programming/states.html
#[derive(States, Default, Clone, Eq, PartialEq, Debug, Hash)]
@@ -41,13 +45,19 @@ impl Plugin for GamePlugin {
LoadingPlugin,
MenuPlugin,
GpsMapPlugin,
GpsServicePlugin,
ActionsPlugin,
SystemManagerPlugin,
PlayerPlugin,
))
.add_systems(OnEnter(GameState::Playing), (setup_instrument_cluster, initialize_vessel_systems));
#[cfg(target_arch = "wasm32")]
{
app.add_plugins(GeoPlugin);
}
#[cfg(debug_assertions)]
{
app.add_plugins((

View File

@@ -41,29 +41,38 @@ fn main() {
.run();
#[cfg(target_arch = "wasm32")]
App::new()
.insert_resource(ClearColor(Color::NONE))
.add_plugins(
DefaultPlugins
.set(WindowPlugin {
primary_window: Some(Window {
// Bind to canvas included in `index.html`
canvas: Some("#yachtpit-canvas".to_owned()),
fit_canvas_to_parent: true,
// Tells wasm not to override default event handling, like F5 and Ctrl+R
prevent_default_event_handling: false,
{
// Add console logging for WASM debugging
console_error_panic_hook::set_once();
info!("Starting WASM Bevy application");
App::new()
.insert_resource(ClearColor(Color::srgb(0.1, 0.1, 0.1))) // Dark gray background instead of transparent
.add_plugins(
DefaultPlugins
.set(WindowPlugin {
primary_window: Some(Window {
// Bind to canvas included in `index.html`
canvas: Some("#yachtpit-canvas".to_owned()),
fit_canvas_to_parent: true,
// Tells wasm not to override default event handling, like F5 and Ctrl+R
prevent_default_event_handling: false,
..default()
}),
..default()
})
.set(AssetPlugin {
meta_check: AssetMetaCheck::Never,
..default()
}),
..default()
})
.set(AssetPlugin {
meta_check: AssetMetaCheck::Never,
..default()
}),
)
.add_plugins(GamePlugin)
.add_systems(Startup, set_window_icon)
.run();
)
.add_plugins(GamePlugin)
.add_systems(Startup, || {
info!("WASM Bevy startup system running");
})
.run();
}
}

View File

@@ -0,0 +1,237 @@
use bevy::prelude::*;
use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct GpsData {
pub latitude: f64,
pub longitude: f64,
pub altitude: Option<f64>,
pub accuracy: Option<f64>,
pub heading: Option<f64>,
pub speed: Option<f64>,
pub timestamp: f64,
}
#[derive(Resource, Default)]
pub struct GpsService {
pub current_position: Option<GpsData>,
pub is_enabled: bool,
pub last_update: f64,
}
impl GpsService {
pub fn new() -> Self {
Self {
current_position: None,
is_enabled: false,
last_update: 0.0,
}
}
pub fn enable(&mut self) {
self.is_enabled = true;
info!("GPS service enabled");
}
pub fn disable(&mut self) {
self.is_enabled = false;
info!("GPS service disabled");
}
pub fn update_position(&mut self, gps_data: GpsData) {
self.current_position = Some(gps_data.clone());
self.last_update = gps_data.timestamp;
info!("GPS position updated: lat={:.6}, lon={:.6}", gps_data.latitude, gps_data.longitude);
}
pub fn get_current_position(&self) -> Option<&GpsData> {
self.current_position.as_ref()
}
}
// Native GPS implementation - Mock implementation for demonstration
// TODO: Replace with real GPS hardware access (e.g., using gpsd, CoreLocation, etc.)
#[cfg(not(target_arch = "wasm32"))]
pub fn start_native_gps_tracking(mut gps_service: ResMut<GpsService>, time: Res<Time>) {
use std::time::{SystemTime, UNIX_EPOCH};
if !gps_service.is_enabled {
return;
}
// Mock GPS data that simulates realistic movement
// In a real implementation, this would read from GPS hardware
let timestamp = SystemTime::now()
.duration_since(UNIX_EPOCH)
.unwrap()
.as_secs_f64();
// Only update every 2 seconds to simulate realistic GPS update rate
if timestamp - gps_service.last_update < 2.0 {
return;
}
// Simulate GPS coordinates around Monaco with realistic movement
let base_lat = 43.7384;
let base_lon = 7.4246;
let time_factor = time.elapsed_secs() * 0.1;
// Simulate a boat moving in a realistic pattern
let lat_offset = (time_factor.sin() * 0.002) as f64;
let lon_offset = (time_factor.cos() * 0.003) as f64;
let gps_data = GpsData {
latitude: base_lat + lat_offset,
longitude: base_lon + lon_offset,
altitude: Some(0.0), // Sea level
accuracy: Some(3.0), // 3 meter accuracy
heading: Some(((time_factor * 20.0) % 360.0) as f64),
speed: Some(5.2), // 5.2 knots
timestamp,
};
gps_service.update_position(gps_data);
}
// Web GPS implementation using geolocation API
// For web platforms, we'll use a simplified approach that requests position periodically
#[cfg(target_arch = "wasm32")]
pub fn start_web_gps_tracking(mut gps_service: ResMut<GpsService>, time: Res<Time>) {
if !gps_service.is_enabled {
return;
}
// Use Bevy's time instead of std::time for WASM compatibility
let current_time = time.elapsed_secs_f64();
// Only try to get GPS every 5 seconds to avoid overwhelming the browser
if current_time - gps_service.last_update < 5.0 {
return;
}
// For now, use mock data for web as well
// TODO: Implement proper web geolocation API integration using channels or events
let time_factor = time.elapsed_secs() * 0.1;
let base_lat = 43.7384;
let base_lon = 7.4246;
let lat_offset = (time_factor.sin() * 0.001) as f64;
let lon_offset = (time_factor.cos() * 0.002) as f64;
let gps_data = GpsData {
latitude: base_lat + lat_offset,
longitude: base_lon + lon_offset,
altitude: Some(0.0),
accuracy: Some(5.0), // Slightly less accurate on web
heading: Some(((time_factor * 15.0) % 360.0) as f64),
speed: Some(4.8), // Slightly different speed for web
timestamp: current_time,
};
gps_service.update_position(gps_data.clone());
info!("Web GPS position updated: lat={:.6}, lon={:.6}", gps_data.latitude, gps_data.longitude);
}
pub struct GpsServicePlugin;
impl Plugin for GpsServicePlugin {
fn build(&self, app: &mut App) {
app.init_resource::<GpsService>()
.add_systems(Update, (
#[cfg(not(target_arch = "wasm32"))]
start_native_gps_tracking,
#[cfg(target_arch = "wasm32")]
start_web_gps_tracking,
));
}
}
#[cfg(test)]
mod tests {
use super::*;
#[cfg(not(target_arch = "wasm32"))]
use std::time::{SystemTime, UNIX_EPOCH};
#[test]
fn test_gps_service_initialization() {
let mut gps_service = GpsService::new();
assert!(!gps_service.is_enabled);
assert!(gps_service.current_position.is_none());
gps_service.enable();
assert!(gps_service.is_enabled);
}
#[test]
#[cfg(not(target_arch = "wasm32"))]
fn test_gps_data_update() {
let mut gps_service = GpsService::new();
let timestamp = SystemTime::now()
.duration_since(UNIX_EPOCH)
.unwrap()
.as_secs_f64();
let test_gps_data = GpsData {
latitude: 43.7384,
longitude: 7.4246,
altitude: Some(0.0),
accuracy: Some(3.0),
heading: Some(45.0),
speed: Some(5.2),
timestamp,
};
gps_service.update_position(test_gps_data.clone());
let current_pos = gps_service.get_current_position().unwrap();
assert_eq!(current_pos.latitude, 43.7384);
assert_eq!(current_pos.longitude, 7.4246);
assert_eq!(current_pos.speed, Some(5.2));
assert_eq!(current_pos.heading, Some(45.0));
}
#[test]
#[cfg(target_arch = "wasm32")]
fn test_gps_data_update_wasm() {
let mut gps_service = GpsService::new();
// Use a mock timestamp for WASM testing
let timestamp = 1234567890.0;
let test_gps_data = GpsData {
latitude: 43.7384,
longitude: 7.4246,
altitude: Some(0.0),
accuracy: Some(3.0),
heading: Some(45.0),
speed: Some(5.2),
timestamp,
};
gps_service.update_position(test_gps_data.clone());
let current_pos = gps_service.get_current_position().unwrap();
assert_eq!(current_pos.latitude, 43.7384);
assert_eq!(current_pos.longitude, 7.4246);
assert_eq!(current_pos.speed, Some(5.2));
assert_eq!(current_pos.heading, Some(45.0));
}
#[test]
fn test_gps_service_enable_disable() {
let mut gps_service = GpsService::new();
// Test initial state
assert!(!gps_service.is_enabled);
// Test enable
gps_service.enable();
assert!(gps_service.is_enabled);
// Test disable
gps_service.disable();
assert!(!gps_service.is_enabled);
}
}

View File

@@ -0,0 +1,3 @@
pub mod gps_service;
pub use gps_service::*;

View File

@@ -2,14 +2,14 @@ use bevy::prelude::*;
use bevy::render::view::RenderLayers;
use bevy::window::Window;
use std::collections::HashMap;
use bevy_flurx::prelude::*;
use bevy_webview_wry::prelude::*;
use serde::{Deserialize, Serialize};
/// Render layer for GPS map entities to isolate them from other cameras
use crate::services::{GpsService, GpsData};
#[cfg(not(target_arch = "wasm32"))]
use bevy_flurx::prelude::*;
#[cfg(not(target_arch = "wasm32"))]
use bevy_webview_wry::prelude::*;
use web_sys::window;
/// Render layer for GPS map entities to isolate them from other cameras
const GPS_MAP_LAYER: usize = 1;
@@ -97,8 +97,9 @@ impl Plugin for GpsMapPlugin {
.add_systems(Update, (
handle_gps_map_window_events,
update_map_tiles,
send_periodic_gps_updates,
));
update_gps_from_service,
))
.add_systems(Startup, enable_gps_service);
}
}
@@ -182,18 +183,26 @@ fn spawn_placeholder_map(commands: &mut Commands, _asset_server: &Res<AssetServe
/// Function to spawn the GPS map window
pub fn spawn_gps_map_window(commands: &mut Commands, gps_map_state: &mut ResMut<GpsMapState>) {
#[cfg(not(target_arch = "wasm32"))]
spawn_webview(commands, gps_map_state);
#[cfg(target_arch = "wasm32")]
web_sys::window().unwrap().document().unwrap().create_element("div").unwrap().set_id("bevy-gps-map");
}
#[cfg(not(target_arch = "wasm32"))]
pub fn spawn_webview(commands: &mut Commands, gps_map_state: &mut ResMut<GpsMapState>) {
if gps_map_state.window_id.is_some() {
info!("GPS map window already open");
return;
}
info!("Spawning GPS map window");
// Create a new window for the GPS map
let window_entity = commands
.spawn((
Window {
title: "GPS Navigation - OpenStreetMap".to_string(),
title: "GPS".to_string(),
resolution: (800.0, 600.0).into(),
position: bevy::window::WindowPosition::Centered(
bevy::window::MonitorSelection::Current,
@@ -204,6 +213,8 @@ pub fn spawn_gps_map_window(commands: &mut Commands, gps_map_state: &mut ResMut<
))
.id();
gps_map_state.window_id = Some(window_entity);
// Create a camera for the map window
commands.spawn((
Camera2d,
@@ -217,29 +228,25 @@ pub fn spawn_gps_map_window(commands: &mut Commands, gps_map_state: &mut ResMut<
GpsMapWindow,
));
gps_map_state.window_id = Some(window_entity);
info!("GPS map window spawned with entity: {:?}", window_entity);
#[cfg(not(target_arch = "wasm32"))]
spawn_gps_webview(commands, gps_map_state);
}
#[cfg(not(target_arch = "wasm32"))]
fn spawn_gps_webview(commands: &mut Commands, gps_map_state: &mut ResMut<GpsMapState>) {
if let Some(win) = gps_map_state.window_id {
commands.entity(win).insert((
IpcHandlers::new([
navigation_clicked,
search_clicked,
map_view_changed,
auth_status_changed,
get_map_init,
get_vessel_status
ipc_commands::navigation_clicked,
ipc_commands::search_clicked,
ipc_commands::map_view_changed,
ipc_commands::auth_status_changed,
ipc_commands::get_map_init,
ipc_commands::get_vessel_status
]),
Webview::Uri(WebviewUri::relative_local(
// Using the build output of the base-map package
@@ -249,109 +256,122 @@ fn spawn_gps_webview(commands: &mut Commands, gps_map_state: &mut ResMut<GpsMapS
}
}
// GPS Map IPC Commands using bevy_flurx_ipc
#[cfg(not(target_arch = "wasm32"))]
mod ipc_commands {
use super::*;
/// Handle navigation button click
#[command]
fn navigation_clicked(
WebviewEntity(_entity): WebviewEntity,
) -> Action<(), ()> {
once::run(|_: In<()>| {
info!("Navigation button clicked in React");
// Handle navigation logic here
}).into()
// GPS Map IPC Commands using bevy_flurx_ipc
/// Handle navigation button click
#[command]
pub fn navigation_clicked(
WebviewEntity(_entity): WebviewEntity,
) -> Action<(), ()> {
once::run(|_: In<()>| {
info!("Navigation button clicked in React");
// Handle navigation logic here
}).into()
}
/// Handle search button click
#[command]
pub fn search_clicked(
WebviewEntity(_entity): WebviewEntity,
) -> Action<(), ()> {
once::run(|_: In<()>| {
info!("Search button clicked in React");
// Handle search logic here
}).into()
}
/// Handle map view change
#[command]
pub fn map_view_changed(
In(params): In<MapViewParams>,
WebviewEntity(_entity): WebviewEntity,
) -> Action<(f64, f64, u8), ()> {
once::run(|In((latitude, longitude, zoom)): In<(f64, f64, u8)>, mut gps_map_state: ResMut<GpsMapState>| {
info!("Map view changed: lat={}, lon={}, zoom={}", latitude, longitude, zoom);
gps_map_state.center_lat = latitude;
gps_map_state.center_lon = longitude;
gps_map_state.zoom_level = zoom;
}).with((params.latitude, params.longitude, params.zoom)).into()
}
/// Handle authentication status change
#[command]
pub fn auth_status_changed(
In(params): In<AuthParams>,
WebviewEntity(_entity): WebviewEntity,
) -> Action<(bool, Option<String>), ()> {
once::run(|In((authenticated, token)): In<(bool, Option<String>)>| {
info!("Auth status changed: authenticated={}, token={:?}", authenticated, token);
// Handle authentication status change
}).with((params.authenticated, params.token)).into()
}
/// Get map initialization data
#[command]
pub async fn get_map_init(
WebviewEntity(_entity): WebviewEntity,
task: ReactorTask,
) -> GpsPosition {
task.will(Update, once::run(|gps_map_state: Res<GpsMapState>| {
GpsPosition {
latitude: gps_map_state.center_lat,
longitude: gps_map_state.center_lon,
zoom: gps_map_state.zoom_level,
}
})).await
}
/// Get current vessel status
#[command]
pub async fn get_vessel_status(
WebviewEntity(_entity): WebviewEntity,
task: ReactorTask,
) -> VesselStatus {
task.will(Update, once::run(|gps_map_state: Res<GpsMapState>| {
VesselStatus {
latitude: gps_map_state.vessel_lat,
longitude: gps_map_state.vessel_lon,
heading: gps_map_state.vessel_heading,
speed: gps_map_state.vessel_speed,
}
})).await
}
}
/// Handle search button click
#[command]
fn search_clicked(
WebviewEntity(_entity): WebviewEntity,
) -> Action<(), ()> {
once::run(|_: In<()>| {
info!("Search button clicked in React");
// Handle search logic here
}).into()
/// System to enable GPS service on startup
fn enable_gps_service(mut gps_service: ResMut<GpsService>) {
gps_service.enable();
info!("GPS service enabled for map tracking");
}
/// Handle map view change
#[command]
fn map_view_changed(
In(params): In<MapViewParams>,
WebviewEntity(_entity): WebviewEntity,
) -> Action<(f64, f64, u8), ()> {
once::run(|In((latitude, longitude, zoom)): In<(f64, f64, u8)>, mut gps_map_state: ResMut<GpsMapState>| {
info!("Map view changed: lat={}, lon={}, zoom={}", latitude, longitude, zoom);
gps_map_state.center_lat = latitude;
gps_map_state.center_lon = longitude;
gps_map_state.zoom_level = zoom;
}).with((params.latitude, params.longitude, params.zoom)).into()
}
/// Handle authentication status change
#[command]
fn auth_status_changed(
In(params): In<AuthParams>,
WebviewEntity(_entity): WebviewEntity,
) -> Action<(bool, Option<String>), ()> {
once::run(|In((authenticated, token)): In<(bool, Option<String>)>| {
info!("Auth status changed: authenticated={}, token={:?}", authenticated, token);
// Handle authentication status change
}).with((params.authenticated, params.token)).into()
}
/// Get map initialization data
#[command]
async fn get_map_init(
WebviewEntity(_entity): WebviewEntity,
task: ReactorTask,
) -> GpsPosition {
task.will(Update, once::run(|gps_map_state: Res<GpsMapState>| {
GpsPosition {
latitude: gps_map_state.center_lat,
longitude: gps_map_state.center_lon,
zoom: gps_map_state.zoom_level,
}
})).await
}
/// Get current vessel status
#[command]
async fn get_vessel_status(
WebviewEntity(_entity): WebviewEntity,
task: ReactorTask,
) -> VesselStatus {
task.will(Update, once::run(|gps_map_state: Res<GpsMapState>| {
VesselStatus {
latitude: gps_map_state.vessel_lat,
longitude: gps_map_state.vessel_lon,
heading: gps_map_state.vessel_heading,
speed: gps_map_state.vessel_speed,
}
})).await
}
/// System to send periodic GPS updates for testing
fn send_periodic_gps_updates(
/// System to update GPS map state from GPS service
fn update_gps_from_service(
mut gps_map_state: ResMut<GpsMapState>,
time: Res<Time>,
gps_service: Res<GpsService>,
) {
// Update vessel position every frame for testing
if time.delta_secs() > 0.0 {
// Simulate slight movement around Monaco
let base_lat = 43.6377;
let base_lon = -1.4497;
let offset = (time.elapsed_secs().sin() * 0.001) as f64;
if let Some(gps_data) = gps_service.get_current_position() {
// Update vessel position from real GPS data
gps_map_state.vessel_lat = gps_data.latitude;
gps_map_state.vessel_lon = gps_data.longitude;
gps_map_state.vessel_lat = base_lat + offset;
gps_map_state.vessel_lon = base_lon + offset * 0.5;
gps_map_state.vessel_speed = 5.0 + (time.elapsed_secs().cos() * 2.0) as f64;
gps_map_state.vessel_heading = ((time.elapsed_secs() * 10.0) % 360.0) as f64;
// Update speed and heading if available
if let Some(speed) = gps_data.speed {
gps_map_state.vessel_speed = speed;
}
if let Some(heading) = gps_data.heading {
gps_map_state.vessel_heading = heading;
}
// React side can poll for updates using get_vessel_status command
if time.elapsed_secs() as u32 % 5 == 0 && time.delta_secs() < 0.1 {
info!("Vessel position updated: lat={:.4}, lon={:.4}, speed={:.1}, heading={:.1}",
gps_map_state.vessel_lat, gps_map_state.vessel_lon,
gps_map_state.vessel_speed, gps_map_state.vessel_heading);
// Also update map center to follow vessel if this is the first GPS fix
if gps_map_state.center_lat == 43.6377 && gps_map_state.center_lon == -1.4497 {
gps_map_state.center_lat = gps_data.latitude;
gps_map_state.center_lon = gps_data.longitude;
info!("Map centered on GPS position: lat={:.6}, lon={:.6}",
gps_data.latitude, gps_data.longitude);
}
}
}

View File

@@ -13,18 +13,28 @@ pub struct LoadingPlugin;
/// If interested, take a look at <https://bevy-cheatbook.github.io/features/assets.html>
impl Plugin for LoadingPlugin {
fn build(&self, app: &mut App) {
app.add_loading_state(
LoadingState::new(GameState::Loading)
.continue_to_state(GameState::Playing)
// .load_collection::<AudioAssets>()
// .load_collection::<TextureAssets>(),
);
// Temporarily bypass asset loading and go directly to Playing state
app.add_systems(Startup, || {
info!("LoadingPlugin: Starting up, transitioning to Playing state");
});
app.add_systems(Update, transition_to_playing.run_if(in_state(GameState::Loading)));
// Add a system to hide the loading indicator when transitioning to the Playing state
app.add_systems(OnEnter(GameState::Playing), hide_loading_indicator);
// Add debug systems to track state transitions
app.add_systems(OnEnter(GameState::Loading), || info!("Entered Loading state"));
app.add_systems(OnExit(GameState::Loading), || info!("Exiting Loading state"));
app.add_systems(OnEnter(GameState::Playing), || info!("Entered Playing state"));
}
}
fn transition_to_playing(mut next_state: ResMut<NextState<GameState>>) {
info!("Transitioning from Loading to Playing state");
next_state.set(GameState::Playing);
}
/// Hides the loading indicator when transitioning to the Playing state
#[cfg(target_arch = "wasm32")]
fn hide_loading_indicator() {

View File

@@ -1,15 +0,0 @@
{
"name": "yachtpit",
"private": true,
"workspaces": ["packages/*"],
"scripts": {
"build-and-deploy-map": "cd packages/base-map && npm run build && cd ../.. && mkdir -p crates/yachtpit/assets/ui/packages/base-map/dist && cp -r packages/base-map/dist/* crates/yachtpit/assets/ui/packages/base-map/dist/",
"postinstall": "npm run build-and-deploy-map"
},
"devDependencies": {
"@types/bun": "latest"
},
"peerDependencies": {
"typescript": "^5"
}
}

View File

@@ -1,163 +0,0 @@
import Map from 'react-map-gl/mapbox'; // ↔ v5+ uses this import path
import 'mapbox-gl/dist/mapbox-gl.css';
import {Box, Button, HStack} from '@chakra-ui/react';
import {useCallback, useEffect, useState} from "react";
// public key
const key =
'cGsuZXlKMUlqb2laMlZ2Wm1aelpXVWlMQ0poSWpvaVkycDFOalo0YkdWNk1EUTRjRE41YjJnNFp6VjNNelp6YXlKOS56LUtzS1l0X3VGUGdCSDYwQUFBNFNn';
// Types for bevy_flurx_ipc communication
interface GpsPosition {
latitude: number;
longitude: number;
zoom: number;
}
interface VesselStatus {
latitude: number;
longitude: number;
heading: number;
speed: number;
}
interface MapViewParams {
latitude: number;
longitude: number;
zoom: number;
}
interface AuthParams {
authenticated: boolean;
token: string | null;
}
function App() {
// Map state that can be updated from Rust
const [mapView, setMapView] = useState({
longitude: -122.4,
latitude: 37.8,
zoom: 14
});
// Button click handlers
const handleNavigationClick = useCallback(async () => {
if (typeof window !== 'undefined' && (window as any).__FLURX__) {
try {
await (window as any).__FLURX__.invoke("navigation_clicked");
console.log('Navigation clicked');
} catch (error) {
console.error('Failed to invoke navigation_clicked:', error);
}
}
}, []);
const handleSearchClick = useCallback(async () => {
if (typeof window !== 'undefined' && (window as any).__FLURX__) {
try {
await (window as any).__FLURX__.invoke("search_clicked");
console.log('Search clicked');
} catch (error) {
console.error('Failed to invoke search_clicked:', error);
}
}
}, []);
const handleMapViewChange = useCallback(async (evt: any) => {
const { longitude, latitude, zoom } = evt.viewState;
setMapView({ longitude, latitude, zoom });
if (typeof window !== 'undefined' && (window as any).__FLURX__) {
try {
const mapViewParams: MapViewParams = {
latitude,
longitude,
zoom
};
await (window as any).__FLURX__.invoke("map_view_changed", mapViewParams);
console.log('Map view changed:', mapViewParams);
} catch (error) {
console.error('Failed to invoke map_view_changed:', error);
}
}
}, []);
// Poll for vessel status updates
useEffect(() => {
const pollVesselStatus = async () => {
if (typeof window !== 'undefined' && (window as any).__FLURX__) {
try {
const vesselStatus: VesselStatus = await (window as any).__FLURX__.invoke("get_vessel_status");
console.log('Vessel status:', vesselStatus);
// You can update vessel position on map here if needed
} catch (error) {
console.error('Failed to get vessel status:', error);
}
}
};
// Poll every 5 seconds
const interval = setInterval(pollVesselStatus, 5000);
return () => clearInterval(interval);
}, []);
// Initialize map with data from Rust
useEffect(() => {
const initializeMap = async () => {
if (typeof window !== 'undefined' && (window as any).__FLURX__) {
try {
const mapInit: GpsPosition = await (window as any).__FLURX__.invoke("get_map_init");
console.log('Map initialization data:', mapInit);
setMapView({
latitude: mapInit.latitude,
longitude: mapInit.longitude,
zoom: mapInit.zoom
});
} catch (error) {
console.error('Failed to get map initialization data:', error);
}
}
};
initializeMap();
}, []);
return (
/* Full-screen wrapper — fills the viewport and becomes the positioning context */
<Box w="100vw" h="100vh" position="relative" overflow="hidden">
{/* Button bar — absolutely positioned inside the wrapper */}
<HStack position="absolute" top={4} right={4} zIndex={1}>
<Button
colorScheme="blue"
size="sm"
variant="solid"
onClick={handleNavigationClick}
>
Navigation
</Button>
<Button
colorScheme="teal"
size="sm"
variant="solid"
onClick={handleSearchClick}
>
Search
</Button>
</HStack>
<Map
mapboxAccessToken={atob(key)}
initialViewState={mapView}
onMove={handleMapViewChange}
mapStyle="mapbox://styles/mapbox/dark-v11"
reuseMaps
attributionControl={false}
style={{width: '100%', height: '100%'}} // let the wrapper dictate size
/>
</Box>
);
}
export default App;

View File

@@ -1,7 +0,0 @@
{
"files": [],
"references": [
{ "path": "./tsconfig.app.json" },
{ "path": "./tsconfig.node.json" }
],
}