diff --git a/.prettierrc b/.prettierrc index 0967ef42..222861c3 100644 --- a/.prettierrc +++ b/.prettierrc @@ -1 +1,4 @@ -{} +{ + "tabWidth": 2, + "useTabs": false +} diff --git a/package.json b/package.json index a836551c..25a8fa4e 100644 --- a/package.json +++ b/package.json @@ -20,22 +20,23 @@ "homepage": "https://meshtastic.org", "dependencies": { "@emeraldpay/hashicon-react": "^0.5.2", - "@hookform/resolvers": "^2.9.7", + "@headlessui/react": "^1.7.2", + "@heroicons/react": "^2.0.11", + "@hookform/resolvers": "^2.9.8", "@meshtastic/eslint-config": "^1.0.8", - "@meshtastic/meshtasticjs": "^0.6.98", + "@meshtastic/meshtasticjs": "^0.6.99", + "@tailwindcss/line-clamp": "^0.4.2", + "@tailwindcss/typography": "^0.5.7", "base64-js": "^1.5.1", "class-transformer": "^0.5.1", "class-validator": "^0.13.2", - "evergreen-ui": "^6.10.3", "geodesy": "^2.4.0", "immer": "^9.0.15", "mapbox-gl": "npm:empty-npm-package@^1.0.0", "maplibre-gl": "^2.4.0", - "modern-css-reset": "^1.4.0", - "prettier": "^2.7.1", "react": "^18.2.0", "react-dom": "^18.2.0", - "react-hook-form": "^7.34.2", + "react-hook-form": "^7.35.0", "react-icons": "^4.4.0", "react-json-pretty": "^2.2.0", "react-map-gl": "^7.0.19", @@ -44,20 +45,25 @@ "zustand": "4.1.1" }, "devDependencies": { - "@types/chrome": "^0.0.196", + "@types/chrome": "^0.0.197", "@types/geodesy": "^2.2.3", - "@types/node": "^18.7.16", - "@types/react": "^18.0.18", + "@types/node": "^18.7.18", + "@types/react": "^18.0.20", "@types/react-dom": "^18.0.6", "@types/w3c-web-serial": "^1.0.2", "@types/web-bluetooth": "^0.0.15", "@vitejs/plugin-react": "^2.1.0", + "autoprefixer": "^10.4.11", "gzipper": "^7.1.0", + "postcss": "^8.4.16", + "prettier": "^2.7.1", + "prettier-plugin-tailwindcss": "^0.1.13", "rollup-plugin-visualizer": "^5.8.1", + "tailwindcss": "^3.1.8", "tar": "^6.1.11", "tslib": "^2.4.0", "typescript": "^4.8.3", - "vite": "^3.1.0", + "vite": "^3.1.3", "vite-plugin-environment": "^1.1.2" } } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 01ce74ed..006f8704 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -2,62 +2,69 @@ lockfileVersion: 5.4 specifiers: '@emeraldpay/hashicon-react': ^0.5.2 - '@hookform/resolvers': ^2.9.7 + '@headlessui/react': ^1.7.2 + '@heroicons/react': ^2.0.11 + '@hookform/resolvers': ^2.9.8 '@meshtastic/eslint-config': ^1.0.8 - '@meshtastic/meshtasticjs': ^0.6.98 - '@types/chrome': ^0.0.196 + '@meshtastic/meshtasticjs': ^0.6.99 + '@tailwindcss/line-clamp': ^0.4.2 + '@tailwindcss/typography': ^0.5.7 + '@types/chrome': ^0.0.197 '@types/geodesy': ^2.2.3 - '@types/node': ^18.7.16 - '@types/react': ^18.0.18 + '@types/node': ^18.7.18 + '@types/react': ^18.0.20 '@types/react-dom': ^18.0.6 '@types/w3c-web-serial': ^1.0.2 '@types/web-bluetooth': ^0.0.15 '@vitejs/plugin-react': ^2.1.0 + autoprefixer: ^10.4.11 base64-js: ^1.5.1 class-transformer: ^0.5.1 class-validator: ^0.13.2 - evergreen-ui: ^6.10.3 geodesy: ^2.4.0 gzipper: ^7.1.0 immer: ^9.0.15 mapbox-gl: npm:empty-npm-package@^1.0.0 maplibre-gl: ^2.4.0 - modern-css-reset: ^1.4.0 + postcss: ^8.4.16 prettier: ^2.7.1 + prettier-plugin-tailwindcss: ^0.1.13 react: ^18.2.0 react-dom: ^18.2.0 - react-hook-form: ^7.34.2 + react-hook-form: ^7.35.0 react-icons: ^4.4.0 react-json-pretty: ^2.2.0 react-map-gl: ^7.0.19 react-qrcode-logo: ^2.8.0 rfc4648: ^1.5.2 rollup-plugin-visualizer: ^5.8.1 + tailwindcss: ^3.1.8 tar: ^6.1.11 tslib: ^2.4.0 typescript: ^4.8.3 - vite: ^3.1.0 + vite: ^3.1.3 vite-plugin-environment: ^1.1.2 zustand: 4.1.1 dependencies: '@emeraldpay/hashicon-react': 0.5.2 - '@hookform/resolvers': 2.9.7_react-hook-form@7.34.2 + '@headlessui/react': 1.7.2_biqbaboplfbrettd7655fr4n2y + '@heroicons/react': 2.0.11_react@18.2.0 + '@hookform/resolvers': 2.9.8_react-hook-form@7.35.0 '@meshtastic/eslint-config': 1.0.8 - '@meshtastic/meshtasticjs': 0.6.98 + '@meshtastic/meshtasticjs': link:../meshtastic.js + '@tailwindcss/line-clamp': 0.4.2_tailwindcss@3.1.8 + '@tailwindcss/typography': 0.5.7_tailwindcss@3.1.8 base64-js: 1.5.1 class-transformer: 0.5.1 class-validator: 0.13.2 - evergreen-ui: 6.10.3_biqbaboplfbrettd7655fr4n2y geodesy: 2.4.0 immer: 9.0.15 mapbox-gl: /empty-npm-package/1.0.0 maplibre-gl: 2.4.0 - modern-css-reset: 1.4.0 - prettier: 2.7.1 react: 18.2.0 react-dom: 18.2.0_react@18.2.0 - react-hook-form: 7.34.2_react@18.2.0 + react-hook-form: 7.35.0_react@18.2.0 react-icons: 4.4.0_react@18.2.0 react-json-pretty: 2.2.0_biqbaboplfbrettd7655fr4n2y react-map-gl: 7.0.19_6eczaga5xxiwzxtfiyk6fioasq @@ -66,21 +73,26 @@ dependencies: zustand: 4.1.1_immer@9.0.15+react@18.2.0 devDependencies: - '@types/chrome': 0.0.196 + '@types/chrome': 0.0.197 '@types/geodesy': 2.2.3 - '@types/node': 18.7.16 - '@types/react': 18.0.18 + '@types/node': 18.7.18 + '@types/react': 18.0.20 '@types/react-dom': 18.0.6 '@types/w3c-web-serial': 1.0.2 '@types/web-bluetooth': 0.0.15 - '@vitejs/plugin-react': 2.1.0_vite@3.1.0 + '@vitejs/plugin-react': 2.1.0_vite@3.1.3 + autoprefixer: 10.4.11_postcss@8.4.16 gzipper: 7.1.0 + postcss: 8.4.16 + prettier: 2.7.1 + prettier-plugin-tailwindcss: 0.1.13_prettier@2.7.1 rollup-plugin-visualizer: 5.8.1 + tailwindcss: 3.1.8_postcss@8.4.16 tar: 6.1.11 tslib: 2.4.0 typescript: 4.8.3 - vite: 3.1.0 - vite-plugin-environment: 1.1.2_vite@3.1.0 + vite: 3.1.3 + vite-plugin-environment: 1.1.2_vite@3.1.3 packages: @@ -99,24 +111,24 @@ packages: '@babel/highlight': 7.18.6 dev: true - /@babel/compat-data/7.19.0: - resolution: {integrity: sha512-y5rqgTTPTmaF5e2nVhOxw+Ur9HDJLsWb6U/KpgUzRZEdPfE6VOubXBKLdbcUTijzRptednSBDQbYZBOSqJxpJw==} + /@babel/compat-data/7.19.1: + resolution: {integrity: sha512-72a9ghR0gnESIa7jBN53U32FOVCEoztyIlKaNoU05zRhEecduGK9L9c3ww7Mp06JiR+0ls0GBPFJQwwtjn9ksg==} engines: {node: '>=6.9.0'} dev: true - /@babel/core/7.19.0: - resolution: {integrity: sha512-reM4+U7B9ss148rh2n1Qs9ASS+w94irYXga7c2jaQv9RVzpS7Mv1a9rnYYwuDa45G+DkORt9g6An2k/V4d9LbQ==} + /@babel/core/7.19.1: + resolution: {integrity: sha512-1H8VgqXme4UXCRv7/Wa1bq7RVymKOzC7znjyFM8KiEzwFqcKUKYNoQef4GhdklgNvoBXyW4gYhuBNCM5o1zImw==} engines: {node: '>=6.9.0'} dependencies: '@ampproject/remapping': 2.2.0 '@babel/code-frame': 7.18.6 '@babel/generator': 7.19.0 - '@babel/helper-compilation-targets': 7.19.0_@babel+core@7.19.0 + '@babel/helper-compilation-targets': 7.19.1_@babel+core@7.19.1 '@babel/helper-module-transforms': 7.19.0 '@babel/helpers': 7.19.0 - '@babel/parser': 7.19.0 + '@babel/parser': 7.19.1 '@babel/template': 7.18.10 - '@babel/traverse': 7.19.0 + '@babel/traverse': 7.19.1 '@babel/types': 7.19.0 convert-source-map: 1.8.0 debug: 4.3.4 @@ -143,16 +155,16 @@ packages: '@babel/types': 7.19.0 dev: true - /@babel/helper-compilation-targets/7.19.0_@babel+core@7.19.0: - resolution: {integrity: sha512-Ai5bNWXIvwDvWM7njqsG3feMlL9hCVQsPYXodsZyLwshYkZVJt59Gftau4VrE8S9IT9asd2uSP1hG6wCNw+sXA==} + /@babel/helper-compilation-targets/7.19.1_@babel+core@7.19.1: + resolution: {integrity: sha512-LlLkkqhCMyz2lkQPvJNdIYU7O5YjWRgC2R4omjCTpZd8u8KMQzZvX4qce+/BluN1rcQiV7BoGUpmQ0LeHerbhg==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0 dependencies: - '@babel/compat-data': 7.19.0 - '@babel/core': 7.19.0 + '@babel/compat-data': 7.19.1 + '@babel/core': 7.19.1 '@babel/helper-validator-option': 7.18.6 - browserslist: 4.21.3 + browserslist: 4.21.4 semver: 6.3.0 dev: true @@ -191,9 +203,9 @@ packages: '@babel/helper-module-imports': 7.18.6 '@babel/helper-simple-access': 7.18.6 '@babel/helper-split-export-declaration': 7.18.6 - '@babel/helper-validator-identifier': 7.18.6 + '@babel/helper-validator-identifier': 7.19.1 '@babel/template': 7.18.10 - '@babel/traverse': 7.19.0 + '@babel/traverse': 7.19.1 '@babel/types': 7.19.0 transitivePeerDependencies: - supports-color @@ -223,8 +235,8 @@ packages: engines: {node: '>=6.9.0'} dev: true - /@babel/helper-validator-identifier/7.18.6: - resolution: {integrity: sha512-MmetCkz9ej86nJQV+sFCxoGGrUbU3q02kgLciwkrt9QqEB7cP39oKEY0PakknEO0Gu20SskMRi+AYZ3b1TpN9g==} + /@babel/helper-validator-identifier/7.19.1: + resolution: {integrity: sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w==} engines: {node: '>=6.9.0'} dev: true @@ -238,7 +250,7 @@ packages: engines: {node: '>=6.9.0'} dependencies: '@babel/template': 7.18.10 - '@babel/traverse': 7.19.0 + '@babel/traverse': 7.19.1 '@babel/types': 7.19.0 transitivePeerDependencies: - supports-color @@ -248,91 +260,84 @@ packages: resolution: {integrity: sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g==} engines: {node: '>=6.9.0'} dependencies: - '@babel/helper-validator-identifier': 7.18.6 + '@babel/helper-validator-identifier': 7.19.1 chalk: 2.4.2 js-tokens: 4.0.0 dev: true - /@babel/parser/7.19.0: - resolution: {integrity: sha512-74bEXKX2h+8rrfQUfsBfuZZHzsEs6Eql4pqy/T4Nn6Y9wNPggQOqD6z6pn5Bl8ZfysKouFZT/UXEH94ummEeQw==} + /@babel/parser/7.19.1: + resolution: {integrity: sha512-h7RCSorm1DdTVGJf3P2Mhj3kdnkmF/EiysUkzS2TdgAYqyjFdMQJbVuXOBej2SBJaXan/lIVtT6KkGbyyq753A==} engines: {node: '>=6.0.0'} hasBin: true dependencies: '@babel/types': 7.19.0 dev: true - /@babel/plugin-syntax-jsx/7.18.6_@babel+core@7.19.0: + /@babel/plugin-syntax-jsx/7.18.6_@babel+core@7.19.1: resolution: {integrity: sha512-6mmljtAedFGTWu2p/8WIORGwy+61PLgOMPOdazc7YoJ9ZCWUyFy3A6CpPkRKLKD1ToAesxX8KGEViAiLo9N+7Q==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.19.0 + '@babel/core': 7.19.1 '@babel/helper-plugin-utils': 7.19.0 dev: true - /@babel/plugin-transform-react-jsx-development/7.18.6_@babel+core@7.19.0: + /@babel/plugin-transform-react-jsx-development/7.18.6_@babel+core@7.19.1: resolution: {integrity: sha512-SA6HEjwYFKF7WDjWcMcMGUimmw/nhNRDWxr+KaLSCrkD/LMDBvWRmHAYgE1HDeF8KUuI8OAu+RT6EOtKxSW2qA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.19.0 - '@babel/plugin-transform-react-jsx': 7.19.0_@babel+core@7.19.0 + '@babel/core': 7.19.1 + '@babel/plugin-transform-react-jsx': 7.19.0_@babel+core@7.19.1 dev: true - /@babel/plugin-transform-react-jsx-self/7.18.6_@babel+core@7.19.0: + /@babel/plugin-transform-react-jsx-self/7.18.6_@babel+core@7.19.1: resolution: {integrity: sha512-A0LQGx4+4Jv7u/tWzoJF7alZwnBDQd6cGLh9P+Ttk4dpiL+J5p7NSNv/9tlEFFJDq3kjxOavWmbm6t0Gk+A3Ig==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.19.0 + '@babel/core': 7.19.1 '@babel/helper-plugin-utils': 7.19.0 dev: true - /@babel/plugin-transform-react-jsx-source/7.18.6_@babel+core@7.19.0: + /@babel/plugin-transform-react-jsx-source/7.18.6_@babel+core@7.19.1: resolution: {integrity: sha512-utZmlASneDfdaMh0m/WausbjUjEdGrQJz0vFK93d7wD3xf5wBtX219+q6IlCNZeguIcxS2f/CvLZrlLSvSHQXw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.19.0 + '@babel/core': 7.19.1 '@babel/helper-plugin-utils': 7.19.0 dev: true - /@babel/plugin-transform-react-jsx/7.19.0_@babel+core@7.19.0: + /@babel/plugin-transform-react-jsx/7.19.0_@babel+core@7.19.1: resolution: {integrity: sha512-UVEvX3tXie3Szm3emi1+G63jyw1w5IcMY0FSKM+CRnKRI5Mr1YbCNgsSTwoTwKphQEG9P+QqmuRFneJPZuHNhg==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.19.0 + '@babel/core': 7.19.1 '@babel/helper-annotate-as-pure': 7.18.6 '@babel/helper-module-imports': 7.18.6 '@babel/helper-plugin-utils': 7.19.0 - '@babel/plugin-syntax-jsx': 7.18.6_@babel+core@7.19.0 + '@babel/plugin-syntax-jsx': 7.18.6_@babel+core@7.19.1 '@babel/types': 7.19.0 dev: true - /@babel/runtime/7.19.0: - resolution: {integrity: sha512-eR8Lo9hnDS7tqkO7NsV+mKvCmv5boaXFSZ70DnfhcgiEne8hv9oCEd36Klw74EtizEqLsy4YnW8UWwpBVolHZA==} - engines: {node: '>=6.9.0'} - dependencies: - regenerator-runtime: 0.13.9 - dev: false - /@babel/template/7.18.10: resolution: {integrity: sha512-TI+rCtooWHr3QJ27kJxfjutghu44DLnasDMwpDqCXVTal9RLp3RSYNh4NdBrRP2cQAoG9A8juOQl6P6oZG4JxA==} engines: {node: '>=6.9.0'} dependencies: '@babel/code-frame': 7.18.6 - '@babel/parser': 7.19.0 + '@babel/parser': 7.19.1 '@babel/types': 7.19.0 dev: true - /@babel/traverse/7.19.0: - resolution: {integrity: sha512-4pKpFRDh+utd2mbRC8JLnlsMUii3PMHjpL6a0SZ4NMZy7YFP9aXORxEhdMVOc9CpWtDF09IkciQLEhK7Ml7gRA==} + /@babel/traverse/7.19.1: + resolution: {integrity: sha512-0j/ZfZMxKukDaag2PtOPDbwuELqIar6lLskVPPJDjXMXjfLb1Obo/1yjxIGqqAJrmfaTIY3z2wFLAQ7qSkLsuA==} engines: {node: '>=6.9.0'} dependencies: '@babel/code-frame': 7.18.6 @@ -341,7 +346,7 @@ packages: '@babel/helper-function-name': 7.19.0 '@babel/helper-hoist-variables': 7.18.6 '@babel/helper-split-export-declaration': 7.18.6 - '@babel/parser': 7.19.0 + '@babel/parser': 7.19.1 '@babel/types': 7.19.0 debug: 4.3.4 globals: 11.12.0 @@ -354,7 +359,7 @@ packages: engines: {node: '>=6.9.0'} dependencies: '@babel/helper-string-parser': 7.18.10 - '@babel/helper-validator-identifier': 7.18.6 + '@babel/helper-validator-identifier': 7.19.1 to-fast-properties: 2.0.0 dev: true @@ -374,12 +379,19 @@ packages: js-sha3: 0.8.0 dev: false - /@emotion/hash/0.7.4: - resolution: {integrity: sha512-fxfMSBMX3tlIbKUdtGKxqB1fyrH6gVrX39Gsv3y8lRYKUqlgDt3UMqQyGnR1bQMa2B8aGnhLZokZgg8vT0Le+A==} - dev: false + /@esbuild/android-arm/0.15.8: + resolution: {integrity: sha512-CyEWALmn+no/lbgbAJsbuuhT8s2J19EJGHkeyAwjbFJMrj80KJ9zuYsoAvidPTU7BgBf87r/sgae8Tw0dbOc4Q==} + engines: {node: '>=12'} + cpu: [arm] + os: [android] + requiresBuild: true + dependencies: + esbuild-wasm: 0.15.8 + dev: true + optional: true - /@esbuild/linux-loong64/0.15.7: - resolution: {integrity: sha512-IKznSJOsVUuyt7cDzzSZyqBEcZe+7WlBqTVXiF1OXP/4Nm387ToaXZ0fyLwI1iBlI/bzpxVq411QE2/Bt2XWWw==} + /@esbuild/linux-loong64/0.15.8: + resolution: {integrity: sha512-pE5RQsOTSERCtfZdfCT25wzo7dfhOSlhAXcsZmuvRYhendOv7djcdvtINdnDp2DAjP17WXlBB4nBO6sHLczmsg==} engines: {node: '>=12'} cpu: [loong64] os: [linux] @@ -387,8 +399,8 @@ packages: dev: true optional: true - /@eslint/eslintrc/1.3.1: - resolution: {integrity: sha512-OhSY22oQQdw3zgPOOwdoj01l/Dzl1Z+xyUP33tkSN+aqyEhymJCcPHyXt+ylW8FSe0TfRC2VG+ROQOapD0aZSQ==} + /@eslint/eslintrc/1.3.2: + resolution: {integrity: sha512-AXYd23w1S/bv3fTs3Lz0vjiYemS08jWkI3hYyS9I1ry+0f+Yjs1wm+sU0BS8qDOPrBIkp4qHYC16I8uVtpLajQ==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} dependencies: ajv: 6.12.6 @@ -411,12 +423,31 @@ packages: base64-js: 1.5.1 dev: true - /@hookform/resolvers/2.9.7_react-hook-form@7.34.2: - resolution: {integrity: sha512-BloehX3MOLwuFEwT4yZnmolPjVmqyn8VsSuodLfazbCIqxBHsQ4qUZsi+bvNNCduRli1AGWFrkDLGD5QoNzsoA==} + /@headlessui/react/1.7.2_biqbaboplfbrettd7655fr4n2y: + resolution: {integrity: sha512-snLv2lxwsf2HNTOBNgHYdvoYZ3ChJE8QszPi1d/hl9js8KrFrUulTaQBfSyPbJP5BybVreWh9DxCgz9S0Z6hKQ==} + engines: {node: '>=10'} + peerDependencies: + react: ^16 || ^17 || ^18 + react-dom: ^16 || ^17 || ^18 + dependencies: + react: 18.2.0 + react-dom: 18.2.0_react@18.2.0 + dev: false + + /@heroicons/react/2.0.11_react@18.2.0: + resolution: {integrity: sha512-bASjOgSSaYj8HqXWsOqaBiB6ZLalE/g90WYGgZ5lPm4KCCG7wPXntY4kzHf5NrLh6UBAcnPwvbiw1Ne9GYfJtw==} + peerDependencies: + react: '>= 16' + dependencies: + react: 18.2.0 + dev: false + + /@hookform/resolvers/2.9.8_react-hook-form@7.35.0: + resolution: {integrity: sha512-iVVjH0USq+1TqDdGkWe2M1x7Wn5OFPgVRo7CbWFsXTqqXqCaZtZcnzJu+UhljCWbthFWxWGXKLGYUDPZ04oVvQ==} peerDependencies: react-hook-form: ^7.0.0 dependencies: - react-hook-form: 7.34.2_react@18.2.0 + react-hook-form: 7.35.0_react@18.2.0 dev: false /@humanwhocodes/config-array/0.10.4: @@ -524,15 +555,15 @@ packages: /@meshtastic/eslint-config/1.0.8: resolution: {integrity: sha512-Jzwaf3TyYFGeFuxLRQA5Yj5Rmz097VleFQUkswXH9nvLO81JjJbHgJWbHQ6RpxC31q/2hWV03QdaH98swpYcQA==} dependencies: - '@typescript-eslint/eslint-plugin': 5.36.2_2l2r3i3lm6jysqd4ac3ql4n2mm - '@typescript-eslint/parser': 5.36.2_itqs5654cmlnjraw6gjzqacppi - eslint: 8.23.0 - eslint-config-prettier: 8.5.0_eslint@8.23.0 - eslint-import-resolver-typescript: 2.7.1_faomjyrlgqmwswvqymymzkxcqi - eslint-plugin-eslint-comments: 3.2.0_eslint@8.23.0 - eslint-plugin-import: 2.26.0_ijmu6epd3rsbb7y7umh7oqxvja - eslint-plugin-react: 7.31.8_eslint@8.23.0 - eslint-plugin-react-hooks: 4.6.0_eslint@8.23.0 + '@typescript-eslint/eslint-plugin': 5.38.0_wsb62dxj2oqwgas4kadjymcmry + '@typescript-eslint/parser': 5.38.0_irgkl5vooow2ydyo6aokmferha + eslint: 8.23.1 + eslint-config-prettier: 8.5.0_eslint@8.23.1 + eslint-import-resolver-typescript: 2.7.1_hdzsmr7kawaomymueo2tso6fjq + eslint-plugin-eslint-comments: 3.2.0_eslint@8.23.1 + eslint-plugin-import: 2.26.0_ar2mambzda7ptwcepuhox2isnu + eslint-plugin-react: 7.31.8_eslint@8.23.1 + eslint-plugin-react-hooks: 4.6.0_eslint@8.23.1 prettier: 2.7.1 prettier-plugin-tailwindcss: 0.1.13_prettier@2.7.1 typescript: 4.8.3 @@ -541,32 +572,16 @@ packages: - supports-color dev: false - /@meshtastic/meshtasticjs/0.6.98: - resolution: {integrity: sha512-ZEG0q2ZSfBqoS49ESjrnDou3NGZozd8/So586FtTB96J1RsQuWukZJu3vE1eWvzQ1yP3Oweg14s+Wycq1J2yTA==} - dependencies: - '@meshtastic/eslint-config': 1.0.8 - '@protobuf-ts/runtime': 2.8.1 - '@serialport/stream': 10.3.0 - prettier: 2.7.1 - serialport: 10.4.0 - sub-events: 1.8.9 - transitivePeerDependencies: - - eslint-import-resolver-webpack - - supports-color - dev: false - /@nodelib/fs.scandir/2.1.5: resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} engines: {node: '>= 8'} dependencies: '@nodelib/fs.stat': 2.0.5 run-parallel: 1.2.0 - dev: false /@nodelib/fs.stat/2.0.5: resolution: {integrity: sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==} engines: {node: '>= 8'} - dev: false /@nodelib/fs.walk/1.2.8: resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} @@ -574,116 +589,6 @@ packages: dependencies: '@nodelib/fs.scandir': 2.1.5 fastq: 1.13.0 - dev: false - - /@protobuf-ts/runtime/2.8.1: - resolution: {integrity: sha512-D9M5hSumYCovIfNllt7N6ODh4q+LrjiMWtNETvooaf+a2XheZJ7kgjFlsFghti0CFWwtA//of4JXQfw9hU+cCw==} - dev: false - - /@segment/react-tiny-virtual-list/2.2.1_react@18.2.0: - resolution: {integrity: sha512-G01b9DrsQLF+8yFRyyJeZBZkzbFuqILG9C7SFFS+GtTFbjdprkHt0CL0riCPOZfe1ZXiT8z8MaKoWfNhrfUjhQ==} - peerDependencies: - react: '>=16.3' - dependencies: - prop-types: 15.8.1 - react: 18.2.0 - dev: false - - /@serialport/binding-mock/10.2.2: - resolution: {integrity: sha512-HAFzGhk9OuFMpuor7aT5G1ChPgn5qSsklTFOTUX72Rl6p0xwcSVsRtG/xaGp6bxpN7fI9D/S8THLBWbBgS6ldw==} - engines: {node: '>=12.0.0'} - dependencies: - '@serialport/bindings-interface': 1.2.2 - debug: 4.3.4 - transitivePeerDependencies: - - supports-color - dev: false - - /@serialport/bindings-cpp/10.7.0: - resolution: {integrity: sha512-Xx1wA2UCG2loS32hxNvWJI4smCzGKhWqE85//fLRzHoGgE1lSLe3Nk7W40/ebrlGFHWRbQZmeaIF4chb2XLliA==} - engines: {node: '>=12.17.0 <13.0 || >=14.0.0'} - requiresBuild: true - dependencies: - '@serialport/bindings-interface': 1.2.1 - '@serialport/parser-readline': 10.3.0 - debug: 4.3.4 - node-addon-api: 4.3.0 - node-gyp-build: 4.5.0 - transitivePeerDependencies: - - supports-color - dev: false - - /@serialport/bindings-interface/1.2.1: - resolution: {integrity: sha512-63Dyqz2gtryRDDckFusOYqLYhR3Hq/M4sEdbF9i/VsvDb6T+tNVgoAKUZ+FMrXXKnCSu+hYbk+MTc0XQANszxw==} - engines: {node: ^12.22 || ^14.13 || >=16} - dev: false - - /@serialport/bindings-interface/1.2.2: - resolution: {integrity: sha512-CJaUd5bLvtM9c5dmO9rPBHPXTa9R2UwpkJ0wdh9JCYcbrPWsKz+ErvR0hBLeo7NPeiFdjFO4sonRljiw4d2XiA==} - engines: {node: ^12.22 || ^14.13 || >=16} - dev: false - - /@serialport/parser-byte-length/10.3.0: - resolution: {integrity: sha512-pJ/VoFemzKRRNDHLhFfPThwP40QrGaEnm9TtwL7o2GihEPwzBg3T0bN13ew5TpbbUYZdMpUtpm3CGfl6av9rUQ==} - engines: {node: '>=12.0.0'} - dev: false - - /@serialport/parser-cctalk/10.3.0: - resolution: {integrity: sha512-8ujmk8EvVbDPrNF4mM33bWvUYJOZ0wXbY3WCRazHRWvyCdL0VO0DQvW81ZqgoTpiDQZm5r8wQu9rmuemahF6vQ==} - engines: {node: '>=12.0.0'} - dev: false - - /@serialport/parser-delimiter/10.3.0: - resolution: {integrity: sha512-9E4Vj6s0UbbcCCTclwegHGPYjJhdm9qLCS0lowXQDEQC5naZnbsELemMHs93nD9jHPcyx1B4oXkMnVZLxX5TYw==} - engines: {node: '>=12.0.0'} - dev: false - - /@serialport/parser-inter-byte-timeout/10.3.0: - resolution: {integrity: sha512-wKP0QK85NHgvT6BBB1qBfKBBU4pf8kespNXAZBUYmFT+P4n8r8IZE2mqigCD+AiZcfWNQoAizwOsT/Jx/qeVig==} - engines: {node: '>=12.0.0'} - dev: false - - /@serialport/parser-packet-length/10.3.0: - resolution: {integrity: sha512-bj0cWzt8YSQj/E5fRQVYdi4TsfTlZQrXlXrUwjyTsCONv8IPOHzsz+yY0fw5SEMiJtaLyqvPkCHLsttOd/zFsg==} - engines: {node: '>=8.6.0'} - dev: false - - /@serialport/parser-readline/10.3.0: - resolution: {integrity: sha512-ki3ATZ3/RAqnqGROBKE7k+OeZ0DZXZ53GTca4q71OU5RazbbNhTOBQLKLXD3v9QZXCMJdg4hGW/2Y0DuMUqMQg==} - engines: {node: '>=12.0.0'} - dependencies: - '@serialport/parser-delimiter': 10.3.0 - dev: false - - /@serialport/parser-ready/10.3.0: - resolution: {integrity: sha512-1owywJ4p592dJyVrEJZPIh6pUZ3/y/LN6kGTDH2wxdewRUITo/sGvDy0er5i2+dJD3yuowiAz0dOHSdz8tevJA==} - engines: {node: '>=12.0.0'} - dev: false - - /@serialport/parser-regex/10.3.0: - resolution: {integrity: sha512-tIogTs7CvTH+UUFnsvE7i33MSISyTPTGPWlglWYH2/5coipXY503jlaYS1YGe818wWNcSx6YAjMZRdhTWwM39w==} - engines: {node: '>=12.0.0'} - dev: false - - /@serialport/parser-slip-encoder/10.3.0: - resolution: {integrity: sha512-JI0ILF5sylWn8f0MuMzHFBix/iMUTa79/Z95KaPZYnVaEdA7h7hh/o21Jmon/26P3RJwL1SNJCjZ81zfan+LtQ==} - engines: {node: '>=12.0.0'} - dev: false - - /@serialport/parser-spacepacket/10.3.0: - resolution: {integrity: sha512-PDF73ClEPsClD1FEJZHNuBevDKsJCkqy/XD5+S5eA6+tY5D4HLrVgSWsg+3qqB6+dlpwf2CzHe+uO8D3teuKHA==} - engines: {node: '>=12.0.0'} - dev: false - - /@serialport/stream/10.3.0: - resolution: {integrity: sha512-7sooi5fHogYNVEJwxVdg872xO6TuMgQd2E9iRmv+o8pk/1dbBnPkmH6Ka3st1mVE+0KnIJqVlgei+ncSsqXIGw==} - engines: {node: '>=12.0.0'} - dependencies: - '@serialport/bindings-interface': 1.2.1 - debug: 4.3.4 - transitivePeerDependencies: - - supports-color - dev: false /@stablelib/binary/1.0.1: resolution: {integrity: sha512-ClJWvmL6UBM/wjkvv/7m5VP3GMr9t0osr4yVgLZsLCOz4hGN9gIAFEqnJ0TsSMAN+n840nf2cHZnA5/KFqHC7Q==} @@ -711,8 +616,28 @@ packages: resolution: {integrity: sha512-WfqfX/eXGiAd3RJe4VU2snh/ZPwtSjLG4ynQ/vYzvghTh7dHFcI1wl+nrkWG6lGhukOxOsUHfv8dUXr58D0ayg==} dev: false - /@types/chrome/0.0.196: - resolution: {integrity: sha512-LAjGIQYC0wyiYu6lVT03dBrHBfYTMsM8EmNfQ+UdZipGZe8OUiir6weoa9oQoBw3T3RLzBCp9m904T+rFtpPAg==} + /@tailwindcss/line-clamp/0.4.2_tailwindcss@3.1.8: + resolution: {integrity: sha512-HFzAQuqYCjyy/SX9sLGB1lroPzmcnWv1FHkIpmypte10hptf4oPUfucryMKovZh2u0uiS9U5Ty3GghWfEJGwVw==} + peerDependencies: + tailwindcss: '>=2.0.0 || >=3.0.0 || >=3.0.0-alpha.1' + dependencies: + tailwindcss: 3.1.8_postcss@8.4.16 + dev: false + + /@tailwindcss/typography/0.5.7_tailwindcss@3.1.8: + resolution: {integrity: sha512-JTTSTrgZfp6Ki4svhPA4mkd9nmQ/j9EfE7SbHJ1cLtthKkpW2OxsFXzSmxbhYbEkfNIyAyhle5p4SYyKRbz/jg==} + peerDependencies: + tailwindcss: '>=3.0.0 || insiders' + dependencies: + lodash.castarray: 4.4.0 + lodash.isplainobject: 4.0.6 + lodash.merge: 4.6.2 + postcss-selector-parser: 6.0.10 + tailwindcss: 3.1.8_postcss@8.4.16 + dev: false + + /@types/chrome/0.0.197: + resolution: {integrity: sha512-m1NfS5bOjaypyqQfaX6CxmJodZVcvj5+Mt/K94EBHkflYjPNmXHAzbxfifdLMa0YM3PDyOxohoTS5ug/e6p5jA==} dependencies: '@types/filesystem': 0.0.32 '@types/har-format': 1.2.8 @@ -766,8 +691,8 @@ packages: '@types/pbf': 3.0.2 dev: false - /@types/node/18.7.16: - resolution: {integrity: sha512-EQHhixfu+mkqHMZl1R2Ovuvn47PUw18azMJOTwSZr9/fhzHNGXAJ0ma0dayRVchprpCj0Kc1K1xKoWaATWF1qg==} + /@types/node/18.7.18: + resolution: {integrity: sha512-m+6nTEOadJZuTPkKR/SYK3A2d7FZrgElol9UP1Kae90VVU4a6mxnPuLiIW1m4Cq4gZ/nWb9GrdVXJCoCazDAbg==} dev: true /@types/pbf/3.0.2: @@ -776,36 +701,25 @@ packages: /@types/prop-types/15.7.5: resolution: {integrity: sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w==} + dev: true /@types/react-dom/18.0.6: resolution: {integrity: sha512-/5OFZgfIPSwy+YuIBP/FgJnQnsxhZhjjrnxudMddeblOouIodEQ75X14Rr4wGSG/bknL+Omy9iWlLo1u/9GzAA==} dependencies: - '@types/react': 18.0.18 + '@types/react': 18.0.20 dev: true - /@types/react-transition-group/4.4.5: - resolution: {integrity: sha512-juKD/eiSM3/xZYzjuzH6ZwpP+/lejltmiS3QEzV/vmb/Q8+HfDmxu+Baga8UEMGBqV88Nbg4l2hY/K2DkyaLLA==} - dependencies: - '@types/react': 18.0.18 - dev: false - - /@types/react/16.14.31: - resolution: {integrity: sha512-CD3LuBW4xIeGy6BxuNZdXBOsuP00OHFuNOq/4e2xKDq6z02XvdH9wIkuPNmz7BRQpo5ncy1zT9fz4tTDqXbjzQ==} + /@types/react/18.0.20: + resolution: {integrity: sha512-MWul1teSPxujEHVwZl4a5HxQ9vVNsjTchVA+xRqv/VYGCuKGAU6UhfrTdF5aBefwD1BHUD8i/zq+O/vyCm/FrA==} dependencies: '@types/prop-types': 15.7.5 '@types/scheduler': 0.16.2 - csstype: 3.1.0 - dev: false - - /@types/react/18.0.18: - resolution: {integrity: sha512-6hI08umYs6NaiHFEEGioXnxJ+oEhY3eRz8VCUaudZmGdtvPviCJB8mgaMxaDWAdPSYd4eFavrPk2QIolwbLYrg==} - dependencies: - '@types/prop-types': 15.7.5 - '@types/scheduler': 0.16.2 - csstype: 3.1.0 + csstype: 3.1.1 + dev: true /@types/scheduler/0.16.2: resolution: {integrity: sha512-hppQEBDmlwhFAXKJX2KnWLYu5yMfi91yazPb2l+lbJiwW+wdo1gNeRA+3RgNSO39WYX2euey41KEwnqesU2Jew==} + dev: true /@types/w3c-web-serial/1.0.2: resolution: {integrity: sha512-Ftx4BtLxgAnel7V7GbHylCYjSq827A+jeEE3SnTS7huCGUN0pSwUn+CchTCT9TkZj9w+NVMUq4Bk2R0GvUNmAQ==} @@ -815,8 +729,8 @@ packages: resolution: {integrity: sha512-w7hEHXnPMEZ+4nGKl/KDRVpxkwYxYExuHOYXyzIzCDzEZ9ZCGMAewulr9IqJu2LR4N37fcnb1XVeuZ09qgOxhA==} dev: true - /@typescript-eslint/eslint-plugin/5.36.2_2l2r3i3lm6jysqd4ac3ql4n2mm: - resolution: {integrity: sha512-OwwR8LRwSnI98tdc2z7mJYgY60gf7I9ZfGjN5EjCwwns9bdTuQfAXcsjSB2wSQ/TVNYSGKf4kzVXbNGaZvwiXw==} + /@typescript-eslint/eslint-plugin/5.38.0_wsb62dxj2oqwgas4kadjymcmry: + resolution: {integrity: sha512-GgHi/GNuUbTOeoJiEANi0oI6fF3gBQc3bGFYj40nnAPCbhrtEDf2rjBmefFadweBmO1Du1YovHeDP2h5JLhtTQ==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} peerDependencies: '@typescript-eslint/parser': ^5.0.0 @@ -826,13 +740,12 @@ packages: typescript: optional: true dependencies: - '@typescript-eslint/parser': 5.36.2_itqs5654cmlnjraw6gjzqacppi - '@typescript-eslint/scope-manager': 5.36.2 - '@typescript-eslint/type-utils': 5.36.2_itqs5654cmlnjraw6gjzqacppi - '@typescript-eslint/utils': 5.36.2_itqs5654cmlnjraw6gjzqacppi + '@typescript-eslint/parser': 5.38.0_irgkl5vooow2ydyo6aokmferha + '@typescript-eslint/scope-manager': 5.38.0 + '@typescript-eslint/type-utils': 5.38.0_irgkl5vooow2ydyo6aokmferha + '@typescript-eslint/utils': 5.38.0_irgkl5vooow2ydyo6aokmferha debug: 4.3.4 - eslint: 8.23.0 - functional-red-black-tree: 1.0.1 + eslint: 8.23.1 ignore: 5.2.0 regexpp: 3.2.0 semver: 7.3.7 @@ -842,8 +755,8 @@ packages: - supports-color dev: false - /@typescript-eslint/parser/5.36.2_itqs5654cmlnjraw6gjzqacppi: - resolution: {integrity: sha512-qS/Kb0yzy8sR0idFspI9Z6+t7mqk/oRjnAYfewG+VN73opAUvmYL3oPIMmgOX6CnQS6gmVIXGshlb5RY/R22pA==} + /@typescript-eslint/parser/5.38.0_irgkl5vooow2ydyo6aokmferha: + resolution: {integrity: sha512-/F63giJGLDr0ms1Cr8utDAxP2SPiglaD6V+pCOcG35P2jCqdfR7uuEhz1GIC3oy4hkUF8xA1XSXmd9hOh/a5EA==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} peerDependencies: eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 @@ -852,26 +765,26 @@ packages: typescript: optional: true dependencies: - '@typescript-eslint/scope-manager': 5.36.2 - '@typescript-eslint/types': 5.36.2 - '@typescript-eslint/typescript-estree': 5.36.2_typescript@4.8.3 + '@typescript-eslint/scope-manager': 5.38.0 + '@typescript-eslint/types': 5.38.0 + '@typescript-eslint/typescript-estree': 5.38.0_typescript@4.8.3 debug: 4.3.4 - eslint: 8.23.0 + eslint: 8.23.1 typescript: 4.8.3 transitivePeerDependencies: - supports-color dev: false - /@typescript-eslint/scope-manager/5.36.2: - resolution: {integrity: sha512-cNNP51L8SkIFSfce8B1NSUBTJTu2Ts4nWeWbFrdaqjmn9yKrAaJUBHkyTZc0cL06OFHpb+JZq5AUHROS398Orw==} + /@typescript-eslint/scope-manager/5.38.0: + resolution: {integrity: sha512-ByhHIuNyKD9giwkkLqzezZ9y5bALW8VNY6xXcP+VxoH4JBDKjU5WNnsiD4HJdglHECdV+lyaxhvQjTUbRboiTA==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} dependencies: - '@typescript-eslint/types': 5.36.2 - '@typescript-eslint/visitor-keys': 5.36.2 + '@typescript-eslint/types': 5.38.0 + '@typescript-eslint/visitor-keys': 5.38.0 dev: false - /@typescript-eslint/type-utils/5.36.2_itqs5654cmlnjraw6gjzqacppi: - resolution: {integrity: sha512-rPQtS5rfijUWLouhy6UmyNquKDPhQjKsaKH0WnY6hl/07lasj8gPaH2UD8xWkePn6SC+jW2i9c2DZVDnL+Dokw==} + /@typescript-eslint/type-utils/5.38.0_irgkl5vooow2ydyo6aokmferha: + resolution: {integrity: sha512-iZq5USgybUcj/lfnbuelJ0j3K9dbs1I3RICAJY9NZZpDgBYXmuUlYQGzftpQA9wC8cKgtS6DASTvF3HrXwwozA==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} peerDependencies: eslint: '*' @@ -880,23 +793,23 @@ packages: typescript: optional: true dependencies: - '@typescript-eslint/typescript-estree': 5.36.2_typescript@4.8.3 - '@typescript-eslint/utils': 5.36.2_itqs5654cmlnjraw6gjzqacppi + '@typescript-eslint/typescript-estree': 5.38.0_typescript@4.8.3 + '@typescript-eslint/utils': 5.38.0_irgkl5vooow2ydyo6aokmferha debug: 4.3.4 - eslint: 8.23.0 + eslint: 8.23.1 tsutils: 3.21.0_typescript@4.8.3 typescript: 4.8.3 transitivePeerDependencies: - supports-color dev: false - /@typescript-eslint/types/5.36.2: - resolution: {integrity: sha512-9OJSvvwuF1L5eS2EQgFUbECb99F0mwq501w0H0EkYULkhFa19Qq7WFbycdw1PexAc929asupbZcgjVIe6OK/XQ==} + /@typescript-eslint/types/5.38.0: + resolution: {integrity: sha512-HHu4yMjJ7i3Cb+8NUuRCdOGu2VMkfmKyIJsOr9PfkBVYLYrtMCK/Ap50Rpov+iKpxDTfnqvDbuPLgBE5FwUNfA==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} dev: false - /@typescript-eslint/typescript-estree/5.36.2_typescript@4.8.3: - resolution: {integrity: sha512-8fyH+RfbKc0mTspfuEjlfqA4YywcwQK2Amcf6TDOwaRLg7Vwdu4bZzyvBZp4bjt1RRjQ5MDnOZahxMrt2l5v9w==} + /@typescript-eslint/typescript-estree/5.38.0_typescript@4.8.3: + resolution: {integrity: sha512-6P0RuphkR+UuV7Avv7MU3hFoWaGcrgOdi8eTe1NwhMp2/GjUJoODBTRWzlHpZh6lFOaPmSvgxGlROa0Sg5Zbyg==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} peerDependencies: typescript: '*' @@ -904,8 +817,8 @@ packages: typescript: optional: true dependencies: - '@typescript-eslint/types': 5.36.2 - '@typescript-eslint/visitor-keys': 5.36.2 + '@typescript-eslint/types': 5.38.0 + '@typescript-eslint/visitor-keys': 5.38.0 debug: 4.3.4 globby: 11.1.0 is-glob: 4.0.3 @@ -916,46 +829,46 @@ packages: - supports-color dev: false - /@typescript-eslint/utils/5.36.2_itqs5654cmlnjraw6gjzqacppi: - resolution: {integrity: sha512-uNcopWonEITX96v9pefk9DC1bWMdkweeSsewJ6GeC7L6j2t0SJywisgkr9wUTtXk90fi2Eljj90HSHm3OGdGRg==} + /@typescript-eslint/utils/5.38.0_irgkl5vooow2ydyo6aokmferha: + resolution: {integrity: sha512-6sdeYaBgk9Fh7N2unEXGz+D+som2QCQGPAf1SxrkEr+Z32gMreQ0rparXTNGRRfYUWk/JzbGdcM8NSSd6oqnTA==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} peerDependencies: eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 dependencies: '@types/json-schema': 7.0.11 - '@typescript-eslint/scope-manager': 5.36.2 - '@typescript-eslint/types': 5.36.2 - '@typescript-eslint/typescript-estree': 5.36.2_typescript@4.8.3 - eslint: 8.23.0 + '@typescript-eslint/scope-manager': 5.38.0 + '@typescript-eslint/types': 5.38.0 + '@typescript-eslint/typescript-estree': 5.38.0_typescript@4.8.3 + eslint: 8.23.1 eslint-scope: 5.1.1 - eslint-utils: 3.0.0_eslint@8.23.0 + eslint-utils: 3.0.0_eslint@8.23.1 transitivePeerDependencies: - supports-color - typescript dev: false - /@typescript-eslint/visitor-keys/5.36.2: - resolution: {integrity: sha512-BtRvSR6dEdrNt7Net2/XDjbYKU5Ml6GqJgVfXT0CxTCJlnIqK7rAGreuWKMT2t8cFUT2Msv5oxw0GMRD7T5J7A==} + /@typescript-eslint/visitor-keys/5.38.0: + resolution: {integrity: sha512-MxnrdIyArnTi+XyFLR+kt/uNAcdOnmT+879os7qDRI+EYySR4crXJq9BXPfRzzLGq0wgxkwidrCJ9WCAoacm1w==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} dependencies: - '@typescript-eslint/types': 5.36.2 + '@typescript-eslint/types': 5.38.0 eslint-visitor-keys: 3.3.0 dev: false - /@vitejs/plugin-react/2.1.0_vite@3.1.0: + /@vitejs/plugin-react/2.1.0_vite@3.1.3: resolution: {integrity: sha512-am6rPyyU3LzUYne3Gd9oj9c4Rzbq5hQnuGXSMT6Gujq45Il/+bunwq3lrB7wghLkiF45ygMwft37vgJ/NE8IAA==} engines: {node: ^14.18.0 || >=16.0.0} peerDependencies: vite: ^3.0.0 dependencies: - '@babel/core': 7.19.0 - '@babel/plugin-transform-react-jsx': 7.19.0_@babel+core@7.19.0 - '@babel/plugin-transform-react-jsx-development': 7.18.6_@babel+core@7.19.0 - '@babel/plugin-transform-react-jsx-self': 7.18.6_@babel+core@7.19.0 - '@babel/plugin-transform-react-jsx-source': 7.18.6_@babel+core@7.19.0 + '@babel/core': 7.19.1 + '@babel/plugin-transform-react-jsx': 7.19.0_@babel+core@7.19.1 + '@babel/plugin-transform-react-jsx-development': 7.18.6_@babel+core@7.19.1 + '@babel/plugin-transform-react-jsx-self': 7.18.6_@babel+core@7.19.1 + '@babel/plugin-transform-react-jsx-source': 7.18.6_@babel+core@7.19.1 magic-string: 0.26.3 react-refresh: 0.14.0 - vite: 3.1.0 + vite: 3.1.3 transitivePeerDependencies: - supports-color dev: true @@ -968,6 +881,22 @@ packages: acorn: 8.8.0 dev: false + /acorn-node/1.8.2: + resolution: {integrity: sha512-8mt+fslDufLYntIoPAaIMUe/lrbrehIiwmR3t2k9LljIzoigEPF27eLk2hy8zSGzmR/ogr7zbRKINMo1u0yh5A==} + dependencies: + acorn: 7.4.1 + acorn-walk: 7.2.0 + xtend: 4.0.2 + + /acorn-walk/7.2.0: + resolution: {integrity: sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA==} + engines: {node: '>=0.4.0'} + + /acorn/7.4.1: + resolution: {integrity: sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==} + engines: {node: '>=0.4.0'} + hasBin: true + /acorn/8.8.0: resolution: {integrity: sha512-QOxyigPVrpZ2GXT+PFyZTl6TtOFc5egxHIP9IlQ+RbupQuX4RkT/Bee4/kQuC02Xkzg84JcT7oLYtDIQxp+v7w==} engines: {node: '>=0.4.0'} @@ -1000,6 +929,16 @@ packages: dependencies: color-convert: 2.0.1 + /anymatch/3.1.2: + resolution: {integrity: sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==} + engines: {node: '>= 8'} + dependencies: + normalize-path: 3.0.0 + picomatch: 2.3.1 + + /arg/5.0.2: + resolution: {integrity: sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==} + /argparse/2.0.1: resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} dev: false @@ -1011,7 +950,7 @@ packages: call-bind: 1.0.2 define-properties: 1.1.4 es-abstract: 1.20.2 - get-intrinsic: 1.1.2 + get-intrinsic: 1.1.3 is-string: 1.0.7 dev: false @@ -1040,14 +979,21 @@ packages: es-shim-unscopables: 1.0.0 dev: false - /arrify/1.0.1: - resolution: {integrity: sha512-3CYzex9M9FGQjCGMGyi6/31c8GJbgb0qGyrx5HWxPd0aCwh4cB2YjMb2Xf9UuoogrMrlO9cTqnB5rI5GHZTcUA==} - engines: {node: '>=0.10.0'} - dev: false - - /asap/2.0.6: - resolution: {integrity: sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==} - dev: false + /autoprefixer/10.4.11_postcss@8.4.16: + resolution: {integrity: sha512-5lHp6DgRodxlBLSkzHOTcufWFflH1ewfy2hvFQyjrblBFlP/0Yh4O/Wrg4ow8WRlN3AAUFFLAQwX8hTptzqVHg==} + engines: {node: ^10 || ^12 || >=14} + hasBin: true + peerDependencies: + postcss: ^8.1.0 + dependencies: + browserslist: 4.21.4 + caniuse-lite: 1.0.30001407 + fraction.js: 4.2.0 + normalize-range: 0.1.2 + picocolors: 1.0.0 + postcss: 8.4.16 + postcss-value-parser: 4.2.0 + dev: true /available-typed-arrays/1.0.5: resolution: {integrity: sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw==} @@ -1061,9 +1007,9 @@ packages: /base64-js/1.5.1: resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} - /bowser/1.9.4: - resolution: {integrity: sha512-9IdMmj2KjigRq6oWhmwv1W36pDuA4STQZ8q6YO9um+x07xgYNCD3Oou+WP/3L1HNz7iqythGet3/p4wvc8AAwQ==} - dev: false + /binary-extensions/2.2.0: + resolution: {integrity: sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==} + engines: {node: '>=8'} /brace-expansion/1.1.11: resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==} @@ -1077,17 +1023,16 @@ packages: engines: {node: '>=8'} dependencies: fill-range: 7.0.1 - dev: false - /browserslist/4.21.3: - resolution: {integrity: sha512-898rgRXLAyRkM1GryrrBHGkqA5hlpkV5MhtZwg9QXeiyLUYs2k00Un05aX5l2/yJIOObYKOpS2JNo8nJDE7fWQ==} + /browserslist/4.21.4: + resolution: {integrity: sha512-CBHJJdDmgjl3daYjN5Cp5kbTf1mUhZoS+beLklHIvkOWscs83YAhLlF3Wsh/lciQYAcbBJgTOD44VtG31ZM4Hw==} engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} hasBin: true dependencies: - caniuse-lite: 1.0.30001393 - electron-to-chromium: 1.4.246 + caniuse-lite: 1.0.30001407 + electron-to-chromium: 1.4.255 node-releases: 2.0.6 - update-browserslist-db: 1.0.7_browserslist@4.21.3 + update-browserslist-db: 1.0.9_browserslist@4.21.4 dev: true /buffer-from/1.1.2: @@ -1098,15 +1043,19 @@ packages: resolution: {integrity: sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==} dependencies: function-bind: 1.1.1 - get-intrinsic: 1.1.2 + get-intrinsic: 1.1.3 /callsites/3.1.0: resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} engines: {node: '>=6'} dev: false - /caniuse-lite/1.0.30001393: - resolution: {integrity: sha512-N/od11RX+Gsk+1qY/jbPa0R6zJupEa0lxeBG598EbrtblxVCTJsQwbRBm6+V+rxpc5lHKdsXb9RY83cZIPLseA==} + /camelcase-css/2.0.1: + resolution: {integrity: sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==} + engines: {node: '>= 6'} + + /caniuse-lite/1.0.30001407: + resolution: {integrity: sha512-4ydV+t4P7X3zH83fQWNDX/mQEzYomossfpViCOx9zHBSMV+rIe3LFqglHHtVyvNl1FhTNxPxs3jei82iqOW04w==} dev: true /chalk/2.4.2: @@ -1126,6 +1075,20 @@ packages: supports-color: 7.2.0 dev: false + /chokidar/3.5.3: + resolution: {integrity: sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==} + engines: {node: '>= 8.10.0'} + dependencies: + anymatch: 3.1.2 + braces: 3.0.2 + glob-parent: 5.1.2 + is-binary-path: 2.1.0 + is-glob: 4.0.3 + normalize-path: 3.0.0 + readdirp: 3.6.0 + optionalDependencies: + fsevents: 2.3.2 + /chownr/2.0.0: resolution: {integrity: sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==} engines: {node: '>=10'} @@ -1142,10 +1105,6 @@ packages: validator: 13.7.0 dev: false - /classnames/2.3.1: - resolution: {integrity: sha512-OlQdbZ7gLfGarSqxesMesDa5uz7KFbID8Kpq/SxIoNGDqY8lSYs0D+hhtBXhcdB3rcbXArFr7vlHheLk1voeNA==} - dev: false - /cliui/7.0.4: resolution: {integrity: sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==} dependencies: @@ -1178,10 +1137,6 @@ packages: engines: {node: '>= 10'} dev: true - /compute-scroll-into-view/1.0.17: - resolution: {integrity: sha512-j4dx+Fb0URmzbwwMUrhqWM2BEWHdFGx+qZ9qqASHRPqvTYdqvWnHg0H1hIbcyLnvgnoNAVMlwkepyqM3DaIFUg==} - dev: false - /concat-map/0.0.1: resolution: {integrity: sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=} dev: false @@ -1192,11 +1147,6 @@ packages: safe-buffer: 5.1.2 dev: true - /core-js/1.2.7: - resolution: {integrity: sha512-ZiPp9pZlgxpWRu0M+YWbm6+aQ84XEfH1JRXvfOc/fILWI0VKhLC2LX13X1NYq4fULzLMq7Hfh43CSo2/aIaUPA==} - deprecated: core-js@<3.23.3 is no longer maintained and not recommended for usage due to the number of issues. Because of the V8 engine whims, feature detection in old core-js versions could cause a slowdown up to 100x even if nothing is polyfilled. Some versions have web compatibility issues. Please, upgrade your dependencies to the actual version of core-js. - dev: false - /core-util-is/1.0.3: resolution: {integrity: sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==} dev: true @@ -1210,19 +1160,18 @@ packages: which: 2.0.2 dev: false - /css-in-js-utils/2.0.1: - resolution: {integrity: sha512-PJF0SpJT+WdbVVt0AOYp9C8GnuruRlL/UFW7932nLWmFLQTaWEzTBQEx7/hn4BuV+WON75iAViSUJLiU3PKbpA==} - dependencies: - hyphenate-style-name: 1.0.4 - isobject: 3.0.1 - dev: false - /csscolorparser/1.0.3: resolution: {integrity: sha512-umPSgYwZkdFoUrH5hIq5kf0wPSXiro51nPw0j2K/c83KflkPSTBGMz6NJvMB+07VlL0y7VPo6QJcDjcgKTTm3w==} dev: false - /csstype/3.1.0: - resolution: {integrity: sha512-uX1KG+x9h5hIJsaKR9xHUeUraxf8IODOwq9JLNPq6BwB04a/xgpq3rcx47l5BZu5zBPlgD342tdke3Hom/nJRA==} + /cssesc/3.0.0: + resolution: {integrity: sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==} + engines: {node: '>=4'} + hasBin: true + + /csstype/3.1.1: + resolution: {integrity: sha512-DJR/VvkAvSZW9bTouZue2sSxDwdTN92uHjqeKVm+0dAqdfNykRzQ95tay8aXMBAAPpUiq4Qcug2L7neoRh2Egw==} + dev: true /debug/2.6.9: resolution: {integrity: sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==} @@ -1262,7 +1211,7 @@ packages: dependencies: call-bind: 1.0.2 es-get-iterator: 1.1.2 - get-intrinsic: 1.1.2 + get-intrinsic: 1.1.3 is-arguments: 1.1.1 is-date-object: 1.0.5 is-regex: 1.1.4 @@ -1293,6 +1242,21 @@ packages: has-property-descriptors: 1.0.0 object-keys: 1.1.1 + /defined/1.0.0: + resolution: {integrity: sha512-Y2caI5+ZwS5c3RiNDJ6u53VhQHv+hHKwhkI1iHvceKUHw9Df6EK2zRLfjejRgMuCuxK7PfSWIMwWecceVvThjQ==} + + /detective/5.2.1: + resolution: {integrity: sha512-v9XE1zRnz1wRtgurGu0Bs8uHKFSTdteYZNbIPFVhUZ39L/S79ppMpdmVOZAnoz1jfEFodc48n6MX483Xo3t1yw==} + engines: {node: '>=0.8.0'} + hasBin: true + dependencies: + acorn-node: 1.8.2 + defined: 1.0.0 + minimist: 1.2.6 + + /didyoumean/1.2.2: + resolution: {integrity: sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==} + /dir-glob/3.0.1: resolution: {integrity: sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==} engines: {node: '>=8'} @@ -1300,6 +1264,9 @@ packages: path-type: 4.0.0 dev: false + /dlv/1.1.3: + resolution: {integrity: sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==} + /doctrine/2.1.0: resolution: {integrity: sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==} engines: {node: '>=0.10.0'} @@ -1314,25 +1281,6 @@ packages: esutils: 2.0.3 dev: false - /dom-helpers/5.2.1: - resolution: {integrity: sha512-nRCa7CK3VTrM2NmGkIy4cbK7IZlgBE/PYMn55rrXefr5xXDP0LdtfPnblFDoVdcAfslJ7or6iqAUnx0CCGIWQA==} - dependencies: - '@babel/runtime': 7.19.0 - csstype: 3.1.0 - dev: false - - /downshift/5.4.7_react@18.2.0: - resolution: {integrity: sha512-xaH0RNqwJ5pAsyk9qBmR9XJWmg1OOWMfrhzYv0NH2NjJxn77S3zBcfClw341UfhGyKg5v+qVqg/CQzvAgBNCXQ==} - peerDependencies: - react: '>=16.8.0' - dependencies: - '@babel/runtime': 7.19.0 - compute-scroll-into-view: 1.0.17 - prop-types: 15.8.1 - react: 18.2.0 - react-is: 16.13.1 - dev: false - /duplex-maker/1.0.0: resolution: {integrity: sha512-KoHuzggxg7f+vvjqOHfXxaQYI1POzBm+ah0eec7YDssZmbt6QFBI8d1nl5GQwAgR2f+VQCPvyvZtmWWqWuFtlA==} dev: true @@ -1350,8 +1298,8 @@ packages: resolution: {integrity: sha512-/pjZsA1b4RPHbeWZQn66SWS8nZZWLQQ23oE3Eam7aroEFGEvwKAsJfZ9ytiEMycfzXWpca4FA9QIOehf7PocBQ==} dev: false - /electron-to-chromium/1.4.246: - resolution: {integrity: sha512-/wFCHUE+Hocqr/LlVGsuKLIw4P2lBWwFIDcNMDpJGzyIysQV4aycpoOitAs32FT94EHKnNqDR/CVZJFbXEufJA==} + /electron-to-chromium/1.4.255: + resolution: {integrity: sha512-H+mFNKow6gi2P5Gi2d1Fvd3TUEJlB9CF7zYaIV9T83BE3wP1xZ0mRPbNTm0KUjyd1QiVy7iKXuIcjlDtBQMiAQ==} dev: true /emoji-regex/8.0.0: @@ -1362,12 +1310,6 @@ packages: resolution: {integrity: sha512-q4Mq/+XO7UNDdMiPpR/LIBIW1Zl4V0Z6UT9aKGqIAnBCtCb3lvZJM1KbDbdzdC8fKflwflModfjR29Nt0EpcwA==} dev: false - /encoding/0.1.13: - resolution: {integrity: sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A==} - dependencies: - iconv-lite: 0.6.3 - dev: false - /end-of-stream/1.4.4: resolution: {integrity: sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==} dependencies: @@ -1382,13 +1324,13 @@ packages: es-to-primitive: 1.2.1 function-bind: 1.1.1 function.prototype.name: 1.1.5 - get-intrinsic: 1.1.2 + get-intrinsic: 1.1.3 get-symbol-description: 1.0.0 has: 1.0.3 has-property-descriptors: 1.0.0 has-symbols: 1.0.3 internal-slot: 1.0.3 - is-callable: 1.2.4 + is-callable: 1.2.6 is-negative-zero: 2.0.2 is-regex: 1.1.4 is-shared-array-buffer: 1.0.2 @@ -1406,7 +1348,7 @@ packages: resolution: {integrity: sha512-+DTO8GYwbMCwbywjimwZMHp8AuYXOS2JZFWoi2AlPOS3ebnII9w/NLpNZtA7A0YLaVDw+O7KFCeoIV7OPvM7hQ==} dependencies: call-bind: 1.0.2 - get-intrinsic: 1.1.2 + get-intrinsic: 1.1.3 has-symbols: 1.0.3 is-arguments: 1.1.1 is-map: 2.0.2 @@ -1425,21 +1367,23 @@ packages: resolution: {integrity: sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==} engines: {node: '>= 0.4'} dependencies: - is-callable: 1.2.4 + is-callable: 1.2.6 is-date-object: 1.0.5 is-symbol: 1.0.4 - /esbuild-android-64/0.15.7: - resolution: {integrity: sha512-p7rCvdsldhxQr3YHxptf1Jcd86dlhvc3EQmQJaZzzuAxefO9PvcI0GLOa5nCWem1AJ8iMRu9w0r5TG8pHmbi9w==} + /esbuild-android-64/0.15.8: + resolution: {integrity: sha512-bVh8FIKOolF7/d4AMzt7xHlL0Ljr+mYKSHI39TJWDkybVWHdn6+4ODL3xZGHOxPpdRpitemXA1WwMKYBsw8dGw==} engines: {node: '>=12'} cpu: [x64] os: [android] requiresBuild: true + dependencies: + esbuild-wasm: 0.15.8 dev: true optional: true - /esbuild-android-arm64/0.15.7: - resolution: {integrity: sha512-L775l9ynJT7rVqRM5vo+9w5g2ysbOCfsdLV4CWanTZ1k/9Jb3IYlQ06VCI1edhcosTYJRECQFJa3eAvkx72eyQ==} + /esbuild-android-arm64/0.15.8: + resolution: {integrity: sha512-ReAMDAHuo0H1h9LxRabI6gwYPn8k6WiUeyxuMvx17yTrJO+SCnIfNc/TSPFvDwtK9MiyiKG/2dBYHouT/M0BXQ==} engines: {node: '>=12'} cpu: [arm64] os: [android] @@ -1447,8 +1391,8 @@ packages: dev: true optional: true - /esbuild-darwin-64/0.15.7: - resolution: {integrity: sha512-KGPt3r1c9ww009t2xLB6Vk0YyNOXh7hbjZ3EecHoVDxgtbUlYstMPDaReimKe6eOEfyY4hBEEeTvKwPsiH5WZg==} + /esbuild-darwin-64/0.15.8: + resolution: {integrity: sha512-KaKcGfJ+yto7Fo5gAj3xwxHMd1fBIKatpCHK8znTJLVv+9+NN2/tIPBqA4w5rBwjX0UqXDeIE2v1xJP+nGEXgA==} engines: {node: '>=12'} cpu: [x64] os: [darwin] @@ -1456,8 +1400,8 @@ packages: dev: true optional: true - /esbuild-darwin-arm64/0.15.7: - resolution: {integrity: sha512-kBIHvtVqbSGajN88lYMnR3aIleH3ABZLLFLxwL2stiuIGAjGlQW741NxVTpUHQXUmPzxi6POqc9npkXa8AcSZQ==} + /esbuild-darwin-arm64/0.15.8: + resolution: {integrity: sha512-8tjEaBgAKnXCkP7bhEJmEqdG9HEV6oLkF36BrMzpfW2rgaw0c48Zrxe+9RlfeGvs6gDF4w+agXyTjikzsS3izw==} engines: {node: '>=12'} cpu: [arm64] os: [darwin] @@ -1465,8 +1409,8 @@ packages: dev: true optional: true - /esbuild-freebsd-64/0.15.7: - resolution: {integrity: sha512-hESZB91qDLV5MEwNxzMxPfbjAhOmtfsr9Wnuci7pY6TtEh4UDuevmGmkUIjX/b+e/k4tcNBMf7SRQ2mdNuK/HQ==} + /esbuild-freebsd-64/0.15.8: + resolution: {integrity: sha512-jaxcsGHYzn2L0/lffON2WfH4Nc+d/EwozVTP5K2v016zxMb5UQMhLoJzvLgBqHT1SG0B/mO+a+THnJCMVg15zw==} engines: {node: '>=12'} cpu: [x64] os: [freebsd] @@ -1474,8 +1418,8 @@ packages: dev: true optional: true - /esbuild-freebsd-arm64/0.15.7: - resolution: {integrity: sha512-dLFR0ChH5t+b3J8w0fVKGvtwSLWCv7GYT2Y2jFGulF1L5HftQLzVGN+6pi1SivuiVSmTh28FwUhi9PwQicXI6Q==} + /esbuild-freebsd-arm64/0.15.8: + resolution: {integrity: sha512-2xp2UlljMvX8HExtcg7VHaeQk8OBU0CSl1j18B5CcZmSDkLF9p3utuMXIopG3a08fr9Hv+Dz6+seSXUow/G51w==} engines: {node: '>=12'} cpu: [arm64] os: [freebsd] @@ -1483,8 +1427,8 @@ packages: dev: true optional: true - /esbuild-linux-32/0.15.7: - resolution: {integrity: sha512-v3gT/LsONGUZcjbt2swrMjwxo32NJzk+7sAgtxhGx1+ZmOFaTRXBAi1PPfgpeo/J//Un2jIKm/I+qqeo4caJvg==} + /esbuild-linux-32/0.15.8: + resolution: {integrity: sha512-9u1E54BRz1FQMl86iaHK146+4ID2KYNxL3trLZT4QLLx3M7Q9n4lGG3lrzqUatGR2cKy8c33b0iaCzsItZWkFg==} engines: {node: '>=12'} cpu: [ia32] os: [linux] @@ -1492,8 +1436,8 @@ packages: dev: true optional: true - /esbuild-linux-64/0.15.7: - resolution: {integrity: sha512-LxXEfLAKwOVmm1yecpMmWERBshl+Kv5YJ/1KnyAr6HRHFW8cxOEsEfisD3sVl/RvHyW//lhYUVSuy9jGEfIRAQ==} + /esbuild-linux-64/0.15.8: + resolution: {integrity: sha512-4HxrsN9eUzJXdVGMTYA5Xler82FuZUu21bXKN42zcLHHNKCAMPUzD62I+GwDhsdgUBAUj0tRXDdsQHgaP6v0HA==} engines: {node: '>=12'} cpu: [x64] os: [linux] @@ -1501,8 +1445,8 @@ packages: dev: true optional: true - /esbuild-linux-arm/0.15.7: - resolution: {integrity: sha512-JKgAHtMR5f75wJTeuNQbyznZZa+pjiUHV7sRZp42UNdyXC6TiUYMW/8z8yIBAr2Fpad8hM1royZKQisqPABPvQ==} + /esbuild-linux-arm/0.15.8: + resolution: {integrity: sha512-7DVBU9SFjX4+vBwt8tHsUCbE6Vvl6y6FQWHAgyw1lybC5gULqn/WnjHYHN2/LJaZRsDBvxWT4msEgwLGq1Wd3Q==} engines: {node: '>=12'} cpu: [arm] os: [linux] @@ -1510,8 +1454,8 @@ packages: dev: true optional: true - /esbuild-linux-arm64/0.15.7: - resolution: {integrity: sha512-P3cfhudpzWDkglutWgXcT2S7Ft7o2e3YDMrP1n0z2dlbUZghUkKCyaWw0zhp4KxEEzt/E7lmrtRu/pGWnwb9vw==} + /esbuild-linux-arm64/0.15.8: + resolution: {integrity: sha512-1OCm7Aq0tEJT70PbxmHSGYDLYP8DKH8r4Nk7/XbVzWaduo9beCjGBB+tGZIHK6DdTQ3h00/4Tb/70YMH/bOtKg==} engines: {node: '>=12'} cpu: [arm64] os: [linux] @@ -1519,8 +1463,8 @@ packages: dev: true optional: true - /esbuild-linux-mips64le/0.15.7: - resolution: {integrity: sha512-T7XKuxl0VpeFLCJXub6U+iybiqh0kM/bWOTb4qcPyDDwNVhLUiPcGdG2/0S7F93czUZOKP57YiLV8YQewgLHKw==} + /esbuild-linux-mips64le/0.15.8: + resolution: {integrity: sha512-yeFoNPVFPEzZvFYBfUQNG2TjGRaCyV1E27OcOg4LOtnGrxb2wA+mkW3luckyv1CEyd00mpAg7UdHx8nlx3ghgA==} engines: {node: '>=12'} cpu: [mips64el] os: [linux] @@ -1528,8 +1472,8 @@ packages: dev: true optional: true - /esbuild-linux-ppc64le/0.15.7: - resolution: {integrity: sha512-6mGuC19WpFN7NYbecMIJjeQgvDb5aMuvyk0PDYBJrqAEMkTwg3Z98kEKuCm6THHRnrgsdr7bp4SruSAxEM4eJw==} + /esbuild-linux-ppc64le/0.15.8: + resolution: {integrity: sha512-CEyMMUUNabXibw8OSNmBXhOIGhnjNVl5Lpseiuf00iKN0V47oqDrbo4dsHz1wH62m49AR8iG8wpDlTqfYgKbtg==} engines: {node: '>=12'} cpu: [ppc64] os: [linux] @@ -1537,8 +1481,8 @@ packages: dev: true optional: true - /esbuild-linux-riscv64/0.15.7: - resolution: {integrity: sha512-uUJsezbswAYo/X7OU/P+PuL/EI9WzxsEQXDekfwpQ23uGiooxqoLFAPmXPcRAt941vjlY9jtITEEikWMBr+F/g==} + /esbuild-linux-riscv64/0.15.8: + resolution: {integrity: sha512-OCGSOaspMUjexSCU8ZiA0UnV/NiRU+s2vIfEcAQWQ6u32R+2luyfh/4ZaY6jFbylJE07Esc/yRvb9Q5fXuClXA==} engines: {node: '>=12'} cpu: [riscv64] os: [linux] @@ -1546,8 +1490,8 @@ packages: dev: true optional: true - /esbuild-linux-s390x/0.15.7: - resolution: {integrity: sha512-+tO+xOyTNMc34rXlSxK7aCwJgvQyffqEM5MMdNDEeMU3ss0S6wKvbBOQfgd5jRPblfwJ6b+bKiz0g5nABpY0QQ==} + /esbuild-linux-s390x/0.15.8: + resolution: {integrity: sha512-RHdpdfxRTSrZXZJlFSLazFU4YwXLB5Rgf6Zr5rffqSsO4y9JybgtKO38bFwxZNlDXliYISXN/YROKrG9s7mZQA==} engines: {node: '>=12'} cpu: [s390x] os: [linux] @@ -1555,8 +1499,8 @@ packages: dev: true optional: true - /esbuild-netbsd-64/0.15.7: - resolution: {integrity: sha512-yVc4Wz+Pu3cP5hzm5kIygNPrjar/v5WCSoRmIjCPWfBVJkZNb5brEGKUlf+0Y759D48BCWa0WHrWXaNy0DULTQ==} + /esbuild-netbsd-64/0.15.8: + resolution: {integrity: sha512-VolFFRatBH09T5QMWhiohAWCOien1R1Uz9K0BRVVTBgBaVBt7eArsXTKxVhUgRf2vwu2c2SXkuP0r7HLG0eozw==} engines: {node: '>=12'} cpu: [x64] os: [netbsd] @@ -1564,8 +1508,8 @@ packages: dev: true optional: true - /esbuild-openbsd-64/0.15.7: - resolution: {integrity: sha512-GsimbwC4FSR4lN3wf8XmTQ+r8/0YSQo21rWDL0XFFhLHKlzEA4SsT1Tl8bPYu00IU6UWSJ+b3fG/8SB69rcuEQ==} + /esbuild-openbsd-64/0.15.8: + resolution: {integrity: sha512-HTAPlg+n4kUeE/isQxlCfsOz0xJGNoT5LJ9oYZWFKABfVf4Ycu7Zlf5ITgOnrdheTkz8JeL/gISIOCFAoOXrSA==} engines: {node: '>=12'} cpu: [x64] os: [openbsd] @@ -1573,8 +1517,8 @@ packages: dev: true optional: true - /esbuild-sunos-64/0.15.7: - resolution: {integrity: sha512-8CDI1aL/ts0mDGbWzjEOGKXnU7p3rDzggHSBtVryQzkSOsjCHRVe0iFYUuhczlxU1R3LN/E7HgUO4NXzGGP/Ag==} + /esbuild-sunos-64/0.15.8: + resolution: {integrity: sha512-qMP/jR/FzcIOwKj+W+Lb+8Cfr8GZHbHUJxAPi7DUhNZMQ/6y7sOgRzlOSpRrbbUntrRZh0MqOyDhJ3Gpo6L1QA==} engines: {node: '>=12'} cpu: [x64] os: [sunos] @@ -1582,8 +1526,16 @@ packages: dev: true optional: true - /esbuild-windows-32/0.15.7: - resolution: {integrity: sha512-cOnKXUEPS8EGCzRSFa1x6NQjGhGsFlVgjhqGEbLTPsA7x4RRYiy2RKoArNUU4iR2vHmzqS5Gr84MEumO/wxYKA==} + /esbuild-wasm/0.15.8: + resolution: {integrity: sha512-Y7uCl5RNO4URjlemjdx++ukVHEMt5s5AfMWYUnMiK4Sry+pPCvQIctzXq6r6FKCyGKjX6/NGMCqR2OX6aLxj0w==} + engines: {node: '>=12'} + hasBin: true + requiresBuild: true + dev: true + optional: true + + /esbuild-windows-32/0.15.8: + resolution: {integrity: sha512-RKR1QHh4iWzjUhkP8Yqi75PPz/KS+b8zw3wUrzw6oAkj+iU5Qtyj61ZDaSG3Qf2vc6hTIUiPqVTqBH0NpXFNwg==} engines: {node: '>=12'} cpu: [ia32] os: [win32] @@ -1591,8 +1543,8 @@ packages: dev: true optional: true - /esbuild-windows-64/0.15.7: - resolution: {integrity: sha512-7MI08Ec2sTIDv+zH6StNBKO+2hGUYIT42GmFyW6MBBWWtJhTcQLinKS6ldIN1d52MXIbiJ6nXyCJ+LpL4jBm3Q==} + /esbuild-windows-64/0.15.8: + resolution: {integrity: sha512-ag9ptYrsizgsR+PQE8QKeMqnosLvAMonQREpLw4evA4FFgOBMLEat/dY/9txbpozTw9eEOYyD3a4cE9yTu20FA==} engines: {node: '>=12'} cpu: [x64] os: [win32] @@ -1600,8 +1552,8 @@ packages: dev: true optional: true - /esbuild-windows-arm64/0.15.7: - resolution: {integrity: sha512-R06nmqBlWjKHddhRJYlqDd3Fabx9LFdKcjoOy08YLimwmsswlFBJV4rXzZCxz/b7ZJXvrZgj8DDv1ewE9+StMw==} + /esbuild-windows-arm64/0.15.8: + resolution: {integrity: sha512-dbpAb0VyPaUs9mgw65KRfQ9rqiWCHpNzrJusoPu+LpEoswosjt/tFxN7cd2l68AT4qWdBkzAjDLRon7uqMeWcg==} engines: {node: '>=12'} cpu: [arm64] os: [win32] @@ -1609,33 +1561,34 @@ packages: dev: true optional: true - /esbuild/0.15.7: - resolution: {integrity: sha512-7V8tzllIbAQV1M4QoE52ImKu8hT/NLGlGXkiDsbEU5PS6K8Mn09ZnYoS+dcmHxOS9CRsV4IRAMdT3I67IyUNXw==} + /esbuild/0.15.8: + resolution: {integrity: sha512-Remsk2dmr1Ia65sU+QasE6svJbsHe62lzR+CnjpUvbZ+uSYo1SitiOWPRfZQkCu82YWZBBKXiD/j0i//XWMZ+Q==} engines: {node: '>=12'} hasBin: true requiresBuild: true optionalDependencies: - '@esbuild/linux-loong64': 0.15.7 - esbuild-android-64: 0.15.7 - esbuild-android-arm64: 0.15.7 - esbuild-darwin-64: 0.15.7 - esbuild-darwin-arm64: 0.15.7 - esbuild-freebsd-64: 0.15.7 - esbuild-freebsd-arm64: 0.15.7 - esbuild-linux-32: 0.15.7 - esbuild-linux-64: 0.15.7 - esbuild-linux-arm: 0.15.7 - esbuild-linux-arm64: 0.15.7 - esbuild-linux-mips64le: 0.15.7 - esbuild-linux-ppc64le: 0.15.7 - esbuild-linux-riscv64: 0.15.7 - esbuild-linux-s390x: 0.15.7 - esbuild-netbsd-64: 0.15.7 - esbuild-openbsd-64: 0.15.7 - esbuild-sunos-64: 0.15.7 - esbuild-windows-32: 0.15.7 - esbuild-windows-64: 0.15.7 - esbuild-windows-arm64: 0.15.7 + '@esbuild/android-arm': 0.15.8 + '@esbuild/linux-loong64': 0.15.8 + esbuild-android-64: 0.15.8 + esbuild-android-arm64: 0.15.8 + esbuild-darwin-64: 0.15.8 + esbuild-darwin-arm64: 0.15.8 + esbuild-freebsd-64: 0.15.8 + esbuild-freebsd-arm64: 0.15.8 + esbuild-linux-32: 0.15.8 + esbuild-linux-64: 0.15.8 + esbuild-linux-arm: 0.15.8 + esbuild-linux-arm64: 0.15.8 + esbuild-linux-mips64le: 0.15.8 + esbuild-linux-ppc64le: 0.15.8 + esbuild-linux-riscv64: 0.15.8 + esbuild-linux-s390x: 0.15.8 + esbuild-netbsd-64: 0.15.8 + esbuild-openbsd-64: 0.15.8 + esbuild-sunos-64: 0.15.8 + esbuild-windows-32: 0.15.8 + esbuild-windows-64: 0.15.8 + esbuild-windows-arm64: 0.15.8 dev: true /escalade/3.1.1: @@ -1652,13 +1605,13 @@ packages: engines: {node: '>=10'} dev: false - /eslint-config-prettier/8.5.0_eslint@8.23.0: + /eslint-config-prettier/8.5.0_eslint@8.23.1: resolution: {integrity: sha512-obmWKLUNCnhtQRKc+tmnYuQl0pFU1ibYJQ5BGhTVB08bHe9wC8qUeG7c08dj9XX+AuPj1YSGSQIHl1pnDHZR0Q==} hasBin: true peerDependencies: eslint: '>=7.0.0' dependencies: - eslint: 8.23.0 + eslint: 8.23.1 dev: false /eslint-import-resolver-node/0.3.6: @@ -1670,7 +1623,7 @@ packages: - supports-color dev: false - /eslint-import-resolver-typescript/2.7.1_faomjyrlgqmwswvqymymzkxcqi: + /eslint-import-resolver-typescript/2.7.1_hdzsmr7kawaomymueo2tso6fjq: resolution: {integrity: sha512-00UbgGwV8bSgUv34igBDbTOtKhqoRMy9bFjNehT40bXg6585PNIct8HhXZ0SybqB9rWtXj9crcku8ndDn/gIqQ==} engines: {node: '>=4'} peerDependencies: @@ -1678,8 +1631,8 @@ packages: eslint-plugin-import: '*' dependencies: debug: 4.3.4 - eslint: 8.23.0 - eslint-plugin-import: 2.26.0_ijmu6epd3rsbb7y7umh7oqxvja + eslint: 8.23.1 + eslint-plugin-import: 2.26.0_ar2mambzda7ptwcepuhox2isnu glob: 7.2.3 is-glob: 4.0.3 resolve: 1.22.1 @@ -1688,7 +1641,7 @@ packages: - supports-color dev: false - /eslint-module-utils/2.7.4_5ep4gvkdjjju3hv6nnofcqbqsy: + /eslint-module-utils/2.7.4_ynomfj5kz5mbj5hbqjqvvursdy: resolution: {integrity: sha512-j4GT+rqzCoRKHwURX7pddtIPGySnX9Si/cgMI5ztrcqOPtk5dDEeZ34CQVPphnqkJytlc97Vuk05Um2mJ3gEQA==} engines: {node: '>=4'} peerDependencies: @@ -1709,27 +1662,27 @@ packages: eslint-import-resolver-webpack: optional: true dependencies: - '@typescript-eslint/parser': 5.36.2_itqs5654cmlnjraw6gjzqacppi + '@typescript-eslint/parser': 5.38.0_irgkl5vooow2ydyo6aokmferha debug: 3.2.7 - eslint: 8.23.0 + eslint: 8.23.1 eslint-import-resolver-node: 0.3.6 - eslint-import-resolver-typescript: 2.7.1_faomjyrlgqmwswvqymymzkxcqi + eslint-import-resolver-typescript: 2.7.1_hdzsmr7kawaomymueo2tso6fjq transitivePeerDependencies: - supports-color dev: false - /eslint-plugin-eslint-comments/3.2.0_eslint@8.23.0: + /eslint-plugin-eslint-comments/3.2.0_eslint@8.23.1: resolution: {integrity: sha512-0jkOl0hfojIHHmEHgmNdqv4fmh7300NdpA9FFpF7zaoLvB/QeXOGNLIo86oAveJFrfB1p05kC8hpEMHM8DwWVQ==} engines: {node: '>=6.5.0'} peerDependencies: eslint: '>=4.19.1' dependencies: escape-string-regexp: 1.0.5 - eslint: 8.23.0 + eslint: 8.23.1 ignore: 5.2.0 dev: false - /eslint-plugin-import/2.26.0_ijmu6epd3rsbb7y7umh7oqxvja: + /eslint-plugin-import/2.26.0_ar2mambzda7ptwcepuhox2isnu: resolution: {integrity: sha512-hYfi3FXaM8WPLf4S1cikh/r4IxnO6zrhZbEGz2b660EJRbuxgpDS5gkCuYgGWg2xxh2rBuIr4Pvhve/7c31koA==} engines: {node: '>=4'} peerDependencies: @@ -1739,14 +1692,14 @@ packages: '@typescript-eslint/parser': optional: true dependencies: - '@typescript-eslint/parser': 5.36.2_itqs5654cmlnjraw6gjzqacppi + '@typescript-eslint/parser': 5.38.0_irgkl5vooow2ydyo6aokmferha array-includes: 3.1.5 array.prototype.flat: 1.3.0 debug: 2.6.9 doctrine: 2.1.0 - eslint: 8.23.0 + eslint: 8.23.1 eslint-import-resolver-node: 0.3.6 - eslint-module-utils: 2.7.4_5ep4gvkdjjju3hv6nnofcqbqsy + eslint-module-utils: 2.7.4_ynomfj5kz5mbj5hbqjqvvursdy has: 1.0.3 is-core-module: 2.10.0 is-glob: 4.0.3 @@ -1760,16 +1713,16 @@ packages: - supports-color dev: false - /eslint-plugin-react-hooks/4.6.0_eslint@8.23.0: + /eslint-plugin-react-hooks/4.6.0_eslint@8.23.1: resolution: {integrity: sha512-oFc7Itz9Qxh2x4gNHStv3BqJq54ExXmfC+a1NjAta66IAN87Wu0R/QArgIS9qKzX3dXKPI9H5crl9QchNMY9+g==} engines: {node: '>=10'} peerDependencies: eslint: ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0 dependencies: - eslint: 8.23.0 + eslint: 8.23.1 dev: false - /eslint-plugin-react/7.31.8_eslint@8.23.0: + /eslint-plugin-react/7.31.8_eslint@8.23.1: resolution: {integrity: sha512-5lBTZmgQmARLLSYiwI71tiGVTLUuqXantZM6vlSY39OaDSV0M7+32K5DnLkmFrwTe+Ksz0ffuLUC91RUviVZfw==} engines: {node: '>=4'} peerDependencies: @@ -1778,7 +1731,7 @@ packages: array-includes: 3.1.5 array.prototype.flatmap: 1.3.0 doctrine: 2.1.0 - eslint: 8.23.0 + eslint: 8.23.1 estraverse: 5.3.0 jsx-ast-utils: 3.3.3 minimatch: 3.1.2 @@ -1808,13 +1761,13 @@ packages: estraverse: 5.3.0 dev: false - /eslint-utils/3.0.0_eslint@8.23.0: + /eslint-utils/3.0.0_eslint@8.23.1: resolution: {integrity: sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==} engines: {node: ^10.0.0 || ^12.0.0 || >= 14.0.0} peerDependencies: eslint: '>=5' dependencies: - eslint: 8.23.0 + eslint: 8.23.1 eslint-visitor-keys: 2.1.0 dev: false @@ -1828,12 +1781,12 @@ packages: engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} dev: false - /eslint/8.23.0: - resolution: {integrity: sha512-pBG/XOn0MsJcKcTRLr27S5HpzQo4kLr+HjLQIyK4EiCsijDl/TB+h5uEuJU6bQ8Edvwz1XWOjpaP2qgnXGpTcA==} + /eslint/8.23.1: + resolution: {integrity: sha512-w7C1IXCc6fNqjpuYd0yPlcTKKmHlHHktRkzmBPZ+7cvNBQuiNjx0xaMTjAJGCafJhQkrFJooREv0CtrVzmHwqg==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} hasBin: true dependencies: - '@eslint/eslintrc': 1.3.1 + '@eslint/eslintrc': 1.3.2 '@humanwhocodes/config-array': 0.10.4 '@humanwhocodes/gitignore-to-minimatch': 1.0.2 '@humanwhocodes/module-importer': 1.0.1 @@ -1844,7 +1797,7 @@ packages: doctrine: 3.0.0 escape-string-regexp: 4.0.0 eslint-scope: 7.1.1 - eslint-utils: 3.0.0_eslint@8.23.0 + eslint-utils: 3.0.0_eslint@8.23.1 eslint-visitor-keys: 3.3.0 espree: 9.4.0 esquery: 1.4.0 @@ -1852,7 +1805,6 @@ packages: fast-deep-equal: 3.1.3 file-entry-cache: 6.0.1 find-up: 5.0.0 - functional-red-black-tree: 1.0.1 glob-parent: 6.0.2 globals: 13.17.0 globby: 11.1.0 @@ -1861,6 +1813,7 @@ packages: import-fresh: 3.3.0 imurmurhash: 0.1.4 is-glob: 4.0.3 + js-sdsl: 4.1.4 js-yaml: 4.1.0 json-stable-stringify-without-jsonify: 1.0.1 levn: 0.4.1 @@ -1914,39 +1867,6 @@ packages: engines: {node: '>=0.10.0'} dev: false - /evergreen-ui/6.10.3_biqbaboplfbrettd7655fr4n2y: - resolution: {integrity: sha512-NxDQyntCxYBQbucCm8yVoEL/7bFC0EfFulDEH+OrpLIRVSG3pZPO7qKeCD8YT/sJQJqe/Iv01m8toW4Qlt7TgA==} - engines: {node: '>=14'} - peerDependencies: - react: ^16.8.0 || ^17.0.0 || ^18.0.0 - react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 - react-is: ^16.8.0 || ^17.0.0 || ^18.0.0 - dependencies: - '@babel/runtime': 7.19.0 - '@segment/react-tiny-virtual-list': 2.2.1_react@18.2.0 - '@types/react': 16.14.31 - '@types/react-transition-group': 4.4.5 - arrify: 1.0.1 - classnames: 2.3.1 - downshift: 5.4.7_react@18.2.0 - fuzzaldrin-plus: 0.6.0 - glamor: 2.20.40 - humanize-plus: 1.8.2 - lodash.debounce: 4.0.8 - lodash.differencewith: 4.5.0 - lodash.isempty: 4.4.0 - lodash.merge: 4.6.2 - lodash.omit: 4.5.0 - lodash.uniqby: 4.7.0 - prop-types: 15.8.1 - react: 18.2.0 - react-dom: 18.2.0_react@18.2.0 - react-fast-compare: 3.2.0 - react-transition-group: 4.4.5_biqbaboplfbrettd7655fr4n2y - tinycolor2: 1.4.2 - ui-box: 5.1.0_react@18.2.0 - dev: false - /fast-deep-equal/3.1.3: resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} dev: false @@ -1960,7 +1880,6 @@ packages: glob-parent: 5.1.2 merge2: 1.4.1 micromatch: 4.0.5 - dev: false /fast-json-stable-stringify/2.1.0: resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==} @@ -1974,19 +1893,6 @@ packages: resolution: {integrity: sha512-YpkpUnK8od0o1hmeSc7UUs/eB/vIPWJYjKck2QKIzAf71Vm1AAQ3EbuZB3g2JIy+pg+ERD0vqI79KyZiB2e2Nw==} dependencies: reusify: 1.0.4 - dev: false - - /fbjs/0.8.18: - resolution: {integrity: sha512-EQaWFK+fEPSoibjNy8IxUtaFOMXcWsY0JaVrQoZR9zC8N2Ygf9iDITPWjUTVIax95b6I742JFLqASHfsag/vKA==} - dependencies: - core-js: 1.2.7 - isomorphic-fetch: 2.2.1 - loose-envify: 1.4.0 - object-assign: 4.1.1 - promise: 7.3.1 - setimmediate: 1.0.5 - ua-parser-js: 0.7.31 - dev: false /file-entry-cache/6.0.1: resolution: {integrity: sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==} @@ -2000,7 +1906,6 @@ packages: engines: {node: '>=8'} dependencies: to-regex-range: 5.0.1 - dev: false /find-up/5.0.0: resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==} @@ -2025,7 +1930,11 @@ packages: /for-each/0.3.3: resolution: {integrity: sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==} dependencies: - is-callable: 1.2.4 + is-callable: 1.2.6 + dev: true + + /fraction.js/4.2.0: + resolution: {integrity: sha512-MhLuK+2gUcnZe8ZHlaaINnQLl0xRIGRfcGk2yl8xoQAfHrSsL3rYu6FCmBdkdbhc9EPlwyGHewaRsvwRMJtAlA==} dev: true /fs-minipass/2.1.0: @@ -2044,7 +1953,6 @@ packages: engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} os: [darwin] requiresBuild: true - dev: true optional: true /function-bind/1.1.1: @@ -2059,17 +1967,9 @@ packages: es-abstract: 1.20.2 functions-have-names: 1.2.3 - /functional-red-black-tree/1.0.1: - resolution: {integrity: sha512-dsKNQNdj6xA3T+QlADDA7mOSlX0qiMINjn0cgr+eGHGsbSHzTabcIogz2+p/iqP1Xs6EP/sS2SbqH+brGTbq0g==} - dev: false - /functions-have-names/1.2.3: resolution: {integrity: sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==} - /fuzzaldrin-plus/0.6.0: - resolution: {integrity: sha512-srIDThJHkdp3aPwJpR/HNzYZCRJwm07b/igxseoHSB7qR8e/gQp4F6lMGknE3TQI1Aq14TiFf/wzrHOp9LY/EA==} - dev: false - /gensync/1.0.0-beta.2: resolution: {integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==} engines: {node: '>=6.9.0'} @@ -2089,8 +1989,8 @@ packages: engines: {node: 6.* || 8.* || >= 10.*} dev: true - /get-intrinsic/1.1.2: - resolution: {integrity: sha512-Jfm3OyCxHh9DJyc28qGk+JmfkpO41A4XkneDSujN9MDXrm4oDKdHvndhZ2dN94+ERNfkYJWDclW6k2L/ZGHjXA==} + /get-intrinsic/1.1.3: + resolution: {integrity: sha512-QJVz1Tj7MS099PevUG5jvnt9tSkXN8K14dxQlikJuPt4uD9hHAHjLyLBiLR5zELelBdD9QNRAXZzsJx0WaDL9A==} dependencies: function-bind: 1.1.1 has: 1.0.3 @@ -2106,35 +2006,23 @@ packages: engines: {node: '>= 0.4'} dependencies: call-bind: 1.0.2 - get-intrinsic: 1.1.2 + get-intrinsic: 1.1.3 /gl-matrix/3.4.3: resolution: {integrity: sha512-wcCp8vu8FT22BnvKVPjXa/ICBWRq/zjFfdofZy1WSpQZpphblv12/bOQLBC1rMM7SGOFS9ltVmKOHil5+Ml7gA==} dev: false - /glamor/2.20.40: - resolution: {integrity: sha512-DNXCd+c14N9QF8aAKrfl4xakPk5FdcFwmH7sD0qnC0Pr7xoZ5W9yovhUrY/dJc3psfGGXC58vqQyRtuskyUJxA==} - dependencies: - fbjs: 0.8.18 - inline-style-prefixer: 3.0.8 - object-assign: 4.1.1 - prop-types: 15.8.1 - through: 2.3.8 - dev: false - /glob-parent/5.1.2: resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} engines: {node: '>= 6'} dependencies: is-glob: 4.0.3 - dev: false /glob-parent/6.0.2: resolution: {integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==} engines: {node: '>=10.13.0'} dependencies: is-glob: 4.0.3 - dev: false /glob/7.2.3: resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==} @@ -2212,7 +2100,7 @@ packages: /has-property-descriptors/1.0.0: resolution: {integrity: sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ==} dependencies: - get-intrinsic: 1.1.2 + get-intrinsic: 1.1.3 /has-symbols/1.0.3: resolution: {integrity: sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==} @@ -2230,22 +2118,6 @@ packages: dependencies: function-bind: 1.1.1 - /humanize-plus/1.8.2: - resolution: {integrity: sha512-jaLeQyyzjjINGv7O9JJegjsaUcWjSj/1dcXvLEgU3pGdqCdP1PiC/uwr+saJXhTNBHZtmKnmpXyazgh+eceRxA==} - engines: {node: '>= 0.8.0'} - dev: false - - /hyphenate-style-name/1.0.4: - resolution: {integrity: sha512-ygGZLjmXfPHj+ZWh6LwbC37l43MhfztxetbFCoYTM2VjkIUpeHgSNn7QIyVFj7YQ1Wl9Cbw5sholVJPzWvC2MQ==} - dev: false - - /iconv-lite/0.6.3: - resolution: {integrity: sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==} - engines: {node: '>=0.10.0'} - dependencies: - safer-buffer: 2.1.2 - dev: false - /ieee754/1.2.1: resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==} dev: false @@ -2286,24 +2158,11 @@ packages: resolution: {integrity: sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==} dev: false - /inline-style-prefixer/3.0.8: - resolution: {integrity: sha512-ne8XIyyqkRaNJ1JfL1NYzNdCNxq+MCBQhC8NgOQlzNm2vv3XxlP0VSLQUbSRCF6KPEoveCVEpayHoHzcMyZsMQ==} - dependencies: - bowser: 1.9.4 - css-in-js-utils: 2.0.1 - dev: false - - /inline-style-prefixer/5.1.2: - resolution: {integrity: sha512-PYUF+94gDfhy+LsQxM0g3d6Hge4l1pAqOSOiZuHWzMvQEGsbRQ/ck2WioLqrY2ZkHyPgVUXxn+hrkF7D6QUGbA==} - dependencies: - css-in-js-utils: 2.0.1 - dev: false - /internal-slot/1.0.3: resolution: {integrity: sha512-O0DB1JC/sPyZl7cIo78n5dR7eUSwwpYPiXRhTzNxZVAMUuB8vlnRFyLxdrVToks6XPLVnFfbzaVd5WLjhgg+vA==} engines: {node: '>= 0.4'} dependencies: - get-intrinsic: 1.1.2 + get-intrinsic: 1.1.3 has: 1.0.3 side-channel: 1.0.4 @@ -2320,6 +2179,12 @@ packages: dependencies: has-bigints: 1.0.2 + /is-binary-path/2.1.0: + resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==} + engines: {node: '>=8'} + dependencies: + binary-extensions: 2.2.0 + /is-boolean-object/1.1.2: resolution: {integrity: sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==} engines: {node: '>= 0.4'} @@ -2327,8 +2192,8 @@ packages: call-bind: 1.0.2 has-tostringtag: 1.0.0 - /is-callable/1.2.4: - resolution: {integrity: sha512-nsuwtxZfMX67Oryl9LCQ+upnC0Z0BgpwntpS89m1H/TLF0zNfzfLMV/9Wa/6MZsj0acpEjAO0KF1xT6ZdLl95w==} + /is-callable/1.2.6: + resolution: {integrity: sha512-krO72EO2NptOGAX2KYyqbP9vYMlNAXdB53rq6f8LXY6RY7JdSR/3BD6wLUlPHSAesmY9vstNrjvqGaCiRK/91Q==} engines: {node: '>= 0.4'} /is-core-module/2.10.0: @@ -2351,7 +2216,6 @@ packages: /is-extglob/2.1.1: resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} engines: {node: '>=0.10.0'} - dev: false /is-fullwidth-code-point/3.0.0: resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} @@ -2363,7 +2227,6 @@ packages: engines: {node: '>=0.10.0'} dependencies: is-extglob: 2.1.1 - dev: false /is-map/2.0.2: resolution: {integrity: sha512-cOZFQQozTha1f4MxLFzlgKYPTyj26picdZTx82hbc/Xf4K/tZOOXSCkMvU4pKioRXGDLJRn0GM7Upe7kR721yg==} @@ -2382,7 +2245,6 @@ packages: /is-number/7.0.0: resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} engines: {node: '>=0.12.0'} - dev: false /is-regex/1.1.4: resolution: {integrity: sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==} @@ -2400,11 +2262,6 @@ packages: dependencies: call-bind: 1.0.2 - /is-stream/1.1.0: - resolution: {integrity: sha512-uQPm8kcs47jx38atAcWTVxyltQYoPT68y9aWYdV6yWXSyW8mzSat0TL6CiWdZeCdF3KrAvpVtnHbTv4RN+rqdQ==} - engines: {node: '>=0.10.0'} - dev: false - /is-string/1.0.7: resolution: {integrity: sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==} engines: {node: '>= 0.4'} @@ -2441,7 +2298,7 @@ packages: resolution: {integrity: sha512-t2yVvttHkQktwnNNmBQ98AhENLdPUTDTE21uPqAQ0ARwQfGeQKRVS0NNurH7bTf7RrvcVn1OOge45CnBeHCSmg==} dependencies: call-bind: 1.0.2 - get-intrinsic: 1.1.2 + get-intrinsic: 1.1.3 dev: true /is-wsl/2.2.0: @@ -2467,16 +2324,8 @@ packages: resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} dev: false - /isobject/3.0.1: - resolution: {integrity: sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==} - engines: {node: '>=0.10.0'} - dev: false - - /isomorphic-fetch/2.2.1: - resolution: {integrity: sha512-9c4TNAKYXM5PRyVcwUZrF3W09nQ+sO7+jydgs4ZGW9dhsLG2VOlISJABombdQqQRXCwuYG3sYV/puGf5rp0qmA==} - dependencies: - node-fetch: 1.7.3 - whatwg-fetch: 3.6.2 + /js-sdsl/4.1.4: + resolution: {integrity: sha512-Y2/yD55y5jteOAmY50JbUZYwk3CP3wnLPEZnlR1w9oKhITrBEtAxwuWKebFf8hMrPMgbYwFoWK/lH2sBkErELw==} dev: false /js-sha3/0.8.0: @@ -2549,6 +2398,10 @@ packages: resolution: {integrity: sha512-b74iyWmwb4GprAUPjPkJ11GTC7KX4Pd3onpJfKxYyY8y9Rbb4ERY47LvCMEDM09WD3thiLDMXtkfDK/AX+zT7Q==} dev: false + /lilconfig/2.0.6: + resolution: {integrity: sha512-9JROoBW7pobfsx+Sq2JsASvCo6Pfo6WWoUW79HuB1BCoBXD4PLWJPqDF6fNj67pqBYTbAHkE57M1kS/+L1neOg==} + engines: {node: '>=10'} + /locate-path/6.0.0: resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==} engines: {node: '>=10'} @@ -2556,34 +2409,22 @@ packages: p-locate: 5.0.0 dev: false - /lodash.debounce/4.0.8: - resolution: {integrity: sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==} - dev: false - - /lodash.differencewith/4.5.0: - resolution: {integrity: sha512-/8JFjydAS+4bQuo3CpLMBv7WxGFyk7/etOAsrQUCu0a9QVDemxv0YQ0rFyeZvqlUD314SERfNlgnlqqHmaQ0Cg==} - dev: false - - /lodash.isempty/4.4.0: - resolution: {integrity: sha512-oKMuF3xEeqDltrGMfDxAPGIVMSSRv8tbRSODbrs4KGsRRLEhrW8N8Rd4DRgB2+621hY8A8XwwrTVhXWpxFvMzg==} + /lodash.castarray/4.4.0: + resolution: {integrity: sha512-aVx8ztPv7/2ULbArGJ2Y42bG1mEQ5mGjpdvrbJcJFU3TbYybe+QlLS4pst9zV52ymy2in1KpFPiZnAOATxD4+Q==} dev: false /lodash.isequal/4.5.0: resolution: {integrity: sha512-pDo3lu8Jhfjqls6GkMgpahsF9kCyayhgykjyLMNFTKWrpVdAQtYyB4muAMWozBB4ig/dtWAmsMxLEI8wuz+DYQ==} dev: false + /lodash.isplainobject/4.0.6: + resolution: {integrity: sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==} + dev: false + /lodash.merge/4.6.2: resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==} dev: false - /lodash.omit/4.5.0: - resolution: {integrity: sha512-XeqSp49hNGmlkj2EJlfrQFIzQ6lXdNro9sddtQzcJY8QaoC2GO0DT7xaIokHeyM+mIT0mPMlPvkYzg2xCuHdZg==} - dev: false - - /lodash.uniqby/4.7.0: - resolution: {integrity: sha512-e/zcLx6CSbmaEgFHCA7BnoQKyCtKMxnuWrJygbwPs/AIn+IMKl66L8/s+wBUn5LRw2pZx3bUHibiV1b6aTWIww==} - dev: false - /loose-envify/1.4.0: resolution: {integrity: sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==} hasBin: true @@ -2638,7 +2479,6 @@ packages: /merge2/1.4.1: resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} engines: {node: '>= 8'} - dev: false /micromatch/4.0.5: resolution: {integrity: sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==} @@ -2646,7 +2486,6 @@ packages: dependencies: braces: 3.0.2 picomatch: 2.3.1 - dev: false /minimatch/3.1.2: resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} @@ -2656,7 +2495,6 @@ packages: /minimist/1.2.6: resolution: {integrity: sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==} - dev: false /minipass/3.3.4: resolution: {integrity: sha512-I9WPbWHCGu8W+6k1ZiGpPu0GkoKBeorkfKNuAFBNS1HNFJvke82sxvI5bzcCNpWPorkOO5QQ+zomzzwRxejXiw==} @@ -2679,10 +2517,6 @@ packages: hasBin: true dev: true - /modern-css-reset/1.4.0: - resolution: {integrity: sha512-0crZmSFmrxkI7159rvQWjpDhy0u4+Awg/iOycJdlVn0RSeft/a+6BrQHR3IqvmdK25sqt0o6Z5Ap7cWgUee2rw==} - dev: false - /ms/2.0.0: resolution: {integrity: sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==} dev: false @@ -2702,37 +2536,33 @@ packages: resolution: {integrity: sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw==} engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} hasBin: true - dev: true /natural-compare/1.4.0: resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} dev: false - /node-addon-api/4.3.0: - resolution: {integrity: sha512-73sE9+3UaLYYFmDsFZnqCInzPyh3MqIwZO9cw58yIqAZhONrrabrYyYe3TuIqtIiOuTXVhsGau8hcrhhwSsDIQ==} - dev: false - - /node-fetch/1.7.3: - resolution: {integrity: sha512-NhZ4CsKx7cYm2vSrBAr2PvFOe6sWDf0UYLRqA6svUYg7+/TSfVAu49jYC4BvQ4Sms9SZgdqGBgroqfDhJdTyKQ==} - dependencies: - encoding: 0.1.13 - is-stream: 1.1.0 - dev: false - - /node-gyp-build/4.5.0: - resolution: {integrity: sha512-2iGbaQBV+ITgCz76ZEjmhUKAKVf7xfY1sRl4UiKQspfZMH2h06SyhNsnSVy50cwkFQDGLyif6m/6uFXHkOZ6rg==} - hasBin: true - dev: false - /node-releases/2.0.6: resolution: {integrity: sha512-PiVXnNuFm5+iYkLBNeq5211hvO38y63T0i2KKh2KnUs3RpzJ+JtODFjkD8yjLwnDkTYF1eKXheUwdssR+NRZdg==} dev: true + /normalize-path/3.0.0: + resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} + engines: {node: '>=0.10.0'} + + /normalize-range/0.1.2: + resolution: {integrity: sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==} + engines: {node: '>=0.10.0'} + dev: true + /object-assign/4.1.1: resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==} engines: {node: '>=0.10.0'} dev: false + /object-hash/3.0.0: + resolution: {integrity: sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==} + engines: {node: '>= 6'} + /object-inspect/1.12.2: resolution: {integrity: sha512-z+cPxW0QGUp0mcqcsgQyLVRDoXFQbXOwBaqyF7VIgI4TWNQsDHrBpUQslRmIfAoYWdYzs6UlKJtB2XJpTaNSpQ==} @@ -2884,12 +2714,69 @@ packages: /picocolors/1.0.0: resolution: {integrity: sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==} - dev: true /picomatch/2.3.1: resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} engines: {node: '>=8.6'} - dev: false + + /pify/2.3.0: + resolution: {integrity: sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==} + engines: {node: '>=0.10.0'} + + /postcss-import/14.1.0_postcss@8.4.16: + resolution: {integrity: sha512-flwI+Vgm4SElObFVPpTIT7SU7R3qk2L7PyduMcokiaVKuWv9d/U+Gm/QAd8NDLuykTWTkcrjOeD2Pp1rMeBTGw==} + engines: {node: '>=10.0.0'} + peerDependencies: + postcss: ^8.0.0 + dependencies: + postcss: 8.4.16 + postcss-value-parser: 4.2.0 + read-cache: 1.0.0 + resolve: 1.22.1 + + /postcss-js/4.0.0_postcss@8.4.16: + resolution: {integrity: sha512-77QESFBwgX4irogGVPgQ5s07vLvFqWr228qZY+w6lW599cRlK/HmnlivnnVUxkjHnCu4J16PDMHcH+e+2HbvTQ==} + engines: {node: ^12 || ^14 || >= 16} + peerDependencies: + postcss: ^8.3.3 + dependencies: + camelcase-css: 2.0.1 + postcss: 8.4.16 + + /postcss-load-config/3.1.4_postcss@8.4.16: + resolution: {integrity: sha512-6DiM4E7v4coTE4uzA8U//WhtPwyhiim3eyjEMFCnUpzbrkK9wJHgKDT2mR+HbtSrd/NubVaYTOpSpjUl8NQeRg==} + engines: {node: '>= 10'} + peerDependencies: + postcss: '>=8.0.9' + ts-node: '>=9.0.0' + peerDependenciesMeta: + postcss: + optional: true + ts-node: + optional: true + dependencies: + lilconfig: 2.0.6 + postcss: 8.4.16 + yaml: 1.10.2 + + /postcss-nested/5.0.6_postcss@8.4.16: + resolution: {integrity: sha512-rKqm2Fk0KbA8Vt3AdGN0FB9OBOMDVajMG6ZCf/GoHgdxUJ4sBFp0A/uMIRm+MJUdo33YXEtjqIz8u7DAp8B7DA==} + engines: {node: '>=12.0'} + peerDependencies: + postcss: ^8.2.14 + dependencies: + postcss: 8.4.16 + postcss-selector-parser: 6.0.10 + + /postcss-selector-parser/6.0.10: + resolution: {integrity: sha512-IQ7TZdoaqbT+LCpShg46jnZVlhWD2w6iQYAcYXfHARZ7X1t/UGhhceQDs5X0cGqKvYlHNOuv7Oa1xmb0oQuA3w==} + engines: {node: '>=4'} + dependencies: + cssesc: 3.0.0 + util-deprecate: 1.0.2 + + /postcss-value-parser/4.2.0: + resolution: {integrity: sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==} /postcss/8.4.16: resolution: {integrity: sha512-ipHE1XBvKzm5xI7hiHCZJCSugxvsdq2mPnsq5+UF+VHCjiBvtDrlxJfMBToWaP9D5XlgNmcFGqoHmUn0EYEaRQ==} @@ -2898,7 +2785,6 @@ packages: nanoid: 3.3.4 picocolors: 1.0.0 source-map-js: 1.0.2 - dev: true /potpack/1.0.2: resolution: {integrity: sha512-choctRBIV9EMT9WGAZHn3V7t0Z2pMQyl0EZE6pFc/6ml3ssw7Dlf/oAOvFwjm1HVsqfQN8GfeFyJ+d8tRzqueQ==} @@ -2916,13 +2802,11 @@ packages: prettier: '>=2.2.0' dependencies: prettier: 2.7.1 - dev: false /prettier/2.7.1: resolution: {integrity: sha512-ujppO+MkdPqoVINuDFDRLClm7D78qbDt0/NR+wp5FqEZOoTNAjPHWj17QRhu7geIHJfcNhRk1XVQmF8Bp3ye+g==} engines: {node: '>=10.13.0'} hasBin: true - dev: false /process-nextick-args/2.0.1: resolution: {integrity: sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==} @@ -2936,12 +2820,6 @@ packages: tempfile: 1.1.1 dev: true - /promise/7.3.1: - resolution: {integrity: sha512-nolQXZ/4L+bP/UGlkfaIujX9BKxGwmQ9OT4mOt5yvy8iK1h3wqTEJCijzGANTCCl9nWjY41juyAn2K3Q1hLLTg==} - dependencies: - asap: 2.0.6 - dev: false - /prop-types/15.8.1: resolution: {integrity: sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==} dependencies: @@ -2965,7 +2843,10 @@ packages: /queue-microtask/1.2.3: resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} - dev: false + + /quick-lru/5.1.1: + resolution: {integrity: sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==} + engines: {node: '>=10'} /quickselect/2.0.0: resolution: {integrity: sha512-RKJ22hX8mHe3Y6wH/N3wCM6BWtjaxIyyUIkpHOvfFnxdI4yD4tBXEBKSbriGujF6jnSVkJrffuo6vxACiSSxIw==} @@ -2985,12 +2866,8 @@ packages: scheduler: 0.23.0 dev: false - /react-fast-compare/3.2.0: - resolution: {integrity: sha512-rtGImPZ0YyLrscKI9xTpV8psd6I8VAtjKCzQDlzyDvqJA8XOW78TXYQwNRNd8g8JZnDu8q9Fu/1v4HPAVwVdHA==} - dev: false - - /react-hook-form/7.34.2_react@18.2.0: - resolution: {integrity: sha512-1lYWbEqr0GW7HHUjMScXMidGvV0BE2RJV3ap2BL7G0EJirkqpccTaawbsvBO8GZaB3JjCeFBEbnEWI1P8ZoLRQ==} + /react-hook-form/7.35.0_react@18.2.0: + resolution: {integrity: sha512-9CYdOed+Itbiu5VMVxW0PK9mBR3f0gDGJcZEyUSm0eJbDymQ913TRs2gHcQZZmfTC+rtxyDFRuelMxx/+xwMcw==} engines: {node: '>=12.22.0'} peerDependencies: react: ^16.8.0 || ^17 || ^18 @@ -3049,20 +2926,6 @@ packages: engines: {node: '>=0.10.0'} dev: true - /react-transition-group/4.4.5_biqbaboplfbrettd7655fr4n2y: - resolution: {integrity: sha512-pZcd1MCJoiKiBR2NRxeCRg13uCXbydPnmB4EOeRrY7480qNWO8IIgQG6zlDkm6uRMsURXPuKq0GWtiM59a5Q6g==} - peerDependencies: - react: '>=16.6.0' - react-dom: '>=16.6.0' - dependencies: - '@babel/runtime': 7.19.0 - dom-helpers: 5.2.1 - loose-envify: 1.4.0 - prop-types: 15.8.1 - react: 18.2.0 - react-dom: 18.2.0_react@18.2.0 - dev: false - /react/16.14.0: resolution: {integrity: sha512-0X2CImDkJGApiAlcf0ODKIneSwBPhqJawOa5wCtKbu7ZECrmS26NvtSILynQ66cgkT/RJ4LidJOc3bUESwmU8g==} engines: {node: '>=0.10.0'} @@ -3079,6 +2942,11 @@ packages: loose-envify: 1.4.0 dev: false + /read-cache/1.0.0: + resolution: {integrity: sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA==} + dependencies: + pify: 2.3.0 + /readable-stream/2.3.7: resolution: {integrity: sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==} dependencies: @@ -3100,9 +2968,11 @@ packages: util-deprecate: 1.0.2 dev: true - /regenerator-runtime/0.13.9: - resolution: {integrity: sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA==} - dev: false + /readdirp/3.6.0: + resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==} + engines: {node: '>=8.10.0'} + dependencies: + picomatch: 2.3.1 /regexp.prototype.flags/1.4.3: resolution: {integrity: sha512-fjggEOO3slI6Wvgjwflkc4NFRCTZAu5CnNfBd5qOMYhWdn67nJBBu34/TkD++eeFmd8C9r9jfXJ27+nSiRkSUA==} @@ -3153,7 +3023,6 @@ packages: /reusify/1.0.4: resolution: {integrity: sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==} engines: {iojs: '>=1.0.0', node: '>=0.10.0'} - dev: false /rfc4648/1.5.2: resolution: {integrity: sha512-tLOizhR6YGovrEBLatX1sdcuhoSCXddw3mqNVAcKxGJ+J0hFeJ+SjeWCv5UPA/WU3YzWPPuCVYgXBKZUPGpKtg==} @@ -3194,7 +3063,6 @@ packages: resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} dependencies: queue-microtask: 1.2.3 - dev: false /safe-buffer/5.1.2: resolution: {integrity: sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==} @@ -3204,10 +3072,6 @@ packages: resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} dev: true - /safer-buffer/2.1.2: - resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} - dev: false - /scheduler/0.23.0: resolution: {integrity: sha512-CtuThmgHNg7zIZWAXi3AsyIzA3n4xx7aNyjwC2VJldO2LMVDhFK+63xGqq6CsJH4rTAt6/M+N4GhZiDYPx9eUw==} dependencies: @@ -3226,32 +3090,6 @@ packages: lru-cache: 6.0.0 dev: false - /serialport/10.4.0: - resolution: {integrity: sha512-PszPM5SnFMgSXom60PkKS2A9nMlNbHkuoyRBlzdSWw9rmgOn258+V0dYbWMrETJMM+TJV32vqBzjg5MmmUMwMw==} - engines: {node: '>=12.0.0'} - dependencies: - '@serialport/binding-mock': 10.2.2 - '@serialport/bindings-cpp': 10.7.0 - '@serialport/parser-byte-length': 10.3.0 - '@serialport/parser-cctalk': 10.3.0 - '@serialport/parser-delimiter': 10.3.0 - '@serialport/parser-inter-byte-timeout': 10.3.0 - '@serialport/parser-packet-length': 10.3.0 - '@serialport/parser-readline': 10.3.0 - '@serialport/parser-ready': 10.3.0 - '@serialport/parser-regex': 10.3.0 - '@serialport/parser-slip-encoder': 10.3.0 - '@serialport/parser-spacepacket': 10.3.0 - '@serialport/stream': 10.3.0 - debug: 4.3.4 - transitivePeerDependencies: - - supports-color - dev: false - - /setimmediate/1.0.5: - resolution: {integrity: sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==} - dev: false - /shebang-command/2.0.0: resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} engines: {node: '>=8'} @@ -3268,7 +3106,7 @@ packages: resolution: {integrity: sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==} dependencies: call-bind: 1.0.2 - get-intrinsic: 1.1.2 + get-intrinsic: 1.1.3 object-inspect: 1.12.2 /simple-zstd/1.4.0: @@ -3288,7 +3126,6 @@ packages: /source-map-js/1.0.2: resolution: {integrity: sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==} engines: {node: '>=0.10.0'} - dev: true /source-map/0.7.4: resolution: {integrity: sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==} @@ -3318,7 +3155,7 @@ packages: call-bind: 1.0.2 define-properties: 1.1.4 es-abstract: 1.20.2 - get-intrinsic: 1.1.2 + get-intrinsic: 1.1.3 has-symbols: 1.0.3 internal-slot: 1.0.3 regexp.prototype.flags: 1.4.3 @@ -3367,11 +3204,6 @@ packages: engines: {node: '>=8'} dev: false - /sub-events/1.8.9: - resolution: {integrity: sha512-RhhA2amqVzL6nO+aiZOqxBCgcA3ZLfp4W9iHFUELwq8132TS7pUReJV+bcRjtNKdqm/Ep1sD/h01eAcTBtgrBQ==} - engines: {node: '>=10.0.0'} - dev: false - /supercluster/7.1.5: resolution: {integrity: sha512-EulshI3pGUM66o6ZdH3ReiFcvHpM3vAigyK+vcxdjpJyEbIIrtbmBdY23mGgnI24uXiGFvrGq9Gkum/8U7vJWg==} dependencies: @@ -3396,6 +3228,38 @@ packages: resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} engines: {node: '>= 0.4'} + /tailwindcss/3.1.8_postcss@8.4.16: + resolution: {integrity: sha512-YSneUCZSFDYMwk+TGq8qYFdCA3yfBRdBlS7txSq0LUmzyeqRe3a8fBQzbz9M3WS/iFT4BNf/nmw9mEzrnSaC0g==} + engines: {node: '>=12.13.0'} + hasBin: true + peerDependencies: + postcss: ^8.0.9 + dependencies: + arg: 5.0.2 + chokidar: 3.5.3 + color-name: 1.1.4 + detective: 5.2.1 + didyoumean: 1.2.2 + dlv: 1.1.3 + fast-glob: 3.2.12 + glob-parent: 6.0.2 + is-glob: 4.0.3 + lilconfig: 2.0.6 + normalize-path: 3.0.0 + object-hash: 3.0.0 + picocolors: 1.0.0 + postcss: 8.4.16 + postcss-import: 14.1.0_postcss@8.4.16 + postcss-js: 4.0.0_postcss@8.4.16 + postcss-load-config: 3.1.4_postcss@8.4.16 + postcss-nested: 5.0.6_postcss@8.4.16 + postcss-selector-parser: 6.0.10 + postcss-value-parser: 4.2.0 + quick-lru: 5.1.1 + resolve: 1.22.1 + transitivePeerDependencies: + - ts-node + /tar/6.1.11: resolution: {integrity: sha512-an/KZQzQUkZCkuoAA64hM92X0Urb6VpRhAFllDzz44U2mcD5scmT3zBc4VgVpkugF580+DQn8eAFSyoQt0tznA==} engines: {node: '>= 10'} @@ -3420,10 +3284,6 @@ packages: resolution: {integrity: sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==} dev: false - /through/2.3.8: - resolution: {integrity: sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==} - dev: false - /through2/2.0.5: resolution: {integrity: sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==} dependencies: @@ -3437,10 +3297,6 @@ packages: readable-stream: 3.6.0 dev: true - /tinycolor2/1.4.2: - resolution: {integrity: sha512-vJhccZPs965sV/L2sU4oRQVAos0pQXwsvTLkWYdqJ+a8Q5kPFzJTuOFwy7UniPli44NKQGAglksjvOcpo95aZA==} - dev: false - /tinyqueue/2.0.3: resolution: {integrity: sha512-ppJZNDuKGgxzkHihX8v9v9G5f+18gzaTfrukGrq6ueg0lmH4nqVnA2IPG0AEH3jKEk2GRJCUhDoqpoiw3PHLBA==} dev: false @@ -3455,7 +3311,6 @@ packages: engines: {node: '>=8.0'} dependencies: is-number: 7.0.0 - dev: false /tsconfig-paths/3.14.1: resolution: {integrity: sha512-fxDhWnFSLt3VuTwtvJt5fpwxBHg5AdKWMsgcPOOIilyjymcYVZoCQF8fvFRezCNfblEXmi+PcM1eYHeOAgXCOQ==} @@ -3501,22 +3356,6 @@ packages: engines: {node: '>=4.2.0'} hasBin: true - /ua-parser-js/0.7.31: - resolution: {integrity: sha512-qLK/Xe9E2uzmYI3qLeOmI0tEOt+TBBQyUIAh4aAgU05FVYzeZrKUdkAZfBNVGRaHVgV0TDkdEngJSw/SyQchkQ==} - dev: false - - /ui-box/5.1.0_react@18.2.0: - resolution: {integrity: sha512-3FYTKhYKu8JaZmg1+iYzrHUpZDtrAiIdhLBbaVV/u5TL6Zfg1U7OkI00eFJNASa/D+b0SwJjt5Ph6tzmcub1RQ==} - engines: {node: '>=12'} - peerDependencies: - react: ^16.0.0 || ^17.0.0 || ^18.0.0 - dependencies: - '@emotion/hash': 0.7.4 - inline-style-prefixer: 5.1.2 - prop-types: 15.8.1 - react: 18.2.0 - dev: false - /unbox-primitive/1.0.2: resolution: {integrity: sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==} dependencies: @@ -3525,13 +3364,13 @@ packages: has-symbols: 1.0.3 which-boxed-primitive: 1.0.2 - /update-browserslist-db/1.0.7_browserslist@4.21.3: - resolution: {integrity: sha512-iN/XYesmZ2RmmWAiI4Z5rq0YqSiv0brj9Ce9CfhNE4xIW2h+MFxcgkxIzZ+ShkFPUkjU3gQ+3oypadD3RAMtrg==} + /update-browserslist-db/1.0.9_browserslist@4.21.4: + resolution: {integrity: sha512-/xsqn21EGVdXI3EXSum1Yckj3ZVZugqyOZQ/CxYPBD/R+ko9NSUScf8tFF4dOKY+2pvSSJA/S+5B8s4Zr4kyvg==} hasBin: true peerDependencies: browserslist: '>= 4.21.0' dependencies: - browserslist: 4.21.3 + browserslist: 4.21.4 escalade: 3.1.1 picocolors: 1.0.0 dev: true @@ -3552,7 +3391,6 @@ packages: /util-deprecate/1.0.2: resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} - dev: true /uuid/2.0.3: resolution: {integrity: sha512-FULf7fayPdpASncVy4DLh3xydlXEJJpvIELjYjNeQWYUZ9pclcpvCZSr2gkmN2FrrGcI7G/cJsIEwk5/8vfXpg==} @@ -3569,16 +3407,16 @@ packages: engines: {node: '>= 0.10'} dev: false - /vite-plugin-environment/1.1.2_vite@3.1.0: + /vite-plugin-environment/1.1.2_vite@3.1.3: resolution: {integrity: sha512-WFgM/ibceOEIuficZVaLcmJvcMZiyTkGzeS8+pzfByGYRdewqil7LSLDV1DwJfFQIx/YzcW9YRSWQG7cJ2XT1w==} peerDependencies: vite: '>= 2.7' dependencies: - vite: 3.1.0 + vite: 3.1.3 dev: true - /vite/3.1.0: - resolution: {integrity: sha512-YBg3dUicDpDWFCGttmvMbVyS9ydjntwEjwXRj2KBFwSB8SxmGcudo1yb8FW5+M/G86aS8x828ujnzUVdsLjs9g==} + /vite/3.1.3: + resolution: {integrity: sha512-/3XWiktaopByM5bd8dqvHxRt5EEgRikevnnrpND0gRfNkrMrPaGGexhtLCzv15RcCMtV2CLw+BPas8YFeSG0KA==} engines: {node: ^14.18.0 || >=16.0.0} hasBin: true peerDependencies: @@ -3596,7 +3434,7 @@ packages: terser: optional: true dependencies: - esbuild: 0.15.7 + esbuild: 0.15.8 postcss: 8.4.16 resolve: 1.22.1 rollup: 2.78.1 @@ -3612,10 +3450,6 @@ packages: pbf: 3.2.1 dev: false - /whatwg-fetch/3.6.2: - resolution: {integrity: sha512-bJlen0FcuU/0EMLrdbJ7zOnW6ITZLrZMIarMUVmdKtsGvZna8vxKYaexICWPfZ8qwf9fzNq+UEIZrnSaApt6RA==} - dev: false - /which-boxed-primitive/1.0.2: resolution: {integrity: sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==} dependencies: @@ -3681,7 +3515,6 @@ packages: /xtend/4.0.2: resolution: {integrity: sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==} engines: {node: '>=0.4'} - dev: true /y18n/5.0.8: resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==} @@ -3691,6 +3524,10 @@ packages: /yallist/4.0.0: resolution: {integrity: sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==} + /yaml/1.10.2: + resolution: {integrity: sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==} + engines: {node: '>= 6'} + /yargs-parser/21.1.1: resolution: {integrity: sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==} engines: {node: '>=12'} diff --git a/postcss.config.js b/postcss.config.js new file mode 100644 index 00000000..33ad091d --- /dev/null +++ b/postcss.config.js @@ -0,0 +1,6 @@ +module.exports = { + plugins: { + tailwindcss: {}, + autoprefixer: {}, + }, +} diff --git a/src/App.tsx b/src/App.tsx index 2dee6056..119f6ba9 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -1,20 +1,37 @@ import type React from "react"; -import { Pane } from "evergreen-ui"; import { MapProvider } from "react-map-gl"; -import { AppLayout } from "@components/layout/AppLayout.js"; +import { useAppStore } from "@app/core/stores/appStore.js"; +import { DeviceWrapper } from "@app/DeviceWrapper.js"; +import { useDeviceStore } from "@core/stores/deviceStore.js"; +import { DeviceSelector } from "./components/DeviceSelector.js"; +import { NewDevice } from "./components/NewDevice.js"; +import { PageNav } from "./components/PageNav.js"; +import { Sidebar } from "./components/Sidebar.js"; import { PageRouter } from "./PageRouter.js"; export const App = (): JSX.Element => { + const { getDevice } = useDeviceStore(); + const { selectedDevice } = useAppStore(); + + const device = getDevice(selectedDevice); + return ( - - - - - - - +
+ + + {device && ( + + + + + + + + )} + {selectedDevice === 0 && } +
); }; diff --git a/src/DeviceWrapper.tsx b/src/DeviceWrapper.tsx index 95c56ee4..0e66bb1e 100644 --- a/src/DeviceWrapper.tsx +++ b/src/DeviceWrapper.tsx @@ -1,7 +1,7 @@ -import type React from "react"; +import type React from 'react'; -import { DeviceContext } from "@core/providers/useDevice.js"; -import type { Device } from "@core/stores/deviceStore.js"; +import { DeviceContext } from '@core/providers/useDevice.js'; +import type { Device } from '@core/stores/deviceStore.js'; export interface DeviceProps { children: React.ReactNode; diff --git a/src/PageRouter.tsx b/src/PageRouter.tsx index 6d92da18..7fec0523 100644 --- a/src/PageRouter.tsx +++ b/src/PageRouter.tsx @@ -1,12 +1,12 @@ import type React from "react"; import { useDevice } from "@core/providers/useDevice.js"; -import { ChannelsPage } from "@pages/Channels/index.js"; +import { ChannelsPage } from "@pages/Channels.js"; import { ConfigPage } from "@pages/Config/index.js"; import { ExtensionsPage } from "@pages/Extensions/Index.js"; -import { InfoPage } from "@pages/Info/index.js"; -import { MapPage } from "@pages/Map/index.js"; -import { MessagesPage } from "@pages/Messages/index.js"; +import { InfoPage } from "@pages/Info.js"; +import { MapPage } from "@pages/Map.js"; +import { MessagesPage } from "@pages/Messages.js"; export const PageRouter = (): JSX.Element => { const { activePage } = useDevice(); diff --git a/src/components/Button.tsx b/src/components/Button.tsx new file mode 100644 index 00000000..5c7d8652 --- /dev/null +++ b/src/components/Button.tsx @@ -0,0 +1,43 @@ +import type React from "react"; +import type { ButtonHTMLAttributes } from "react"; + +export interface ButtonProps extends ButtonHTMLAttributes { + size?: "sm" | "md" | "lg"; + variant?: "primary" | "secondary"; + iconBefore?: JSX.Element; + iconAfter?: JSX.Element; +} + +export const Button = ({ + size = "md", + variant = "primary", + iconBefore, + iconAfter, + children, + disabled, + ...rest +}: ButtonProps): JSX.Element => { + return ( + + ); +}; diff --git a/src/components/DeviceSelector.tsx b/src/components/DeviceSelector.tsx new file mode 100644 index 00000000..ceec6a08 --- /dev/null +++ b/src/components/DeviceSelector.tsx @@ -0,0 +1,48 @@ +import type React from "react"; + +import { useAppStore } from "@app/core/stores/appStore.js"; +import { useDeviceStore } from "@app/core/stores/deviceStore.js"; +import { Hashicon } from "@emeraldpay/hashicon-react"; +import { PlusIcon } from "@heroicons/react/24/outline"; + +export const DeviceSelector = (): JSX.Element => { + const { getDevices } = useDeviceStore(); + const { selectedDevice, setSelectedDevice } = useAppStore(); + + return ( +
+ Connected Devices + + {getDevices().map((device) => ( +
{ + setSelectedDevice(device.id); + }} + className="group flex w-8 h-8 p-0.5 cursor-pointer drop-shadow-md" + > + +
+
+ ))} +
{ + setSelectedDevice(0); + }} + className={`w-8 h-8 p-2 border-dashed border-2 rounded-md hover:border-orange-300 cursor-pointer ${ + selectedDevice === 0 ? "border-orange-400" : "border-slate-200" + }`} + > + +
+ + +
+ ); +}; diff --git a/src/components/Dialog/HelpDialog.tsx b/src/components/Dialog/HelpDialog.tsx deleted file mode 100644 index a7aa3808..00000000 --- a/src/components/Dialog/HelpDialog.tsx +++ /dev/null @@ -1,43 +0,0 @@ -import type React from "react"; - -import { CogIcon, CrossIcon, IconButton, Text } from "evergreen-ui"; - -import { TabbedContent, TabType } from "../layout/page/TabbedContent.js"; -import { Dialog } from "./index.js"; - -export interface HelpDialogProps { - isOpen: boolean; - close: () => void; -} - -export const HelpDialog = ({ isOpen, close }: HelpDialogProps): JSX.Element => { - const tabs: TabType[] = [ - { - name: "Device Config", - icon: CogIcon, - element: () => ( -
- Title -
- ), - }, - { - name: "Device Config", - icon: CogIcon, - element: () => ( -
- Title 2 -
- ), - }, - ]; - - return ( - - ]} - /> - - ); -}; diff --git a/src/components/Dialog/PeersDialog.tsx b/src/components/Dialog/PeersDialog.tsx deleted file mode 100644 index 979f7606..00000000 --- a/src/components/Dialog/PeersDialog.tsx +++ /dev/null @@ -1,126 +0,0 @@ -import type React from "react"; - -import { - HelperManagementIcon, - IconButton, - majorScale, - MoreIcon, - Table, - TagIcon, - Tooltip, -} from "evergreen-ui"; - -import { toMGRS } from "@app/core/utils/toMGRS.js"; -import { useDevice } from "@core/providers/useDevice.js"; -import { Hashicon } from "@emeraldpay/hashicon-react"; -import { Protobuf } from "@meshtastic/meshtasticjs"; - -import { Dialog } from "./index.js"; - -export interface PeersDialogProps { - isOpen: boolean; - close: () => void; -} - -export const PeersDialog = ({ - isOpen, - close, -}: PeersDialogProps): JSX.Element => { - const { hardware, nodes, connection, setPeerInfoOpen, setActivePeer } = - useDevice(); - - return ( - - - - - - Number - - - Name - - - SNR - - Location - Telemetry - Last Heard - Actions - - - {nodes - .filter((n) => n.data.num !== hardware.myNodeNum) - .map((node) => ( - { - setActivePeer(node.data.num); - setPeerInfoOpen(true); - }} - > - - - - - {node.data.num} - - - {node.data.user?.longName} - - - {node.data.snr} - - - {toMGRS( - node.data.position?.latitudeI, - node.data.position?.longitudeI - )} - - Tmp - - {new Date(node.data.lastHeard * 1000).toLocaleString()} - - - - - - { - void connection?.sendPacket( - Protobuf.AdminMessage.toBinary({ - payloadVariant: { - oneofKind: "getConfigRequest", - getConfigRequest: - Protobuf.AdminMessage_ConfigType.LORA_CONFIG, - }, - }), - Protobuf.PortNum.ADMIN_APP, - node.data.num, - true, - 7, - true, - false, - async (test) => { - console.log(test); - - console.log("got response"); - return Promise.resolve(); - } - ); - }} - /> - - - - ))} - -
-
- ); -}; diff --git a/src/components/Dialog/QRDialog.tsx b/src/components/Dialog/QRDialog.tsx index ff724985..466729d9 100644 --- a/src/components/Dialog/QRDialog.tsx +++ b/src/components/Dialog/QRDialog.tsx @@ -2,21 +2,14 @@ import type React from "react"; import { useEffect, useState } from "react"; import { fromByteArray } from "base64-js"; -import { - Checkbox, - ClipboardIcon, - FormField, - IconButton, - majorScale, - Pane, - TextInputField, - Tooltip, -} from "evergreen-ui"; import { QRCode } from "react-qrcode-logo"; +import { Dialog } from "@headlessui/react"; +import { ClipboardIcon } from "@heroicons/react/24/outline"; import { Protobuf } from "@meshtastic/meshtasticjs"; -import { Dialog } from "./index.js"; +import { Checkbox } from "../form/Checkbox.js"; +import { Input } from "../form/Input.js"; export interface QRDialogProps { isOpen: boolean; @@ -54,64 +47,65 @@ export const QRDialog = ({ }, [channels, selectedChannels, loraConfig]); return ( - // - - - - {channels.map((channel) => ( - { - if (selectedChannels.includes(channel.index)) { - setSelectedChannels( - selectedChannels.filter((c) => c !== channel.index) - ); - } else { - setSelectedChannels([...selectedChannels, channel.index]); - } - }} - /> - ))} - - - - - - - - - - - - - + + ); }; diff --git a/src/components/Dialog/RegionDialog.tsx b/src/components/Dialog/RegionDialog.tsx deleted file mode 100644 index e5b6ddb0..00000000 --- a/src/components/Dialog/RegionDialog.tsx +++ /dev/null @@ -1,69 +0,0 @@ -import type React from "react"; -import { useEffect, useState } from "react"; - -import { SelectField } from "evergreen-ui"; -import { useForm } from "react-hook-form"; - -import { LoRaValidation } from "@app/validation/config/lora.js"; -import { useDevice } from "@core/providers/useDevice.js"; -import { renderOptions } from "@core/utils/selectEnumOptions.js"; -import { classValidatorResolver } from "@hookform/resolvers/class-validator"; -import { Protobuf } from "@meshtastic/meshtasticjs"; - -import { Form } from "../form/Form.js"; -import { Dialog } from "./index.js"; - -export interface RegionDialogProps { - isOpen: boolean; -} - -export const RegionDialog = ({ isOpen }: RegionDialogProps): JSX.Element => { - const { config, connection } = useDevice(); - const [loading, setLoading] = useState(false); - const { - register, - handleSubmit, - formState: { errors, isDirty }, - reset, - } = useForm({ - defaultValues: config.lora, - resolver: classValidatorResolver(LoRaValidation), - }); - - useEffect(() => { - reset(config.lora); - }, [reset, config.lora]); - - const onSubmit = handleSubmit((data) => { - setLoading(true); - void connection?.setConfig( - { - payloadVariant: { - oneofKind: "lora", - lora: data, - }, - }, - async () => { - reset({ ...data }); - setLoading(false); - await Promise.resolve(); - } - ); - }); - - return ( - -
- - {renderOptions(Protobuf.Config_LoRaConfig_RegionCode)} - -
-
- ); -}; diff --git a/src/components/Dialog/index.tsx b/src/components/Dialog/index.tsx deleted file mode 100644 index 696e94c8..00000000 --- a/src/components/Dialog/index.tsx +++ /dev/null @@ -1,63 +0,0 @@ -import type React from "react"; - -import { - CrossIcon, - Heading, - IconButton, - majorScale, - Overlay, - Pane, -} from "evergreen-ui"; - -export interface DialogProps { - isOpen: boolean; - close: () => void; - title?: string; - background?: boolean; - width?: number; - children: React.ReactNode; -} - -export const Dialog = ({ - isOpen, - close, - title, - background, - width, - children, -}: DialogProps): JSX.Element => { - return ( - - - {background && ( - - {title} - - - )} - - {children} - - - ); -}; diff --git a/src/components/IconButton.tsx b/src/components/IconButton.tsx new file mode 100644 index 00000000..4bf9140c --- /dev/null +++ b/src/components/IconButton.tsx @@ -0,0 +1,33 @@ +import type React from "react"; +import type { ButtonHTMLAttributes } from "react"; + +export interface IconButtonProps + extends ButtonHTMLAttributes { + size?: "sm" | "md" | "lg"; + variant?: "primary" | "secondary"; + icon?: JSX.Element; +} + +export const IconButton = ({ + size = "md", + variant = "primary", + icon, + disabled, + ...rest +}: IconButtonProps): JSX.Element => { + return ( + + ); +}; diff --git a/src/components/NewDevice.tsx b/src/components/NewDevice.tsx new file mode 100644 index 00000000..8ae3c1a1 --- /dev/null +++ b/src/components/NewDevice.tsx @@ -0,0 +1,34 @@ +import type React from "react"; + +import { FiBluetooth, FiTerminal, FiWifi } from "react-icons/fi"; + +import { TabbedContent, TabType } from "./layout/page/TabbedContent.js"; +import { BLE } from "./PageComponents/Connect/BLE.js"; +import { HTTP } from "./PageComponents/Connect/HTTP.js"; +import { Serial } from "./PageComponents/Connect/Serial.js"; + +export const NewDevice = () => { + const tabs: TabType[] = [ + { + name: "BLE", + icon: , + element: BLE, + }, + { + name: "HTTP", + icon: , + element: HTTP, + }, + { + name: "Serial", + icon: , + element: Serial, + }, + ]; + + return ( +
+ +
+ ); +}; diff --git a/src/components/PageComponents/Channel.tsx b/src/components/PageComponents/Channel.tsx new file mode 100644 index 00000000..4bebfa45 --- /dev/null +++ b/src/components/PageComponents/Channel.tsx @@ -0,0 +1,198 @@ +import type React from "react"; +import { useEffect, useState } from "react"; + +import { fromByteArray, toByteArray } from "base64-js"; +import { Controller, useForm } from "react-hook-form"; + +import { Input } from "@app/components/form/Input.js"; +import { Form } from "@components/form/Form"; +import { useDevice } from "@core/providers/useDevice.js"; +import { + ArrowPathIcon, + EyeIcon, + EyeSlashIcon, +} from "@heroicons/react/24/outline"; +import { Protobuf } from "@meshtastic/meshtasticjs"; + +import { Select } from "../form/Select.js"; +import { Toggle } from "../form/Toggle.js"; + +export interface SettingsPanelProps { + channel: Protobuf.Channel; +} + +export const Channel = ({ channel }: SettingsPanelProps): JSX.Element => { + const { connection } = useDevice(); + const [loading, setLoading] = useState(false); + const [keySize, setKeySize] = useState<128 | 256>(256); + const [pskHidden, setPskHidden] = useState(true); + + const { + register, + handleSubmit, + formState: { errors, isDirty }, + reset, + control, + setValue, + } = useForm< + Omit & { psk: string; enabled: boolean } + >({ + defaultValues: { + enabled: [ + Protobuf.Channel_Role.SECONDARY, + Protobuf.Channel_Role.PRIMARY, + ].find((role) => role === channel?.role) + ? true + : false, + ...channel?.settings, + psk: fromByteArray(channel?.settings?.psk ?? new Uint8Array(0)), + }, + }); + + useEffect(() => { + reset({ + enabled: [ + Protobuf.Channel_Role.SECONDARY, + Protobuf.Channel_Role.PRIMARY, + ].find((role) => role === channel?.role) + ? true + : false, + ...channel?.settings, + psk: fromByteArray(channel?.settings?.psk ?? new Uint8Array(0)), + }); + }, [channel, reset]); + + const onSubmit = handleSubmit(async (data) => { + setLoading(true); + const channelData = Protobuf.Channel.create({ + role: + channel?.role === Protobuf.Channel_Role.PRIMARY + ? Protobuf.Channel_Role.PRIMARY + : data.enabled + ? Protobuf.Channel_Role.SECONDARY + : Protobuf.Channel_Role.DISABLED, + index: channel?.index, + settings: { + ...data, + psk: toByteArray(data.psk ?? ""), + }, + }); + + await connection?.setChannel(channelData, (): Promise => { + reset({ ...data }); + setLoading(false); + return Promise.resolve(); + }); + }); + + return ( +
+ reset({ + enabled: [ + Protobuf.Channel_Role.SECONDARY, + Protobuf.Channel_Role.PRIMARY, + ].find((role) => role === channel?.role) + ? true + : false, + ...channel?.settings, + psk: fromByteArray(channel?.settings?.psk ?? new Uint8Array(0)), + }) + } + loading={loading} + dirty={isDirty} + onSubmit={onSubmit} + > + {channel?.index !== 0 && ( + <> + ( + + )} + /> + + + )} + + + ) : ( + + ), + action: () => { + setPskHidden(!pskHidden); + }, + }} + {...register("psk")} + /> + ( + + )} + /> + ( + + )} + /> + + ); +}; diff --git a/src/components/PageComponents/Config/Bluetooth.tsx b/src/components/PageComponents/Config/Bluetooth.tsx index 7038a37b..d9ed83a1 100644 --- a/src/components/PageComponents/Config/Bluetooth.tsx +++ b/src/components/PageComponents/Config/Bluetooth.tsx @@ -1,9 +1,11 @@ import type React from "react"; import { useEffect, useState } from "react"; -import { FormField, SelectField, Switch, TextInputField } from "evergreen-ui"; import { Controller, useForm, useWatch } from "react-hook-form"; +import { Input } from "@app/components/form/Input.js"; +import { Select } from "@app/components/form/Select.js"; +import { Toggle } from "@app/components/form/Toggle.js"; import { BluetoothValidation } from "@app/validation/config/bluetooth.js"; import { Form } from "@components/form/Form"; import { useDevice } from "@core/providers/useDevice.js"; @@ -54,43 +56,41 @@ export const Bluetooth = (): JSX.Element => { }); return ( -
- - ( - - )} - /> - - - reset(config.bluetooth)} + loading={loading} + dirty={isDirty} + onSubmit={onSubmit} + > + ( + + )} + /> + - { }, }, async () => { - toaster.success("Successfully updated device config"); + // toaster.success("Successfully updated device config"); reset({ ...data }); setLoading(false); await Promise.resolve(); @@ -47,58 +48,45 @@ export const Device = (): JSX.Element => { ); }); return ( - - reset(config.device)} + loading={loading} + dirty={isDirty} + onSubmit={onSubmit} + > + + ( + + )} + /> + ( + + )} + /> ); }; diff --git a/src/components/PageComponents/Config/Display.tsx b/src/components/PageComponents/Config/Display.tsx index 411c765a..94c4cf4c 100644 --- a/src/components/PageComponents/Config/Display.tsx +++ b/src/components/PageComponents/Config/Display.tsx @@ -1,9 +1,11 @@ import type React from "react"; import { useEffect, useState } from "react"; -import { FormField, SelectField, Switch, TextInputField } from "evergreen-ui"; import { Controller, useForm } from "react-hook-form"; +import { Input } from "@app/components/form/Input.js"; +import { Select } from "@app/components/form/Select.js"; +import { Toggle } from "@app/components/form/Toggle.js"; import { DisplayValidation } from "@app/validation/config/display.js"; import { Form } from "@components/form/Form"; import { useDevice } from "@core/providers/useDevice.js"; @@ -46,42 +48,47 @@ export const Display = (): JSX.Element => { ); }); return ( -
- reset(config.display)} + loading={loading} + dirty={isDirty} + onSubmit={onSubmit} + > + - - {renderOptions(Protobuf.Config_DisplayConfig_GpsCoordinateFormat)} - - - ( - - )} - /> - + + ( + + )} + /> ); }; diff --git a/src/components/PageComponents/Config/LoRa.tsx b/src/components/PageComponents/Config/LoRa.tsx index 2dd35e33..478ac559 100644 --- a/src/components/PageComponents/Config/LoRa.tsx +++ b/src/components/PageComponents/Config/LoRa.tsx @@ -1,9 +1,11 @@ import type React from "react"; import { useEffect, useState } from "react"; -import { FormField, SelectField, Switch, TextInputField } from "evergreen-ui"; -import { Controller, useForm } from "react-hook-form"; +import { Controller, useForm, useWatch } from "react-hook-form"; +import { Input } from "@app/components/form/Input.js"; +import { Select } from "@app/components/form/Select.js"; +import { Toggle } from "@app/components/form/Toggle.js"; import { LoRaValidation } from "@app/validation/config/lora.js"; import { Form } from "@components/form/Form"; import { useDevice } from "@core/providers/useDevice.js"; @@ -14,7 +16,6 @@ import { Protobuf } from "@meshtastic/meshtasticjs"; export const LoRa = (): JSX.Element => { const { config, connection } = useDevice(); const [loading, setLoading] = useState(false); - const [usePreset, setUsePreset] = useState(true); const { register, @@ -27,6 +28,12 @@ export const LoRa = (): JSX.Element => { resolver: classValidatorResolver(LoRaValidation), }); + const usePreset = useWatch({ + control, + name: "usePreset", + defaultValue: true, + }); + useEffect(() => { reset(config.lora); }, [reset, config.lora]); @@ -49,115 +56,109 @@ export const LoRa = (): JSX.Element => { }); return ( -
- - setUsePreset(e.target.checked)} - /> - - reset(config.lora)} + loading={loading} + dirty={isDirty} + onSubmit={onSubmit} + > + ( + + )} + /> + - - - - - - - ( - - )} - /> - - - {renderOptions(Protobuf.Config_LoRaConfig_RegionCode)} - + + + ( + + )} + /> + ); }; diff --git a/src/components/PageComponents/Config/Network.tsx b/src/components/PageComponents/Config/Network.tsx index 0d2e84b9..f10987e4 100644 --- a/src/components/PageComponents/Config/Network.tsx +++ b/src/components/PageComponents/Config/Network.tsx @@ -1,15 +1,11 @@ import type React from "react"; import { useEffect, useState } from "react"; -import { - FormField, - SelectField, - Switch, - TextInputField, - toaster, -} from "evergreen-ui"; import { Controller, useForm, useWatch } from "react-hook-form"; +import { Input } from "@app/components/form/Input.js"; +import { Select } from "@app/components/form/Select.js"; +import { Toggle } from "@app/components/form/Toggle.js"; import { renderOptions } from "@app/core/utils/selectEnumOptions.js"; import { NetworkValidation } from "@app/validation/config/network.js"; import { Form } from "@components/form/Form"; @@ -51,7 +47,7 @@ export const Network = (): JSX.Element => { }, }, async () => { - toaster.success("Successfully updated Network config"); + // toaster.success("Successfully updated Network config"); reset({ ...data }); setLoading(false); await Promise.resolve(); @@ -59,48 +55,53 @@ export const Network = (): JSX.Element => { ); }); return ( -
- - ( - - )} - /> - - reset(config.network)} + loading={loading} + dirty={isDirty} + onSubmit={onSubmit} + > + ( + + )} + /> + - - diff --git a/src/components/PageComponents/Config/Position.tsx b/src/components/PageComponents/Config/Position.tsx index c68502a5..ac191d95 100644 --- a/src/components/PageComponents/Config/Position.tsx +++ b/src/components/PageComponents/Config/Position.tsx @@ -1,21 +1,14 @@ import type React from "react"; import { useEffect, useState } from "react"; -import { - Button, - FormField, - SelectMenu, - Switch, - TextInputField, -} from "evergreen-ui"; import { Controller, useForm } from "react-hook-form"; +import { Input } from "@app/components/form/Input.js"; +import { Toggle } from "@app/components/form/Toggle.js"; import { PositionValidation } from "@app/validation/config/position.js"; import { Form } from "@components/form/Form"; import { useDevice } from "@core/providers/useDevice.js"; -import { bitwiseDecode } from "@core/utils/bitwise"; import { classValidatorResolver } from "@hookform/resolvers/class-validator"; -import { Protobuf } from "@meshtastic/meshtasticjs"; export const Position = (): JSX.Element => { const { config, connection } = useDevice(); @@ -29,15 +22,6 @@ export const Position = (): JSX.Element => { } = useForm({ defaultValues: config.position, resolver: classValidatorResolver(PositionValidation), - // defaultValues: { - // ...preferences, - // positionBroadcastSecs: - // preferences.positionBroadcastSecs === 0 - // ? preferences.role === Protobuf.Role.Router - // ? 43200 - // : 900 - // : preferences.positionBroadcastSecs, - // }, }); useEffect(() => { @@ -62,76 +46,74 @@ export const Position = (): JSX.Element => { }); return ( -
- reset(config.position)} + loading={loading} + dirty={isDirty} + onSubmit={onSubmit} + > + - - ( - - )} - /> - - - ( - - )} - /> - - - ( - - )} - /> - - ( + + )} + /> + ( + + )} + /> + ( + + )} + /> + - - { @@ -218,7 +200,7 @@ export const Position = (): JSX.Element => { ); }} - /> + /> */} ); }; diff --git a/src/components/PageComponents/Config/Power.tsx b/src/components/PageComponents/Config/Power.tsx index eef14bbf..57f9b04e 100644 --- a/src/components/PageComponents/Config/Power.tsx +++ b/src/components/PageComponents/Config/Power.tsx @@ -1,9 +1,10 @@ import type React from "react"; import { useEffect, useState } from "react"; -import { FormField, Switch, TextInputField } from "evergreen-ui"; import { Controller, useForm } from "react-hook-form"; +import { Input } from "@app/components/form/Input.js"; +import { Toggle } from "@app/components/form/Toggle.js"; import { PowerValidation } from "@app/validation/config/power.js"; import { Form } from "@components/form/Form"; import { useDevice } from "@core/providers/useDevice.js"; @@ -44,81 +45,79 @@ export const Power = (): JSX.Element => { ); }); return ( -
- reset(config.power)} + loading={loading} + dirty={isDirty} + onSubmit={onSubmit} + > + - - ( - - )} - /> - - ( + + )} + /> + - - - - - diff --git a/src/components/PageComponents/Config/User.tsx b/src/components/PageComponents/Config/User.tsx index 4346f19e..899de283 100644 --- a/src/components/PageComponents/Config/User.tsx +++ b/src/components/PageComponents/Config/User.tsx @@ -1,10 +1,12 @@ import type React from "react"; import { useEffect, useState } from "react"; -import { FormField, SelectField, Switch, TextInputField } from "evergreen-ui"; import { Controller, useForm } from "react-hook-form"; import { base16 } from "rfc4648"; +import { Input } from "@app/components/form/Input.js"; +import { Select } from "@app/components/form/Select.js"; +import { Toggle } from "@app/components/form/Toggle.js"; import { UserValidation } from "@app/validation/config/user.js"; import { Form } from "@components/form/Form"; import { useDevice } from "@core/providers/useDevice.js"; @@ -50,27 +52,39 @@ export const User = (): JSX.Element => { }); return ( -
- { + reset({ + longName: myNode?.data.user?.longName, + shortName: myNode?.data.user?.shortName, + isLicensed: myNode?.data.user?.isLicensed, + }); + }} + loading={loading} + dirty={isDirty} + onSubmit={onSubmit} + > + - - - { ?.join(":") ?? "" } /> - {renderOptions(Protobuf.HardwareModel)} - - - ( - - )} - /> - + + ( + + )} + /> ); }; diff --git a/src/components/SlideSheets/tabs/connect/BLE.tsx b/src/components/PageComponents/Connect/BLE.tsx similarity index 69% rename from src/components/SlideSheets/tabs/connect/BLE.tsx rename to src/components/PageComponents/Connect/BLE.tsx index 6341e024..3177d4ec 100644 --- a/src/components/SlideSheets/tabs/connect/BLE.tsx +++ b/src/components/PageComponents/Connect/BLE.tsx @@ -1,17 +1,15 @@ import type React from "react"; import { useCallback, useEffect, useState } from "react"; -import { Button, majorScale, Pane } from "evergreen-ui"; -import { FiPlusCircle } from "react-icons/fi"; - -import type { CloseProps } from "@components/SlideSheets/NewDevice.js"; +import { Button } from "@components/Button.js"; import { useAppStore } from "@core/stores/appStore.js"; import { useDeviceStore } from "@core/stores/deviceStore.js"; import { subscribeAll } from "@core/subscriptions.js"; import { randId } from "@core/utils/randId.js"; +import { PlusCircleIcon } from "@heroicons/react/24/outline"; import { Constants, IBLEConnection } from "@meshtastic/meshtasticjs"; -export const BLE = ({ close }: CloseProps): JSX.Element => { +export const BLE = (): JSX.Element => { const [bleDevices, setBleDevices] = useState([]); const { addDevice } = useDeviceStore(); const { setSelectedDevice } = useAppStore(); @@ -34,30 +32,25 @@ export const BLE = ({ close }: CloseProps): JSX.Element => { }); device.addConnection(connection); subscribeAll(device, connection); - close(); }; return ( - - {bleDevices.map((device, index) => ( - - ))} - +
+
+ {bleDevices.map((device, index) => ( + + ))} +
- +
); }; diff --git a/src/components/SlideSheets/tabs/connect/HTTP.tsx b/src/components/PageComponents/Connect/HTTP.tsx similarity index 54% rename from src/components/SlideSheets/tabs/connect/HTTP.tsx rename to src/components/PageComponents/Connect/HTTP.tsx index 375f98f9..18369e53 100644 --- a/src/components/SlideSheets/tabs/connect/HTTP.tsx +++ b/src/components/PageComponents/Connect/HTTP.tsx @@ -1,27 +1,18 @@ import type React from "react"; -import { - Button, - FormField, - majorScale, - Pane, - Switch, - TextInputField, -} from "evergreen-ui"; -import { Controller, useForm } from "react-hook-form"; -import { FiPlusCircle } from "react-icons/fi"; +import { Controller, useForm, useWatch } from "react-hook-form"; +import { Input } from "@app/components/form/Input.js"; +import { Toggle } from "@app/components/form/Toggle.js"; +import { Button } from "@components/Button.js"; import { useAppStore } from "@core/stores/appStore.js"; import { useDeviceStore } from "@core/stores/deviceStore.js"; import { subscribeAll } from "@core/subscriptions.js"; import { randId } from "@core/utils/randId.js"; +import { PlusCircleIcon } from "@heroicons/react/24/outline"; import { IHTTPConnection } from "@meshtastic/meshtasticjs"; -export interface HTTPProps { - close: () => void; -} - -export const HTTP = ({ close }: HTTPProps): JSX.Element => { +export const HTTP = (): JSX.Element => { const { addDevice } = useDeviceStore(); const { setSelectedDevice } = useAppStore(); const { register, handleSubmit, control } = useForm<{ @@ -34,6 +25,12 @@ export const HTTP = ({ close }: HTTPProps): JSX.Element => { }, }); + const TLSEnabled = useWatch({ + control, + name: "tls", + defaultValue: false, + }); + const onSubmit = handleSubmit((data) => { const id = randId(); const device = addDevice(id); @@ -47,42 +44,34 @@ export const HTTP = ({ close }: HTTPProps): JSX.Element => { }); device.addConnection(connection); subscribeAll(device, connection); - close(); }); return ( // eslint-disable-next-line @typescript-eslint/no-misused-promises -
- - +
+ - - ( - - )} - /> - - - + ( + + )} + /> +
+ ); }; diff --git a/src/components/SlideSheets/tabs/connect/Serial.tsx b/src/components/PageComponents/Connect/Serial.tsx similarity index 58% rename from src/components/SlideSheets/tabs/connect/Serial.tsx rename to src/components/PageComponents/Connect/Serial.tsx index f67ffb34..a74f0762 100644 --- a/src/components/SlideSheets/tabs/connect/Serial.tsx +++ b/src/components/PageComponents/Connect/Serial.tsx @@ -1,14 +1,12 @@ import type React from "react"; import { useCallback, useEffect, useState } from "react"; -import { Button, majorScale, Pane } from "evergreen-ui"; -import { FiPlusCircle } from "react-icons/fi"; - -import type { CloseProps } from "@components/SlideSheets/NewDevice.js"; +import { Button } from "@components/Button.js"; import { useAppStore } from "@core/stores/appStore.js"; import { useDeviceStore } from "@core/stores/deviceStore.js"; import { subscribeAll } from "@core/subscriptions.js"; import { randId } from "@core/utils/randId.js"; +import { PlusCircleIcon } from "@heroicons/react/24/outline"; import { ISerialConnection } from "@meshtastic/meshtasticjs"; interface USBID { @@ -16,7 +14,7 @@ interface USBID { name: string; } -export const Serial = ({ close }: CloseProps): JSX.Element => { +export const Serial = (): JSX.Element => { const [serialPorts, setSerialPorts] = useState([]); const { addDevice } = useDeviceStore(); const { setSelectedDevice } = useAppStore(); @@ -45,50 +43,25 @@ export const Serial = ({ close }: CloseProps): JSX.Element => { }); device.addConnection(connection); subscribeAll(device, connection); - close(); }; - const VID: USBID[] = [ - { - id: 9114, - name: "TBA", - }, - ]; - - const PID: USBID[] = [ - { - id: 32809, - name: "TBA", - }, - ]; - return ( - - {serialPorts.map((port, index) => ( - - ))} - +
+
+ {serialPorts.map((port, index) => ( + + ))} +
- +
); }; diff --git a/src/components/PageComponents/Messages/ChannelChat.tsx b/src/components/PageComponents/Messages/ChannelChat.tsx new file mode 100644 index 00000000..53b5186d --- /dev/null +++ b/src/components/PageComponents/Messages/ChannelChat.tsx @@ -0,0 +1,85 @@ +import type React from "react"; +import { ChangeEvent, useState } from "react"; + +import { Input } from "@app/components/form/Input.js"; +import { IconButton } from "@app/components/IconButton.js"; +import { Message } from "@components/PageComponents/Messages/Message.js"; +import { useDevice } from "@core/providers/useDevice.js"; +import type { Channel } from "@core/stores/deviceStore.js"; +import { MapPinIcon, PaperAirplaneIcon } from "@heroicons/react/24/outline"; + +export interface ChannelChatProps { + channel: Channel; +} + +export const ChannelChat = ({ channel }: ChannelChatProps): JSX.Element => { + const { nodes, connection, ackMessage } = useDevice(); + const [currentMessage, setCurrentMessage] = useState(""); + + const sendMessage = (): void => { + void connection?.sendText( + currentMessage, + undefined, + true, + channel.config.index, + (id) => { + ackMessage(channel.config.index, id); + return Promise.resolve(); + } + ); + setCurrentMessage(""); + }; + + return ( +
+
+ {channel.messages.map((message, index) => ( + node.data.num === message.packet.from)?.data + } + /> + ))} +
+
+
{ + e.preventDefault(); + sendMessage(); + }} + > +
+ + ): void => { + setCurrentMessage(e.target.value); + }} + /> + + } + /> +
+
+ } + /> +
+
+ ); +}; diff --git a/src/components/PageComponents/Messages/Message.tsx b/src/components/PageComponents/Messages/Message.tsx new file mode 100644 index 00000000..b29a1c92 --- /dev/null +++ b/src/components/PageComponents/Messages/Message.tsx @@ -0,0 +1,89 @@ +import type React from "react"; + +import { WaypointMessage } from "@components/PageComponents/Messages/WaypointMessage.js"; +import { useDevice } from "@core/providers/useDevice.js"; +import type { AllMessageTypes } from "@core/stores/deviceStore.js"; +import { Hashicon } from "@emeraldpay/hashicon-react"; +import { + CheckCircleIcon, + EllipsisHorizontalCircleIcon, +} from "@heroicons/react/24/outline"; +import type { Protobuf } from "@meshtastic/meshtasticjs"; + +export interface MessageProps { + lastMsgSameUser: boolean; + message: AllMessageTypes; + sender?: Protobuf.NodeInfo; +} + +export const Message = ({ + lastMsgSameUser, + message, + sender, +}: MessageProps): JSX.Element => { + const { setPeerInfoOpen, setActivePeer } = useDevice(); + + const openPeer = (): void => { + setActivePeer(message.packet.from); + setPeerInfoOpen(true); + }; + + return lastMsgSameUser ? ( +
+ {message.ack ? ( + + ) : ( + + )} + {"waypointID" in message ? ( + + ) : ( + + {message.text} + + )} +
+ ) : ( +
+
+
+ +
+ + {sender?.user?.longName ?? "UNK"} + + + {new Date(message.packet.rxTime).toLocaleTimeString(undefined, { + hour: "2-digit", + minute: "2-digit", + })} + +
+
+ {message.ack ? ( + + ) : ( + + )} + {"waypointID" in message ? ( + + ) : ( + + {message.text} + + )} +
+
+ ); +}; diff --git a/src/pages/Messages/NewLocationMessage.tsx b/src/components/PageComponents/Messages/NewLocationMessage.tsx similarity index 70% rename from src/pages/Messages/NewLocationMessage.tsx rename to src/components/PageComponents/Messages/NewLocationMessage.tsx index 56096b84..41e8f100 100644 --- a/src/pages/Messages/NewLocationMessage.tsx +++ b/src/components/PageComponents/Messages/NewLocationMessage.tsx @@ -1,13 +1,8 @@ import type React from "react"; -import { - Button, - majorScale, - Pane, - SelectField, - TextInputField, -} from "evergreen-ui"; - +import { Input } from "@app/components/form/Input.js"; +import { Select } from "@app/components/form/Select.js"; +import { Button } from "@components/Button.js"; import { useDevice } from "@core/providers/useDevice.js"; import { renderOptions } from "@core/utils/selectEnumOptions.js"; import { Protobuf } from "@meshtastic/meshtasticjs"; @@ -22,20 +17,19 @@ export const NewLocationMessage = (): JSX.Element => { const { connection } = useDevice(); return ( - +
{ e.preventDefault(); }} > - - - + + + + - +
); }; diff --git a/src/components/PageComponents/Messages/WaypointMessage.tsx b/src/components/PageComponents/Messages/WaypointMessage.tsx new file mode 100644 index 00000000..3b993769 --- /dev/null +++ b/src/components/PageComponents/Messages/WaypointMessage.tsx @@ -0,0 +1,33 @@ +import type React from "react"; + +import { useDevice } from "@app/core/providers/useDevice.js"; +import { toMGRS } from "@core/utils/toMGRS.js"; +import { MapPinIcon } from "@heroicons/react/24/outline"; + +export interface WaypointMessageProps { + waypointID: number; +} + +export const WaypointMessage = ({ + waypointID, +}: WaypointMessageProps): JSX.Element => { + const { waypoints } = useDevice(); + const waypoint = waypoints.find((wp) => wp.id === waypointID); + + return ( +
+
+ +
+
+
{waypoint?.name}
+ + {toMGRS(waypoint?.latitudeI, waypoint?.longitudeI)} + +
+ {waypoint?.description} +
+
+
+ ); +}; diff --git a/src/components/PageComponents/ModuleConfig/CannedMessage.tsx b/src/components/PageComponents/ModuleConfig/CannedMessage.tsx index 4cacf614..1ce5640f 100644 --- a/src/components/PageComponents/ModuleConfig/CannedMessage.tsx +++ b/src/components/PageComponents/ModuleConfig/CannedMessage.tsx @@ -1,9 +1,11 @@ import type React from "react"; import { useEffect, useState } from "react"; -import { FormField, SelectField, Switch, TextInputField } from "evergreen-ui"; import { Controller, useForm, useWatch } from "react-hook-form"; +import { Input } from "@app/components/form/Input.js"; +import { Select } from "@app/components/form/Select.js"; +import { Toggle } from "@app/components/form/Toggle.js"; import { CannedMessageValidation } from "@app/validation/moduleConfig/cannedMessage.js"; import { Form } from "@components/form/Form"; import { useDevice } from "@core/providers/useDevice.js"; @@ -52,57 +54,60 @@ export const CannedMessage = (): JSX.Element => { ); }); return ( -
- - ( - - )} - /> - - - ( - - )} - /> - - reset(moduleConfig.cannedMessage)} + loading={loading} + dirty={isDirty} + onSubmit={onSubmit} + > + ( + + )} + /> + ( + + )} + /> + - - - { {renderOptions( Protobuf.ModuleConfig_CannedMessageConfig_InputEventChar )} - - + { {renderOptions( Protobuf.ModuleConfig_CannedMessageConfig_InputEventChar )} - - - ( - - )} - /> - - + ( + + )} + /> + - - ( - - )} - /> - + ( + + )} + /> ); }; diff --git a/src/components/PageComponents/ModuleConfig/ExternalNotification.tsx b/src/components/PageComponents/ModuleConfig/ExternalNotification.tsx index 6209e982..cbb32f8e 100644 --- a/src/components/PageComponents/ModuleConfig/ExternalNotification.tsx +++ b/src/components/PageComponents/ModuleConfig/ExternalNotification.tsx @@ -1,9 +1,10 @@ import type React from "react"; import { useEffect, useState } from "react"; -import { FormField, Switch, TextInputField } from "evergreen-ui"; import { Controller, useForm, useWatch } from "react-hook-form"; +import { Input } from "@app/components/form/Input.js"; +import { Toggle } from "@app/components/form/Toggle.js"; import { ExternalNotificationValidation } from "@app/validation/moduleConfig/externalNotification.js"; import { Form } from "@components/form/Form"; import { useDevice } from "@core/providers/useDevice.js"; @@ -50,32 +51,37 @@ export const ExternalNotification = (): JSX.Element => { }); return ( -
- - ( - - )} - /> - - reset(moduleConfig.externalNotification)} + loading={loading} + dirty={isDirty} + onSubmit={onSubmit} + > + ( + + )} + /> + - { valueAsNumber: true, })} /> - - ( - - )} - /> - - - ( - - )} - /> - - - ( - - )} - /> - + ( + + )} + /> + ( + + )} + /> + ( + + )} + /> ); }; diff --git a/src/components/PageComponents/ModuleConfig/MQTT.tsx b/src/components/PageComponents/ModuleConfig/MQTT.tsx index 5569edeb..a5649431 100644 --- a/src/components/PageComponents/ModuleConfig/MQTT.tsx +++ b/src/components/PageComponents/ModuleConfig/MQTT.tsx @@ -1,9 +1,10 @@ import type React from "react"; import { useEffect, useState } from "react"; -import { FormField, Switch, TextInputField } from "evergreen-ui"; import { Controller, useForm, useWatch } from "react-hook-form"; +import { Input } from "@app/components/form/Input.js"; +import { Toggle } from "@app/components/form/Toggle.js"; import { MQTTValidation } from "@app/validation/moduleConfig/mqtt.js"; import { Form } from "@components/form/Form"; import { useDevice } from "@core/providers/useDevice.js"; @@ -50,34 +51,39 @@ export const MQTT = (): JSX.Element => { ); }); return ( -
- - ( - - )} - /> - - reset(moduleConfig.mqtt)} + loading={loading} + dirty={isDirty} + onSubmit={onSubmit} + > + ( + + )} + /> + - - { disabled={!moduleEnabled} {...register("password")} /> - - ( - - )} - /> - - - ( - - )} - /> - + ( + + )} + /> + ( + + )} + /> ); }; diff --git a/src/components/PageComponents/ModuleConfig/RangeTest.tsx b/src/components/PageComponents/ModuleConfig/RangeTest.tsx index 2a452763..3615b91b 100644 --- a/src/components/PageComponents/ModuleConfig/RangeTest.tsx +++ b/src/components/PageComponents/ModuleConfig/RangeTest.tsx @@ -1,9 +1,10 @@ import type React from "react"; import { useEffect, useState } from "react"; -import { FormField, Switch, TextInputField } from "evergreen-ui"; import { Controller, useForm, useWatch } from "react-hook-form"; +import { Input } from "@app/components/form/Input.js"; +import { Toggle } from "@app/components/form/Toggle.js"; import { RangeTestValidation } from "@app/validation/moduleConfig/rangeTest.js"; import { Form } from "@components/form/Form"; import { useDevice } from "@core/providers/useDevice.js"; @@ -51,46 +52,48 @@ export const RangeTest = (): JSX.Element => { }); return ( -
- - ( - - )} - /> - - reset(moduleConfig.rangeTest)} + loading={loading} + dirty={isDirty} + onSubmit={onSubmit} + > + ( + + )} + /> + - - ( - - )} - /> - + ( + + )} + /> ); }; diff --git a/src/components/PageComponents/ModuleConfig/Serial.tsx b/src/components/PageComponents/ModuleConfig/Serial.tsx index 39e7691d..72369216 100644 --- a/src/components/PageComponents/ModuleConfig/Serial.tsx +++ b/src/components/PageComponents/ModuleConfig/Serial.tsx @@ -1,9 +1,10 @@ import type React from "react"; import { useEffect, useState } from "react"; -import { FormField, Switch, TextInputField } from "evergreen-ui"; import { Controller, useForm, useWatch } from "react-hook-form"; +import { Input } from "@app/components/form/Input.js"; +import { Toggle } from "@app/components/form/Toggle.js"; import { SerialValidation } from "@app/validation/moduleConfig/serial.js"; import { Form } from "@components/form/Form"; import { useDevice } from "@core/providers/useDevice.js"; @@ -51,37 +52,39 @@ export const Serial = (): JSX.Element => { }); return ( -
- - ( - - )} - /> - - - ( - - )} - /> - - reset(moduleConfig.serial)} + loading={loading} + dirty={isDirty} + onSubmit={onSubmit} + > + ( + + )} + /> + ( + + )} + /> + { valueAsNumber: true, })} /> - { valueAsNumber: true, })} /> - { valueAsNumber: true, })} /> - { valueAsNumber: true, })} /> - { }); return ( - - - ( - - )} - /> - - - ( - - )} - /> - - reset(moduleConfig.storeForward)} + loading={loading} + dirty={isDirty} + onSubmit={onSubmit} + > + ( + + )} + /> + ( + + )} + /> + - { valueAsNumber: true, })} /> - { ); }); return ( - - - ( - - )} - /> - - - ( - - )} - /> - - reset(moduleConfig.telemetry)} + loading={loading} + dirty={isDirty} + onSubmit={onSubmit} + > + ( + + )} + /> + ( + + )} + /> + - - ( - - )} - /> - + ( + + )} + /> ); }; diff --git a/src/components/PageNav.tsx b/src/components/PageNav.tsx new file mode 100644 index 00000000..564611e5 --- /dev/null +++ b/src/components/PageNav.tsx @@ -0,0 +1,77 @@ +import type React from "react"; + +import { useDevice } from "@app/core/providers/useDevice.js"; +import type { Page } from "@app/core/stores/deviceStore.js"; +import { + BeakerIcon, + Cog8ToothIcon, + IdentificationIcon, + InboxIcon, + MapIcon, + Square3Stack3DIcon, +} from "@heroicons/react/24/outline"; + +export const PageNav = (): JSX.Element => { + const { activePage, setActivePage } = useDevice(); + + interface NavLink { + name: string; + icon: JSX.Element; + page: Page; + } + + const pages: NavLink[] = [ + { + name: "Messages", + icon: , + page: "messages", + }, + { + name: "Map", + icon: , + page: "map", + }, + { + name: "Extensions", + icon: , + page: "extensions", + }, + { + name: "Config", + icon: , + page: "config", + }, + { + name: "Channels", + icon: , + page: "channels", + }, + { + name: "Info", + icon: , + page: "info", + }, + ]; + + return ( +
+ + {pages.map((Link) => ( +
{ + setActivePage(Link.page); + }} + className={`w-8 h-8 p-1 border-2 rounded-md hover:border-orange-300 cursor-pointer ${ + Link.page === activePage + ? "border-orange-400" + : "border-slate-200" + }`} + > + {Link.icon} +
+ ))} +
+
+ ); +}; diff --git a/src/components/Progress.tsx b/src/components/Progress.tsx deleted file mode 100644 index da38d3d7..00000000 --- a/src/components/Progress.tsx +++ /dev/null @@ -1,109 +0,0 @@ -import React, { useEffect } from "react"; - -import { - Button, - majorScale, - Pane, - ResetIcon, - Spinner, - StatusIndicator, -} from "evergreen-ui"; - -import { useDevice } from "@core/providers/useDevice.js"; - -export const Progress = (): JSX.Element => { - const { - hardware, - channels, - config, - moduleConfig, - setReady, - nodes, - connection, - } = useDevice(); - - useEffect(() => { - if ( - hardware.myNodeNum !== 0 && - Object.keys(config).length === 7 && - Object.keys(moduleConfig).length === 7 && - channels.length === hardware.maxChannels - ) { - setReady(true); - } - }, [ - config, - moduleConfig, - channels, - hardware.maxChannels, - hardware.myNodeNum, - setReady, - ]); - return ( - - - - - - - - - Device Info - - - Peers ({nodes.length}) - - - Device Config {`(${Object.keys(config).length - 1} / 6)`} - - - Module Config {`(${Object.keys(moduleConfig).length - 1} / 6)`} - - 0 && channels.length === hardware.maxChannels - ? "success" - : "disabled" - } - > - Channels{" "} - {hardware.myNodeNum !== 0 && - `(${channels.length} / ${hardware.maxChannels})`} - - - - - - - ); -}; diff --git a/src/components/Sidebar.tsx b/src/components/Sidebar.tsx new file mode 100644 index 00000000..f6e524c8 --- /dev/null +++ b/src/components/Sidebar.tsx @@ -0,0 +1,80 @@ +import type React from "react"; + +import { useDevice } from "@app/core/providers/useDevice.js"; +import { useAppStore } from "@core/stores/appStore.js"; +import { useDeviceStore } from "@core/stores/deviceStore.js"; +import { Types } from "@meshtastic/meshtasticjs"; + +import { ConfiguringWidget } from "./Widgets/ConfiguringWidget.js"; +import { DeviceWidget } from "./Widgets/DeviceWidget.js"; +import { NodeInfoWidget } from "./Widgets/NodeInfoWidget.js"; +import { PeersWidget } from "./Widgets/PeersWidget.js"; +import { PositionWidget } from "./Widgets/PositionWidget.js"; + +export const Sidebar = (): JSX.Element => { + const { removeDevice } = useDeviceStore(); + const { connection, hardware, nodes, status } = useDevice(); + const { selectedDevice, setSelectedDevice } = useAppStore(); + + return ( +
+ n.data.num === hardware.myNodeNum)?.data.user + ?.longName ?? "UNK" + } + nodeNum={hardware.myNodeNum.toString()} + disconnected={status === Types.DeviceStatusEnum.DEVICE_DISCONNECTED} + disconnect={() => { + void connection?.disconnect(); + setSelectedDevice(0); + removeDevice(selectedDevice ?? 0); + }} + reconnect={() => { + console.log(""); + }} + /> + + {/*
+

+ Their Side +

+

+ Conversations with the most tragically misunderstood people of our + time. +

+
*/} + + {/* */} + {/* */} + {/* */} + {/* */} +
+
+

Information

+
+
+
Firmware version
+
+ {hardware.firmwareVersion} +
+
+
+
+
Bitrate
+
+ {hardware.bitrate.toFixed(2)} + bps +
+
+
+ + {/* */} + + + + +
+
+ ); +}; diff --git a/src/components/SlideSheets/NewDevice.tsx b/src/components/SlideSheets/NewDevice.tsx deleted file mode 100644 index 7774ea76..00000000 --- a/src/components/SlideSheets/NewDevice.tsx +++ /dev/null @@ -1,114 +0,0 @@ -import type React from "react"; -import { useState } from "react"; - -import { - Heading, - majorScale, - Pane, - Paragraph, - SideSheet, - Tab, - Tablist, -} from "evergreen-ui"; -import { FiBluetooth, FiTerminal, FiWifi } from "react-icons/fi"; - -import type { TabType } from "@components/layout/page/TabbedContent.js"; -import { BLE } from "@components/SlideSheets/tabs/connect/BLE.js"; -import { HTTP } from "@components/SlideSheets/tabs/connect/HTTP.js"; -import { Serial } from "@components/SlideSheets/tabs/connect/Serial.js"; - -export interface NewDeviceProps { - open: boolean; - onClose: () => void; -} - -export interface CloseProps { - close: () => void; -} - -export type connType = "http" | "ble" | "serial"; - -export interface ConnTab extends Omit { - connType: connType; - element: ({ close }: CloseProps) => JSX.Element; -} - -export const NewDevice = ({ open, onClose }: NewDeviceProps) => { - const [selectedConnType, setSelectedConnType] = useState("ble"); - - const tabs: ConnTab[] = [ - { - connType: "ble", - icon: FiBluetooth, - name: "BLE", - element: BLE, - disabled: !navigator.bluetooth, - }, - { - connType: "http", - icon: FiWifi, - name: "HTTP", - element: HTTP, - }, - { - connType: "serial", - icon: FiTerminal, - name: "Serial", - element: Serial, - disabled: !navigator.serial, - }, - ]; - - return ( - - - - Connect new device - - Optional description or sub title - - - - - {tabs.map((TabData, index) => ( - setSelectedConnType(TabData.connType)} - disabled={TabData.disabled} - > - <> - - {TabData.name} - - - ))} - - - - - {tabs.map((TabData, index) => ( - - {!TabData.disabled && } - - ))} - - - ); -}; diff --git a/src/components/SlideSheets/PeerInfo.tsx b/src/components/SlideSheets/PeerInfo.tsx deleted file mode 100644 index a39cc016..00000000 --- a/src/components/SlideSheets/PeerInfo.tsx +++ /dev/null @@ -1,60 +0,0 @@ -import type React from "react"; -import { useEffect, useState } from "react"; - -import { GeolocationIcon, Pane, PropertyIcon, SideSheet } from "evergreen-ui"; - -import { SlideSheetTabbedContent } from "@components/layout/page/SlideSheetTabbedContent.js"; -import type { TabType } from "@components/layout/page/TabbedContent.js"; -import { Location } from "@components/SlideSheets/tabs/nodes/Location.js"; -import { Overview } from "@components/SlideSheets/tabs/nodes/Overview.js"; -import { useDevice } from "@core/providers/useDevice.js"; -import type { Node } from "@core/stores/deviceStore.js"; -import { Hashicon } from "@emeraldpay/hashicon-react"; -import { Protobuf } from "@meshtastic/meshtasticjs"; - -export const PeerInfo = () => { - const { peerInfoOpen, activePeer, setPeerInfoOpen, nodes } = useDevice(); - const [node, setNode] = useState(); - - useEffect(() => { - setNode(nodes.find((n) => n.data.num === activePeer)); - }, [nodes, activePeer]); - - const tabs: TabType[] = [ - { - name: "Info", - icon: PropertyIcon, - element: () => , - }, - { - name: "Location", - icon: GeolocationIcon, - element: () => , - }, - ]; - - return ( - { - setPeerInfoOpen(false); - }} - containerProps={{ - display: "flex", - flex: "1", - flexDirection: "column", - }} - > - - -
- } - /> - - ); -}; diff --git a/src/components/SlideSheets/tabs/nodes/Location.tsx b/src/components/SlideSheets/tabs/nodes/Location.tsx deleted file mode 100644 index 2d3dd0c1..00000000 --- a/src/components/SlideSheets/tabs/nodes/Location.tsx +++ /dev/null @@ -1,18 +0,0 @@ -import type React from "react"; - -import { Pane } from "evergreen-ui"; -import JSONPretty from "react-json-pretty"; - -import type { Node } from "@core/stores/deviceStore.js"; - -export interface LocationProps { - node?: Node; -} - -export const Location = ({ node }: LocationProps): JSX.Element => { - return ( - - - - ); -}; diff --git a/src/components/SlideSheets/tabs/nodes/Overview.tsx b/src/components/SlideSheets/tabs/nodes/Overview.tsx deleted file mode 100644 index f6631c91..00000000 --- a/src/components/SlideSheets/tabs/nodes/Overview.tsx +++ /dev/null @@ -1,17 +0,0 @@ -import type React from "react"; - -import { Pane } from "evergreen-ui"; -import JSONPretty from "react-json-pretty"; - -import type { Node } from "@core/stores/deviceStore.js"; - -export interface OverviewProps { - node?: Node; -} -export const Overview = ({ node }: OverviewProps): JSX.Element => { - return ( - - - - ); -}; diff --git a/src/components/Widgets/ConfiguringWidget.tsx b/src/components/Widgets/ConfiguringWidget.tsx new file mode 100644 index 00000000..89be9c7c --- /dev/null +++ b/src/components/Widgets/ConfiguringWidget.tsx @@ -0,0 +1,117 @@ +import React, { useEffect } from "react"; + +import { useDevice } from "@core/providers/useDevice.js"; + +export const ConfiguringWidget = (): JSX.Element => { + const { + hardware, + channels, + config, + moduleConfig, + setReady, + nodes, + connection, + } = useDevice(); + + useEffect(() => { + if ( + hardware.myNodeNum !== 0 && + Object.keys(config).length === 7 && + Object.keys(moduleConfig).length === 7 && + channels.length === hardware.maxChannels + ) { + setReady(true); + } + }, [ + config, + moduleConfig, + channels, + hardware.maxChannels, + hardware.myNodeNum, + setReady, + ]); + + return ( +
+

Connecting to device

+
    + + + + + +
+
{ + void connection?.configure(); + }} + > + Retry +
+
+ ); +}; + +export interface StatusIndicatorProps { + title: string; + current: number; + total: number; +} + +const StatusIndicator = ({ + title, + current, + total, +}: StatusIndicatorProps): JSX.Element => { + return ( +
  • +
    = total ? "bg-green-500" : "bg-[#f9e3aa]" + }`} + /> +
    +
    = total + ? "bg-green-500 border-green-500" + : "bg-[#f9e3aa] border-green-500" + }`} + > + 0 ? "bg-green-500" : "bg-[#f9e3aa]" + }`} + /> +
    + + + {title} + + ({current} + {total !== 0 && `/${total}`}) + + +
    +
  • + ); +}; diff --git a/src/components/Widgets/DeviceWidget.tsx b/src/components/Widgets/DeviceWidget.tsx new file mode 100644 index 00000000..b1d4ef68 --- /dev/null +++ b/src/components/Widgets/DeviceWidget.tsx @@ -0,0 +1,50 @@ +import type React from "react"; + +import { Hashicon } from "@emeraldpay/hashicon-react"; +import { XCircleIcon } from "@heroicons/react/24/outline"; + +import { Button } from "../Button.js"; + +export interface DeviceWidgetProps { + name: string; + nodeNum: string; + disconnected: boolean; + disconnect: () => void; + reconnect: () => void; +} + +export const DeviceWidget = ({ + name, + nodeNum, + disconnected, + disconnect, + reconnect, +}: DeviceWidgetProps): JSX.Element => { + return ( +
    +
    + +
    +
    +
    + +
    +
    + + {name} + +
    + +
    +
    +
    +
    + ); +}; diff --git a/src/components/Widgets/NodeInfoWidget.tsx b/src/components/Widgets/NodeInfoWidget.tsx new file mode 100644 index 00000000..cbb8beb8 --- /dev/null +++ b/src/components/Widgets/NodeInfoWidget.tsx @@ -0,0 +1,11 @@ +import type React from "react"; + +export interface NodeInfoWidgetProps {} + +export const NodeInfoWidget = ({}: NodeInfoWidgetProps): JSX.Element => { + return ( +
    + node info +
    + ); +}; diff --git a/src/components/Widgets/PeersWidget.tsx b/src/components/Widgets/PeersWidget.tsx new file mode 100644 index 00000000..74057b54 --- /dev/null +++ b/src/components/Widgets/PeersWidget.tsx @@ -0,0 +1,11 @@ +import type React from "react"; + +export interface PeersWidgetProps {} + +export const PeersWidget = ({}: PeersWidgetProps): JSX.Element => { + return ( +
    + Peers +
    + ); +}; diff --git a/src/components/Widgets/PositionWidget.tsx b/src/components/Widgets/PositionWidget.tsx new file mode 100644 index 00000000..c0d5e833 --- /dev/null +++ b/src/components/Widgets/PositionWidget.tsx @@ -0,0 +1,11 @@ +import type React from "react"; + +export interface PositionWidgetProps {} + +export const PositionWidget = ({}: PositionWidgetProps): JSX.Element => { + return ( +
    + position +
    + ); +}; diff --git a/src/components/form/Checkbox.tsx b/src/components/form/Checkbox.tsx new file mode 100644 index 00000000..8505dd1d --- /dev/null +++ b/src/components/form/Checkbox.tsx @@ -0,0 +1,53 @@ +import type React from "react"; +import { forwardRef, InputHTMLAttributes } from "react"; + +export interface CheckboxProps extends InputHTMLAttributes { + label: string; + description?: string; + options?: string[]; + prefix?: string; + suffix?: string; + action?: { + icon: JSX.Element; + action: () => void; + }; + error?: string; +} + +export const Checkbox = forwardRef( + function Input( + { + label, + description, + options, + prefix, + suffix, + action, + error, + children, + ...rest + }: CheckboxProps, + ref + ) { + return ( +
    +
    + +
    +
    + +

    + {description} +

    +
    +
    + ); + } +); diff --git a/src/components/form/Form.tsx b/src/components/form/Form.tsx index d24df160..262c5150 100644 --- a/src/components/form/Form.tsx +++ b/src/components/form/Form.tsx @@ -1,15 +1,29 @@ import type React from "react"; import type { HTMLProps } from "react"; -import { Button, majorScale, Pane, SavedIcon, Spinner } from "evergreen-ui"; +import { FiSave } from "react-icons/fi"; + +import { Button } from "@components/Button.js"; +import { + ArrowPathIcon, + ArrowUturnLeftIcon, + ChevronRightIcon, + HomeIcon, +} from "@heroicons/react/24/outline"; export interface FormProps extends HTMLProps { + title: string; + breadcrumbs: string[]; + reset: () => void; onSubmit: (event: React.FormEvent) => Promise; loading: boolean; dirty: boolean; } export const Form = ({ + title, + breadcrumbs, + reset, loading, dirty, children, @@ -18,31 +32,48 @@ export const Form = ({ }: FormProps): JSX.Element => { return ( // eslint-disable-next-line @typescript-eslint/no-misused-promises -
    + {loading && ( - - - +
    + +
    )} - {children} - - - +
    +
      +
    1. + +
    2. + {breadcrumbs.map((breadcrumb, index) => ( +
    3. + + + {breadcrumb} + +
    4. + ))} +
    +
    +

    + {title} +

    +
    + + +
    +
    +
    +
    {children}
    ); }; diff --git a/src/components/form/Input.tsx b/src/components/form/Input.tsx new file mode 100644 index 00000000..7e28ec59 --- /dev/null +++ b/src/components/form/Input.tsx @@ -0,0 +1,75 @@ +import type React from "react"; +import { forwardRef, InputHTMLAttributes } from "react"; + +import { ExclamationCircleIcon } from "@heroicons/react/24/outline"; + +export interface InputProps extends InputHTMLAttributes { + label: string; + description?: string; + prefix?: string; + suffix?: string; + action?: { + icon: JSX.Element; + action: () => void; + }; + error?: string; +} + +export const Input = forwardRef(function Input( + { label, description, prefix, suffix, action, error, ...rest }: InputProps, + ref +) { + return ( +
    + {/* Label */} + + {/* */} +
    + {prefix && ( + + {prefix} + + )} + + {suffix && ( +
    + + {suffix} + +
    + )} + {action && ( + + )} + {error && ( +
    + +
    + )} +
    + {description && ( +

    + {description} +

    + )} + {error && ( +

    + {error} +

    + )} +
    + ); +}); diff --git a/src/components/form/Select.tsx b/src/components/form/Select.tsx new file mode 100644 index 00000000..4531ff4a --- /dev/null +++ b/src/components/form/Select.tsx @@ -0,0 +1,65 @@ +import type React from "react"; +import { forwardRef, SelectHTMLAttributes } from "react"; + +export interface SelectProps extends SelectHTMLAttributes { + label: string; + description?: string; + options?: string[]; + prefix?: string; + suffix?: string; + action?: { + icon: JSX.Element; + action: () => void; + }; + error?: string; +} + +export const Select = forwardRef(function Input( + { + label, + description, + options, + prefix, + suffix, + action, + error, + children, + ...rest + }: SelectProps, + ref +) { + return ( +
    + +
    + + {action && ( + + )} +
    +
    + ); +}); diff --git a/src/components/form/Toggle.tsx b/src/components/form/Toggle.tsx new file mode 100644 index 00000000..1127313f --- /dev/null +++ b/src/components/form/Toggle.tsx @@ -0,0 +1,48 @@ +import type React from "react"; + +import { Switch } from "@headlessui/react"; + +export interface ToggleProps { + label: string; + description: string; + checked: boolean; + onChange?: (checked: boolean) => void; +} + +export const Toggle = ({ + label, + description, + checked, + onChange, +}: ToggleProps): JSX.Element => { + return ( + + + + {label} + + + {description} + + + + + + ); +}; diff --git a/src/components/layout/AppLayout.tsx b/src/components/layout/AppLayout.tsx deleted file mode 100644 index ca93b9ff..00000000 --- a/src/components/layout/AppLayout.tsx +++ /dev/null @@ -1,76 +0,0 @@ -import type React from "react"; - -import { majorScale, Pane } from "evergreen-ui"; - -import { useAppStore } from "@app/core/stores/appStore.js"; -import { DeviceWrapper } from "@app/DeviceWrapper.js"; -import { useDeviceStore } from "@core/stores/deviceStore.js"; - -import { NoDevice } from "../misc/NoDevice.js"; -import { Progress } from "../Progress.js"; -import { PeerInfo } from "../SlideSheets/PeerInfo.js"; -import { Header } from "./Header.js"; -import { Sidebar } from "./Sidebar/index.js"; - -export interface AppLayoutProps { - children: React.ReactNode; -} - -export const AppLayout = ({ children }: AppLayoutProps): JSX.Element => { - const { getDevices } = useDeviceStore(); - const { selectedDevice } = useAppStore(); - - const devices = getDevices(); - - return ( - -
    - - {devices.length ? ( - devices.map((device) => ( - - - {device && device.ready ? ( - <> - - - - {children} - - - ) : ( - <> - - - - )} - - - )) - ) : ( - - )} - - - ); -}; diff --git a/src/components/layout/Header.tsx b/src/components/layout/Header.tsx deleted file mode 100644 index d23954ce..00000000 --- a/src/components/layout/Header.tsx +++ /dev/null @@ -1,167 +0,0 @@ -import type React from "react"; -import { useState } from "react"; - -import { - Button, - CrossIcon, - GlobeIcon, - HelpIcon, - IconButton, - Link, - majorScale, - Pane, - PlusIcon, - StatusIndicator, - Tab, - Tablist, - Tooltip, -} from "evergreen-ui"; -import { FiGithub } from "react-icons/fi"; - -import { HelpDialog } from "@components/Dialog/HelpDialog.js"; -import { NewDevice } from "@components/SlideSheets/NewDevice.js"; -import { useAppStore } from "@core/stores/appStore.js"; -import { useDeviceStore } from "@core/stores/deviceStore.js"; -import { Hashicon } from "@emeraldpay/hashicon-react"; -import { Types } from "@meshtastic/meshtasticjs"; - -export const Header = (): JSX.Element => { - const { getDevices, removeDevice } = useDeviceStore(); - const [newConnectionOpen, setNewConnectionOpen] = useState(false); - const [helpDialogOpen, setHelpDialogOpen] = useState(false); - const { selectedDevice, setSelectedDevice } = useAppStore(); - - return ( - - { - setNewConnectionOpen(false); - }} - /> - - - - - - - {getDevices().map((device) => ( - { - setSelectedDevice(device.id); - }} - > - - {device.nodes.find((n) => n.data.num === device.hardware.myNodeNum) - ?.data.user?.shortName ?? "UNK"} - - - ))} - - - - - - {getDevices().length !== 0 && ( - - - - )} - - - - - - { - setHelpDialogOpen(true); - }} - /> - { - setHelpDialogOpen(false); - }} - /> - - - - - - - - ); -}; diff --git a/src/components/layout/Sidebar/DeviceCard.tsx b/src/components/layout/Sidebar/DeviceCard.tsx deleted file mode 100644 index 196a0e36..00000000 --- a/src/components/layout/Sidebar/DeviceCard.tsx +++ /dev/null @@ -1,103 +0,0 @@ -import type React from "react"; - -import { - Badge, - Heading, - Link, - majorScale, - MapMarkerIcon, - Pane, -} from "evergreen-ui"; -import { FiBluetooth, FiTerminal, FiWifi } from "react-icons/fi"; - -import { useDevice } from "@core/providers/useDevice.js"; -import { toMGRS } from "@core/utils/toMGRS.js"; -import { Hashicon } from "@emeraldpay/hashicon-react"; -import { Types } from "@meshtastic/meshtasticjs"; - -export const DeviceCard = (): JSX.Element => { - const { hardware, nodes, status, connection } = useDevice(); - const myNode = nodes.find((n) => n.data.num === hardware.myNodeNum); - - return ( - - - - - {myNode?.data.user?.longName} - - - {hardware.firmwareVersion} - - - - - - - - {toMGRS( - myNode?.data.position?.latitudeI, - myNode?.data.position?.longitudeI - )} - - - - {connection?.connType === "ble" && } - {connection?.connType === "http" && } - {connection?.connType === "serial" && } - - {[ - Types.DeviceStatusEnum.DEVICE_CONNECTED, - Types.DeviceStatusEnum.DEVICE_CONFIGURED, - Types.DeviceStatusEnum.DEVICE_CONFIGURING, - ].includes(status) - ? "Connected" - : [ - Types.DeviceStatusEnum.DEVICE_CONNECTING, - Types.DeviceStatusEnum.DEVICE_RECONNECTING, - Types.DeviceStatusEnum.DEVICE_CONNECTED, - ].includes(status) - ? "Connecting" - : "Disconnected"} - - - - ); -}; diff --git a/src/components/layout/Sidebar/index.tsx b/src/components/layout/Sidebar/index.tsx deleted file mode 100644 index e8750c5a..00000000 --- a/src/components/layout/Sidebar/index.tsx +++ /dev/null @@ -1,122 +0,0 @@ -import type React from "react"; -import { useState } from "react"; - -import { - ArrayIcon, - GlobeIcon, - IconComponent, - InboxIcon, - InfoSignIcon, - LabTestIcon, - LayersIcon, - majorScale, - Pane, - SettingsIcon, - Tab, - Tablist, -} from "evergreen-ui"; - -import { PeersDialog } from "@components/Dialog/PeersDialog.js"; -import { useDevice } from "@core/providers/useDevice.js"; -import type { Page } from "@core/stores/deviceStore.js"; - -import { DeviceCard } from "./DeviceCard.js"; - -interface NavLink { - name: string; - icon: IconComponent; - page: Page; - disabled?: boolean; -} - -export const Sidebar = (): JSX.Element => { - const { activePage, setActivePage } = useDevice(); - const [PeersDialogOpen, setPeersDialogOpen] = useState(false); - - const navLinks: NavLink[] = [ - { - name: "Messages", - icon: InboxIcon, - page: "messages", - }, - { - name: "Map", - icon: GlobeIcon, - page: "map", - }, - { - name: "Extensions", - icon: LabTestIcon, - page: "extensions", - }, - { - name: "Config", - icon: SettingsIcon, - page: "config", - }, - { - name: "Channels", - icon: LayersIcon, - page: "channels", - }, - { - name: "Info", - icon: InfoSignIcon, - page: "info", - }, - ]; - - return ( - - - {navLinks.map((Link) => ( - { - setActivePage(Link.page); - }} - > - - {Link.name} - - ))} - { - setPeersDialogOpen(true); - }} - > - - Peers - - - { - setPeersDialogOpen(false); - }} - /> - - - - - ); -}; diff --git a/src/components/layout/page/SlideSheetTabbedContent.tsx b/src/components/layout/page/SlideSheetTabbedContent.tsx deleted file mode 100644 index 7a483d93..00000000 --- a/src/components/layout/page/SlideSheetTabbedContent.tsx +++ /dev/null @@ -1,88 +0,0 @@ -import type React from "react"; -import { useState } from "react"; - -import { - Heading, - IconComponent, - majorScale, - Pane, - Paragraph, - Tab, - Tablist, -} from "evergreen-ui"; -import type { IconType } from "react-icons"; - -export interface TabType { - name: string; - icon: IconComponent | IconType; - element: () => JSX.Element; - disabled?: boolean; -} - -export interface SlideSheetTabbedContentProps { - heading: string; - description: string; - tabs: TabType[]; - tabIcon?: React.ReactNode; -} - -export const SlideSheetTabbedContent = ({ - heading, - description, - tabs, - tabIcon, -}: SlideSheetTabbedContentProps): JSX.Element => { - const [selectedTab, setSelectedTab] = useState(0); - - return ( - <> - - - {tabIcon} - - {heading} - - {description} - - - - - - {tabs.map((Entry, index) => ( - setSelectedTab(index)} - isSelected={selectedTab === index} - > - - {Entry.name} - - ))} - - - - - {tabs.map((Entry, index) => ( - - {!Entry.disabled && } - - ))} - - - ); -}; diff --git a/src/components/layout/page/TabbedContent.tsx b/src/components/layout/page/TabbedContent.tsx index dd2a920c..47b6ca0f 100644 --- a/src/components/layout/page/TabbedContent.tsx +++ b/src/components/layout/page/TabbedContent.tsx @@ -1,12 +1,11 @@ import type React from "react"; -import { useState } from "react"; +import { Fragment } from "react"; -import { IconComponent, majorScale, Pane, Tab, Tablist } from "evergreen-ui"; -import type { IconType } from "react-icons"; +import { Tab } from "@headlessui/react"; export interface TabType { name: string; - icon: IconComponent | IconType; + icon?: JSX.Element; element: () => JSX.Element; disabled?: boolean; } @@ -20,55 +19,41 @@ export const TabbedContent = ({ tabs, actions, }: TabbedContentProps): JSX.Element => { - const [selectedTab, setSelectedTab] = useState(0); - return ( - - - - - {tabs.map((Entry, index) => ( - setSelectedTab(index)} - isSelected={selectedTab === index} + + + {tabs.map((entry, index) => ( + + {({ selected }) => ( +
    - - {Entry.name} - - ))} - - - - {actions?.map((Action, index) => ( - - ))} - - - - {tabs.map((Entry, index) => ( - - {!Entry.disabled && } - - ))} - + {entry.icon && ( +
    {entry.icon}
    + )} + {entry.name} +
    + )} +
    + ))} +
    + {actions?.map((Action, index) => ( + + ))} +
    +
    + + {tabs.map((entry, index) => ( + + + + ))} + +
    ); }; diff --git a/src/components/misc/NoDevice.tsx b/src/components/misc/NoDevice.tsx deleted file mode 100644 index 5baa68ae..00000000 --- a/src/components/misc/NoDevice.tsx +++ /dev/null @@ -1,18 +0,0 @@ -import type React from "react"; - -import { DisableIcon, EmptyState, Pane } from "evergreen-ui"; - -export const NoDevice = (): JSX.Element => { - return ( - - } - iconBgColor="#F8E3DA" - description="You must connect a Meshtastic device to continue." - /> - - ); -}; diff --git a/src/core/providers/useDevice.ts b/src/core/providers/useDevice.ts index 998f9463..838fc6c1 100644 --- a/src/core/providers/useDevice.ts +++ b/src/core/providers/useDevice.ts @@ -1,13 +1,13 @@ -import { createContext, useContext } from "react"; +import { createContext, useContext } from 'react'; -import type { Device } from "@core/stores/deviceStore.js"; +import type { Device } from '@core/stores/deviceStore.js'; export const DeviceContext = createContext(undefined); export const useDevice = (): Device => { const context = useContext(DeviceContext); if (context === undefined) { - throw new Error("useDevice must be used within a ConnectionProvider"); + throw new Error("useDevice must be used within a DeviceProvider"); } return context; }; diff --git a/src/core/stores/appStore.ts b/src/core/stores/appStore.ts index 310ecd42..0e1aa0c1 100644 --- a/src/core/stores/appStore.ts +++ b/src/core/stores/appStore.ts @@ -1,7 +1,7 @@ -import create from "zustand"; +import create from 'zustand'; interface AppState { - selectedDevice?: number; + selectedDevice: number; devices: { id: number; num: number; diff --git a/src/core/stores/deviceStore.ts b/src/core/stores/deviceStore.ts index 88db45ca..25b03959 100644 --- a/src/core/stores/deviceStore.ts +++ b/src/core/stores/deviceStore.ts @@ -79,6 +79,7 @@ export interface DeviceState { addDevice: (id: number) => Device; removeDevice: (id: number) => void; getDevices: () => Device[]; + getDevice: (id: number) => Device | undefined; } export const useDeviceStore = create((set, get) => ({ @@ -470,6 +471,8 @@ export const useDeviceStore = create((set, get) => ({ }, getDevices: () => Array.from(get().devices.values()), + + getDevice: (id) => get().devices.get(id), })); export const DeviceContext = createContext(undefined); diff --git a/src/index.css b/src/index.css new file mode 100644 index 00000000..bd6213e1 --- /dev/null +++ b/src/index.css @@ -0,0 +1,3 @@ +@tailwind base; +@tailwind components; +@tailwind utilities; \ No newline at end of file diff --git a/src/index.tsx b/src/index.tsx index 6033556e..adaa935f 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -1,4 +1,4 @@ -import "modern-css-reset/dist/reset.min.css"; +import "./index.css"; import "maplibre-gl/dist/maplibre-gl.css"; import type React from "react"; diff --git a/src/pages/Channels/index.tsx b/src/pages/Channels.tsx similarity index 65% rename from src/pages/Channels/index.tsx rename to src/pages/Channels.tsx index 1f631b05..e1636761 100644 --- a/src/pages/Channels/index.tsx +++ b/src/pages/Channels.tsx @@ -1,14 +1,13 @@ import type React from "react"; import { useState } from "react"; -import { Button, LayerIcon, LayerOutlineIcon, Tooltip } from "evergreen-ui"; -import { IoQrCodeOutline } from "react-icons/io5"; - +import { Channel } from "@app/components/PageComponents/Channel.js"; +import { Button } from "@components/Button.js"; import { QRDialog } from "@components/Dialog/QRDialog.js"; import { TabbedContent, TabType } from "@components/layout/page/TabbedContent"; import { useDevice } from "@core/providers/useDevice.js"; +import { QrCodeIcon } from "@heroicons/react/24/outline"; import { Protobuf } from "@meshtastic/meshtasticjs"; -import { Channel } from "@pages/Channels/Channel.js"; export const ChannelsPage = (): JSX.Element => { const { channels, config } = useDevice(); @@ -21,10 +20,6 @@ export const ChannelsPage = (): JSX.Element => { : channel.config.role === Protobuf.Channel_Role.PRIMARY ? "Primary" : `Channel: ${channel.config.index}`, - icon: - channel.config.role !== Protobuf.Channel_Role.DISABLED - ? LayerIcon - : LayerOutlineIcon, element: () => , }; }); @@ -43,16 +38,15 @@ export const ChannelsPage = (): JSX.Element => { tabs={tabs} actions={[ () => ( - - - + ), ]} /> diff --git a/src/pages/Channels/Channel.tsx b/src/pages/Channels/Channel.tsx deleted file mode 100644 index 796e6f03..00000000 --- a/src/pages/Channels/Channel.tsx +++ /dev/null @@ -1,205 +0,0 @@ -import type React from "react"; -import { useEffect, useState } from "react"; - -import { fromByteArray, toByteArray } from "base64-js"; -import { - Button, - EyeOffIcon, - EyeOpenIcon, - FormField, - IconButton, - majorScale, - Pane, - RefreshIcon, - SelectField, - Switch, - TextInputField, - Tooltip, -} from "evergreen-ui"; -import { Controller, useForm } from "react-hook-form"; - -import { Form } from "@components/form/Form"; -import { useDevice } from "@core/providers/useDevice.js"; -import { Protobuf } from "@meshtastic/meshtasticjs"; - -export interface SettingsPanelProps { - channel: Protobuf.Channel; -} - -export const Channel = ({ channel }: SettingsPanelProps): JSX.Element => { - const { connection } = useDevice(); - const [loading, setLoading] = useState(false); - const [keySize, setKeySize] = useState<128 | 256>(256); - const [pskHidden, setPskHidden] = useState(true); - - const { - register, - handleSubmit, - formState: { errors, isDirty }, - reset, - control, - setValue, - } = useForm< - Omit & { psk: string; enabled: boolean } - >({ - defaultValues: { - enabled: [ - Protobuf.Channel_Role.SECONDARY, - Protobuf.Channel_Role.PRIMARY, - ].find((role) => role === channel?.role) - ? true - : false, - ...channel?.settings, - psk: fromByteArray(channel?.settings?.psk ?? new Uint8Array(0)), - }, - }); - - useEffect(() => { - reset({ - enabled: [ - Protobuf.Channel_Role.SECONDARY, - Protobuf.Channel_Role.PRIMARY, - ].find((role) => role === channel?.role) - ? true - : false, - ...channel?.settings, - psk: fromByteArray(channel?.settings?.psk ?? new Uint8Array(0)), - }); - }, [channel, reset]); - - const onSubmit = handleSubmit(async (data) => { - setLoading(true); - const channelData = Protobuf.Channel.create({ - role: - channel?.role === Protobuf.Channel_Role.PRIMARY - ? Protobuf.Channel_Role.PRIMARY - : data.enabled - ? Protobuf.Channel_Role.SECONDARY - : Protobuf.Channel_Role.DISABLED, - index: channel?.index, - settings: { - ...data, - psk: toByteArray(data.psk ?? ""), - }, - }); - - await connection?.setChannel(channelData, (): Promise => { - reset({ ...data }); - setLoading(false); - return Promise.resolve(); - }); - }); - - return ( -
    - {channel?.index !== 0 && ( - <> - - ( - - )} - /> - - - - )} - - { - setKeySize(parseInt(e.target.value) as 128 | 256); - }} - > - - - - - - ): void => { - e.preventDefault(); - const key = new Uint8Array(keySize / 8); - crypto.getRandomValues(key); - setValue("psk", fromByteArray(key)); - }} - icon={} - /> - - - - - - - - - - ( - - )} - /> - - - ( - - )} - /> - - - ); -}; diff --git a/src/pages/Config/AppConfig.tsx b/src/pages/Config/AppConfig.tsx index f5305549..c27a6383 100644 --- a/src/pages/Config/AppConfig.tsx +++ b/src/pages/Config/AppConfig.tsx @@ -1,15 +1,12 @@ import type React from "react"; -import { useState } from "react"; - -import { Pane, Tab, Tablist } from "evergreen-ui"; +import { Fragment } from "react"; import { ExternalNotification } from "@components/PageComponents/ModuleConfig/ExternalNotification.js"; import { MQTT } from "@components/PageComponents/ModuleConfig/MQTT.js"; import { Serial } from "@components/PageComponents/ModuleConfig/Serial.js"; +import { Tab } from "@headlessui/react"; export const AppConfig = (): JSX.Element => { - const [selectedIndex, setSelectedIndex] = useState(0); - const configSections = [ { label: "Interface", @@ -26,31 +23,31 @@ export const AppConfig = (): JSX.Element => { ]; return ( - - - - {configSections.map((Config, index) => ( - setSelectedIndex(index)} - > - {Config.label} - - ))} - - - + + {configSections.map((Config, index) => ( - - - + + {({ selected }) => ( +
    + {Config.label} +
    + )} +
    ))} -
    -
    + + + {configSections.map((Config, index) => ( + + + + ))} + + ); }; diff --git a/src/pages/Config/DeviceConfig.tsx b/src/pages/Config/DeviceConfig.tsx index 92938c43..5bf29ebb 100644 --- a/src/pages/Config/DeviceConfig.tsx +++ b/src/pages/Config/DeviceConfig.tsx @@ -1,7 +1,5 @@ import type React from "react"; -import { useState } from "react"; - -import { Pane, Tab, Tablist } from "evergreen-ui"; +import { Fragment } from "react"; import { Network } from "@app/components/PageComponents/Config/Network.js"; import { Bluetooth } from "@components/PageComponents/Config/Bluetooth.js"; @@ -12,9 +10,9 @@ import { Position } from "@components/PageComponents/Config/Position.js"; import { Power } from "@components/PageComponents/Config/Power.js"; import { User } from "@components/PageComponents/Config/User.js"; import { useDevice } from "@core/providers/useDevice.js"; +import { Tab } from "@headlessui/react"; export const DeviceConfig = (): JSX.Element => { - const [selectedIndex, setSelectedIndex] = useState(0); const { hardware } = useDevice(); const configSections = [ @@ -54,32 +52,31 @@ export const DeviceConfig = (): JSX.Element => { ]; return ( - - - - {configSections.map((Config, index) => ( - setSelectedIndex(index)} - disabled={Config.disabled} - > - {Config.label} - - ))} - - - + + {configSections.map((Config, index) => ( - - - + + {({ selected }) => ( +
    + {Config.label} +
    + )} +
    ))} -
    -
    + + + {configSections.map((Config, index) => ( + + + + ))} + + ); }; diff --git a/src/pages/Config/ModuleConfig.tsx b/src/pages/Config/ModuleConfig.tsx index dba9c378..ca396908 100644 --- a/src/pages/Config/ModuleConfig.tsx +++ b/src/pages/Config/ModuleConfig.tsx @@ -1,7 +1,5 @@ import type React from "react"; -import { useState } from "react"; - -import { Pane, Tab, Tablist } from "evergreen-ui"; +import { Fragment, useState } from "react"; import { CannedMessage } from "@components/PageComponents/ModuleConfig/CannedMessage"; import { ExternalNotification } from "@components/PageComponents/ModuleConfig/ExternalNotification.js"; @@ -10,6 +8,7 @@ import { RangeTest } from "@components/PageComponents/ModuleConfig/RangeTest.js" import { Serial } from "@components/PageComponents/ModuleConfig/Serial.js"; import { StoreForward } from "@components/PageComponents/ModuleConfig/StoreForward.js"; import { Telemetry } from "@components/PageComponents/ModuleConfig/Telemetry.js"; +import { Tab } from "@headlessui/react"; export const ModuleConfig = (): JSX.Element => { const [selectedIndex, setSelectedIndex] = useState(0); @@ -46,31 +45,31 @@ export const ModuleConfig = (): JSX.Element => { ]; return ( - - - - {configSections.map((Config, index) => ( - setSelectedIndex(index)} - > - {Config.label} - - ))} - - - + + {configSections.map((Config, index) => ( - - - + + {({ selected }) => ( +
    + {Config.label} +
    + )} +
    ))} -
    -
    + + + {configSections.map((Config, index) => ( + + + + ))} + + ); }; diff --git a/src/pages/Config/index.tsx b/src/pages/Config/index.tsx index 42dd1437..e8b431b4 100644 --- a/src/pages/Config/index.tsx +++ b/src/pages/Config/index.tsx @@ -1,8 +1,11 @@ import type React from "react"; -import { ApplicationsIcon, CogIcon, CubeIcon } from "evergreen-ui"; - import { TabbedContent, TabType } from "@components/layout/page/TabbedContent"; +import { + Cog8ToothIcon, + CubeTransparentIcon, + WindowIcon, +} from "@heroicons/react/24/outline"; import { AppConfig } from "@pages/Config/AppConfig.js"; import { DeviceConfig } from "@pages/Config/DeviceConfig.js"; import { ModuleConfig } from "@pages/Config/ModuleConfig.js"; @@ -11,17 +14,17 @@ export const ConfigPage = (): JSX.Element => { const tabs: TabType[] = [ { name: "Device Config", - icon: CogIcon, + icon: , element: DeviceConfig, }, { name: "Module Config", - icon: CubeIcon, + icon: , element: ModuleConfig, }, { name: "App Config", - icon: ApplicationsIcon, + icon: , element: AppConfig, }, ]; diff --git a/src/pages/Extensions/Environment.tsx b/src/pages/Extensions/Environment.tsx index 171f92f9..39b4338b 100644 --- a/src/pages/Extensions/Environment.tsx +++ b/src/pages/Extensions/Environment.tsx @@ -1,17 +1,15 @@ import type React from "react"; -import { Pane } from "evergreen-ui"; - import { useDevice } from "@core/providers/useDevice.js"; export const Environment = (): JSX.Element => { const { nodes } = useDevice(); return ( - +
    {nodes.map((node, index) => ( - {JSON.stringify(node.environmentMetrics)} +
    {JSON.stringify(node.environmentMetrics)}
    ))} - +
    ); }; diff --git a/src/pages/Extensions/FileBrowser.tsx b/src/pages/Extensions/FileBrowser.tsx index e9a7c94d..fae6828c 100644 --- a/src/pages/Extensions/FileBrowser.tsx +++ b/src/pages/Extensions/FileBrowser.tsx @@ -1,8 +1,6 @@ import type React from "react"; import { useEffect, useState } from "react"; -import { Pane } from "evergreen-ui"; - export interface File { nameModified: string; name: string; @@ -33,9 +31,9 @@ export const FileBrowser = (): JSX.Element => { }); return ( - +
    {data?.data.files.map((file) => ( - + ))} - +
    ); }; diff --git a/src/pages/Extensions/Index.tsx b/src/pages/Extensions/Index.tsx index 5c6f2e69..6a893e24 100644 --- a/src/pages/Extensions/Index.tsx +++ b/src/pages/Extensions/Index.tsx @@ -1,9 +1,12 @@ import type React from "react"; -import { DocumentIcon, GanttChartIcon, RainIcon } from "evergreen-ui"; - import { TabbedContent, TabType } from "@components/layout/page/TabbedContent"; import { useDevice } from "@core/providers/useDevice.js"; +import { + CloudIcon, + DocumentIcon, + SignalIcon, +} from "@heroicons/react/24/outline"; import { Environment } from "@pages/Extensions/Environment.js"; import { FileBrowser } from "@pages/Extensions/FileBrowser"; @@ -13,19 +16,19 @@ export const ExtensionsPage = (): JSX.Element => { const tabs: TabType[] = [ { name: "File Browser", - icon: DocumentIcon, + icon: , element: FileBrowser, disabled: !hardware.hasWifi, }, { name: "Range Test", - icon: GanttChartIcon, + icon: , element: FileBrowser, disabled: !hardware.hasWifi, }, { name: "Environment", - icon: RainIcon, + icon: , element: Environment, }, ]; diff --git a/src/pages/Info/index.tsx b/src/pages/Info.tsx similarity index 86% rename from src/pages/Info/index.tsx rename to src/pages/Info.tsx index ccf1892d..031b0431 100644 --- a/src/pages/Info/index.tsx +++ b/src/pages/Info.tsx @@ -1,6 +1,5 @@ import type React from "react"; -import { Pane } from "evergreen-ui"; import JSONPretty from "react-json-pretty"; import { useDevice } from "@core/providers/useDevice.js"; @@ -11,9 +10,9 @@ export const InfoPage = (): JSX.Element => { const myNode = nodes.find((n) => n.data.num === hardware.myNodeNum); return ( - +
    - +
    ); }; diff --git a/src/pages/Map/index.tsx b/src/pages/Map.tsx similarity index 60% rename from src/pages/Map/index.tsx rename to src/pages/Map.tsx index 47628033..cde11dbf 100644 --- a/src/pages/Map/index.tsx +++ b/src/pages/Map.tsx @@ -1,61 +1,29 @@ import type React from "react"; -import { - Heading, - IconButton, - LocateIcon, - majorScale, - MapMarkerIcon, - Pane, - Text, -} from "evergreen-ui"; import maplibregl from "maplibre-gl"; import { Map, Marker, useMap } from "react-map-gl"; +import { IconButton } from "@app/components/IconButton.js"; import { useDevice } from "@core/providers/useDevice.js"; import { Hashicon } from "@emeraldpay/hashicon-react"; +import { MapPinIcon } from "@heroicons/react/24/outline"; export const MapPage = (): JSX.Element => { const { nodes, waypoints } = useDevice(); const { current: map } = useMap(); return ( - - - - Title - - +
    +
    +
    Title
    +
    {nodes.map((n) => ( - +
    - {n.data.user?.longName} +
    {n.data.user?.longName}
    } + size="sm" onClick={() => { if (n.data.position?.latitudeI) { map?.flyTo({ @@ -68,10 +36,10 @@ export const MapPage = (): JSX.Element => { } }} /> - +
    ))} -
    - +
    +
    { latitude={wp.latitudeI / 1e7} anchor="bottom" > - - - +
    + +
    ))} {nodes.map((n) => { @@ -104,6 +72,6 @@ export const MapPage = (): JSX.Element => { } })}
    - +
    ); }; diff --git a/src/pages/Messages/index.tsx b/src/pages/Messages.tsx similarity index 56% rename from src/pages/Messages/index.tsx rename to src/pages/Messages.tsx index a966b4bd..3a1f471d 100644 --- a/src/pages/Messages/index.tsx +++ b/src/pages/Messages.tsx @@ -1,23 +1,19 @@ import type React from "react"; -import { - CircleIcon, - EditIcon, - IconButton, - Pane, - RingIcon, - Tooltip, -} from "evergreen-ui"; - +import { IconButton } from "@app/components/IconButton.js"; import { TabbedContent, TabType, } from "@components/layout/page/TabbedContent.js"; +import { ChannelChat } from "@components/PageComponents/Messages/ChannelChat.js"; import { useDevice } from "@core/providers/useDevice.js"; +import { + EllipsisHorizontalCircleIcon, + PencilIcon, + XCircleIcon, +} from "@heroicons/react/24/outline"; import { Protobuf } from "@meshtastic/meshtasticjs"; -import { ChannelChat } from "./ChannelChat.js"; - export const MessagesPage = (): JSX.Element => { const { channels, setActivePage } = useDevice(); @@ -28,29 +24,32 @@ export const MessagesPage = (): JSX.Element => { : channel.config.index === 0 ? "Primary" : `Ch ${channel.config.index}`, - icon: channel.messages.length ? RingIcon : CircleIcon, + icon: channel.messages.length ? ( + + ) : ( + + ), element: () => , disabled: channel.config.role === Protobuf.Channel_Role.DISABLED, }; }); return ( - +
    ( - - { - setActivePage("channels"); - }} - /> - + } + onClick={() => { + setActivePage("channels"); + }} + /> ), ]} /> - +
    ); }; diff --git a/src/pages/Messages/ChannelChat.tsx b/src/pages/Messages/ChannelChat.tsx deleted file mode 100644 index ab2a0aae..00000000 --- a/src/pages/Messages/ChannelChat.tsx +++ /dev/null @@ -1,103 +0,0 @@ -import type React from "react"; -import { ChangeEvent, useState } from "react"; - -import { - AddLocationIcon, - IconButton, - majorScale, - Pane, - Popover, - SendMessageIcon, - TextInputField, - Tooltip, -} from "evergreen-ui"; - -import { useDevice } from "@core/providers/useDevice.js"; -import type { Channel } from "@core/stores/deviceStore.js"; -import { Message } from "@pages/Messages/Message.js"; -import { NewLocationMessage } from "@pages/Messages/NewLocationMessage.js"; - -export interface ChannelChatProps { - channel: Channel; -} - -export const ChannelChat = ({ channel }: ChannelChatProps): JSX.Element => { - const { nodes, connection, ackMessage } = useDevice(); - const [currentMessage, setCurrentMessage] = useState(""); - - const sendMessage = (): void => { - void connection?.sendText( - currentMessage, - undefined, - true, - channel.config.index, - (id) => { - ackMessage(channel.config.index, id); - return Promise.resolve(); - } - ); - setCurrentMessage(""); - }; - - return ( - - - {channel.messages.map((message, index) => ( - node.data.num === message.packet.from)?.data - } - /> - ))} - - -
    { - e.preventDefault(); - sendMessage(); - }} - > - - ): void => { - setCurrentMessage(e.target.value); - }} - /> - - - - -
    - - }> - - - -
    -
    - ); -}; diff --git a/src/pages/Messages/Message.tsx b/src/pages/Messages/Message.tsx deleted file mode 100644 index 787d3356..00000000 --- a/src/pages/Messages/Message.tsx +++ /dev/null @@ -1,94 +0,0 @@ -import type React from "react"; - -import { - CircleIcon, - FullCircleIcon, - majorScale, - Pane, - Small, - Strong, - Text, -} from "evergreen-ui"; - -import type { AllMessageTypes } from "@app/core/stores/deviceStore.js"; -import { WaypointMessage } from "@app/pages/Messages/WaypointMessage.js"; -import { useDevice } from "@core/providers/useDevice.js"; -import { Hashicon } from "@emeraldpay/hashicon-react"; -import type { Protobuf } from "@meshtastic/meshtasticjs"; - -export interface MessageProps { - lastMsgSameUser: boolean; - message: AllMessageTypes; - sender?: Protobuf.NodeInfo; -} - -export const Message = ({ - lastMsgSameUser, - message, - sender, -}: MessageProps): JSX.Element => { - const { setPeerInfoOpen, setActivePeer } = useDevice(); - - const openPeer = (): void => { - setActivePeer(message.packet.from); - setPeerInfoOpen(true); - }; - - return lastMsgSameUser ? ( - - {message.ack ? ( - - ) : ( - - )} - {"waypointID" in message ? ( - - ) : ( - - {message.text} - - )} - - ) : ( - - - - - - - {sender?.user?.longName ?? "UNK"} - - - {new Date(message.packet.rxTime).toLocaleTimeString(undefined, { - hour: "2-digit", - minute: "2-digit", - })} - - - - {message.ack ? ( - - ) : ( - - )} - {"waypointID" in message ? ( - - ) : ( - - {message.text} - - )} - - - ); -}; diff --git a/src/pages/Messages/WaypointMessage.tsx b/src/pages/Messages/WaypointMessage.tsx deleted file mode 100644 index 445ea192..00000000 --- a/src/pages/Messages/WaypointMessage.tsx +++ /dev/null @@ -1,52 +0,0 @@ -import type React from "react"; - -import { - Heading, - LocateIcon, - majorScale, - minorScale, - Pane, - Small, - Text, -} from "evergreen-ui"; - -import { useDevice } from "@app/core/providers/useDevice.js"; -import { toMGRS } from "@core/utils/toMGRS.js"; - -export interface WaypointMessageProps { - waypointID: number; -} - -export const WaypointMessage = ({ - waypointID, -}: WaypointMessageProps): JSX.Element => { - const { waypoints } = useDevice(); - const waypoint = waypoints.find((wp) => wp.id === waypointID); - - return ( - - - - - - {waypoint?.name} - - {toMGRS(waypoint?.latitudeI, waypoint?.longitudeI)} - - - {waypoint?.description} - - - - ); -}; diff --git a/src/validation/config/device.ts b/src/validation/config/device.ts index e96713d3..09c556d2 100644 --- a/src/validation/config/device.ts +++ b/src/validation/config/device.ts @@ -1,16 +1,13 @@ -import { IsBoolean, IsEnum } from "class-validator"; +import { IsBoolean, IsEnum } from 'class-validator'; -import { Protobuf } from "@meshtastic/meshtasticjs"; +import { Protobuf } from '@meshtastic/meshtasticjs'; export class DeviceValidation implements Protobuf.Config_DeviceConfig { @IsEnum(Protobuf.Config_DeviceConfig_Role) role: Protobuf.Config_DeviceConfig_Role; @IsBoolean() - serialDisabled: boolean; - - @IsBoolean() - factoryReset: boolean; + serialEnabled: boolean; @IsBoolean() debugLogEnabled: boolean; diff --git a/src/validation/config/lora.ts b/src/validation/config/lora.ts index 2708fc65..7b574900 100644 --- a/src/validation/config/lora.ts +++ b/src/validation/config/lora.ts @@ -3,10 +3,8 @@ import { IsArray, IsBoolean, IsEnum, IsInt, Max, Min } from "class-validator"; import { Protobuf } from "@meshtastic/meshtasticjs"; export class LoRaValidation implements Protobuf.Config_LoRaConfig { - @IsInt() - @Min(0) - @Max(10) - txPower: number; + @IsBoolean() + usePreset: boolean; @IsEnum(Protobuf.Config_LoRaConfig_ModemPreset) modemPreset: Protobuf.Config_LoRaConfig_ModemPreset; @@ -36,7 +34,11 @@ export class LoRaValidation implements Protobuf.Config_LoRaConfig { hopLimit: number; @IsBoolean() - txDisabled: boolean; + txEnabled: boolean; + + @IsInt() + @Min(0) + txPower: number; @IsArray() ignoreIncoming: number[]; diff --git a/src/validation/config/position.ts b/src/validation/config/position.ts index a67c93da..9ec3320a 100644 --- a/src/validation/config/position.ts +++ b/src/validation/config/position.ts @@ -1,19 +1,19 @@ -import { IsBoolean, IsInt } from "class-validator"; +import { IsBoolean, IsInt } from 'class-validator'; -import type { Protobuf } from "@meshtastic/meshtasticjs"; +import type { Protobuf } from '@meshtastic/meshtasticjs'; export class PositionValidation implements Protobuf.Config_PositionConfig { @IsInt() positionBroadcastSecs: number; @IsBoolean() - positionBroadcastSmartDisabled: boolean; + positionBroadcastSmartEnabled: boolean; @IsBoolean() fixedPosition: boolean; @IsBoolean() - gpsDisabled: boolean; + gpsEnabled: boolean; @IsInt() gpsUpdateInterval: number; diff --git a/tailwind.config.cjs b/tailwind.config.cjs new file mode 100644 index 00000000..ffb9a839 --- /dev/null +++ b/tailwind.config.cjs @@ -0,0 +1,8 @@ +/** @type {import('tailwindcss').Config} */ +module.exports = { + content: ["./index.html", "./src/**/*.{ts,tsx}"], + theme: { + extend: {}, + }, + plugins: [], +};