diff --git a/.storybook/preview.tsx b/.storybook/preview.tsx index 30db3e8b3f..f3ed7decac 100644 --- a/.storybook/preview.tsx +++ b/.storybook/preview.tsx @@ -1,5 +1,6 @@ import '@/app/index.css'; import '@/app/styles/theme/default.css'; +import './theme/root.css'; import { I18Provider } from '@/shared/i18n'; import { ThemeProvider } from '@/shared/ui-kit'; diff --git a/.storybook/theme/root.css b/.storybook/theme/root.css new file mode 100644 index 0000000000..d07c217b0c --- /dev/null +++ b/.storybook/theme/root.css @@ -0,0 +1,3 @@ +html, body { + height: 100%; +} diff --git a/app.config.js b/app.config.js index 6bb27370e9..5aa19c20fb 100644 --- a/app.config.js +++ b/app.config.js @@ -43,6 +43,7 @@ module.exports = { RENDERER: 'src/renderer/app/index.tsx', }, + APP_ROOT: 'src/renderer/app', INDEX_HTML: 'src/renderer/app/index.html', RESOURCES: 'src/main/resources', DEV_BUILD: 'release/build/', diff --git a/package.json b/package.json index f4e7ce33cb..5d84e3e061 100644 --- a/package.json +++ b/package.json @@ -76,16 +76,16 @@ "@polkadot/types": "15.0.2", "@polkadot/util": "13.2.3", "@polkadot/util-crypto": "13.2.3", - "@radix-ui/react-accordion": "1.2.1", - "@radix-ui/react-checkbox": "1.1.2", - "@radix-ui/react-dialog": "1.1.2", - "@radix-ui/react-dropdown-menu": "2.1.2", - "@radix-ui/react-popover": "1.1.2", - "@radix-ui/react-progress": "1.1.0", - "@radix-ui/react-scroll-area": "1.2.1", - "@radix-ui/react-select": "2.1.2", - "@radix-ui/react-slider": "1.2.1", - "@radix-ui/react-tooltip": "1.1.4", + "@radix-ui/react-accordion": "1.2.2", + "@radix-ui/react-checkbox": "1.1.3", + "@radix-ui/react-dialog": "1.1.4", + "@radix-ui/react-dropdown-menu": "2.1.4", + "@radix-ui/react-popover": "1.1.4", + "@radix-ui/react-progress": "1.1.1", + "@radix-ui/react-scroll-area": "1.2.0", + "@radix-ui/react-select": "2.1.4", + "@radix-ui/react-slider": "1.2.2", + "@radix-ui/react-tooltip": "1.1.6", "@react-spring/web": "9.7.5", "@remote-ui/rpc": "^1.4.4", "@substrate/connect": "2.1.1", @@ -205,6 +205,8 @@ "eslint-plugin-react": "7.37.1", "eslint-plugin-unused-imports": "4.1.4", "fake-indexeddb": "4.0.2", + "favicons": "7.2.0", + "favicons-webpack-plugin": "6.0.1", "file-loader": "6.2.0", "html-webpack-plugin": "5.6.0", "husky": "9.1.6", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 6dddf396e0..bea9073b40 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -39,35 +39,35 @@ importers: specifier: 13.2.3 version: 13.2.3(@polkadot/util@13.2.3) '@radix-ui/react-accordion': - specifier: 1.2.1 - version: 1.2.1(@types/react-dom@18.0.5)(@types/react@18.0.14)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + specifier: 1.2.2 + version: 1.2.2(@types/react-dom@18.0.5)(@types/react@18.0.14)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@radix-ui/react-checkbox': - specifier: 1.1.2 - version: 1.1.2(@types/react-dom@18.0.5)(@types/react@18.0.14)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + specifier: 1.1.3 + version: 1.1.3(@types/react-dom@18.0.5)(@types/react@18.0.14)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@radix-ui/react-dialog': - specifier: 1.1.2 - version: 1.1.2(@types/react-dom@18.0.5)(@types/react@18.0.14)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + specifier: 1.1.4 + version: 1.1.4(@types/react-dom@18.0.5)(@types/react@18.0.14)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@radix-ui/react-dropdown-menu': - specifier: 2.1.2 - version: 2.1.2(@types/react-dom@18.0.5)(@types/react@18.0.14)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + specifier: 2.1.4 + version: 2.1.4(@types/react-dom@18.0.5)(@types/react@18.0.14)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@radix-ui/react-popover': - specifier: 1.1.2 - version: 1.1.2(@types/react-dom@18.0.5)(@types/react@18.0.14)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + specifier: 1.1.4 + version: 1.1.4(@types/react-dom@18.0.5)(@types/react@18.0.14)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@radix-ui/react-progress': - specifier: 1.1.0 - version: 1.1.0(@types/react-dom@18.0.5)(@types/react@18.0.14)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + specifier: 1.1.1 + version: 1.1.1(@types/react-dom@18.0.5)(@types/react@18.0.14)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@radix-ui/react-scroll-area': - specifier: 1.2.1 - version: 1.2.1(@types/react-dom@18.0.5)(@types/react@18.0.14)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + specifier: 1.2.0 + version: 1.2.0(@types/react-dom@18.0.5)(@types/react@18.0.14)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@radix-ui/react-select': - specifier: 2.1.2 - version: 2.1.2(@types/react-dom@18.0.5)(@types/react@18.0.14)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + specifier: 2.1.4 + version: 2.1.4(@types/react-dom@18.0.5)(@types/react@18.0.14)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@radix-ui/react-slider': - specifier: 1.2.1 - version: 1.2.1(@types/react-dom@18.0.5)(@types/react@18.0.14)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + specifier: 1.2.2 + version: 1.2.2(@types/react-dom@18.0.5)(@types/react@18.0.14)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@radix-ui/react-tooltip': - specifier: 1.1.4 - version: 1.1.4(@types/react-dom@18.0.5)(@types/react@18.0.14)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + specifier: 1.1.6 + version: 1.1.6(@types/react-dom@18.0.5)(@types/react@18.0.14)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@react-spring/web': specifier: 9.7.5 version: 9.7.5(react-dom@18.3.1(react@18.3.1))(react@18.3.1) @@ -420,6 +420,12 @@ importers: fake-indexeddb: specifier: 4.0.2 version: 4.0.2 + favicons: + specifier: 7.2.0 + version: 7.2.0 + favicons-webpack-plugin: + specifier: 6.0.1 + version: 6.0.1(favicons@7.2.0)(webpack@5.95.0) file-loader: specifier: 6.2.0 version: 6.2.0(webpack@5.95.0) @@ -1400,6 +1406,9 @@ packages: resolution: {integrity: sha512-fKpv9kg4SPmt+hY7SVBnIYULE9QJl8L3sCfcBsnqbJwwBwAeTLokJ9TRt9y7bK0JAzIW2y78TVVjvnQEms/yyA==} engines: {node: '>=16.4'} + '@emnapi/runtime@1.3.1': + resolution: {integrity: sha512-kEBmG8KyqtxJZv+ygbEim+KCGtIq1fC22Ms3S4ziXmYKm8uyoLX0MHONVKwp+9opg390VaKRNt4a7A9NwmpNhw==} + '@emotion/is-prop-valid@1.2.1': resolution: {integrity: sha512-61Mf7Ufx4aDxx1xlDeOm8aFFigGHE4z+0sKCa+IHCeZKiyP9RLD0Mmx7m8b9/Cf37f7NAvQOOJAbQQGVr5uERw==} @@ -1683,6 +1692,111 @@ packages: resolution: {integrity: sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==} deprecated: Use @eslint/object-schema instead + '@img/sharp-darwin-arm64@0.33.5': + resolution: {integrity: sha512-UT4p+iz/2H4twwAoLCqfA9UH5pI6DggwKEGuaPy7nCVQ8ZsiY5PIcrRvD1DzuY3qYL07NtIQcWnBSY/heikIFQ==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [arm64] + os: [darwin] + + '@img/sharp-darwin-x64@0.33.5': + resolution: {integrity: sha512-fyHac4jIc1ANYGRDxtiqelIbdWkIuQaI84Mv45KvGRRxSAa7o7d1ZKAOBaYbnepLC1WqxfpimdeWfvqqSGwR2Q==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [x64] + os: [darwin] + + '@img/sharp-libvips-darwin-arm64@1.0.4': + resolution: {integrity: sha512-XblONe153h0O2zuFfTAbQYAX2JhYmDHeWikp1LM9Hul9gVPjFY427k6dFEcOL72O01QxQsWi761svJ/ev9xEDg==} + cpu: [arm64] + os: [darwin] + + '@img/sharp-libvips-darwin-x64@1.0.4': + resolution: {integrity: sha512-xnGR8YuZYfJGmWPvmlunFaWJsb9T/AO2ykoP3Fz/0X5XV2aoYBPkX6xqCQvUTKKiLddarLaxpzNe+b1hjeWHAQ==} + cpu: [x64] + os: [darwin] + + '@img/sharp-libvips-linux-arm64@1.0.4': + resolution: {integrity: sha512-9B+taZ8DlyyqzZQnoeIvDVR/2F4EbMepXMc/NdVbkzsJbzkUjhXv/70GQJ7tdLA4YJgNP25zukcxpX2/SueNrA==} + cpu: [arm64] + os: [linux] + + '@img/sharp-libvips-linux-arm@1.0.5': + resolution: {integrity: sha512-gvcC4ACAOPRNATg/ov8/MnbxFDJqf/pDePbBnuBDcjsI8PssmjoKMAz4LtLaVi+OnSb5FK/yIOamqDwGmXW32g==} + cpu: [arm] + os: [linux] + + '@img/sharp-libvips-linux-s390x@1.0.4': + resolution: {integrity: sha512-u7Wz6ntiSSgGSGcjZ55im6uvTrOxSIS8/dgoVMoiGE9I6JAfU50yH5BoDlYA1tcuGS7g/QNtetJnxA6QEsCVTA==} + cpu: [s390x] + os: [linux] + + '@img/sharp-libvips-linux-x64@1.0.4': + resolution: {integrity: sha512-MmWmQ3iPFZr0Iev+BAgVMb3ZyC4KeFc3jFxnNbEPas60e1cIfevbtuyf9nDGIzOaW9PdnDciJm+wFFaTlj5xYw==} + cpu: [x64] + os: [linux] + + '@img/sharp-libvips-linuxmusl-arm64@1.0.4': + resolution: {integrity: sha512-9Ti+BbTYDcsbp4wfYib8Ctm1ilkugkA/uscUn6UXK1ldpC1JjiXbLfFZtRlBhjPZ5o1NCLiDbg8fhUPKStHoTA==} + cpu: [arm64] + os: [linux] + + '@img/sharp-libvips-linuxmusl-x64@1.0.4': + resolution: {integrity: sha512-viYN1KX9m+/hGkJtvYYp+CCLgnJXwiQB39damAO7WMdKWlIhmYTfHjwSbQeUK/20vY154mwezd9HflVFM1wVSw==} + cpu: [x64] + os: [linux] + + '@img/sharp-linux-arm64@0.33.5': + resolution: {integrity: sha512-JMVv+AMRyGOHtO1RFBiJy/MBsgz0x4AWrT6QoEVVTyh1E39TrCUpTRI7mx9VksGX4awWASxqCYLCV4wBZHAYxA==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [arm64] + os: [linux] + + '@img/sharp-linux-arm@0.33.5': + resolution: {integrity: sha512-JTS1eldqZbJxjvKaAkxhZmBqPRGmxgu+qFKSInv8moZ2AmT5Yib3EQ1c6gp493HvrvV8QgdOXdyaIBrhvFhBMQ==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [arm] + os: [linux] + + '@img/sharp-linux-s390x@0.33.5': + resolution: {integrity: sha512-y/5PCd+mP4CA/sPDKl2961b+C9d+vPAveS33s6Z3zfASk2j5upL6fXVPZi7ztePZ5CuH+1kW8JtvxgbuXHRa4Q==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [s390x] + os: [linux] + + '@img/sharp-linux-x64@0.33.5': + resolution: {integrity: sha512-opC+Ok5pRNAzuvq1AG0ar+1owsu842/Ab+4qvU879ippJBHvyY5n2mxF1izXqkPYlGuP/M556uh53jRLJmzTWA==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [x64] + os: [linux] + + '@img/sharp-linuxmusl-arm64@0.33.5': + resolution: {integrity: sha512-XrHMZwGQGvJg2V/oRSUfSAfjfPxO+4DkiRh6p2AFjLQztWUuY/o8Mq0eMQVIY7HJ1CDQUJlxGGZRw1a5bqmd1g==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [arm64] + os: [linux] + + '@img/sharp-linuxmusl-x64@0.33.5': + resolution: {integrity: sha512-WT+d/cgqKkkKySYmqoZ8y3pxx7lx9vVejxW/W4DOFMYVSkErR+w7mf2u8m/y4+xHe7yY9DAXQMWQhpnMuFfScw==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [x64] + os: [linux] + + '@img/sharp-wasm32@0.33.5': + resolution: {integrity: sha512-ykUW4LVGaMcU9lu9thv85CbRMAwfeadCJHRsg2GmeRa/cJxsVY9Rbd57JcMxBkKHag5U/x7TSBpScF4U8ElVzg==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [wasm32] + + '@img/sharp-win32-ia32@0.33.5': + resolution: {integrity: sha512-T36PblLaTwuVJ/zw/LaH0PdZkRz5rd3SmMHX8GSmR7vtNSP5Z6bQkExdSK7xGWyxLw4sUknBuugTelgw2faBbQ==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [ia32] + os: [win32] + + '@img/sharp-win32-x64@0.33.5': + resolution: {integrity: sha512-MpY/o8/8kj+EcnxwvrP4aTJSWw/aZ7JIGR4aBeZkZw5B7/Jn+tY9/VNwtcoGmdT7GfggGIU4kygOMSbYnOrAbg==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [x64] + os: [win32] + '@ioredis/commands@1.2.0': resolution: {integrity: sha512-Sx1pU8EM64o2BrqNpEO1CNLtKQwyhuXuqyfH7oGKCk+1a33d2r5saW8zNwm3j6BTExtjrv2BxTgzzkMwts6vGg==} @@ -2235,8 +2349,11 @@ packages: '@radix-ui/primitive@1.1.0': resolution: {integrity: sha512-4Z8dn6Upk0qk4P74xBhZ6Hd/w0mPEzOOLxy4xiPXOXqjF7jZS0VAKk7/x/H6FyY2zCkYJqePf1G5KmkmNJ4RBA==} - '@radix-ui/react-accordion@1.2.1': - resolution: {integrity: sha512-bg/l7l5QzUjgsh8kjwDFommzAshnUsuVMV5NM56QVCm+7ZckYdd9P/ExR8xG/Oup0OajVxNLaHJ1tb8mXk+nzQ==} + '@radix-ui/primitive@1.1.1': + resolution: {integrity: sha512-SJ31y+Q/zAyShtXJc8x83i9TYdbAfHZ++tUZnvjJJqFjzsdUnKsxPL6IEtBlxKkU7yzer//GQtZSV4GbldL3YA==} + + '@radix-ui/react-accordion@1.2.2': + resolution: {integrity: sha512-b1oh54x4DMCdGsB4/7ahiSrViXxaBwRPotiZNnYXjLha9vfuURSAZErki6qjDoSIV0eXx5v57XnTGVtGwnfp2g==} peerDependencies: '@types/react': '*' '@types/react-dom': '*' @@ -2248,8 +2365,8 @@ packages: '@types/react-dom': optional: true - '@radix-ui/react-arrow@1.1.0': - resolution: {integrity: sha512-FmlW1rCg7hBpEBwFbjHwCW6AmWLQM6g/v0Sn8XbP9NvmSZ2San1FpQeyPtufzOMSIx7Y4dzjlHoifhp+7NkZhw==} + '@radix-ui/react-arrow@1.1.1': + resolution: {integrity: sha512-NaVpZfmv8SKeZbn4ijN2V3jlHA9ngBG16VnIIm22nUR0Yk8KUALyBxT3KYEUnNuch9sTE8UTsS3whzBgKOL30w==} peerDependencies: '@types/react': '*' '@types/react-dom': '*' @@ -2261,8 +2378,8 @@ packages: '@types/react-dom': optional: true - '@radix-ui/react-checkbox@1.1.2': - resolution: {integrity: sha512-/i0fl686zaJbDQLNKrkCbMyDm6FQMt4jg323k7HuqitoANm9sE23Ql8yOK3Wusk34HSLKDChhMux05FnP6KUkw==} + '@radix-ui/react-checkbox@1.1.3': + resolution: {integrity: sha512-HD7/ocp8f1B3e6OHygH0n7ZKjONkhciy1Nh0yuBgObqThc3oyx+vuMfFHKAknXRHHWVE9XvXStxJFyjUmB8PIw==} peerDependencies: '@types/react': '*' '@types/react-dom': '*' @@ -2274,8 +2391,8 @@ packages: '@types/react-dom': optional: true - '@radix-ui/react-collapsible@1.1.1': - resolution: {integrity: sha512-1///SnrfQHJEofLokyczERxQbWfCGQlQ2XsCZMucVs6it+lq9iw4vXy+uDn1edlb58cOZOWSldnfPAYcT4O/Yg==} + '@radix-ui/react-collapsible@1.1.2': + resolution: {integrity: sha512-PliMB63vxz7vggcyq0IxNYk8vGDrLXVWw4+W4B8YnwI1s18x7YZYqlG9PLX7XxAJUi0g2DxP4XKJMFHh/iVh9A==} peerDependencies: '@types/react': '*' '@types/react-dom': '*' @@ -2287,8 +2404,8 @@ packages: '@types/react-dom': optional: true - '@radix-ui/react-collection@1.1.0': - resolution: {integrity: sha512-GZsZslMJEyo1VKm5L1ZJY8tGDxZNPAoUeQUIbKeJfoi7Q4kmig5AsgLMYYuyYbfjd8fBmFORAIwYAkXMnXZgZw==} + '@radix-ui/react-collection@1.1.1': + resolution: {integrity: sha512-LwT3pSho9Dljg+wY2KN2mrrh6y3qELfftINERIzBUO9e0N+t0oMTyn3k9iv+ZqgrwGkRnLpNJrsMv9BZlt2yuA==} peerDependencies: '@types/react': '*' '@types/react-dom': '*' @@ -2309,8 +2426,8 @@ packages: '@types/react': optional: true - '@radix-ui/react-context@1.1.0': - resolution: {integrity: sha512-OKrckBy+sMEgYM/sMmqmErVn0kZqrHPJze+Ql3DzYsDDp0hl0L62nx/2122/Bvps1qz645jlcu2tD9lrRSdf8A==} + '@radix-ui/react-compose-refs@1.1.1': + resolution: {integrity: sha512-Y9VzoRDSJtgFMUCoiZBDVo084VQ5hfpXxVE+NgkdNsjiDBByiImMZKKhxMwCbdHvhlENG6a833CbFkOQvTricw==} peerDependencies: '@types/react': '*' react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc @@ -2327,8 +2444,8 @@ packages: '@types/react': optional: true - '@radix-ui/react-dialog@1.1.2': - resolution: {integrity: sha512-Yj4dZtqa2o+kG61fzB0H2qUvmwBA2oyQroGLyNtBj1beo1khoQ3q1a2AO8rrQYjd8256CO9+N8L9tvsS+bnIyA==} + '@radix-ui/react-dialog@1.1.4': + resolution: {integrity: sha512-Ur7EV1IwQGCyaAuyDRiOLA5JIUZxELJljF+MbM/2NC0BYwfuRrbpS30BiQBJrVruscgUkieKkqXYDOoByaxIoA==} peerDependencies: '@types/react': '*' '@types/react-dom': '*' @@ -2349,8 +2466,8 @@ packages: '@types/react': optional: true - '@radix-ui/react-dismissable-layer@1.1.1': - resolution: {integrity: sha512-QSxg29lfr/xcev6kSz7MAlmDnzbP1eI/Dwn3Tp1ip0KT5CUELsxkekFEMVBEoykI3oV39hKT4TKZzBNMbcTZYQ==} + '@radix-ui/react-dismissable-layer@1.1.3': + resolution: {integrity: sha512-onrWn/72lQoEucDmJnr8uczSNTujT0vJnA/X5+3AkChVPowr8n1yvIKIabhWyMQeMvvmdpsvcyDqx3X1LEXCPg==} peerDependencies: '@types/react': '*' '@types/react-dom': '*' @@ -2362,8 +2479,8 @@ packages: '@types/react-dom': optional: true - '@radix-ui/react-dropdown-menu@2.1.2': - resolution: {integrity: sha512-GVZMR+eqK8/Kes0a36Qrv+i20bAPXSn8rCBTHx30w+3ECnR5o3xixAlqcVaYvLeyKUsm0aqyhWfmUcqufM8nYA==} + '@radix-ui/react-dropdown-menu@2.1.4': + resolution: {integrity: sha512-iXU1Ab5ecM+yEepGAWK8ZhMyKX4ubFdCNtol4sT9D0OVErG9PNElfx3TQhjw7n7BC5nFVz68/5//clWy+8TXzA==} peerDependencies: '@types/react': '*' '@types/react-dom': '*' @@ -2384,8 +2501,8 @@ packages: '@types/react': optional: true - '@radix-ui/react-focus-scope@1.1.0': - resolution: {integrity: sha512-200UD8zylvEyL8Bx+z76RJnASR2gRMuxlgFCPAe/Q/679a/r0eK3MBVYMb7vZODZcffZBdob1EGnky78xmVvcA==} + '@radix-ui/react-focus-scope@1.1.1': + resolution: {integrity: sha512-01omzJAYRxXdG2/he/+xy+c8a8gCydoQ1yOxnWNcRhrrBW5W+RQJ22EK1SaO8tb3WoUsuEw7mJjBozPzihDFjA==} peerDependencies: '@types/react': '*' '@types/react-dom': '*' @@ -2406,8 +2523,8 @@ packages: '@types/react': optional: true - '@radix-ui/react-menu@2.1.2': - resolution: {integrity: sha512-lZ0R4qR2Al6fZ4yCCZzu/ReTFrylHFxIqy7OezIpWF4bL0o9biKo0pFIvkaew3TyZ9Fy5gYVrR5zCGZBVbO1zg==} + '@radix-ui/react-menu@2.1.4': + resolution: {integrity: sha512-BnOgVoL6YYdHAG6DtXONaR29Eq4nvbi8rutrV/xlr3RQCMMb3yqP85Qiw/3NReozrSW+4dfLkK+rc1hb4wPU/A==} peerDependencies: '@types/react': '*' '@types/react-dom': '*' @@ -2419,8 +2536,8 @@ packages: '@types/react-dom': optional: true - '@radix-ui/react-popover@1.1.2': - resolution: {integrity: sha512-u2HRUyWW+lOiA2g0Le0tMmT55FGOEWHwPFt1EPfbLly7uXQExFo5duNKqG2DzmFXIdqOeNd+TpE8baHWJCyP9w==} + '@radix-ui/react-popover@1.1.4': + resolution: {integrity: sha512-aUACAkXx8LaFymDma+HQVji7WhvEhpFJ7+qPz17Nf4lLZqtreGOFRiNQWQmhzp7kEWg9cOyyQJpdIMUMPc/CPw==} peerDependencies: '@types/react': '*' '@types/react-dom': '*' @@ -2432,8 +2549,8 @@ packages: '@types/react-dom': optional: true - '@radix-ui/react-popper@1.2.0': - resolution: {integrity: sha512-ZnRMshKF43aBxVWPWvbj21+7TQCvhuULWJ4gNIKYpRlQt5xGRhLx66tMp8pya2UkGHTSlhpXwmjqltDYHhw7Vg==} + '@radix-ui/react-popper@1.2.1': + resolution: {integrity: sha512-3kn5Me69L+jv82EKRuQCXdYyf1DqHwD2U/sxoNgBGCB7K9TRc3bQamQ+5EPM9EvyPdli0W41sROd+ZU1dTCztw==} peerDependencies: '@types/react': '*' '@types/react-dom': '*' @@ -2445,8 +2562,8 @@ packages: '@types/react-dom': optional: true - '@radix-ui/react-portal@1.1.2': - resolution: {integrity: sha512-WeDYLGPxJb/5EGBoedyJbT0MpoULmwnIPMJMSldkuiMsBAv7N1cRdsTWZWht9vpPOiN3qyiGAtbK2is47/uMFg==} + '@radix-ui/react-portal@1.1.3': + resolution: {integrity: sha512-NciRqhXnGojhT93RPyDaMPfLH3ZSl4jjIFbZQ1b/vxvZEdHsBZ49wP9w8L3HzUQwep01LcWtkUvm0OVB5JAHTw==} peerDependencies: '@types/react': '*' '@types/react-dom': '*' @@ -2471,6 +2588,19 @@ packages: '@types/react-dom': optional: true + '@radix-ui/react-presence@1.1.2': + resolution: {integrity: sha512-18TFr80t5EVgL9x1SwF/YGtfG+l0BS0PRAlCWBDoBEiDQjeKgnNZRVJp/oVBl24sr3Gbfwc/Qpj4OcWTQMsAEg==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + '@radix-ui/react-primitive@2.0.0': resolution: {integrity: sha512-ZSpFm0/uHa8zTvKBDjLFWLo8dkr4MBsiDLz0g3gMUwqgLHz9rTaRRGYDgvZPtBJgYCBKXkS9fzmoySgr8CO6Cw==} peerDependencies: @@ -2484,8 +2614,8 @@ packages: '@types/react-dom': optional: true - '@radix-ui/react-progress@1.1.0': - resolution: {integrity: sha512-aSzvnYpP725CROcxAOEBVZZSIQVQdHgBr2QQFKySsaD14u8dNT0batuXI+AAGDdAHfXH8rbnHmjYFqVJ21KkRg==} + '@radix-ui/react-primitive@2.0.1': + resolution: {integrity: sha512-sHCWTtxwNn3L3fH8qAfnF3WbUZycW93SM1j3NFDzXBiz8D6F5UTTy8G1+WFEaiCdvCVRJWj6N2R4Xq6HdiHmDg==} peerDependencies: '@types/react': '*' '@types/react-dom': '*' @@ -2497,8 +2627,8 @@ packages: '@types/react-dom': optional: true - '@radix-ui/react-roving-focus@1.1.0': - resolution: {integrity: sha512-EA6AMGeq9AEeQDeSH0aZgG198qkfHSbvWTf1HvoDmOB5bBG/qTxjYMWUKMnYiV6J/iP/J8MEFSuB2zRU2n7ODA==} + '@radix-ui/react-progress@1.1.1': + resolution: {integrity: sha512-6diOawA84f/eMxFHcWut0aE1C2kyE9dOyCTQOMRR2C/qPiXz/X0SaiA/RLbapQaXUCmy0/hLMf9meSccD1N0pA==} peerDependencies: '@types/react': '*' '@types/react-dom': '*' @@ -2510,8 +2640,8 @@ packages: '@types/react-dom': optional: true - '@radix-ui/react-scroll-area@1.2.1': - resolution: {integrity: sha512-FnM1fHfCtEZ1JkyfH/1oMiTcFBQvHKl4vD9WnpwkLgtF+UmnXMCad6ECPTaAjcDjam+ndOEJWgHyKDGNteWSHw==} + '@radix-ui/react-roving-focus@1.1.1': + resolution: {integrity: sha512-QE1RoxPGJ/Nm8Qmk0PxP8ojmoaS67i0s7hVssS7KuI2FQoc/uzVlZsqKfQvxPE6D8hICCPHJ4D88zNhT3OOmkw==} peerDependencies: '@types/react': '*' '@types/react-dom': '*' @@ -2523,8 +2653,8 @@ packages: '@types/react-dom': optional: true - '@radix-ui/react-select@2.1.2': - resolution: {integrity: sha512-rZJtWmorC7dFRi0owDmoijm6nSJH1tVw64QGiNIZ9PNLyBDtG+iAq+XGsya052At4BfarzY/Dhv9wrrUr6IMZA==} + '@radix-ui/react-scroll-area@1.2.0': + resolution: {integrity: sha512-q2jMBdsJ9zB7QG6ngQNzNwlvxLQqONyL58QbEGwuyRZZb/ARQwk3uQVbCF7GvQVOtV6EU/pDxAw3zRzJZI3rpQ==} peerDependencies: '@types/react': '*' '@types/react-dom': '*' @@ -2536,8 +2666,21 @@ packages: '@types/react-dom': optional: true - '@radix-ui/react-slider@1.2.1': - resolution: {integrity: sha512-bEzQoDW0XP+h/oGbutF5VMWJPAl/UU8IJjr7h02SOHDIIIxq+cep8nItVNoBV+OMmahCdqdF38FTpmXoqQUGvw==} + '@radix-ui/react-select@2.1.4': + resolution: {integrity: sha512-pOkb2u8KgO47j/h7AylCj7dJsm69BXcjkrvTqMptFqsE2i0p8lHkfgneXKjAgPzBMivnoMyt8o4KiV4wYzDdyQ==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-slider@1.2.2': + resolution: {integrity: sha512-sNlU06ii1/ZcbHf8I9En54ZPW0Vil/yPVg4vQMcFNjrIx51jsHbFl1HYHQvCIWJSr1q0ZmA+iIs/ZTv8h7HHSA==} peerDependencies: '@types/react': '*' '@types/react-dom': '*' @@ -2558,8 +2701,17 @@ packages: '@types/react': optional: true - '@radix-ui/react-tooltip@1.1.4': - resolution: {integrity: sha512-QpObUH/ZlpaO4YgHSaYzrLO2VuO+ZBFFgGzjMUPwtiYnAzzNNDPJeEGRrT7qNOrWm/Jr08M1vlp+vTHtnSQ0Uw==} + '@radix-ui/react-slot@1.1.1': + resolution: {integrity: sha512-RApLLOcINYJA+dMVbOju7MYv1Mb2EBp2nH4HdDzXTSyaR5optlm6Otrz1euW3HbdOR8UmmFK06TD+A9frYWv+g==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-tooltip@1.1.6': + resolution: {integrity: sha512-TLB5D8QLExS1uDn7+wH/bjEmRurNMTzNrtq7IjaS4kjion9NtzsTGkvR5+i7yc9q01Pi2KMM2cN3f8UG4IvvXA==} peerDependencies: '@types/react': '*' '@types/react-dom': '*' @@ -2634,8 +2786,8 @@ packages: '@types/react': optional: true - '@radix-ui/react-visually-hidden@1.1.0': - resolution: {integrity: sha512-N8MDZqtgCgG5S3aV60INAB475osJousYpZ4cTJ2cFbMpdHS5Y6loLTH8LPtkj2QN0x93J30HT/M3qJXM0+lyeQ==} + '@radix-ui/react-visually-hidden@1.1.1': + resolution: {integrity: sha512-vVfA2IZ9q/J+gEamvj761Oq1FpWgCDaNOOIfbPVp2MVPLEomUr5+Vf7kJGwQ24YxZSlQVar7Bes8kyTo5Dshpg==} peerDependencies: '@types/react': '*' '@types/react-dom': '*' @@ -4062,6 +4214,10 @@ packages: resolution: {integrity: sha512-Xcz9l0z7y9yQ9rdDaxlmaI4uJHf/T8g9hOEzJcsEqX2SjCj4J20uK7+ldkDHMbpJDK76wF7xEIgxc/vSlsfw5w==} engines: {node: '>=10.12.0'} + author-regex@1.0.0: + resolution: {integrity: sha512-KbWgR8wOYRAPekEmMXrYYdc7BRyhn2Ftk7KWfMUnQ43hFdojWEFRxhhRUm3/OFEdPa1r0KAvTTg9YQK57xTe0g==} + engines: {node: '>=0.8'} + autoprefixer@10.4.20: resolution: {integrity: sha512-XY25y5xSv/wEoqzDyXXME4AFfkZI0P23z6Fs3YgymDnKJkCGOnkL0iTxCa85UTqaSgfcqyf3UA6+c7wUvx/16g==} engines: {node: ^10 || ^12 || >=14} @@ -4496,10 +4652,17 @@ packages: color-name@1.1.4: resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} + color-string@1.9.1: + resolution: {integrity: sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==} + color-support@1.1.3: resolution: {integrity: sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==} hasBin: true + color@4.2.3: + resolution: {integrity: sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A==} + engines: {node: '>=12.5.0'} + colord@2.9.3: resolution: {integrity: sha512-jeC1axXpnb0/2nn/Y1LPuLdgXBLH7aDcHu4KEKfqw3CUhX7ZpfBSlPKyqXE6btIgEzfWtrX3/tyBCaCvXvMkOw==} @@ -5755,6 +5918,17 @@ packages: fastq@1.15.0: resolution: {integrity: sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==} + favicons-webpack-plugin@6.0.1: + resolution: {integrity: sha512-Gl0Co4zIZq74EKXdpfe8FaoJqbuf0undV4UgpsL34vqICRAYUDwQdp3D+z+uxEOV0i9o+vHDn7Q6jaSxRiDJUA==} + engines: {node: '>=16'} + peerDependencies: + favicons: ^7.0.1 + webpack: ^5.0.0 + + favicons@7.2.0: + resolution: {integrity: sha512-k/2rVBRIRzOeom3wI9jBPaSEvoTSQEW4iM0EveBmBBKFxO8mSyyRWtDlfC3VnEfu0avmjrMzy8/ZFPSe6F71Hw==} + engines: {node: '>=14.0.0'} + faye-websocket@0.11.4: resolution: {integrity: sha512-CzbClwlXAuiRQAlUyfqPgvPoNKTckTPGfwZV4ZdAhVcP2lh9KUxJg2b5GkE7XbjKQ3YJnQ9z6D9ntLAlB+tP8g==} engines: {node: '>=0.8.0'} @@ -5806,6 +5980,9 @@ packages: resolution: {integrity: sha512-wXZV5emFEjrridIgED11OoUKLxiYjAcqot/NJdAkOhlJ+vGzwhOAfcG5OX1jP+S0PcjEn8bdMJv+g2jwQ3Onig==} engines: {node: '>=8'} + find-root@1.1.0: + resolution: {integrity: sha512-NKfW6bec6GfKc0SGx1e07QZY9PE99u0Bft/0rzSD5k3sO/vwkVUpDUKVm5Gpp5Ue3YfShPFTX2070tDs5kB9Ng==} + find-up@3.0.0: resolution: {integrity: sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==} engines: {node: '>=6'} @@ -6443,6 +6620,9 @@ packages: is-arrayish@0.2.1: resolution: {integrity: sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==} + is-arrayish@0.3.2: + resolution: {integrity: sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==} + is-async-function@2.0.0: resolution: {integrity: sha512-Y1JXKrfykRJGdlDwdKlLpLyMIiWqWvuSd17TvZk68PLAOGOoF4Xyav1z0Xhoi+gCYjZVeC5SI+hYFOfvXmGRCA==} engines: {node: '>= 0.4'} @@ -7896,6 +8076,10 @@ packages: parse-asn1@5.1.6: resolution: {integrity: sha512-RnZRo1EPU6JBnra2vGHj0yhp6ebyjBZpmUCLHWiFhxlzvBCCpAuZ7elsBp1PVAbQN0/04VD/19rfzlBSwLstMw==} + parse-author@2.0.0: + resolution: {integrity: sha512-yx5DfvkN8JsHL2xk2Os9oTia467qnvRgey4ahSm2X8epehBLx/gWLcy5KI+Y36ful5DzGbCS6RazqZGgy1gHNw==} + engines: {node: '>=0.10.0'} + parse-entities@4.0.1: resolution: {integrity: sha512-SWzvYcSJh4d/SGLIOQfZ/CoNv6BTlI6YEQ7Nj82oDVnRpwe/Z/F1EMx42x3JAOwGBlCjeCH0BRJQbQ/opHL17w==} @@ -8678,22 +8862,22 @@ packages: resolution: {integrity: sha512-jCvmsr+1IUSMUyzOkRcvnVbX3ZYC6g9TDrDbFuFmRDq7PD4yaGbLKNQL6k2jnArV8hjYxh7hVhAZB6s9HDGpZA==} engines: {node: '>=0.10.0'} - react-remove-scroll-bar@2.3.6: - resolution: {integrity: sha512-DtSYaao4mBmX+HDo5YWYdBWQwYIQQshUV/dVxFxK+KM26Wjwp1gZ6rv6OC3oujI6Bfu6Xyg3TwK533AQutsn/g==} + react-remove-scroll-bar@2.3.8: + resolution: {integrity: sha512-9r+yi9+mgU33AKcj6IbT9oRCO78WriSj6t/cF8DWBZJ9aOGPOTEDvdUDz1FwKim7QXWwmHqtdHnRJfhAxEG46Q==} engines: {node: '>=10'} peerDependencies: - '@types/react': ^16.8.0 || ^17.0.0 || ^18.0.0 - react: ^16.8.0 || ^17.0.0 || ^18.0.0 + '@types/react': '*' + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 peerDependenciesMeta: '@types/react': optional: true - react-remove-scroll@2.6.0: - resolution: {integrity: sha512-I2U4JVEsQenxDAKaVa3VZ/JeJZe0/2DxPWL8Tj8yLKctQJQiZM52pn/GWFpSp8dftjM3pSAHVJZscAnC/y+ySQ==} + react-remove-scroll@2.6.2: + resolution: {integrity: sha512-KmONPx5fnlXYJQqC62Q+lwIeAk64ws/cUw6omIumRzMRPqgnYqhSSti99nbj0Ry13bv7dF+BKn7NB+OqkdZGTw==} engines: {node: '>=10'} peerDependencies: - '@types/react': ^16.8.0 || ^17.0.0 || ^18.0.0 - react: ^16.8.0 || ^17.0.0 || ^18.0.0 + '@types/react': '*' + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc peerDependenciesMeta: '@types/react': optional: true @@ -8721,6 +8905,16 @@ packages: '@types/react': optional: true + react-style-singleton@2.2.3: + resolution: {integrity: sha512-b6jSvxvVnyptAiLjbkWLE/lOnR4lfTtDAl+eUC7RZy+QQWc6wRzIV2CE6xBuMmDxc2qIihtDCZD5NPOFl7fRBQ==} + engines: {node: '>=10'} + peerDependencies: + '@types/react': '*' + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + react@18.3.1: resolution: {integrity: sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==} engines: {node: '>=0.10.0'} @@ -9119,6 +9313,10 @@ packages: shallowequal@1.1.0: resolution: {integrity: sha512-y0m1JoUZSlPAjXVtPPW70aZWfIL/dSP7AFkRnniLCrK/8MDKog3TySTBmckD+RObVxH0v4Tox67+F14PdED2oQ==} + sharp@0.33.5: + resolution: {integrity: sha512-haPVm1EkS9pgvHrQ/F3Xy+hgcuMV0Wm9vfIBSiwZ05k+xgb0PkBQpGsAA/oWdDobNaZTH5ppvHtzCFbnSEwHVw==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + shebang-command@1.2.0: resolution: {integrity: sha512-EV3L1+UQWGor21OmnvojK36mhg+TyIKDh3iFBKBohr5xeXIhNBcx8oWdgkTEEQ+BEFFYdLRuqMfd5L84N1V5Vg==} engines: {node: '>=0.10.0'} @@ -9157,6 +9355,9 @@ packages: peerDependencies: webpack: '>=2.0.0' + simple-swizzle@0.2.2: + resolution: {integrity: sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==} + simple-update-notifier@1.1.0: resolution: {integrity: sha512-VpsrsJSUcJEseSbMHkrsrAVSdvVS5I96Qo1QAQ4FxQ9wXFcB+pjj7FB7/us9+GcgfW4ziHtYMc1J0PLczb55mg==} engines: {node: '>=8.10.0'} @@ -10039,12 +10240,12 @@ packages: resolution: {integrity: sha512-oCwdVC7mTuWiPyjLUz/COz5TLk6wgp0RCsN+wHZ2Ekneac9w8uuV0njcbbie2ME+Vs+d6duwmYuR3HgQXs1fOg==} engines: {node: '>= 0.4'} - use-callback-ref@1.3.2: - resolution: {integrity: sha512-elOQwe6Q8gqZgDA8mrh44qRTQqpIHDcZ3hXTLjBe1i4ph8XpNJnO+aQf3NaG+lriLopI4HMx9VjQLfPQ6vhnoA==} + use-callback-ref@1.3.3: + resolution: {integrity: sha512-jQL3lRnocaFtu3V00JToYz/4QkNWswxijDaCVNZRiRTO3HQDLsdu1ZtmIUvV4yPp+rvWm5j0y0TG/S61cuijTg==} engines: {node: '>=10'} peerDependencies: - '@types/react': ^16.8.0 || ^17.0.0 || ^18.0.0 - react: ^16.8.0 || ^17.0.0 || ^18.0.0 + '@types/react': '*' + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc peerDependenciesMeta: '@types/react': optional: true @@ -10373,9 +10574,17 @@ packages: resolution: {integrity: sha512-ICP2e+jsHvAj2E2lIHxa5tjXRlKDJo4IdvPvCXbXQGdzSfmSpNVyIKMvoZHjDY9DP0zV17iI85o90vRFXNccRw==} engines: {node: '>=12'} + xml2js@0.6.2: + resolution: {integrity: sha512-T4rieHaC1EXcES0Kxxj4JWgaUQHDk+qwHcYOCFHfiwKz7tOVPLq7Hjq9dM1WCMhylqMEfP7hMcOIChvotiZegA==} + engines: {node: '>=4.0.0'} + xml@1.0.1: resolution: {integrity: sha512-huCv9IH9Tcf95zuYCsQraZtWnJvBtLVE0QHMOs8bWyZAFZNDcYjsPq1nEx8jKA9y+Beo9v+7OBPRisQTjinQMw==} + xmlbuilder@11.0.1: + resolution: {integrity: sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA==} + engines: {node: '>=4.0'} + xmlbuilder@15.1.1: resolution: {integrity: sha512-yMqGBqtXyeN1e3TGYvgNgDVZ3j84W4cwkOXQswghol6APgZWaff9lnbvN7MHYJOiXsvGPXtjTYJEiC9J2wv9Eg==} engines: {node: '>=8.0'} @@ -11603,6 +11812,11 @@ snapshots: transitivePeerDependencies: - supports-color + '@emnapi/runtime@1.3.1': + dependencies: + tslib: 2.7.0 + optional: true + '@emotion/is-prop-valid@1.2.1': dependencies: '@emotion/memoize': 0.8.1 @@ -11882,6 +12096,81 @@ snapshots: '@humanwhocodes/object-schema@2.0.3': {} + '@img/sharp-darwin-arm64@0.33.5': + optionalDependencies: + '@img/sharp-libvips-darwin-arm64': 1.0.4 + optional: true + + '@img/sharp-darwin-x64@0.33.5': + optionalDependencies: + '@img/sharp-libvips-darwin-x64': 1.0.4 + optional: true + + '@img/sharp-libvips-darwin-arm64@1.0.4': + optional: true + + '@img/sharp-libvips-darwin-x64@1.0.4': + optional: true + + '@img/sharp-libvips-linux-arm64@1.0.4': + optional: true + + '@img/sharp-libvips-linux-arm@1.0.5': + optional: true + + '@img/sharp-libvips-linux-s390x@1.0.4': + optional: true + + '@img/sharp-libvips-linux-x64@1.0.4': + optional: true + + '@img/sharp-libvips-linuxmusl-arm64@1.0.4': + optional: true + + '@img/sharp-libvips-linuxmusl-x64@1.0.4': + optional: true + + '@img/sharp-linux-arm64@0.33.5': + optionalDependencies: + '@img/sharp-libvips-linux-arm64': 1.0.4 + optional: true + + '@img/sharp-linux-arm@0.33.5': + optionalDependencies: + '@img/sharp-libvips-linux-arm': 1.0.5 + optional: true + + '@img/sharp-linux-s390x@0.33.5': + optionalDependencies: + '@img/sharp-libvips-linux-s390x': 1.0.4 + optional: true + + '@img/sharp-linux-x64@0.33.5': + optionalDependencies: + '@img/sharp-libvips-linux-x64': 1.0.4 + optional: true + + '@img/sharp-linuxmusl-arm64@0.33.5': + optionalDependencies: + '@img/sharp-libvips-linuxmusl-arm64': 1.0.4 + optional: true + + '@img/sharp-linuxmusl-x64@0.33.5': + optionalDependencies: + '@img/sharp-libvips-linuxmusl-x64': 1.0.4 + optional: true + + '@img/sharp-wasm32@0.33.5': + dependencies: + '@emnapi/runtime': 1.3.1 + optional: true + + '@img/sharp-win32-ia32@0.33.5': + optional: true + + '@img/sharp-win32-x64@0.33.5': + optional: true + '@ioredis/commands@1.2.0': {} '@isaacs/cliui@8.0.2': @@ -12761,16 +13050,18 @@ snapshots: '@radix-ui/primitive@1.1.0': {} - '@radix-ui/react-accordion@1.2.1(@types/react-dom@18.0.5)(@types/react@18.0.14)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@radix-ui/primitive@1.1.1': {} + + '@radix-ui/react-accordion@1.2.2(@types/react-dom@18.0.5)(@types/react@18.0.14)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: - '@radix-ui/primitive': 1.1.0 - '@radix-ui/react-collapsible': 1.1.1(@types/react-dom@18.0.5)(@types/react@18.0.14)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-collection': 1.1.0(@types/react-dom@18.0.5)(@types/react@18.0.14)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-compose-refs': 1.1.0(@types/react@18.0.14)(react@18.3.1) + '@radix-ui/primitive': 1.1.1 + '@radix-ui/react-collapsible': 1.1.2(@types/react-dom@18.0.5)(@types/react@18.0.14)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-collection': 1.1.1(@types/react-dom@18.0.5)(@types/react@18.0.14)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-compose-refs': 1.1.1(@types/react@18.0.14)(react@18.3.1) '@radix-ui/react-context': 1.1.1(@types/react@18.0.14)(react@18.3.1) '@radix-ui/react-direction': 1.1.0(@types/react@18.0.14)(react@18.3.1) '@radix-ui/react-id': 1.1.0(@types/react@18.0.14)(react@18.3.1) - '@radix-ui/react-primitive': 2.0.0(@types/react-dom@18.0.5)(@types/react@18.0.14)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-primitive': 2.0.1(@types/react-dom@18.0.5)(@types/react@18.0.14)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@radix-ui/react-use-controllable-state': 1.1.0(@types/react@18.0.14)(react@18.3.1) react: 18.3.1 react-dom: 18.3.1(react@18.3.1) @@ -12778,22 +13069,22 @@ snapshots: '@types/react': 18.0.14 '@types/react-dom': 18.0.5 - '@radix-ui/react-arrow@1.1.0(@types/react-dom@18.0.5)(@types/react@18.0.14)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@radix-ui/react-arrow@1.1.1(@types/react-dom@18.0.5)(@types/react@18.0.14)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: - '@radix-ui/react-primitive': 2.0.0(@types/react-dom@18.0.5)(@types/react@18.0.14)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-primitive': 2.0.1(@types/react-dom@18.0.5)(@types/react@18.0.14)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) react: 18.3.1 react-dom: 18.3.1(react@18.3.1) optionalDependencies: '@types/react': 18.0.14 '@types/react-dom': 18.0.5 - '@radix-ui/react-checkbox@1.1.2(@types/react-dom@18.0.5)(@types/react@18.0.14)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@radix-ui/react-checkbox@1.1.3(@types/react-dom@18.0.5)(@types/react@18.0.14)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: - '@radix-ui/primitive': 1.1.0 - '@radix-ui/react-compose-refs': 1.1.0(@types/react@18.0.14)(react@18.3.1) + '@radix-ui/primitive': 1.1.1 + '@radix-ui/react-compose-refs': 1.1.1(@types/react@18.0.14)(react@18.3.1) '@radix-ui/react-context': 1.1.1(@types/react@18.0.14)(react@18.3.1) - '@radix-ui/react-presence': 1.1.1(@types/react-dom@18.0.5)(@types/react@18.0.14)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-primitive': 2.0.0(@types/react-dom@18.0.5)(@types/react@18.0.14)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-presence': 1.1.2(@types/react-dom@18.0.5)(@types/react@18.0.14)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-primitive': 2.0.1(@types/react-dom@18.0.5)(@types/react@18.0.14)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@radix-ui/react-use-controllable-state': 1.1.0(@types/react@18.0.14)(react@18.3.1) '@radix-ui/react-use-previous': 1.1.0(@types/react@18.0.14)(react@18.3.1) '@radix-ui/react-use-size': 1.1.0(@types/react@18.0.14)(react@18.3.1) @@ -12803,14 +13094,14 @@ snapshots: '@types/react': 18.0.14 '@types/react-dom': 18.0.5 - '@radix-ui/react-collapsible@1.1.1(@types/react-dom@18.0.5)(@types/react@18.0.14)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@radix-ui/react-collapsible@1.1.2(@types/react-dom@18.0.5)(@types/react@18.0.14)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: - '@radix-ui/primitive': 1.1.0 - '@radix-ui/react-compose-refs': 1.1.0(@types/react@18.0.14)(react@18.3.1) + '@radix-ui/primitive': 1.1.1 + '@radix-ui/react-compose-refs': 1.1.1(@types/react@18.0.14)(react@18.3.1) '@radix-ui/react-context': 1.1.1(@types/react@18.0.14)(react@18.3.1) '@radix-ui/react-id': 1.1.0(@types/react@18.0.14)(react@18.3.1) - '@radix-ui/react-presence': 1.1.1(@types/react-dom@18.0.5)(@types/react@18.0.14)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-primitive': 2.0.0(@types/react-dom@18.0.5)(@types/react@18.0.14)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-presence': 1.1.2(@types/react-dom@18.0.5)(@types/react@18.0.14)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-primitive': 2.0.1(@types/react-dom@18.0.5)(@types/react@18.0.14)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@radix-ui/react-use-controllable-state': 1.1.0(@types/react@18.0.14)(react@18.3.1) '@radix-ui/react-use-layout-effect': 1.1.0(@types/react@18.0.14)(react@18.3.1) react: 18.3.1 @@ -12819,12 +13110,12 @@ snapshots: '@types/react': 18.0.14 '@types/react-dom': 18.0.5 - '@radix-ui/react-collection@1.1.0(@types/react-dom@18.0.5)(@types/react@18.0.14)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@radix-ui/react-collection@1.1.1(@types/react-dom@18.0.5)(@types/react@18.0.14)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: - '@radix-ui/react-compose-refs': 1.1.0(@types/react@18.0.14)(react@18.3.1) - '@radix-ui/react-context': 1.1.0(@types/react@18.0.14)(react@18.3.1) - '@radix-ui/react-primitive': 2.0.0(@types/react-dom@18.0.5)(@types/react@18.0.14)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-slot': 1.1.0(@types/react@18.0.14)(react@18.3.1) + '@radix-ui/react-compose-refs': 1.1.1(@types/react@18.0.14)(react@18.3.1) + '@radix-ui/react-context': 1.1.1(@types/react@18.0.14)(react@18.3.1) + '@radix-ui/react-primitive': 2.0.1(@types/react-dom@18.0.5)(@types/react@18.0.14)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-slot': 1.1.1(@types/react@18.0.14)(react@18.3.1) react: 18.3.1 react-dom: 18.3.1(react@18.3.1) optionalDependencies: @@ -12837,7 +13128,7 @@ snapshots: optionalDependencies: '@types/react': 18.0.14 - '@radix-ui/react-context@1.1.0(@types/react@18.0.14)(react@18.3.1)': + '@radix-ui/react-compose-refs@1.1.1(@types/react@18.0.14)(react@18.3.1)': dependencies: react: 18.3.1 optionalDependencies: @@ -12849,24 +13140,24 @@ snapshots: optionalDependencies: '@types/react': 18.0.14 - '@radix-ui/react-dialog@1.1.2(@types/react-dom@18.0.5)(@types/react@18.0.14)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@radix-ui/react-dialog@1.1.4(@types/react-dom@18.0.5)(@types/react@18.0.14)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: - '@radix-ui/primitive': 1.1.0 - '@radix-ui/react-compose-refs': 1.1.0(@types/react@18.0.14)(react@18.3.1) + '@radix-ui/primitive': 1.1.1 + '@radix-ui/react-compose-refs': 1.1.1(@types/react@18.0.14)(react@18.3.1) '@radix-ui/react-context': 1.1.1(@types/react@18.0.14)(react@18.3.1) - '@radix-ui/react-dismissable-layer': 1.1.1(@types/react-dom@18.0.5)(@types/react@18.0.14)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-dismissable-layer': 1.1.3(@types/react-dom@18.0.5)(@types/react@18.0.14)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@radix-ui/react-focus-guards': 1.1.1(@types/react@18.0.14)(react@18.3.1) - '@radix-ui/react-focus-scope': 1.1.0(@types/react-dom@18.0.5)(@types/react@18.0.14)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-focus-scope': 1.1.1(@types/react-dom@18.0.5)(@types/react@18.0.14)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@radix-ui/react-id': 1.1.0(@types/react@18.0.14)(react@18.3.1) - '@radix-ui/react-portal': 1.1.2(@types/react-dom@18.0.5)(@types/react@18.0.14)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-presence': 1.1.1(@types/react-dom@18.0.5)(@types/react@18.0.14)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-primitive': 2.0.0(@types/react-dom@18.0.5)(@types/react@18.0.14)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-slot': 1.1.0(@types/react@18.0.14)(react@18.3.1) + '@radix-ui/react-portal': 1.1.3(@types/react-dom@18.0.5)(@types/react@18.0.14)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-presence': 1.1.2(@types/react-dom@18.0.5)(@types/react@18.0.14)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-primitive': 2.0.1(@types/react-dom@18.0.5)(@types/react@18.0.14)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-slot': 1.1.1(@types/react@18.0.14)(react@18.3.1) '@radix-ui/react-use-controllable-state': 1.1.0(@types/react@18.0.14)(react@18.3.1) aria-hidden: 1.2.4 react: 18.3.1 react-dom: 18.3.1(react@18.3.1) - react-remove-scroll: 2.6.0(@types/react@18.0.14)(react@18.3.1) + react-remove-scroll: 2.6.2(@types/react@18.0.14)(react@18.3.1) optionalDependencies: '@types/react': 18.0.14 '@types/react-dom': 18.0.5 @@ -12877,11 +13168,11 @@ snapshots: optionalDependencies: '@types/react': 18.0.14 - '@radix-ui/react-dismissable-layer@1.1.1(@types/react-dom@18.0.5)(@types/react@18.0.14)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@radix-ui/react-dismissable-layer@1.1.3(@types/react-dom@18.0.5)(@types/react@18.0.14)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: - '@radix-ui/primitive': 1.1.0 - '@radix-ui/react-compose-refs': 1.1.0(@types/react@18.0.14)(react@18.3.1) - '@radix-ui/react-primitive': 2.0.0(@types/react-dom@18.0.5)(@types/react@18.0.14)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/primitive': 1.1.1 + '@radix-ui/react-compose-refs': 1.1.1(@types/react@18.0.14)(react@18.3.1) + '@radix-ui/react-primitive': 2.0.1(@types/react-dom@18.0.5)(@types/react@18.0.14)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@radix-ui/react-use-callback-ref': 1.1.0(@types/react@18.0.14)(react@18.3.1) '@radix-ui/react-use-escape-keydown': 1.1.0(@types/react@18.0.14)(react@18.3.1) react: 18.3.1 @@ -12890,14 +13181,14 @@ snapshots: '@types/react': 18.0.14 '@types/react-dom': 18.0.5 - '@radix-ui/react-dropdown-menu@2.1.2(@types/react-dom@18.0.5)(@types/react@18.0.14)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@radix-ui/react-dropdown-menu@2.1.4(@types/react-dom@18.0.5)(@types/react@18.0.14)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: - '@radix-ui/primitive': 1.1.0 - '@radix-ui/react-compose-refs': 1.1.0(@types/react@18.0.14)(react@18.3.1) + '@radix-ui/primitive': 1.1.1 + '@radix-ui/react-compose-refs': 1.1.1(@types/react@18.0.14)(react@18.3.1) '@radix-ui/react-context': 1.1.1(@types/react@18.0.14)(react@18.3.1) '@radix-ui/react-id': 1.1.0(@types/react@18.0.14)(react@18.3.1) - '@radix-ui/react-menu': 2.1.2(@types/react-dom@18.0.5)(@types/react@18.0.14)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-primitive': 2.0.0(@types/react-dom@18.0.5)(@types/react@18.0.14)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-menu': 2.1.4(@types/react-dom@18.0.5)(@types/react@18.0.14)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-primitive': 2.0.1(@types/react-dom@18.0.5)(@types/react@18.0.14)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@radix-ui/react-use-controllable-state': 1.1.0(@types/react@18.0.14)(react@18.3.1) react: 18.3.1 react-dom: 18.3.1(react@18.3.1) @@ -12911,10 +13202,10 @@ snapshots: optionalDependencies: '@types/react': 18.0.14 - '@radix-ui/react-focus-scope@1.1.0(@types/react-dom@18.0.5)(@types/react@18.0.14)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@radix-ui/react-focus-scope@1.1.1(@types/react-dom@18.0.5)(@types/react@18.0.14)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: - '@radix-ui/react-compose-refs': 1.1.0(@types/react@18.0.14)(react@18.3.1) - '@radix-ui/react-primitive': 2.0.0(@types/react-dom@18.0.5)(@types/react@18.0.14)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-compose-refs': 1.1.1(@types/react@18.0.14)(react@18.3.1) + '@radix-ui/react-primitive': 2.0.1(@types/react-dom@18.0.5)(@types/react@18.0.14)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@radix-ui/react-use-callback-ref': 1.1.0(@types/react@18.0.14)(react@18.3.1) react: 18.3.1 react-dom: 18.3.1(react@18.3.1) @@ -12929,62 +13220,62 @@ snapshots: optionalDependencies: '@types/react': 18.0.14 - '@radix-ui/react-menu@2.1.2(@types/react-dom@18.0.5)(@types/react@18.0.14)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@radix-ui/react-menu@2.1.4(@types/react-dom@18.0.5)(@types/react@18.0.14)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: - '@radix-ui/primitive': 1.1.0 - '@radix-ui/react-collection': 1.1.0(@types/react-dom@18.0.5)(@types/react@18.0.14)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-compose-refs': 1.1.0(@types/react@18.0.14)(react@18.3.1) + '@radix-ui/primitive': 1.1.1 + '@radix-ui/react-collection': 1.1.1(@types/react-dom@18.0.5)(@types/react@18.0.14)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-compose-refs': 1.1.1(@types/react@18.0.14)(react@18.3.1) '@radix-ui/react-context': 1.1.1(@types/react@18.0.14)(react@18.3.1) '@radix-ui/react-direction': 1.1.0(@types/react@18.0.14)(react@18.3.1) - '@radix-ui/react-dismissable-layer': 1.1.1(@types/react-dom@18.0.5)(@types/react@18.0.14)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-dismissable-layer': 1.1.3(@types/react-dom@18.0.5)(@types/react@18.0.14)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@radix-ui/react-focus-guards': 1.1.1(@types/react@18.0.14)(react@18.3.1) - '@radix-ui/react-focus-scope': 1.1.0(@types/react-dom@18.0.5)(@types/react@18.0.14)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-focus-scope': 1.1.1(@types/react-dom@18.0.5)(@types/react@18.0.14)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@radix-ui/react-id': 1.1.0(@types/react@18.0.14)(react@18.3.1) - '@radix-ui/react-popper': 1.2.0(@types/react-dom@18.0.5)(@types/react@18.0.14)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-portal': 1.1.2(@types/react-dom@18.0.5)(@types/react@18.0.14)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-presence': 1.1.1(@types/react-dom@18.0.5)(@types/react@18.0.14)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-primitive': 2.0.0(@types/react-dom@18.0.5)(@types/react@18.0.14)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-roving-focus': 1.1.0(@types/react-dom@18.0.5)(@types/react@18.0.14)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-slot': 1.1.0(@types/react@18.0.14)(react@18.3.1) + '@radix-ui/react-popper': 1.2.1(@types/react-dom@18.0.5)(@types/react@18.0.14)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-portal': 1.1.3(@types/react-dom@18.0.5)(@types/react@18.0.14)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-presence': 1.1.2(@types/react-dom@18.0.5)(@types/react@18.0.14)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-primitive': 2.0.1(@types/react-dom@18.0.5)(@types/react@18.0.14)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-roving-focus': 1.1.1(@types/react-dom@18.0.5)(@types/react@18.0.14)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-slot': 1.1.1(@types/react@18.0.14)(react@18.3.1) '@radix-ui/react-use-callback-ref': 1.1.0(@types/react@18.0.14)(react@18.3.1) aria-hidden: 1.2.4 react: 18.3.1 react-dom: 18.3.1(react@18.3.1) - react-remove-scroll: 2.6.0(@types/react@18.0.14)(react@18.3.1) + react-remove-scroll: 2.6.2(@types/react@18.0.14)(react@18.3.1) optionalDependencies: '@types/react': 18.0.14 '@types/react-dom': 18.0.5 - '@radix-ui/react-popover@1.1.2(@types/react-dom@18.0.5)(@types/react@18.0.14)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@radix-ui/react-popover@1.1.4(@types/react-dom@18.0.5)(@types/react@18.0.14)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: - '@radix-ui/primitive': 1.1.0 - '@radix-ui/react-compose-refs': 1.1.0(@types/react@18.0.14)(react@18.3.1) + '@radix-ui/primitive': 1.1.1 + '@radix-ui/react-compose-refs': 1.1.1(@types/react@18.0.14)(react@18.3.1) '@radix-ui/react-context': 1.1.1(@types/react@18.0.14)(react@18.3.1) - '@radix-ui/react-dismissable-layer': 1.1.1(@types/react-dom@18.0.5)(@types/react@18.0.14)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-dismissable-layer': 1.1.3(@types/react-dom@18.0.5)(@types/react@18.0.14)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@radix-ui/react-focus-guards': 1.1.1(@types/react@18.0.14)(react@18.3.1) - '@radix-ui/react-focus-scope': 1.1.0(@types/react-dom@18.0.5)(@types/react@18.0.14)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-focus-scope': 1.1.1(@types/react-dom@18.0.5)(@types/react@18.0.14)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@radix-ui/react-id': 1.1.0(@types/react@18.0.14)(react@18.3.1) - '@radix-ui/react-popper': 1.2.0(@types/react-dom@18.0.5)(@types/react@18.0.14)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-portal': 1.1.2(@types/react-dom@18.0.5)(@types/react@18.0.14)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-presence': 1.1.1(@types/react-dom@18.0.5)(@types/react@18.0.14)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-primitive': 2.0.0(@types/react-dom@18.0.5)(@types/react@18.0.14)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-slot': 1.1.0(@types/react@18.0.14)(react@18.3.1) + '@radix-ui/react-popper': 1.2.1(@types/react-dom@18.0.5)(@types/react@18.0.14)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-portal': 1.1.3(@types/react-dom@18.0.5)(@types/react@18.0.14)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-presence': 1.1.2(@types/react-dom@18.0.5)(@types/react@18.0.14)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-primitive': 2.0.1(@types/react-dom@18.0.5)(@types/react@18.0.14)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-slot': 1.1.1(@types/react@18.0.14)(react@18.3.1) '@radix-ui/react-use-controllable-state': 1.1.0(@types/react@18.0.14)(react@18.3.1) aria-hidden: 1.2.4 react: 18.3.1 react-dom: 18.3.1(react@18.3.1) - react-remove-scroll: 2.6.0(@types/react@18.0.14)(react@18.3.1) + react-remove-scroll: 2.6.2(@types/react@18.0.14)(react@18.3.1) optionalDependencies: '@types/react': 18.0.14 '@types/react-dom': 18.0.5 - '@radix-ui/react-popper@1.2.0(@types/react-dom@18.0.5)(@types/react@18.0.14)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@radix-ui/react-popper@1.2.1(@types/react-dom@18.0.5)(@types/react@18.0.14)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: '@floating-ui/react-dom': 2.1.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-arrow': 1.1.0(@types/react-dom@18.0.5)(@types/react@18.0.14)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-compose-refs': 1.1.0(@types/react@18.0.14)(react@18.3.1) - '@radix-ui/react-context': 1.1.0(@types/react@18.0.14)(react@18.3.1) - '@radix-ui/react-primitive': 2.0.0(@types/react-dom@18.0.5)(@types/react@18.0.14)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-arrow': 1.1.1(@types/react-dom@18.0.5)(@types/react@18.0.14)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-compose-refs': 1.1.1(@types/react@18.0.14)(react@18.3.1) + '@radix-ui/react-context': 1.1.1(@types/react@18.0.14)(react@18.3.1) + '@radix-ui/react-primitive': 2.0.1(@types/react-dom@18.0.5)(@types/react@18.0.14)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@radix-ui/react-use-callback-ref': 1.1.0(@types/react@18.0.14)(react@18.3.1) '@radix-ui/react-use-layout-effect': 1.1.0(@types/react@18.0.14)(react@18.3.1) '@radix-ui/react-use-rect': 1.1.0(@types/react@18.0.14)(react@18.3.1) @@ -12996,9 +13287,9 @@ snapshots: '@types/react': 18.0.14 '@types/react-dom': 18.0.5 - '@radix-ui/react-portal@1.1.2(@types/react-dom@18.0.5)(@types/react@18.0.14)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@radix-ui/react-portal@1.1.3(@types/react-dom@18.0.5)(@types/react@18.0.14)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: - '@radix-ui/react-primitive': 2.0.0(@types/react-dom@18.0.5)(@types/react@18.0.14)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-primitive': 2.0.1(@types/react-dom@18.0.5)(@types/react@18.0.14)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@radix-ui/react-use-layout-effect': 1.1.0(@types/react@18.0.14)(react@18.3.1) react: 18.3.1 react-dom: 18.3.1(react@18.3.1) @@ -13016,6 +13307,16 @@ snapshots: '@types/react': 18.0.14 '@types/react-dom': 18.0.5 + '@radix-ui/react-presence@1.1.2(@types/react-dom@18.0.5)(@types/react@18.0.14)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@radix-ui/react-compose-refs': 1.1.1(@types/react@18.0.14)(react@18.3.1) + '@radix-ui/react-use-layout-effect': 1.1.0(@types/react@18.0.14)(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + optionalDependencies: + '@types/react': 18.0.14 + '@types/react-dom': 18.0.5 + '@radix-ui/react-primitive@2.0.0(@types/react-dom@18.0.5)(@types/react@18.0.14)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: '@radix-ui/react-slot': 1.1.0(@types/react@18.0.14)(react@18.3.1) @@ -13025,25 +13326,34 @@ snapshots: '@types/react': 18.0.14 '@types/react-dom': 18.0.5 - '@radix-ui/react-progress@1.1.0(@types/react-dom@18.0.5)(@types/react@18.0.14)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@radix-ui/react-primitive@2.0.1(@types/react-dom@18.0.5)(@types/react@18.0.14)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: - '@radix-ui/react-context': 1.1.0(@types/react@18.0.14)(react@18.3.1) - '@radix-ui/react-primitive': 2.0.0(@types/react-dom@18.0.5)(@types/react@18.0.14)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-slot': 1.1.1(@types/react@18.0.14)(react@18.3.1) react: 18.3.1 react-dom: 18.3.1(react@18.3.1) optionalDependencies: '@types/react': 18.0.14 '@types/react-dom': 18.0.5 - '@radix-ui/react-roving-focus@1.1.0(@types/react-dom@18.0.5)(@types/react@18.0.14)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@radix-ui/react-progress@1.1.1(@types/react-dom@18.0.5)(@types/react@18.0.14)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: - '@radix-ui/primitive': 1.1.0 - '@radix-ui/react-collection': 1.1.0(@types/react-dom@18.0.5)(@types/react@18.0.14)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-compose-refs': 1.1.0(@types/react@18.0.14)(react@18.3.1) - '@radix-ui/react-context': 1.1.0(@types/react@18.0.14)(react@18.3.1) + '@radix-ui/react-context': 1.1.1(@types/react@18.0.14)(react@18.3.1) + '@radix-ui/react-primitive': 2.0.1(@types/react-dom@18.0.5)(@types/react@18.0.14)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + optionalDependencies: + '@types/react': 18.0.14 + '@types/react-dom': 18.0.5 + + '@radix-ui/react-roving-focus@1.1.1(@types/react-dom@18.0.5)(@types/react@18.0.14)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@radix-ui/primitive': 1.1.1 + '@radix-ui/react-collection': 1.1.1(@types/react-dom@18.0.5)(@types/react@18.0.14)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-compose-refs': 1.1.1(@types/react@18.0.14)(react@18.3.1) + '@radix-ui/react-context': 1.1.1(@types/react@18.0.14)(react@18.3.1) '@radix-ui/react-direction': 1.1.0(@types/react@18.0.14)(react@18.3.1) '@radix-ui/react-id': 1.1.0(@types/react@18.0.14)(react@18.3.1) - '@radix-ui/react-primitive': 2.0.0(@types/react-dom@18.0.5)(@types/react@18.0.14)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-primitive': 2.0.1(@types/react-dom@18.0.5)(@types/react@18.0.14)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@radix-ui/react-use-callback-ref': 1.1.0(@types/react@18.0.14)(react@18.3.1) '@radix-ui/react-use-controllable-state': 1.1.0(@types/react@18.0.14)(react@18.3.1) react: 18.3.1 @@ -13052,7 +13362,7 @@ snapshots: '@types/react': 18.0.14 '@types/react-dom': 18.0.5 - '@radix-ui/react-scroll-area@1.2.1(@types/react-dom@18.0.5)(@types/react@18.0.14)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@radix-ui/react-scroll-area@1.2.0(@types/react-dom@18.0.5)(@types/react@18.0.14)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: '@radix-ui/number': 1.1.0 '@radix-ui/primitive': 1.1.0 @@ -13069,44 +13379,44 @@ snapshots: '@types/react': 18.0.14 '@types/react-dom': 18.0.5 - '@radix-ui/react-select@2.1.2(@types/react-dom@18.0.5)(@types/react@18.0.14)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@radix-ui/react-select@2.1.4(@types/react-dom@18.0.5)(@types/react@18.0.14)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: '@radix-ui/number': 1.1.0 - '@radix-ui/primitive': 1.1.0 - '@radix-ui/react-collection': 1.1.0(@types/react-dom@18.0.5)(@types/react@18.0.14)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-compose-refs': 1.1.0(@types/react@18.0.14)(react@18.3.1) + '@radix-ui/primitive': 1.1.1 + '@radix-ui/react-collection': 1.1.1(@types/react-dom@18.0.5)(@types/react@18.0.14)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-compose-refs': 1.1.1(@types/react@18.0.14)(react@18.3.1) '@radix-ui/react-context': 1.1.1(@types/react@18.0.14)(react@18.3.1) '@radix-ui/react-direction': 1.1.0(@types/react@18.0.14)(react@18.3.1) - '@radix-ui/react-dismissable-layer': 1.1.1(@types/react-dom@18.0.5)(@types/react@18.0.14)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-dismissable-layer': 1.1.3(@types/react-dom@18.0.5)(@types/react@18.0.14)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@radix-ui/react-focus-guards': 1.1.1(@types/react@18.0.14)(react@18.3.1) - '@radix-ui/react-focus-scope': 1.1.0(@types/react-dom@18.0.5)(@types/react@18.0.14)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-focus-scope': 1.1.1(@types/react-dom@18.0.5)(@types/react@18.0.14)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@radix-ui/react-id': 1.1.0(@types/react@18.0.14)(react@18.3.1) - '@radix-ui/react-popper': 1.2.0(@types/react-dom@18.0.5)(@types/react@18.0.14)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-portal': 1.1.2(@types/react-dom@18.0.5)(@types/react@18.0.14)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-primitive': 2.0.0(@types/react-dom@18.0.5)(@types/react@18.0.14)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-slot': 1.1.0(@types/react@18.0.14)(react@18.3.1) + '@radix-ui/react-popper': 1.2.1(@types/react-dom@18.0.5)(@types/react@18.0.14)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-portal': 1.1.3(@types/react-dom@18.0.5)(@types/react@18.0.14)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-primitive': 2.0.1(@types/react-dom@18.0.5)(@types/react@18.0.14)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-slot': 1.1.1(@types/react@18.0.14)(react@18.3.1) '@radix-ui/react-use-callback-ref': 1.1.0(@types/react@18.0.14)(react@18.3.1) '@radix-ui/react-use-controllable-state': 1.1.0(@types/react@18.0.14)(react@18.3.1) '@radix-ui/react-use-layout-effect': 1.1.0(@types/react@18.0.14)(react@18.3.1) '@radix-ui/react-use-previous': 1.1.0(@types/react@18.0.14)(react@18.3.1) - '@radix-ui/react-visually-hidden': 1.1.0(@types/react-dom@18.0.5)(@types/react@18.0.14)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-visually-hidden': 1.1.1(@types/react-dom@18.0.5)(@types/react@18.0.14)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) aria-hidden: 1.2.4 react: 18.3.1 react-dom: 18.3.1(react@18.3.1) - react-remove-scroll: 2.6.0(@types/react@18.0.14)(react@18.3.1) + react-remove-scroll: 2.6.2(@types/react@18.0.14)(react@18.3.1) optionalDependencies: '@types/react': 18.0.14 '@types/react-dom': 18.0.5 - '@radix-ui/react-slider@1.2.1(@types/react-dom@18.0.5)(@types/react@18.0.14)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@radix-ui/react-slider@1.2.2(@types/react-dom@18.0.5)(@types/react@18.0.14)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: '@radix-ui/number': 1.1.0 - '@radix-ui/primitive': 1.1.0 - '@radix-ui/react-collection': 1.1.0(@types/react-dom@18.0.5)(@types/react@18.0.14)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-compose-refs': 1.1.0(@types/react@18.0.14)(react@18.3.1) + '@radix-ui/primitive': 1.1.1 + '@radix-ui/react-collection': 1.1.1(@types/react-dom@18.0.5)(@types/react@18.0.14)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-compose-refs': 1.1.1(@types/react@18.0.14)(react@18.3.1) '@radix-ui/react-context': 1.1.1(@types/react@18.0.14)(react@18.3.1) '@radix-ui/react-direction': 1.1.0(@types/react@18.0.14)(react@18.3.1) - '@radix-ui/react-primitive': 2.0.0(@types/react-dom@18.0.5)(@types/react@18.0.14)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-primitive': 2.0.1(@types/react-dom@18.0.5)(@types/react@18.0.14)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@radix-ui/react-use-controllable-state': 1.1.0(@types/react@18.0.14)(react@18.3.1) '@radix-ui/react-use-layout-effect': 1.1.0(@types/react@18.0.14)(react@18.3.1) '@radix-ui/react-use-previous': 1.1.0(@types/react@18.0.14)(react@18.3.1) @@ -13124,20 +13434,27 @@ snapshots: optionalDependencies: '@types/react': 18.0.14 - '@radix-ui/react-tooltip@1.1.4(@types/react-dom@18.0.5)(@types/react@18.0.14)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@radix-ui/react-slot@1.1.1(@types/react@18.0.14)(react@18.3.1)': dependencies: - '@radix-ui/primitive': 1.1.0 - '@radix-ui/react-compose-refs': 1.1.0(@types/react@18.0.14)(react@18.3.1) + '@radix-ui/react-compose-refs': 1.1.1(@types/react@18.0.14)(react@18.3.1) + react: 18.3.1 + optionalDependencies: + '@types/react': 18.0.14 + + '@radix-ui/react-tooltip@1.1.6(@types/react-dom@18.0.5)(@types/react@18.0.14)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@radix-ui/primitive': 1.1.1 + '@radix-ui/react-compose-refs': 1.1.1(@types/react@18.0.14)(react@18.3.1) '@radix-ui/react-context': 1.1.1(@types/react@18.0.14)(react@18.3.1) - '@radix-ui/react-dismissable-layer': 1.1.1(@types/react-dom@18.0.5)(@types/react@18.0.14)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-dismissable-layer': 1.1.3(@types/react-dom@18.0.5)(@types/react@18.0.14)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@radix-ui/react-id': 1.1.0(@types/react@18.0.14)(react@18.3.1) - '@radix-ui/react-popper': 1.2.0(@types/react-dom@18.0.5)(@types/react@18.0.14)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-portal': 1.1.2(@types/react-dom@18.0.5)(@types/react@18.0.14)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-presence': 1.1.1(@types/react-dom@18.0.5)(@types/react@18.0.14)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-primitive': 2.0.0(@types/react-dom@18.0.5)(@types/react@18.0.14)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@radix-ui/react-slot': 1.1.0(@types/react@18.0.14)(react@18.3.1) + '@radix-ui/react-popper': 1.2.1(@types/react-dom@18.0.5)(@types/react@18.0.14)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-portal': 1.1.3(@types/react-dom@18.0.5)(@types/react@18.0.14)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-presence': 1.1.2(@types/react-dom@18.0.5)(@types/react@18.0.14)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-primitive': 2.0.1(@types/react-dom@18.0.5)(@types/react@18.0.14)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-slot': 1.1.1(@types/react@18.0.14)(react@18.3.1) '@radix-ui/react-use-controllable-state': 1.1.0(@types/react@18.0.14)(react@18.3.1) - '@radix-ui/react-visually-hidden': 1.1.0(@types/react-dom@18.0.5)(@types/react@18.0.14)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-visually-hidden': 1.1.1(@types/react-dom@18.0.5)(@types/react@18.0.14)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) react: 18.3.1 react-dom: 18.3.1(react@18.3.1) optionalDependencies: @@ -13190,9 +13507,9 @@ snapshots: optionalDependencies: '@types/react': 18.0.14 - '@radix-ui/react-visually-hidden@1.1.0(@types/react-dom@18.0.5)(@types/react@18.0.14)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@radix-ui/react-visually-hidden@1.1.1(@types/react-dom@18.0.5)(@types/react@18.0.14)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: - '@radix-ui/react-primitive': 2.0.0(@types/react-dom@18.0.5)(@types/react@18.0.14)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-primitive': 2.0.1(@types/react-dom@18.0.5)(@types/react@18.0.14)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) react: 18.3.1 react-dom: 18.3.1(react@18.3.1) optionalDependencies: @@ -15216,6 +15533,8 @@ snapshots: atomically@1.7.0: {} + author-regex@1.0.0: {} + autoprefixer@10.4.20(postcss@8.4.47): dependencies: browserslist: 4.23.3 @@ -15776,8 +16095,18 @@ snapshots: color-name@1.1.4: {} + color-string@1.9.1: + dependencies: + color-name: 1.1.4 + simple-swizzle: 0.2.2 + color-support@1.1.3: {} + color@4.2.3: + dependencies: + color-convert: 2.0.1 + color-string: 1.9.1 + colord@2.9.3: {} colorette@2.0.20: {} @@ -17396,6 +17725,24 @@ snapshots: dependencies: reusify: 1.0.4 + favicons-webpack-plugin@6.0.1(favicons@7.2.0)(webpack@5.95.0): + dependencies: + favicons: 7.2.0 + find-root: 1.1.0 + parse-author: 2.0.0 + parse5: 7.1.2 + webpack: 5.95.0(@swc/core@1.9.3(@swc/helpers@0.5.15))(esbuild@0.23.1)(webpack-cli@5.1.4) + optionalDependencies: + html-webpack-plugin: 5.6.0(webpack@5.95.0) + transitivePeerDependencies: + - '@rspack/core' + + favicons@7.2.0: + dependencies: + escape-html: 1.0.3 + sharp: 0.33.5 + xml2js: 0.6.2 + faye-websocket@0.11.4: dependencies: websocket-driver: 0.7.4 @@ -17467,6 +17814,8 @@ snapshots: make-dir: 3.1.0 pkg-dir: 4.2.0 + find-root@1.1.0: {} + find-up@3.0.0: dependencies: locate-path: 3.0.0 @@ -18222,6 +18571,8 @@ snapshots: is-arrayish@0.2.1: {} + is-arrayish@0.3.2: {} + is-async-function@2.0.0: dependencies: has-tostringtag: 1.0.2 @@ -20125,6 +20476,10 @@ snapshots: pbkdf2: 3.1.2 safe-buffer: 5.2.1 + parse-author@2.0.0: + dependencies: + author-regex: 1.0.0 + parse-entities@4.0.1: dependencies: '@types/unist': 2.0.10 @@ -20819,21 +21174,21 @@ snapshots: react-refresh@0.14.2: {} - react-remove-scroll-bar@2.3.6(@types/react@18.0.14)(react@18.3.1): + react-remove-scroll-bar@2.3.8(@types/react@18.0.14)(react@18.3.1): dependencies: react: 18.3.1 - react-style-singleton: 2.2.1(@types/react@18.0.14)(react@18.3.1) + react-style-singleton: 2.2.3(@types/react@18.0.14)(react@18.3.1) tslib: 2.7.0 optionalDependencies: '@types/react': 18.0.14 - react-remove-scroll@2.6.0(@types/react@18.0.14)(react@18.3.1): + react-remove-scroll@2.6.2(@types/react@18.0.14)(react@18.3.1): dependencies: react: 18.3.1 - react-remove-scroll-bar: 2.3.6(@types/react@18.0.14)(react@18.3.1) + react-remove-scroll-bar: 2.3.8(@types/react@18.0.14)(react@18.3.1) react-style-singleton: 2.2.1(@types/react@18.0.14)(react@18.3.1) tslib: 2.7.0 - use-callback-ref: 1.3.2(@types/react@18.0.14)(react@18.3.1) + use-callback-ref: 1.3.3(@types/react@18.0.14)(react@18.3.1) use-sidecar: 1.1.2(@types/react@18.0.14)(react@18.3.1) optionalDependencies: '@types/react': 18.0.14 @@ -20859,6 +21214,14 @@ snapshots: optionalDependencies: '@types/react': 18.0.14 + react-style-singleton@2.2.3(@types/react@18.0.14)(react@18.3.1): + dependencies: + get-nonce: 1.0.1 + react: 18.3.1 + tslib: 2.7.0 + optionalDependencies: + '@types/react': 18.0.14 + react@18.3.1: dependencies: loose-envify: 1.4.0 @@ -21377,6 +21740,32 @@ snapshots: shallowequal@1.1.0: {} + sharp@0.33.5: + dependencies: + color: 4.2.3 + detect-libc: 2.0.3 + semver: 7.6.3 + optionalDependencies: + '@img/sharp-darwin-arm64': 0.33.5 + '@img/sharp-darwin-x64': 0.33.5 + '@img/sharp-libvips-darwin-arm64': 1.0.4 + '@img/sharp-libvips-darwin-x64': 1.0.4 + '@img/sharp-libvips-linux-arm': 1.0.5 + '@img/sharp-libvips-linux-arm64': 1.0.4 + '@img/sharp-libvips-linux-s390x': 1.0.4 + '@img/sharp-libvips-linux-x64': 1.0.4 + '@img/sharp-libvips-linuxmusl-arm64': 1.0.4 + '@img/sharp-libvips-linuxmusl-x64': 1.0.4 + '@img/sharp-linux-arm': 0.33.5 + '@img/sharp-linux-arm64': 0.33.5 + '@img/sharp-linux-s390x': 0.33.5 + '@img/sharp-linux-x64': 0.33.5 + '@img/sharp-linuxmusl-arm64': 0.33.5 + '@img/sharp-linuxmusl-x64': 0.33.5 + '@img/sharp-wasm32': 0.33.5 + '@img/sharp-win32-ia32': 0.33.5 + '@img/sharp-win32-x64': 0.33.5 + shebang-command@1.2.0: dependencies: shebang-regex: 1.0.0 @@ -21415,6 +21804,10 @@ snapshots: log-update: 4.0.0 webpack: 5.95.0(@swc/core@1.9.3(@swc/helpers@0.5.15))(esbuild@0.23.1)(webpack-cli@5.1.4) + simple-swizzle@0.2.2: + dependencies: + is-arrayish: 0.3.2 + simple-update-notifier@1.1.0: dependencies: semver: 7.0.0 @@ -22378,7 +22771,7 @@ snapshots: punycode: 1.4.1 qs: 6.13.0 - use-callback-ref@1.3.2(@types/react@18.0.14)(react@18.3.1): + use-callback-ref@1.3.3(@types/react@18.0.14)(react@18.3.1): dependencies: react: 18.3.1 tslib: 2.7.0 @@ -22765,8 +23158,15 @@ snapshots: xml-name-validator@4.0.0: {} + xml2js@0.6.2: + dependencies: + sax: 1.3.0 + xmlbuilder: 11.0.1 + xml@1.0.1: {} + xmlbuilder@11.0.1: {} + xmlbuilder@15.1.1: {} xmlchars@2.2.0: {} diff --git a/public/android-chrome-192x192.png b/public/android-chrome-192x192.png deleted file mode 100644 index 850004caeb..0000000000 Binary files a/public/android-chrome-192x192.png and /dev/null differ diff --git a/public/android-chrome-256x256.png b/public/android-chrome-256x256.png deleted file mode 100644 index db228e127c..0000000000 Binary files a/public/android-chrome-256x256.png and /dev/null differ diff --git a/public/apple-touch-icon.png b/public/apple-touch-icon.png deleted file mode 100644 index 198a430d80..0000000000 Binary files a/public/apple-touch-icon.png and /dev/null differ diff --git a/public/favicon-16x16.png b/public/favicon-16x16.png deleted file mode 100644 index f5251ba99c..0000000000 Binary files a/public/favicon-16x16.png and /dev/null differ diff --git a/public/favicon-32x32.png b/public/favicon-32x32.png deleted file mode 100644 index ebf51b3dad..0000000000 Binary files a/public/favicon-32x32.png and /dev/null differ diff --git a/public/favicon.ico b/public/favicon.ico deleted file mode 100644 index 1d86b21d2d..0000000000 Binary files a/public/favicon.ico and /dev/null differ diff --git a/public/mstile-150x150.png b/public/mstile-150x150.png deleted file mode 100644 index 195e0d1499..0000000000 Binary files a/public/mstile-150x150.png and /dev/null differ diff --git a/public/safari-pinned-tab.svg b/public/safari-pinned-tab.svg deleted file mode 100644 index 9da2f3e187..0000000000 --- a/public/safari-pinned-tab.svg +++ /dev/null @@ -1,18 +0,0 @@ - - - - -Created by potrace 1.14, written by Peter Selinger 2001-2017 - - - - - diff --git a/public/site.webmanifest b/public/site.webmanifest deleted file mode 100644 index de65106f48..0000000000 --- a/public/site.webmanifest +++ /dev/null @@ -1,19 +0,0 @@ -{ - "name": "", - "short_name": "", - "icons": [ - { - "src": "/android-chrome-192x192.png", - "sizes": "192x192", - "type": "image/png" - }, - { - "src": "/android-chrome-256x256.png", - "sizes": "256x256", - "type": "image/png" - } - ], - "theme_color": "#ffffff", - "background_color": "#ffffff", - "display": "standalone" -} diff --git a/src/renderer/app/favicon.dev.png b/src/renderer/app/favicon.dev.png new file mode 100644 index 0000000000..c970a75b3f Binary files /dev/null and b/src/renderer/app/favicon.dev.png differ diff --git a/src/renderer/app/favicon.png b/src/renderer/app/favicon.png new file mode 100644 index 0000000000..d09533a6ad Binary files /dev/null and b/src/renderer/app/favicon.png differ diff --git a/src/renderer/app/index.html b/src/renderer/app/index.html index 6078a5917e..a3a9d3eee8 100644 --- a/src/renderer/app/index.html +++ b/src/renderer/app/index.html @@ -3,13 +3,7 @@ - - - - - - @@ -29,11 +23,6 @@ - - - - - Nova Spektr diff --git a/src/renderer/app/index.tsx b/src/renderer/app/index.tsx index bbf5532b46..1103c1173d 100644 --- a/src/renderer/app/index.tsx +++ b/src/renderer/app/index.tsx @@ -11,6 +11,7 @@ import { resetFeatureStatuses, updateFeatureStatus } from '@/shared/config/featu import { I18Provider } from '@/shared/i18n'; import { isElectron } from '@/shared/lib/utils'; import { FallbackScreen } from '@/shared/ui'; +import { ThemeProvider } from '@/shared/ui-kit'; import { APP_CONFIG } from '../../../app.config'; import { LoadingDelay, controlledLazy, suspenseDelay } from './DelayedSuspense'; @@ -61,16 +62,18 @@ const Root = () => { const splashScreen = renderSplashScreen ? isElectron() ? : : null; return ( - - - - - setAppLoaded(true)} /> - - - - - + + + + + + setAppLoaded(true)} /> + + + + + + ); }; diff --git a/src/renderer/app/manifest.webmanifest b/src/renderer/app/manifest.webmanifest new file mode 100644 index 0000000000..0233dc4852 --- /dev/null +++ b/src/renderer/app/manifest.webmanifest @@ -0,0 +1,6 @@ +{ + "name": "Nova Spektr", + "short_name": "Spektr", + "display": "standalone", + "start_url": "/" +} diff --git a/src/renderer/domains/collectives/model/members/service.ts b/src/renderer/domains/collectives/model/members/service.ts index 2b30b1efb1..abb6a98110 100644 --- a/src/renderer/domains/collectives/model/members/service.ts +++ b/src/renderer/domains/collectives/model/members/service.ts @@ -1,19 +1,19 @@ -import { type Account, type Chain } from '@/shared/core'; +import { type Account, type Chain, type Wallet } from '@/shared/core'; import { dictionary } from '@/shared/lib/utils'; import { accountUtils } from '@/entities/wallet'; import { type CoreMember, type Member } from './types'; -const findMachingMember = (accounts: Account[], members: Member[], chain: Chain) => { +const findMatchingMember = (wallet: Wallet, accounts: Account[], chain: Chain, members: Member[]) => { const walletAccounts = accounts.filter(account => { - return !accountUtils.isBaseAccount(account) && accountUtils.isChainAndCryptoMatch(account, chain); + return accountUtils.isNonBaseVaultAccount(account, wallet) && accountUtils.isChainAndCryptoMatch(account, chain); }); const accountsDictionary = dictionary(walletAccounts, 'accountId'); return members.find(member => member.accountId in accountsDictionary) ?? null; }; -const findMachingAccount = (accounts: Account[], member: Member) => { +const findMatchingAccount = (accounts: Account[], member: Member) => { return accounts.find(a => a.accountId === member.accountId) ?? null; }; @@ -26,7 +26,7 @@ const isCoreMember = (member: Member | CoreMember): member is CoreMember => { }; export const membersService = { - findMachingMember, - findMachingAccount, + findMatchingMember, + findMatchingAccount, isCoreMember, }; diff --git a/src/renderer/domains/identity/model/identity/model.ts b/src/renderer/domains/identity/model/identity/model.ts index 9e2a58e69a..f32a4b6da7 100644 --- a/src/renderer/domains/identity/model/identity/model.ts +++ b/src/renderer/domains/identity/model/identity/model.ts @@ -1,5 +1,5 @@ import { type ApiPromise } from '@polkadot/api'; -import { createEvent, sample } from 'effector'; +import { attach } from 'effector'; import { type ChainId } from '@/shared/core'; import { createDataSource } from '@/shared/effector'; @@ -27,6 +27,7 @@ type InnerRequestParams = { const { $: $list, request: requestIdentity, + fulfilled, pending, fail, } = createDataSource({ @@ -73,15 +74,10 @@ const { const { $apis, $chains } = networkModel; -const request = createEvent(); - -sample({ - clock: request, - source: { - apis: $apis, - chains: $chains, - }, - fn: ({ apis, chains }, { chainId, accounts }) => { +const request = attach({ + effect: requestIdentity, + source: { apis: $apis, chains: $chains }, + mapParams: ({ chainId, accounts }: RequestParams, { apis, chains }) => { const identityChain = identityService.findIdentityChain(chains, chainId); if (nullable(identityChain)) { throw new Error(`Chain path from ${chainId} is broken, trace chain.parentId fields in config.`); @@ -98,11 +94,11 @@ sample({ api, }; }, - target: requestIdentity, }); export const identityDomainModel = { $list, + $fulfilled: fulfilled, request, pending, fail, diff --git a/src/renderer/entities/transaction/lib/callDataDecoder.ts b/src/renderer/entities/transaction/lib/callDataDecoder.ts index f61e417dc6..2d679eadca 100644 --- a/src/renderer/entities/transaction/lib/callDataDecoder.ts +++ b/src/renderer/entities/transaction/lib/callDataDecoder.ts @@ -230,6 +230,15 @@ export const useCallDataDecoder = (): ICallDataDecoder => { return xcmService.decodeXcm(chainId, parsedData); }, + [TransactionType.POLKADOT_XCM_TRANSFER_ASSETS]: (decoded, chainId): Record => { + const parsedData = xcmService.parseXcmPalletExtrinsic({ + dest: decoded.args[0].toHuman(), + beneficiary: decoded.args[1].toHuman(), + assets: decoded.args[2].toHuman(), + }); + + return xcmService.decodeXcm(chainId, parsedData); + }, [TransactionType.XTOKENS_TRANSFER_MULTIASSET]: (decoded, chainId): Record => { const parsedData = xcmService.parseXTokensExtrinsic({ asset: decoded.args[0].toHuman(), diff --git a/src/renderer/entities/transaction/lib/common/constants.ts b/src/renderer/entities/transaction/lib/common/constants.ts index e0333e46a3..899027fbfc 100644 --- a/src/renderer/entities/transaction/lib/common/constants.ts +++ b/src/renderer/entities/transaction/lib/common/constants.ts @@ -40,6 +40,7 @@ export const XcmTypes = [ TransactionType.XCM_LIMITED_TRANSFER, TransactionType.POLKADOT_XCM_TELEPORT, TransactionType.POLKADOT_XCM_LIMITED_TRANSFER, + TransactionType.POLKADOT_XCM_TRANSFER_ASSETS, TransactionType.XTOKENS_TRANSFER_MULTIASSET, ]; @@ -53,6 +54,7 @@ export type XcmTransactionTypes = | TransactionType.XCM_LIMITED_TRANSFER | TransactionType.POLKADOT_XCM_TELEPORT | TransactionType.POLKADOT_XCM_LIMITED_TRANSFER + | TransactionType.POLKADOT_XCM_TRANSFER_ASSETS | TransactionType.XTOKENS_TRANSFER_MULTIASSET; export type MultisigTransactionTypes = diff --git a/src/renderer/entities/transaction/lib/common/utils.ts b/src/renderer/entities/transaction/lib/common/utils.ts index a7bb6af49d..d06b9d34f2 100644 --- a/src/renderer/entities/transaction/lib/common/utils.ts +++ b/src/renderer/entities/transaction/lib/common/utils.ts @@ -147,7 +147,9 @@ export const findCoreBatchAll = (coreTx: Transaction | DecodedTransaction): Tran return coreTx.args?.transactions?.find((t: Transaction) => t.type === TransactionType.UNLOCK) || coreTx; } - return coreTx.args?.transactions?.find((tx: Transaction) => isWrappedInBatchAll(tx.type)); + const supportedTransaction = coreTx.args?.transactions?.find((tx: Transaction) => isWrappedInBatchAll(tx.type)); + + return supportedTransaction || coreTx.args?.transactions?.[0]; }; export const getTransactionAmount = (tx: Transaction | DecodedTransaction): string | null => { @@ -231,6 +233,7 @@ const TransactionTitles: Record = { [TransactionType.XCM_TELEPORT]: 'operations.titles.crossChainTransfer', [TransactionType.POLKADOT_XCM_LIMITED_TRANSFER]: 'operations.titles.crossChainTransfer', [TransactionType.POLKADOT_XCM_TELEPORT]: 'operations.titles.crossChainTransfer', + [TransactionType.POLKADOT_XCM_TRANSFER_ASSETS]: 'operations.titles.crossChainTransfer', [TransactionType.XTOKENS_TRANSFER_MULTIASSET]: 'operations.titles.crossChainTransfer', // Staking [TransactionType.BOND]: 'operations.titles.startStaking', @@ -242,7 +245,7 @@ const TransactionTitles: Record = { [TransactionType.UNSTAKE]: 'operations.titles.unstake', // Technical [TransactionType.CHILL]: 'operations.titles.unstake', - [TransactionType.BATCH_ALL]: 'operations.titles.unknown', + [TransactionType.BATCH_ALL]: 'operations.titles.batchAll', // Proxy [TransactionType.ADD_PROXY]: 'operations.titles.addProxy', [TransactionType.CREATE_PURE_PROXY]: 'operations.titles.createPureProxy', @@ -283,6 +286,8 @@ const TransactionTitlesModal: Record s `operations.modalTitles.${crossChain ? 'transferFrom' : 'transferOn'}`, [TransactionType.POLKADOT_XCM_TELEPORT]: (crossChain) => `operations.modalTitles.${crossChain ? 'transferFrom' : 'transferOn'}`, + [TransactionType.POLKADOT_XCM_TRANSFER_ASSETS]: (crossChain) => + `operations.modalTitles.${crossChain ? 'transferFrom' : 'transferOn'}`, [TransactionType.XTOKENS_TRANSFER_MULTIASSET]: (crossChain) => `operations.modalTitles.${crossChain ? 'transferFrom' : 'transferOn'}`, // Staking @@ -355,7 +360,9 @@ export const getModalTransactionTitle = ( } if (transaction.type === TransactionType.BATCH_ALL) { - return getModalTransactionTitle(crossChain, t, transaction.args?.transactions?.[0]); + const txMatch = findCoreBatchAll(transaction); + + return getModalTransactionTitle(crossChain, t, txMatch); } if (transaction.type === TransactionType.PROXY) { diff --git a/src/renderer/entities/transaction/lib/common/xcmMethods.ts b/src/renderer/entities/transaction/lib/common/xcmMethods.ts index d87391f0cc..b97deb2b0c 100644 --- a/src/renderer/entities/transaction/lib/common/xcmMethods.ts +++ b/src/renderer/entities/transaction/lib/common/xcmMethods.ts @@ -45,6 +45,25 @@ export function limitedTeleportAssets( ); } +export function transferAssets( + pallet: XcmPallet, + args: XcmPalletTransferArgs, + info: BaseTxInfo, + options: OptionsWithMeta, +): UnsignedTransaction { + return defineMethod( + { + method: { + args, + name: 'transferAssets', + pallet, + }, + ...info, + }, + options, + ); +} + export function transferMultiAsset( args: XTokenPalletTransferArgs, info: BaseTxInfo, diff --git a/src/renderer/entities/transaction/lib/extrinsicService.ts b/src/renderer/entities/transaction/lib/extrinsicService.ts index e19d4bc10e..e169889e30 100644 --- a/src/renderer/entities/transaction/lib/extrinsicService.ts +++ b/src/renderer/entities/transaction/lib/extrinsicService.ts @@ -199,6 +199,20 @@ export const getUnsignedTransaction: Record< options, ); }, + [TransactionType.POLKADOT_XCM_TRANSFER_ASSETS]: (transaction, info, options) => { + return xcmMethods.transferAssets( + 'polkadotXcm', + { + dest: transaction.args.xcmDest, + beneficiary: transaction.args.xcmBeneficiary, + assets: transaction.args.xcmAsset, + feeAssetItem: DEFAULT_FEE_ASSET_ITEM, + weightLimit: { Unlimited: true }, + }, + info, + options, + ); + }, [TransactionType.XTOKENS_TRANSFER_MULTIASSET]: (transaction, info, options) => { return xcmMethods.transferMultiAsset( { @@ -527,6 +541,11 @@ export const getExtrinsic: Record< Unlimited: true, }); }, + [TransactionType.POLKADOT_XCM_TRANSFER_ASSETS]: ({ xcmDest, xcmBeneficiary, xcmAsset }, api) => { + return api.tx.polkadotXcm.transferAssets(xcmDest, xcmBeneficiary, xcmAsset, DEFAULT_FEE_ASSET_ITEM, { + Unlimited: true, + }); + }, [TransactionType.XTOKENS_TRANSFER_MULTIASSET]: ({ xcmDest, xcmAsset, xcmWeight }, api) => { const weight = hasDestWeight(api) ? xcmWeight : { Unlimited: true }; diff --git a/src/renderer/entities/transaction/lib/transactionConfirmIcon.ts b/src/renderer/entities/transaction/lib/transactionConfirmIcon.ts index 353a340900..82719124c2 100644 --- a/src/renderer/entities/transaction/lib/transactionConfirmIcon.ts +++ b/src/renderer/entities/transaction/lib/transactionConfirmIcon.ts @@ -16,6 +16,7 @@ const TransactionIcons: Record = { [TransactionType.XCM_TELEPORT]: 'crossChainConfirm', [TransactionType.POLKADOT_XCM_LIMITED_TRANSFER]: 'crossChainConfirm', [TransactionType.POLKADOT_XCM_TELEPORT]: 'crossChainConfirm', + [TransactionType.POLKADOT_XCM_TRANSFER_ASSETS]: 'crossChainConfirm', [TransactionType.XTOKENS_TRANSFER_MULTIASSET]: 'crossChainConfirm', // Staking [TransactionType.BOND]: 'startStakingConfirm', diff --git a/src/renderer/entities/transaction/lib/transactionIcon.ts b/src/renderer/entities/transaction/lib/transactionIcon.ts index 2d1f02bb2b..2de6fa1f6a 100644 --- a/src/renderer/entities/transaction/lib/transactionIcon.ts +++ b/src/renderer/entities/transaction/lib/transactionIcon.ts @@ -16,6 +16,7 @@ const TransactionIcons: Record = { [TransactionType.XCM_TELEPORT]: 'crossChain', [TransactionType.POLKADOT_XCM_LIMITED_TRANSFER]: 'crossChain', [TransactionType.POLKADOT_XCM_TELEPORT]: 'crossChain', + [TransactionType.POLKADOT_XCM_TRANSFER_ASSETS]: 'crossChain', [TransactionType.XTOKENS_TRANSFER_MULTIASSET]: 'crossChain', // Staking [TransactionType.BOND]: 'startStakingMst', diff --git a/src/renderer/features/assets/AssetsPortfolioView/ui/AssembledAssetAmount.tsx b/src/renderer/features/assets/AssetsPortfolioView/ui/AssembledAssetAmount.tsx index 9c206b5147..1b4868df86 100644 --- a/src/renderer/features/assets/AssetsPortfolioView/ui/AssembledAssetAmount.tsx +++ b/src/renderer/features/assets/AssetsPortfolioView/ui/AssembledAssetAmount.tsx @@ -16,13 +16,14 @@ type Props = PropsWithChildren & { export const AssembledAssetAmount = ({ balance, asset }: Props) => { const { t } = useI18n(); + const fiatFlag = useUnit(priceProviderModel.$fiatFlag); if (!balance?.free) { return (
- - {fiatFlag && } + + {fiatFlag && }
); } diff --git a/src/renderer/features/fellowship-members/model/members.ts b/src/renderer/features/fellowship-members/model/members.ts index 293f65a613..dddc2e6eb2 100644 --- a/src/renderer/features/fellowship-members/model/members.ts +++ b/src/renderer/features/fellowship-members/model/members.ts @@ -1,5 +1,5 @@ import { sample } from 'effector'; -import { or } from 'patronum'; +import { and, or } from 'patronum'; import { collectiveDomain } from '@/domains/collectives'; @@ -10,6 +10,11 @@ const $list = fellowshipModel.$store.map( store => store?.members?.filter(collectiveDomain.membersService.isCoreMember) ?? [], ); +const $pendingMembers = and( + collectiveDomain.members.pending, + $list.map(member => member.length === 0), +); + sample({ clock: membersFeatureStatus.running, target: collectiveDomain.members.subscribe, @@ -22,6 +27,6 @@ sample({ export const membersModel = { $list, - $pending: or(collectiveDomain.members.pending, membersFeatureStatus.isStarting), + $pending: or($pendingMembers, membersFeatureStatus.isStarting), $fulfilled: collectiveDomain.members.fulfilled, }; diff --git a/src/renderer/features/fellowship-profile/components/ProfileCard.tsx b/src/renderer/features/fellowship-profile/components/ProfileCard.tsx index f53f4ca011..0135919def 100644 --- a/src/renderer/features/fellowship-profile/components/ProfileCard.tsx +++ b/src/renderer/features/fellowship-profile/components/ProfileCard.tsx @@ -2,10 +2,10 @@ import { useGate, useUnit } from 'effector-react'; import { memo } from 'react'; import { useI18n } from '@/shared/i18n'; -import { toAddress } from '@/shared/lib/utils'; +import { nonNullable, nullable, toAddress } from '@/shared/lib/utils'; import { FootnoteText, Icon, SmallTitleText } from '@/shared/ui'; import { Address } from '@/shared/ui-entities'; -import { Box, Skeleton, Surface } from '@/shared/ui-kit'; +import { Box, Skeleton, Surface, Tooltip } from '@/shared/ui-kit'; import { ERROR } from '../constants'; import { profileModel } from '../model/profile'; import { profileFeatureStatus } from '../model/status'; @@ -18,7 +18,8 @@ export const ProfileCard = memo(() => { const featureInput = useUnit(profileFeatureStatus.input); const member = useUnit(profileModel.$currentMember); const identity = useUnit(profileModel.$identity); - const fulfilled = useUnit(profileModel.$fulfilled); + const pending = useUnit(profileModel.$pending); + const isAccountExist = useUnit(profileModel.$isAccountExist); const isNetworkDisabled = featureState.status === 'failed' && featureState.error.message === ERROR.networkDisabled; @@ -30,8 +31,40 @@ export const ProfileCard = memo(() => { {t('fellowship.yourProfile')} - - {member ? ( + + {!isAccountExist && ( + + {t('fellowship.noAccount')} + + + +
+ +
+
+ + {t('fellowship.tooltips.noAccount', { chain: featureInput?.chain.name || '' })} + +
+
+ )} + + {isAccountExist && nullable(member) && ( + + {t('fellowship.noProfile')} + + + +
+ +
+
+ {t('fellowship.tooltips.noProfile')} +
+
+ )} + + {isAccountExist && nonNullable(member) && (
{ /> - ) : ( - {t('fellowship.noProfile')} )} diff --git a/src/renderer/features/fellowship-profile/model/profile.ts b/src/renderer/features/fellowship-profile/model/profile.ts index 4ed522d09c..c079dae3ec 100644 --- a/src/renderer/features/fellowship-profile/model/profile.ts +++ b/src/renderer/features/fellowship-profile/model/profile.ts @@ -1,15 +1,17 @@ import { combine, sample } from 'effector'; -import { or } from 'patronum'; +import { and, or } from 'patronum'; import { attachToFeatureInput } from '@/shared/effector'; import { nullable } from '@/shared/lib/utils'; import { collectiveDomain } from '@/domains/collectives'; import { identityDomain } from '@/domains/identity'; +import { accountUtils } from '@/entities/wallet'; import { fellowshipModel } from './fellowship'; import { profileFeatureStatus } from './status'; -const $members = fellowshipModel.$store.map(x => x?.members ?? []); +const $members = fellowshipModel.$store.map(store => store?.members ?? []); + const $identities = combine(profileFeatureStatus.input, identityDomain.identity.$list, (featureInput, list) => { if (nullable(featureInput)) return {}; @@ -19,7 +21,9 @@ const $identities = combine(profileFeatureStatus.input, identityDomain.identity. const $currentMember = combine(profileFeatureStatus.input, $members, (featureInput, members) => { if (nullable(featureInput) || members.length === 0) return null; - return collectiveDomain.membersService.findMachingMember(featureInput.accounts, members, featureInput.chain); + const { wallet, accounts, chain } = featureInput; + + return collectiveDomain.membersService.findMatchingMember(wallet, accounts, chain, members); }); const $identity = combine($currentMember, $identities, (member, identities) => { @@ -28,7 +32,18 @@ const $identity = combine($currentMember, $identities, (member, identities) => { return identities[member.accountId] ?? null; }); -const accountUpdate = attachToFeatureInput(profileFeatureStatus, $currentMember); +const $isAccountExist = profileFeatureStatus.input.map(store => { + if (!store) return false; + + return store.accounts.some(account => { + return !accountUtils.isBaseAccount(account) && accountUtils.isChainAndCryptoMatch(account, store.chain); + }); +}); + +const $pendingMember = and(collectiveDomain.members.pending, $currentMember.map(nullable)); +const $pendingIdentity = and(identityDomain.identity.pending, $identity.map(nullable)); + +const memberUpdate = attachToFeatureInput(profileFeatureStatus, $currentMember); sample({ clock: profileFeatureStatus.running, @@ -41,7 +56,7 @@ sample({ }); sample({ - clock: accountUpdate, + clock: memberUpdate, fn: ({ input: { chainId }, data: member }) => ({ chainId, accounts: member ? [member.accountId] : [], @@ -52,6 +67,6 @@ sample({ export const profileModel = { $currentMember, $identity, - $pending: or(collectiveDomain.members.pending, identityDomain.identity.pending, profileFeatureStatus.isStarting), - $fulfilled: collectiveDomain.members.fulfilled, + $isAccountExist, + $pending: or($pendingMember, $pendingIdentity, profileFeatureStatus.isStarting), }; diff --git a/src/renderer/features/fellowship-profile/model/status.ts b/src/renderer/features/fellowship-profile/model/status.ts index 4d7c2e02f8..954ab7d1be 100644 --- a/src/renderer/features/fellowship-profile/model/status.ts +++ b/src/renderer/features/fellowship-profile/model/status.ts @@ -19,6 +19,7 @@ const $input = combine( chainId: network.chainId, palletType: network.palletType, accounts: wallet.accounts, + wallet, }; }, ); diff --git a/src/renderer/features/fellowship-referendum-details/components/ReferendumDescription.tsx b/src/renderer/features/fellowship-referendum-details/components/ReferendumDescription.tsx new file mode 100644 index 0000000000..94a1d3b9bc --- /dev/null +++ b/src/renderer/features/fellowship-referendum-details/components/ReferendumDescription.tsx @@ -0,0 +1,40 @@ +import { useUnit } from 'effector-react'; + +import { useI18n } from '@/shared/i18n'; +import { nullable } from '@/shared/lib/utils'; +import { FootnoteText, HeaderTitleText, Icon, Markdown } from '@/shared/ui'; +import { Box, Skeleton } from '@/shared/ui-kit'; +import { referendumDetailsModel } from '../model/details'; + +import { ProposerName } from './ProposerName'; + +export const ReferendumDescription = () => { + const { t } = useI18n(); + + const referendumMeta = useUnit(referendumDetailsModel.$referendumMeta); + const pendingReferendumMeta = useUnit(referendumDetailsModel.$pendingMeta); + + const metaLoadingState = pendingReferendumMeta && nullable(referendumMeta); + + const empty = !metaLoadingState && !referendumMeta?.title && !referendumMeta?.description; + + return ( + + + + {metaLoadingState ? : referendumMeta?.title} + + {metaLoadingState ? ( + + ) : ( + {referendumMeta?.description ?? ''} + )} + {empty && ( + + + {t('fellowship.details.noDetails')} + + )} + + ); +}; diff --git a/src/renderer/features/fellowship-referendum-details/components/ReferendumDetailsModal.tsx b/src/renderer/features/fellowship-referendum-details/components/ReferendumDetailsModal.tsx index 75e06f89e6..9cc31a6812 100644 --- a/src/renderer/features/fellowship-referendum-details/components/ReferendumDetailsModal.tsx +++ b/src/renderer/features/fellowship-referendum-details/components/ReferendumDetailsModal.tsx @@ -3,15 +3,15 @@ import { useGate, useUnit } from 'effector-react'; import { useI18n } from '@/shared/i18n'; import { nullable } from '@/shared/lib/utils'; import { type ReferendumId } from '@/shared/pallet/referenda'; -import { HeaderTitleText, Markdown, SmallTitleText } from '@/shared/ui'; -import { Box, Modal, Skeleton } from '@/shared/ui-kit'; +import { SmallTitleText } from '@/shared/ui'; +import { Box, Modal, ScrollArea } from '@/shared/ui-kit'; import { fellowshipVotingFeature } from '@/features/fellowship-voting'; import { fellowshipVotingHistoryFeature } from '@/features/fellowship-voting-history'; import { referendumDetailsModel } from '../model/details'; import { referendumsDetailsFeatureStatus } from '../model/status'; import { Card } from './Card'; -import { ProposerName } from './ProposerName'; +import { ReferendumDescription } from './ReferendumDescription'; import { Threshold } from './Threshold'; import { ReferendumVoteChart } from './shared/ReferendumVoteChart'; import { ReferendumVotingStatusBadge } from './shared/ReferendumVotingStatusBadge'; @@ -32,58 +32,47 @@ export const ReferendumDetailsModal = ({ referendumId, isOpen, onToggle }: Props const { t } = useI18n(); const referendum = useUnit(referendumDetailsModel.$referendum); - const referendumMeta = useUnit(referendumDetailsModel.$referendumMeta); - const pendingReferendumMeta = useUnit(referendumDetailsModel.$pendingMeta); const pendingReferendum = useUnit(referendumDetailsModel.$pending); const loadingState = pendingReferendum && nullable(referendum); - const metaLoadingState = pendingReferendumMeta && nullable(referendumMeta); return ( {`Referendum #${referendumId}`} - -
- - - - - - - {metaLoadingState ? : referendumMeta?.title} - - {metaLoadingState ? ( - - ) : ( - {referendumMeta?.description ?? ''} - )} - - - - - - - - {t('fellowship.voting.votingStatus')} - - - - - - - - - - {t('fellowship.voting.summary')} - - + +
+ + + + + + + + + + + + {t('fellowship.voting.votingStatus')} + + + + + + + + + {t('fellowship.voting.summary')} - - - + + + + + + + - +
diff --git a/src/renderer/features/fellowship-referendums/components/List/CompletedReferendums.tsx b/src/renderer/features/fellowship-referendums/components/List/CompletedReferendums.tsx index bff5f3ea5e..59420e2d15 100644 --- a/src/renderer/features/fellowship-referendums/components/List/CompletedReferendums.tsx +++ b/src/renderer/features/fellowship-referendums/components/List/CompletedReferendums.tsx @@ -3,8 +3,7 @@ import { memo } from 'react'; import { useI18n } from '@/shared/i18n'; import { useDeferredList } from '@/shared/lib/hooks'; -import { Accordion, CaptionText } from '@/shared/ui'; -import { Box, Skeleton } from '@/shared/ui-kit'; +import { Accordion, Box, Skeleton } from '@/shared/ui-kit'; import { type Referendum } from '@/domains/collectives'; import { referendumListModel } from '../../model/list'; @@ -37,28 +36,28 @@ export const CompletedReferendums = memo(({ isTitlesLoading, mixLoadingWi if (!pending && referendums.length === 0) return null; return ( - - + + - - {t('governance.referendums.completed')} - - + {t('governance.referendums.completed')} + {referendums.length.toString()} - + + + + + + {(!shouldRenderLoadingState || mixLoadingWithData) && + deferredReferendums.map(referendum => ( + + ))} + {(shouldRenderLoadingState || mixLoadingWithData) && createPlaceholders(placeholdersCount)} - - - {(!shouldRenderLoadingState || mixLoadingWithData) && - deferredReferendums.map(referendum => ( - - ))} - {(shouldRenderLoadingState || mixLoadingWithData) && createPlaceholders(placeholdersCount)} ); diff --git a/src/renderer/features/fellowship-referendums/components/List/OngoingReferendums.tsx b/src/renderer/features/fellowship-referendums/components/List/OngoingReferendums.tsx index 016a3b3466..88c7aded28 100644 --- a/src/renderer/features/fellowship-referendums/components/List/OngoingReferendums.tsx +++ b/src/renderer/features/fellowship-referendums/components/List/OngoingReferendums.tsx @@ -3,8 +3,7 @@ import { memo } from 'react'; import { useI18n } from '@/shared/i18n'; import { useDeferredList } from '@/shared/lib/hooks'; -import { Accordion, CaptionText } from '@/shared/ui'; -import { Box, Skeleton } from '@/shared/ui-kit'; +import { Accordion, Box, Skeleton } from '@/shared/ui-kit'; import { type Referendum } from '@/domains/collectives'; import { referendumListModel } from '../../model/list'; @@ -37,28 +36,28 @@ export const OngoingReferendums = memo(({ isTitlesLoading, mixLoadingWith if (!pending && referendums.length === 0) return null; return ( - - + + - - {t('governance.referendums.ongoing')} - - + {t('governance.referendums.ongoing')} + {referendums.length.toString()} - + + + + + + {(!shouldRenderLoadingState || mixLoadingWithData) && + deferredReferendums.map(referendum => ( + + ))} + {(shouldRenderLoadingState || mixLoadingWithData) && createPlaceholders(placeholdersCount)} - - - {(!shouldRenderLoadingState || mixLoadingWithData) && - deferredReferendums.map(referendum => ( - - ))} - {(shouldRenderLoadingState || mixLoadingWithData) && createPlaceholders(placeholdersCount)} ); diff --git a/src/renderer/features/fellowship-referendums/components/List/ReferendumItem.tsx b/src/renderer/features/fellowship-referendums/components/List/ReferendumItem.tsx index 2d5372cda3..0a64afb4b3 100644 --- a/src/renderer/features/fellowship-referendums/components/List/ReferendumItem.tsx +++ b/src/renderer/features/fellowship-referendums/components/List/ReferendumItem.tsx @@ -38,7 +38,7 @@ export const ReferendumItem = memo(({ referendum, isTitlesLoading, onSele ); return ( - onSelect(referendum)}> + onSelect(referendum)}> diff --git a/src/renderer/features/fellowship-referendums/model/filter.ts b/src/renderer/features/fellowship-referendums/model/filter.ts index 78bb5d59de..6aaaf29e65 100644 --- a/src/renderer/features/fellowship-referendums/model/filter.ts +++ b/src/renderer/features/fellowship-referendums/model/filter.ts @@ -1,5 +1,5 @@ import { combine, createEvent, restore, sample } from 'effector'; -import { debounce } from 'patronum'; +import { readonly } from 'patronum'; import { nonNullable } from '@/shared/lib/utils'; import { type TrackId } from '@/shared/pallet/referenda'; @@ -15,7 +15,7 @@ const selectTracks = createEvent(); const selectVotingStatus = createEvent(); const filtersReset = createEvent(); -const $query = restore(debounce(queryChanged, 100), ''); +const $query = restore(queryChanged, ''); const $selectedTracks = restore(selectTracks, []); const $selectedVotingStatus = restore(selectVotingStatus, null); @@ -34,11 +34,11 @@ sample({ }); export const filterModel = { - $query, + $query: readonly($query), $tracks, - $selectedTracks, - $selectedVotingStatus, - $isFiltersSelected, + $selectedTracks: readonly($selectedTracks), + $selectedVotingStatus: readonly($selectedVotingStatus), + $isFiltersSelected: readonly($isFiltersSelected), events: { queryChanged, diff --git a/src/renderer/features/fellowship-referendums/model/list.ts b/src/renderer/features/fellowship-referendums/model/list.ts index 21e6b7adc1..9a85727c54 100644 --- a/src/renderer/features/fellowship-referendums/model/list.ts +++ b/src/renderer/features/fellowship-referendums/model/list.ts @@ -1,5 +1,5 @@ -import { combine, sample } from 'effector'; -import { and, either, or } from 'patronum'; +import { combine, restore, sample } from 'effector'; +import { and, debounce, either, or } from 'patronum'; import { attachToFeatureInput } from '@/shared/effector'; import { dictionary, nonNullable, performSearch } from '@/shared/lib/utils'; @@ -14,6 +14,8 @@ import { votingModel } from './voting'; // TODO do smth about it, this connection looks terrible const metadataProviderUpdated = attachToFeatureInput(referendumsFeatureStatus, governanceModel.$governanceApi); +const $deboucedQuery = restore(debounce(filterModel.$query, 300), ''); + sample({ clock: metadataProviderUpdated, filter: ({ data }) => nonNullable(data), @@ -39,7 +41,7 @@ const $referendums = fellowshipModel.$store.map(store => store?.referendums ?? [ const $meta = fellowshipModel.$store.map(store => store?.referendumMeta ?? {}); const $referendumsFilteredByQuery = combine( - { referendums: $referendums, meta: $meta, query: filterModel.$query }, + { referendums: $referendums, meta: $meta, query: $deboucedQuery }, ({ referendums, meta, query }) => { return performSearch({ records: referendums, diff --git a/src/renderer/features/fellowship-voting-history/components/Vote.tsx b/src/renderer/features/fellowship-voting-history/components/Vote.tsx index eb09fa1f2e..182fe91a6a 100644 --- a/src/renderer/features/fellowship-voting-history/components/Vote.tsx +++ b/src/renderer/features/fellowship-voting-history/components/Vote.tsx @@ -29,14 +29,16 @@ export const Vote = ({ item, chain }: Props) => { }); return ( - - {t('fellowship.votingHistory.votes', { count: item.votes })} - +
+ + {t('fellowship.votingHistory.votes', { count: item.votes })} + +
); }; diff --git a/src/renderer/features/fellowship-voting-history/components/VotesModal.tsx b/src/renderer/features/fellowship-voting-history/components/VotesModal.tsx index 6715babbe7..3742aa34bb 100644 --- a/src/renderer/features/fellowship-voting-history/components/VotesModal.tsx +++ b/src/renderer/features/fellowship-voting-history/components/VotesModal.tsx @@ -6,7 +6,7 @@ import { useI18n } from '@/shared/i18n'; import { cnTw } from '@/shared/lib/utils'; import { FootnoteText, Icon, Tabs } from '@/shared/ui'; import { type TabItem } from '@/shared/ui/types'; -import { Box, Modal } from '@/shared/ui-kit'; +import { Box, Carousel, Modal, SearchInput } from '@/shared/ui-kit'; import { votingHistoryFeatureStatus } from '../model/status'; import { votesModel } from '../model/votes'; @@ -16,6 +16,7 @@ export const VotesModal = ({ children }: PropsWithChildren) => { useGate(votingHistoryFeatureStatus.gate); const { t } = useI18n(); + const [query, setQuery] = useState(''); const [selectedTab, setSelectedTab] = useState(0); const votes = useUnit(votesModel.$votesList); @@ -48,7 +49,7 @@ export const VotesModal = ({ children }: PropsWithChildren) => { ), - panel: , + panel: null, }, { id: 'nays', @@ -59,7 +60,7 @@ export const VotesModal = ({ children }: PropsWithChildren) => { {nays.length.toString()} ), - panel: , + panel: null, }, ]; @@ -67,10 +68,21 @@ export const VotesModal = ({ children }: PropsWithChildren) => { {children} {t('fellowship.votingHistory.modalTitle')} - - - + + + + + + + + + + + + + + ); diff --git a/src/renderer/features/fellowship-voting-history/components/VotingHistory.tsx b/src/renderer/features/fellowship-voting-history/components/VotingHistory.tsx index ebe9b36631..6a87a5b56d 100644 --- a/src/renderer/features/fellowship-voting-history/components/VotingHistory.tsx +++ b/src/renderer/features/fellowship-voting-history/components/VotingHistory.tsx @@ -23,11 +23,11 @@ export const VotingHistory = ({ referendumId }: Props) => { const pending = useUnit(votesModel.$pending); const isNetworkDisabled = featureState.status === 'failed' && featureState.error.message === ERROR.networkDisabled; - if (pending || isNetworkDisabled) return ; + if (pending || isNetworkDisabled) return ; return ( - diff --git a/src/renderer/features/fellowship-voting-history/components/VotingHistoryList.tsx b/src/renderer/features/fellowship-voting-history/components/VotingHistoryList.tsx index 51cd31af05..1a2a90388e 100644 --- a/src/renderer/features/fellowship-voting-history/components/VotingHistoryList.tsx +++ b/src/renderer/features/fellowship-voting-history/components/VotingHistoryList.tsx @@ -1,12 +1,12 @@ import { useUnit } from 'effector-react'; -import { useState } from 'react'; +import { useMemo } from 'react'; import { type Chain } from '@/shared/core'; import { useI18n } from '@/shared/i18n'; import { useDeferredList } from '@/shared/lib/hooks'; import { performSearch, toAddress } from '@/shared/lib/utils'; -import { FootnoteText } from '@/shared/ui'; -import { SearchInput } from '@/shared/ui-kit'; +import { FootnoteText, Icon } from '@/shared/ui'; +import { Box, ScrollArea, Tooltip } from '@/shared/ui-kit'; import { type Vote as VoteType } from '@/domains/collectives'; import { identityModel } from '../model/identity'; @@ -14,24 +14,28 @@ import { Vote } from './Vote'; import { VotingHistoryListEmptyState } from './VotingHistoryListEmptyState'; type Props = { + query: string; items: VoteType[]; chain: Chain | null; loading?: boolean; }; -export const VotingHistoryList = ({ items, chain, loading }: Props) => { +export const VotingHistoryList = ({ items, query, chain, loading }: Props) => { const { t } = useI18n(); - const [query, setQuery] = useState(''); const identity = useUnit(identityModel.$identity); - const extendedItems = items.map(item => ({ - ...item, - address: toAddress(item.accountId, { prefix: chain?.addressPrefix }), - name: identity[item.accountId].name ?? null, - })); - - const filteredItems = performSearch({ records: extendedItems, query, weights: { address: 0.5, name: 1 } }); + const filteredItems = useMemo(() => { + return performSearch({ + records: items, + getMeta: item => ({ + address: toAddress(item.accountId, { prefix: chain?.addressPrefix }), + name: identity[item.accountId].name ?? null, + }), + query, + weights: { address: 0.5, name: 1 }, + }); + }, [items, query]); const { list: deferredItems, isLoading: shouldRenderLoader } = useDeferredList({ list: filteredItems, @@ -46,22 +50,37 @@ export const VotingHistoryList = ({ items, chain, loading }: Props) => { const shouldRenderList = !shouldRenderLoader && deferredItems.length > 0; return ( -
- +
+
+ {shouldRenderEmptyState && } + {shouldRenderList && ( + + + + {t('governance.voteHistory.listColumnAccount')} + + + + {t('governance.voteHistory.listColumnVotingPower')} + + + +
+ +
+
+ {t('fellowship.votingHistory.votingPowerDescription')} +
+
+
-
-
-
- {t('governance.voteHistory.listColumnAccount')} - - {t('governance.voteHistory.listColumnVotingPower')} - -
-
- {shouldRenderEmptyState && } - {shouldRenderList && deferredItems.map(vote => )} -
-
+ + {deferredItems.map(vote => ( + + ))} + + + )}
); diff --git a/src/renderer/features/fellowship-voting-history/components/VotingHistoryListEmptyState.tsx b/src/renderer/features/fellowship-voting-history/components/VotingHistoryListEmptyState.tsx index 0e2bf11fb3..bb2c999dc9 100644 --- a/src/renderer/features/fellowship-voting-history/components/VotingHistoryListEmptyState.tsx +++ b/src/renderer/features/fellowship-voting-history/components/VotingHistoryListEmptyState.tsx @@ -1,13 +1,14 @@ import { useI18n } from '@/shared/i18n'; import { FootnoteText, Icon } from '@/shared/ui'; +import { Box } from '@/shared/ui-kit'; export const VotingHistoryListEmptyState = () => { const { t } = useI18n(); return ( -
+ {t('fellowship.votingHistory.emptyList')} -
+ ); }; diff --git a/src/renderer/features/fellowship-voting/components/WalletVotingInfo.tsx b/src/renderer/features/fellowship-voting/components/WalletVotingInfo.tsx index 8c182ba8c3..81867c0566 100644 --- a/src/renderer/features/fellowship-voting/components/WalletVotingInfo.tsx +++ b/src/renderer/features/fellowship-voting/components/WalletVotingInfo.tsx @@ -5,7 +5,7 @@ import { useI18n } from '@/shared/i18n'; import { nullable } from '@/shared/lib/utils'; import { type ReferendumId } from '@/shared/pallet/referenda'; import { Icon } from '@/shared/ui'; -import { Box, Surface } from '@/shared/ui-kit'; +import { Box } from '@/shared/ui-kit'; import { votingStatusModel } from '../model/votingStatus'; type Props = { @@ -26,7 +26,7 @@ export const WalletVotingInfo = memo(({ referendumId }: Props) => { const nayVotes = voting.nay ? `NAY ${voting.nay} votes` : null; return ( - +
{t('fellowship.voting.voted')} @@ -34,6 +34,6 @@ export const WalletVotingInfo = memo(({ referendumId }: Props) => { {ayeVotes} {nayVotes} - +
); }); diff --git a/src/renderer/features/fellowship-voting/model/status.ts b/src/renderer/features/fellowship-voting/model/status.ts index 9665616835..0806679e6f 100644 --- a/src/renderer/features/fellowship-voting/model/status.ts +++ b/src/renderer/features/fellowship-voting/model/status.ts @@ -20,9 +20,9 @@ const $input = combine( chain: network.chain, chainId: network.chainId, palletType: network.palletType, + accounts: wallet.accounts, wallets, wallet, - accounts: wallet.accounts, }; }, ); diff --git a/src/renderer/features/fellowship-voting/model/votingStatus.ts b/src/renderer/features/fellowship-voting/model/votingStatus.ts index 65b314b786..f09df5f9cd 100644 --- a/src/renderer/features/fellowship-voting/model/votingStatus.ts +++ b/src/renderer/features/fellowship-voting/model/votingStatus.ts @@ -27,13 +27,15 @@ const $referendum = combine($referendums, $referendumId, (referendums, referendu const $currentMember = combine(votingFeatureStatus.input, $members, (featureInput, members) => { if (nullable(featureInput)) return null; - return collectiveDomain.membersService.findMachingMember(featureInput.accounts, members, featureInput.chain); + const { wallet, accounts, chain } = featureInput; + + return collectiveDomain.membersService.findMatchingMember(wallet, accounts, chain, members); }); const $votingAccount = combine(votingFeatureStatus.input, $currentMember, (input, member) => { if (nullable(member) || nullable(input)) return null; - return collectiveDomain.membersService.findMachingAccount(input.accounts, member); + return collectiveDomain.membersService.findMatchingAccount(input.accounts, member); }); const $hasRequiredRank = combine( diff --git a/src/renderer/pages/Fellowship/ui/Fellowship.tsx b/src/renderer/pages/Fellowship/ui/Fellowship.tsx index 2be7559b8f..3b90fa5f67 100644 --- a/src/renderer/pages/Fellowship/ui/Fellowship.tsx +++ b/src/renderer/pages/Fellowship/ui/Fellowship.tsx @@ -32,7 +32,7 @@ export const Fellowship = () => { const selectedChain = useUnit(fellowshipNetworkFeature.model.network.$selectedChainId); useLayoutEffect(() => { - if (chainId && chainId.startsWith('0x')) { + if (chainId?.startsWith('0x')) { fellowshipNetworkFeature.model.network.selectCollective({ chainId: chainId as ChainId }); } else { // navigate to default chain @@ -42,15 +42,15 @@ export const Fellowship = () => { return (
-
+
- - + +
{}} /> diff --git a/src/renderer/pages/Onboarding/Vault/ManageMultishard/ManageMultishard.tsx b/src/renderer/pages/Onboarding/Vault/ManageMultishard/ManageMultishard.tsx index 21aa9af427..1c8066fbcb 100644 --- a/src/renderer/pages/Onboarding/Vault/ManageMultishard/ManageMultishard.tsx +++ b/src/renderer/pages/Onboarding/Vault/ManageMultishard/ManageMultishard.tsx @@ -199,7 +199,7 @@ export const ManageMultishard = ({ seedInfo, onBack, onClose, onComplete }: Prop }; return ( -
+
{t('onboarding.vault.title')} diff --git a/src/renderer/pages/Onboarding/Vault/ScanStep/ScanStep.tsx b/src/renderer/pages/Onboarding/Vault/ScanStep/ScanStep.tsx index 358fae6b13..60ecda8be4 100644 --- a/src/renderer/pages/Onboarding/Vault/ScanStep/ScanStep.tsx +++ b/src/renderer/pages/Onboarding/Vault/ScanStep/ScanStep.tsx @@ -14,7 +14,7 @@ const ScanStep = ({ onBack, onNextStep }: Props) => { const { t } = useI18n(); return ( -
+
{t('onboarding.vault.title')} diff --git a/src/renderer/pages/Onboarding/Vault/Vault.tsx b/src/renderer/pages/Onboarding/Vault/Vault.tsx index b4cb70ce8a..e09189c59e 100644 --- a/src/renderer/pages/Onboarding/Vault/Vault.tsx +++ b/src/renderer/pages/Onboarding/Vault/Vault.tsx @@ -103,7 +103,7 @@ export const Vault = ({ isOpen, onClose, onComplete }: Props) => { return ( diff --git a/src/renderer/pages/PageLoadingState.tsx b/src/renderer/pages/PageLoadingState.tsx index 72fe1ff727..80d5abe0e2 100644 --- a/src/renderer/pages/PageLoadingState.tsx +++ b/src/renderer/pages/PageLoadingState.tsx @@ -2,7 +2,7 @@ import { Loader } from '@/shared/ui'; export const PageLoadingState = () => { return ( -
+
); diff --git a/src/renderer/shared/api/balances/service/balanceService.ts b/src/renderer/shared/api/balances/service/balanceService.ts index 49786c3455..d8fa934b20 100644 --- a/src/renderer/shared/api/balances/service/balanceService.ts +++ b/src/renderer/shared/api/balances/service/balanceService.ts @@ -157,7 +157,7 @@ function subscribeStatemineAssetsChange( throw new Error(`Pallet ${pallet} not found.`); } - const type = api.tx.foreignAssets.transfer.meta.args[0].type; + const type = api.tx[pallet]?.transfer.meta.args[0].type; if (nullable(type)) { return Promise.resolve(noop); } diff --git a/src/renderer/shared/api/xcm/__tests__/xcm-utils.test.ts b/src/renderer/shared/api/xcm/__tests__/xcm-utils.test.ts index 3cace57ce3..b1359514db 100644 --- a/src/renderer/shared/api/xcm/__tests__/xcm-utils.test.ts +++ b/src/renderer/shared/api/xcm/__tests__/xcm-utils.test.ts @@ -37,28 +37,54 @@ describe('shared/api/xcm/lib/xcm-utils', () => { }); test('should calculate correct location for sibling prachain', () => { - const location = xcmUtils.getDestinationLocation({ parentId: '0x00' }, 2000) as any; + const location = xcmUtils.getDestinationLocation('V2', { parentId: '0x00' }, 2000) as any; expect(location.parents).toEqual(1); - expect(location.interior.X1[0].Parachain).toEqual(2000); + expect(location.interior.X1.Parachain).toEqual(2000); }); test('should calculate correct location for parent parachain', () => { - const location = xcmUtils.getDestinationLocation({ parentId: '0x00' }) as any; + const location = xcmUtils.getDestinationLocation('V2', { parentId: '0x00' }) as any; expect(location.parents).toEqual(1); expect(location.interior).toEqual('Here'); }); test('should calculate correct address location for parent parachain', () => { - const location = xcmUtils.getDestinationLocation({ parentId: '0x00' }, undefined, '0x00') as any; + const location = xcmUtils.getDestinationLocation('V2', { parentId: '0x00' }, undefined, '0x00') as any; + + expect(location.parents).toEqual(1); + expect(location.interior.X1.AccountId32.id).toEqual('0x00'); + }); + + test('should calculate correct address location for parent parachain V4', () => { + const location = xcmUtils.getDestinationLocation('V4', { parentId: '0x00' }, undefined, '0x00') as any; expect(location.parents).toEqual(1); expect(location.interior.X1[0].AccountId32.id).toEqual('0x00'); }); + test('should calculate correct address location for parent parachain V4', () => { + const location = xcmUtils.getDestinationLocation( + 'V4', + { parentId: '0x00' }, + undefined, + '0x3da9ea1622ee74cf87144e3d2c7f7cce4d167d9c', + ) as any; + + expect(location.parents).toEqual(1); + expect(location.interior.X1[0].AccountKey20.key).toEqual('0x3da9ea1622ee74cf87144e3d2c7f7cce4d167d9c'); + }); + test('should calculate correct location for child parachain', () => { - const location = xcmUtils.getDestinationLocation({ parentId: undefined }, 2000) as any; + const location = xcmUtils.getDestinationLocation('V2', { parentId: undefined }, 2000) as any; + + expect(location.parents).toEqual(0); + expect(location.interior.X1.Parachain).toEqual(2000); + }); + + test('should calculate correct location for child parachain V4', () => { + const location = xcmUtils.getDestinationLocation('V4', { parentId: undefined }, 2000) as any; expect(location.parents).toEqual(0); expect(location.interior.X1[0].Parachain).toEqual(2000); diff --git a/src/renderer/shared/api/xcm/lib/types.ts b/src/renderer/shared/api/xcm/lib/types.ts index 3b21c94f55..4bcf8d3340 100644 --- a/src/renderer/shared/api/xcm/lib/types.ts +++ b/src/renderer/shared/api/xcm/lib/types.ts @@ -87,6 +87,7 @@ export const enum XcmTransferType { XTOKENS = 'xtokens', XCMPALLET = 'xcmpallet', XCMPALLET_TELEPORT = 'xcmpallet-teleport', + XCMPALLET_TRANSFER_ASSETS = 'xcmpallet-transferAssets', } export type PathType = 'absolute' | 'relative' | 'concrete'; diff --git a/src/renderer/shared/api/xcm/lib/xcm-utils.ts b/src/renderer/shared/api/xcm/lib/xcm-utils.ts index 4a95cf3359..9af057dd53 100644 --- a/src/renderer/shared/api/xcm/lib/xcm-utils.ts +++ b/src/renderer/shared/api/xcm/lib/xcm-utils.ts @@ -100,11 +100,19 @@ function sortJunctions(a: JunctionTypeKey, b: JunctionTypeKey): number { return JunctionHierarchyLevel[a] - JunctionHierarchyLevel[b]; } -function createJunctionFromObject(data: Record) { +function createJunctionFromObject(version: string, data: Record) { const entries = Object.entries(data); if (entries.length === 0) return 'Here'; + if (['V2', 'V3'].includes(version) && entries.length === 1) { + return { + X1: { + [JunctionType[entries[0][0] as JunctionTypeKey]]: entries[0][1], + }, + }; + } + return { [`X${entries.length}`]: entries .sort((a, b) => sortJunctions(a[0], b[0])) @@ -114,52 +122,53 @@ function createJunctionFromObject(data: Record) { }; } -function getRelativeAssetLocation(assetLocation?: LocalMultiLocation) { +function getRelativeAssetLocation(version: string, assetLocation?: LocalMultiLocation) { if (!assetLocation) return; const { parachainId: _, ...location } = assetLocation; return { parents: 0, - interior: createJunctionFromObject(location), + interior: createJunctionFromObject(version, location), }; } -function getAbsoluteAssetLocation(assetLocation?: LocalMultiLocation) { +function getAbsoluteAssetLocation(version: string, assetLocation?: LocalMultiLocation) { if (!assetLocation) return; return { parents: 1, - interior: createJunctionFromObject(assetLocation), + interior: createJunctionFromObject(version, assetLocation), }; } -function getConcreteAssetLocation(assetLocation?: LocalMultiLocation) { +function getConcreteAssetLocation(version: string, assetLocation?: LocalMultiLocation) { if (!assetLocation) return; const { parents, ...location } = assetLocation; return { parents, - interior: createJunctionFromObject(location), + interior: createJunctionFromObject(version, location), }; } function getDestinationLocation( + version: string, originChain: Pick, destinationParaId?: number, accountId?: AccountId, ) { if (originChain.parentId && destinationParaId) { - return getSiblingLocation(destinationParaId, accountId); + return getSiblingLocation(version, destinationParaId, accountId); } if (originChain.parentId) { - return getParentLocation(accountId); + return getParentLocation(version, accountId); } if (destinationParaId) { - return getChildLocation(destinationParaId, accountId); + return getChildLocation(version, destinationParaId, accountId); } return undefined; @@ -183,7 +192,7 @@ function getAccountLocation(accountId?: AccountId) { }; } -function getChildLocation(parachainId: number, accountId?: AccountId) { +function getChildLocation(version: string, parachainId: number, accountId?: AccountId) { const location: Record = { parachainId }; const isEthereum = isEthereumAccountId(accountId); @@ -196,11 +205,11 @@ function getChildLocation(parachainId: number, accountId?: AccountId) { return { parents: 0, - interior: createJunctionFromObject(location), + interior: createJunctionFromObject(version, location), }; } -function getParentLocation(accountId?: AccountId) { +function getParentLocation(version: string, accountId?: AccountId) { const location: Record = {}; const isEthereum = isEthereumAccountId(accountId); @@ -213,11 +222,11 @@ function getParentLocation(accountId?: AccountId) { return { parents: 1, - interior: createJunctionFromObject(location), + interior: createJunctionFromObject(version, location), }; } -function getSiblingLocation(parachainId: number, accountId?: AccountId) { +function getSiblingLocation(version: string, parachainId: number, accountId?: AccountId) { const location: Record = { parachainId }; const isEthereum = isEthereumAccountId(accountId); @@ -230,7 +239,7 @@ function getSiblingLocation(parachainId: number, accountId?: AccountId) { return { parents: 1, - interior: createJunctionFromObject(location), + interior: createJunctionFromObject(version, location), }; } diff --git a/src/renderer/shared/api/xcm/service/xcmService.ts b/src/renderer/shared/api/xcm/service/xcmService.ts index f732621fb5..6076f2efa7 100644 --- a/src/renderer/shared/api/xcm/service/xcmService.ts +++ b/src/renderer/shared/api/xcm/service/xcmService.ts @@ -118,28 +118,46 @@ function getEstimatedRequiredDestWeight( return weight.gte(reserveWeight) ? weight : reserveWeight; } +function getFixedVersion(location: string) { + return { + // TODO: check Interlay transfer later + INTR: 'V2', + }[location]; +} + function getAssetLocation( api: ApiPromise, transferType: XcmTransferType, asset: AssetXCM, - assets: Record, + assetsConfig: Record, amount: BN, isArray = true, ): NonNullable | undefined { + const type = getTypeName(api, transferType, isArray ? 'assets' : 'asset'); + const assetVersionType = getFixedVersion(asset.assetLocation) || getTypeVersion(api, type || ''); + const PathMap: Record NonNullable | undefined> = { - relative: () => xcmUtils.getRelativeAssetLocation(assets[asset.assetLocation].multiLocation), - absolute: () => xcmUtils.getAbsoluteAssetLocation(assets[asset.assetLocation].multiLocation), - concrete: () => xcmUtils.getConcreteAssetLocation(asset.assetLocationPath.path), + relative: () => + xcmUtils.getRelativeAssetLocation(assetVersionType, assetsConfig[asset.assetLocation].multiLocation), + absolute: () => + xcmUtils.getAbsoluteAssetLocation(assetVersionType, assetsConfig[asset.assetLocation].multiLocation), + concrete: () => xcmUtils.getConcreteAssetLocation(assetVersionType, asset.assetLocationPath.path), }; const location = PathMap[asset.assetLocationPath.type](); - const type = getTypeName(api, transferType, isArray ? 'assets' : 'asset'); - const assetVersionType = getTypeVersion(api, type || ''); - const assetObject = { - id: { + let id; + + if (['V2', 'V3'].includes(assetVersionType)) { + id = { Concrete: location, - }, + }; + } else { + id = location; + } + + const assetObject = { + id, fun: { Fungible: amount.toString(), }, @@ -157,7 +175,7 @@ function getVersionedDestinationLocation( ) { const type = getTypeName(api, transferType, 'dest'); const version = getTypeVersion(api, type || ''); - const location = xcmUtils.getDestinationLocation(originChain, destinationParaId, accountId); + const location = xcmUtils.getDestinationLocation(version, originChain, destinationParaId, accountId); if (!version) return location; diff --git a/src/renderer/shared/core/types/transaction.ts b/src/renderer/shared/core/types/transaction.ts index 7c246bf69b..502b4817bb 100644 --- a/src/renderer/shared/core/types/transaction.ts +++ b/src/renderer/shared/core/types/transaction.ts @@ -16,6 +16,7 @@ export const enum TransactionType { XCM_TELEPORT = 'xcm_limited_teleport_assets', POLKADOT_XCM_LIMITED_TRANSFER = 'polkadotxcm_limited_reserve_transfer_assets', POLKADOT_XCM_TELEPORT = 'polkadotxcm_limited_teleport_assets', + POLKADOT_XCM_TRANSFER_ASSETS = 'polkadotxcm_transfer_assets', XTOKENS_TRANSFER_MULTIASSET = 'xtokens_transfer_multiasset', BOND = 'bond', diff --git a/src/renderer/shared/i18n/locales/en.json b/src/renderer/shared/i18n/locales/en.json index 909f631b5a..4ab6df84bd 100644 --- a/src/renderer/shared/i18n/locales/en.json +++ b/src/renderer/shared/i18n/locales/en.json @@ -307,6 +307,9 @@ "reloadButton": "Refresh" }, "fellowship": { + "details": { + "noDetails": "Details not found" + }, "errors": { "disconnect": { "action": "Open network settings", @@ -322,22 +325,7 @@ "modalAccountTitle": "Account", "modalTitle": "Fellowship members" }, - "voting": { - "voted": "Voted:", - "errors": { - "rankThreshold": "You cannot vote in this referendum because your rank is below the required level." - }, - "votingStatus": "Voting status", - "summary": "Summary", - "title": "Vote on", - "threshold": "Threshold", - "aye": "Aye", - "nay": "Nay", - "confirmation": { - "vote": "Vote", - "fee": "Fee" - } - }, + "noAccount": "Account not found", "noProfile": "Profile doesn’t exist", "referendums": { "tracks": { @@ -365,14 +353,35 @@ } }, "title": "Fellowship", - "yourProfile": "Your profile", + "tooltips": { + "noProfile": "You are not a fellowship member", + "noAccount": "Please add or create account to the { chain } network" + }, + "voting": { + "voted": "Voted:", + "errors": { + "rankThreshold": "You cannot vote in this referendum because your rank is below the required level." + }, + "votingStatus": "Voting status", + "summary": "Summary", + "title": "Vote on", + "threshold": "Threshold", + "aye": "Aye", + "nay": "Nay", + "confirmation": { + "vote": "Vote", + "fee": "Fee" + } + }, "votingHistory": { "modalTitle": "Vote history", "votes_one": "{count} vote", "votes_other": "{count} votes", "showHistoryButton": "View vote history", - "emptyList": "There is no vote history" - } + "emptyList": "There is no vote history", + "votingPowerDescription": "Voting power is a number of votes calculated based on the member's rank." + }, + "yourProfile": "Your profile" }, "general": { "actions": { @@ -1085,6 +1094,7 @@ "titles": { "addProxy": "Add delegated authority (proxy)", "approveMultisig": "Approve multisig operation", + "batchAll": "Batch All", "createPureProxy": "Create pure proxy", "crossChainTransfer": "Cross-chain transfer", "delegate": "Delegate", diff --git a/src/renderer/shared/lib/utils/__tests__/arrays.test.ts b/src/renderer/shared/lib/utils/__tests__/arrays.test.ts index e4d7d7f8aa..e12b233288 100644 --- a/src/renderer/shared/lib/utils/__tests__/arrays.test.ts +++ b/src/renderer/shared/lib/utils/__tests__/arrays.test.ts @@ -60,7 +60,7 @@ describe('merge', () => { expect(res).toEqual(['1', '2', '3', '4', '5']); }); - it('should return first array if second is empty', () => { + test('should return first array if second is empty', () => { const list1 = ['1', '2', '3', '4']; const res = merge({ @@ -120,7 +120,7 @@ describe('merge', () => { expect(res).toEqual([{ id: 1, v: 3 }, { id: 3 }, { id: 5 }]); }); - it('should replace and sort objects', () => { + test('should replace and sort objects', () => { const list1 = [{ id: 1 }, { id: 5 }, { id: 4 }]; const list2 = [{ id: 3 }, { id: 2 }]; @@ -238,7 +238,7 @@ describe('dictionary', () => { }); describe('groupBy', () => { - it('should group', () => { + test('should group', () => { const list = [ { type: 'a', v: 1 }, { type: 'b', v: 1 }, diff --git a/src/renderer/shared/lib/utils/substrate.ts b/src/renderer/shared/lib/utils/substrate.ts index 81f08c71b2..4f5cd31e68 100644 --- a/src/renderer/shared/lib/utils/substrate.ts +++ b/src/renderer/shared/lib/utils/substrate.ts @@ -26,7 +26,7 @@ import { DEFAULT_TIME, ONE_DAY, THRESHOLD } from './constants'; export type TxMetadata = { registry: TypeRegistry; options: OptionsWithMeta; info: BaseTxInfo }; -const SUPPORTED_VERSIONS = ['V3', 'V4']; +const SUPPORTED_VERSIONS = ['V2', 'V3', 'V4']; const UNUSED_LABEL = 'unused'; /** @@ -180,7 +180,7 @@ export const getTypeVersion = (api: ApiPromise, typeName: string): string => { const enumValues = getTypeEnumValues(api, typeName); const supportedVersions = enumValues.filter((value) => SUPPORTED_VERSIONS.includes(value)); - return supportedVersions.pop() || ''; + return supportedVersions.at(-1) || ''; }; export const getProxyTypes = (api: ApiPromise): ProxyType[] => { @@ -227,6 +227,10 @@ export const getPalletAndCallByXcmTransferType = ( return { pallet, call: 'limitedTeleportAssets' }; } + if (transferType === XcmTransferType.XCMPALLET_TRANSFER_ASSETS) { + return { pallet, call: 'transferAssets' }; + } + // Should never be reached as all transferType cases are covered throw new Error('Invalid transferType'); }; diff --git a/src/renderer/shared/ui-kit/Carousel/Carousel.tsx b/src/renderer/shared/ui-kit/Carousel/Carousel.tsx index 1cea7a779c..e0de6a3bdc 100644 --- a/src/renderer/shared/ui-kit/Carousel/Carousel.tsx +++ b/src/renderer/shared/ui-kit/Carousel/Carousel.tsx @@ -105,7 +105,7 @@ const Item = memo(({ id, children }: ItemProps) => { return transitions((styles, item) => item ? ( - + {children} ) : null, @@ -125,7 +125,10 @@ const AnimatedResizableBlock = ({ children }: PropsWithChildren) => { }); return ( -
+
{children}
); diff --git a/src/renderer/shared/ui-kit/Input/Input.tsx b/src/renderer/shared/ui-kit/Input/Input.tsx index b3ea2b153b..627208dd0b 100644 --- a/src/renderer/shared/ui-kit/Input/Input.tsx +++ b/src/renderer/shared/ui-kit/Input/Input.tsx @@ -28,7 +28,7 @@ export const Input = forwardRef( ( { type = 'text', - height = 'md', + height = 'sm', name, value, placeholder, diff --git a/src/renderer/shared/ui-kit/Modal/Modal.tsx b/src/renderer/shared/ui-kit/Modal/Modal.tsx index 086b3aef43..99c2796700 100644 --- a/src/renderer/shared/ui-kit/Modal/Modal.tsx +++ b/src/renderer/shared/ui-kit/Modal/Modal.tsx @@ -96,9 +96,17 @@ const Title = ({ action, close, children }: TitleProps) => { ); }; +const HeaderContent = ({ children }: PropsWithChildren) => { + return ( +
+ {children} +
+ ); +}; + const Content = ({ disableScroll, children }: PropsWithChildren<{ disableScroll?: boolean }>) => { return disableScroll ? ( -
{children}
+
{children}
) : ( {children} ); @@ -115,6 +123,7 @@ const Footer = ({ children }: PropsWithChildren) => { export const Modal = Object.assign(Root, { Trigger, Title, + HeaderContent, Content, Footer, }); diff --git a/src/renderer/shared/ui-kit/Theme/ThemeProvider.tsx b/src/renderer/shared/ui-kit/Theme/ThemeProvider.tsx index 3da7f1d739..17cb869a7b 100644 --- a/src/renderer/shared/ui-kit/Theme/ThemeProvider.tsx +++ b/src/renderer/shared/ui-kit/Theme/ThemeProvider.tsx @@ -25,7 +25,7 @@ export const ThemeProvider = ({ bodyAsPortalContainer, iconStyle, theme, childre return (
{children}
-
+
); }; diff --git a/src/renderer/shared/ui-kit/Tooltip/Tooltip.tsx b/src/renderer/shared/ui-kit/Tooltip/Tooltip.tsx index 7ca64900d6..a756397849 100644 --- a/src/renderer/shared/ui-kit/Tooltip/Tooltip.tsx +++ b/src/renderer/shared/ui-kit/Tooltip/Tooltip.tsx @@ -30,7 +30,7 @@ const Root = ({ onToggle, children, side = 'top', - sideOffset = 2, + sideOffset = 1, align = 'center', alignOffset = 0, testId = 'Tooltip', diff --git a/src/renderer/shared/ui/Inputs/Input/Input.tsx b/src/renderer/shared/ui/Inputs/Input/Input.tsx deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/src/renderer/shared/ui/Inputs/SearchInput/SearchInput.tsx b/src/renderer/shared/ui/Inputs/SearchInput/SearchInput.tsx deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/src/renderer/shared/ui/Modals/BaseModal/BaseModal.tsx b/src/renderer/shared/ui/Modals/BaseModal/BaseModal.tsx index d40a5338cc..a61f74aeba 100644 --- a/src/renderer/shared/ui/Modals/BaseModal/BaseModal.tsx +++ b/src/renderer/shared/ui/Modals/BaseModal/BaseModal.tsx @@ -2,6 +2,7 @@ import * as Dialog from '@radix-ui/react-dialog'; import { type PropsWithChildren, type ReactNode } from 'react'; import { cnTw } from '@/shared/lib/utils'; +import { useTheme } from '@/shared/ui-kit/Theme/useTheme'; import { IconButton } from '../../Buttons'; import { HeaderTitleText } from '../../Typography'; @@ -16,6 +17,7 @@ type Props = { closeButton?: boolean; actionButton?: ReactNode; onClose: () => void; + testId?: string; }; /** @@ -33,12 +35,14 @@ export const BaseModal = ({ children, panelStyle, onClose, + testId = 'BaseModal', }: PropsWithChildren) => { + const { portalContainer } = useTheme(); const headerExist = title || actionButton || closeButton; return ( !open && onClose()}> - + {headerExist && ( diff --git a/src/renderer/shared/ui/Modals/StatusModal/StatusModal.stories.tsx b/src/renderer/shared/ui/Modals/StatusModal/StatusModal.stories.tsx new file mode 100644 index 0000000000..2c5c6b4cf0 --- /dev/null +++ b/src/renderer/shared/ui/Modals/StatusModal/StatusModal.stories.tsx @@ -0,0 +1,51 @@ +import { type Meta, type StoryObj } from '@storybook/react'; + +import { Animation } from '../../Animation/Animation'; +import { Button } from '../../Buttons'; + +import { StatusModal } from './StatusModal'; + +const meta: Meta = { + title: 'v1/ui/StatusModal', + component: StatusModal, + parameters: { actions: { argTypesRegex: '^on.*' } }, +}; + +export default meta; + +type Story = StoryObj; + +export const Default: Story = { + args: { + isOpen: true, + title: 'Status modal example', + onClose: () => {}, + }, +}; + +export const WithContent: Story = { + args: { + isOpen: true, + title: 'Status modal example', + content: , + onClose: () => {}, + }, +}; + +export const WithFooter: Story = { + args: { + isOpen: true, + title: 'Status modal example', + children: ( + <> + + + + ), + onClose: () => {}, + }, +}; diff --git a/src/renderer/shared/ui/Modals/StatusModal/StatusModal.tsx b/src/renderer/shared/ui/Modals/StatusModal/StatusModal.tsx index b85a7f91f4..86c7c250bc 100644 --- a/src/renderer/shared/ui/Modals/StatusModal/StatusModal.tsx +++ b/src/renderer/shared/ui/Modals/StatusModal/StatusModal.tsx @@ -1,10 +1,9 @@ -import { Dialog, Transition } from '@headlessui/react'; -import { Fragment, type PropsWithChildren, type ReactNode } from 'react'; +import * as Dialog from '@radix-ui/react-dialog'; +import { type PropsWithChildren, type ReactNode } from 'react'; import { cnTw } from '@/shared/lib/utils'; import { FootnoteText, SmallTitleText } from '../../Typography'; -import { ModalBackdrop } from '../common/ModalBackdrop'; -import { ModalTransition } from '../common/ModalTransition'; +import { BaseModal } from '../BaseModal/BaseModal'; type Props = { content?: ReactNode; @@ -14,6 +13,7 @@ type Props = { zIndex?: string; onClose: () => void; className?: string; + testId?: string; }; export const StatusModal = ({ @@ -25,38 +25,35 @@ export const StatusModal = ({ className, children, onClose, + testId = 'StatusModal', }: PropsWithChildren) => { return ( - - - + + {content} + + + {title} + + -
- - - {content} + {description && ( + + {description} + + )} - - {title} - - - {description && ( - - {description} - - )} - - {children &&
{children}
} -
-
-
-
-
+ {children &&
{children}
} + ); }; diff --git a/src/renderer/shared/ui/Popovers/Popover/Popover.tsx b/src/renderer/shared/ui/Popovers/Popover/Popover.tsx index 7881762bb5..26a5a2694d 100644 --- a/src/renderer/shared/ui/Popovers/Popover/Popover.tsx +++ b/src/renderer/shared/ui/Popovers/Popover/Popover.tsx @@ -5,6 +5,7 @@ import { createPortal } from 'react-dom'; import { useDebounce } from '@/shared/lib/hooks'; import { cnTw } from '@/shared/lib/utils'; +import { useTheme } from '@/shared/ui-kit/Theme/useTheme'; import { type Horizontal, type Vertical } from '../common/types'; import { useParentScrollLock } from '../common/useParentScrollLock'; @@ -45,6 +46,8 @@ export const Popover = ({ tabIndex = 0, children, }: PropsWithChildren) => { + const { portalContainer } = useTheme(); + const id = useId(); const ref = useRef(null); const [isOpen, setIsOpen] = useState(false); @@ -109,7 +112,7 @@ export const Popover = ({
{content}
, - document.body, + portalContainer ?? document.body, )} ); diff --git a/src/renderer/shared/ui/Tabs/Tabs.tsx b/src/renderer/shared/ui/Tabs/Tabs.tsx index f60b7d9e0b..35da4bea61 100644 --- a/src/renderer/shared/ui/Tabs/Tabs.tsx +++ b/src/renderer/shared/ui/Tabs/Tabs.tsx @@ -43,7 +43,7 @@ export const Tabs = ({ {items.map(({ id, panel }) => ( - + {panel} ))} diff --git a/src/renderer/widgets/CreateWallet/ui/MultisigWallet/ConfirmationStep.tsx b/src/renderer/widgets/CreateWallet/ui/MultisigWallet/ConfirmationStep.tsx index 849a467d78..4fa4104a0d 100644 --- a/src/renderer/widgets/CreateWallet/ui/MultisigWallet/ConfirmationStep.tsx +++ b/src/renderer/widgets/CreateWallet/ui/MultisigWallet/ConfirmationStep.tsx @@ -5,16 +5,17 @@ import { WalletType } from '@/shared/core'; import { useI18n } from '@/shared/i18n'; import { useToggle } from '@/shared/lib/hooks'; import { Step, nonNullable } from '@/shared/lib/utils'; -import { Alert, Button, Counter, DetailRow, Icon, IconButton, Separator } from '@/shared/ui'; +import { Alert, BodyText, Button, Counter, DetailRow, Icon, IconButton, Separator } from '@/shared/ui'; import { Box, Modal } from '@/shared/ui-kit'; import { SignButton } from '@/entities/operations'; import { FeeWithLabel, MultisigDepositWithLabel } from '@/entities/transaction'; +import { WalletIcon } from '@/entities/wallet'; import { confirmModel } from '../../model/confirm-model'; import { flowModel } from '../../model/flow-model'; import { formModel } from '../../model/form-model'; import { signatoryModel } from '../../model/signatory-model'; -import { SelectedSignatoriesModal, WalletItem } from './components'; +import { SelectedSignatoriesModal } from './components'; export const ConfirmationStep = () => { const { t } = useI18n(); @@ -65,10 +66,15 @@ export const ConfirmationStep = () => { - +
+ + +
+ + {signer?.name || (signerWallet?.type === WalletType.POLKADOT_VAULT && signerWallet?.name) || ''} + +
+
{chain ? ( diff --git a/src/renderer/widgets/CreateWallet/ui/MultisigWallet/components/MultisigCreationFees.tsx b/src/renderer/widgets/CreateWallet/ui/MultisigWallet/components/MultisigCreationFees.tsx index 1f8b9eeee7..d2a26f5f9c 100644 --- a/src/renderer/widgets/CreateWallet/ui/MultisigWallet/components/MultisigCreationFees.tsx +++ b/src/renderer/widgets/CreateWallet/ui/MultisigWallet/components/MultisigCreationFees.tsx @@ -29,7 +29,7 @@ export const MultisigCreationFees = memo(({ api, asset, threshold, onDepositChan const [isDepositLoading, setIsDepositLoading] = useState(true); const [deposit, setDeposit] = useState(BN_ZERO); - const [networkFee, setNeworkFee] = useState(BN_ZERO); + const [networkFee, setNetworkFee] = useState(BN_ZERO); const fee = useMemo(() => deposit.add(networkFee), [deposit, networkFee]); const isLoading = useMemo(() => isNetworkFeeLoading || isDepositLoading, [isNetworkFeeLoading, isDepositLoading]); @@ -52,9 +52,9 @@ export const MultisigCreationFees = memo(({ api, asset, threshold, onDepositChan setIsNetworkFeeLoading(true); transactionService .getTransactionFee(transaction, api) - .then((fee) => setNeworkFee(new BN(fee))) + .then((fee) => setNetworkFee(new BN(fee))) .catch((error) => { - setNeworkFee(BN_ZERO); + setNetworkFee(BN_ZERO); console.info('Error getting fee - ', error); }) .finally(() => setIsNetworkFeeLoading(false)); diff --git a/src/renderer/widgets/CreateWallet/ui/MultisigWallet/components/Signatory.tsx b/src/renderer/widgets/CreateWallet/ui/MultisigWallet/components/Signatory.tsx index 849dbbeda0..4fca7ba7de 100644 --- a/src/renderer/widgets/CreateWallet/ui/MultisigWallet/components/Signatory.tsx +++ b/src/renderer/widgets/CreateWallet/ui/MultisigWallet/components/Signatory.tsx @@ -179,12 +179,14 @@ export const Signatory = ({ }); }; - const onAddressChange = (address: AccountAddress, walletId?: ID) => { + const onAddressChange = (value: AccountAddress | { address: AccountAddress; walletId?: ID }) => { + const newSignatory = typeof value === 'string' ? { address: value } : value; + signatoryModel.events.changeSignatory({ index: signatoryIndex, name: signatoryName, - address: address, - walletId: walletId?.toString(), // will be undefined for contact + address: newSignatory.address, + walletId: newSignatory.walletId?.toString(), // will be undefined for contact }); }; @@ -207,6 +209,7 @@ export const Signatory = ({ placeholder={t('createMultisigAccount.signatorySelection')} options={options} query={query} + invalid={isDuplicate} value={toAddress(signatoryAddress, { prefix: chain?.addressPrefix })} prefixElement={ } - onChange={({ value }) => onAddressChange(value.address, value.walletId)} + onChange={({ value }) => onAddressChange(value)} onInput={setQuery} /> diff --git a/src/renderer/widgets/CreateWallet/ui/MultisigWallet/components/SignerSelection.tsx b/src/renderer/widgets/CreateWallet/ui/MultisigWallet/components/SignerSelection.tsx index 4cd61cc1cb..a0de57da49 100644 --- a/src/renderer/widgets/CreateWallet/ui/MultisigWallet/components/SignerSelection.tsx +++ b/src/renderer/widgets/CreateWallet/ui/MultisigWallet/components/SignerSelection.tsx @@ -8,9 +8,9 @@ import { Step } from '@/shared/lib/utils'; import { Button } from '@/shared/ui'; import { Box, Modal } from '@/shared/ui-kit'; import { accountUtils } from '@/entities/wallet'; -import { flowModel } from '@/widgets/CreateWallet/model/flow-model'; -import { formModel } from '@/widgets/CreateWallet/model/form-model'; -import { signatoryModel } from '@/widgets/CreateWallet/model/signatory-model'; +import { flowModel } from '../../../model/flow-model'; +import { formModel } from '../../../model/form-model'; +import { signatoryModel } from '../../../model/signatory-model'; import { Signer } from './Signer'; diff --git a/src/renderer/widgets/CreateWallet/ui/MultisigWallet/components/WalletItem.tsx b/src/renderer/widgets/CreateWallet/ui/MultisigWallet/components/WalletItem.tsx deleted file mode 100644 index 8c3e80d0b9..0000000000 --- a/src/renderer/widgets/CreateWallet/ui/MultisigWallet/components/WalletItem.tsx +++ /dev/null @@ -1,27 +0,0 @@ -import { memo } from 'react'; - -import { type WalletType } from '@/shared/core'; -import { cnTw } from '@/shared/lib/utils'; -import { BodyText } from '@/shared/ui'; -import { WalletIcon } from '@/entities/wallet'; - -type Props = { - name: string; - type: WalletType; - className?: string; -}; - -// TODO: Rebuild with new components -export const WalletItem = memo(({ name, type, className = '' }: Props) => { - return ( -
- - -
- - {name} - -
-
- ); -}); diff --git a/src/renderer/widgets/CreateWallet/ui/MultisigWallet/components/index.ts b/src/renderer/widgets/CreateWallet/ui/MultisigWallet/components/index.ts index 6b12746e9a..2331cdb4e5 100644 --- a/src/renderer/widgets/CreateWallet/ui/MultisigWallet/components/index.ts +++ b/src/renderer/widgets/CreateWallet/ui/MultisigWallet/components/index.ts @@ -1,3 +1,2 @@ -export { WalletItem } from './WalletItem'; export { MultisigCreationFees } from './MultisigCreationFees'; export { SelectedSignatoriesModal } from './SelectedSignatoriesModal'; diff --git a/src/renderer/widgets/Transfer/lib/xcm-transfer-utils.ts b/src/renderer/widgets/Transfer/lib/xcm-transfer-utils.ts index abbb06f5f1..81c0a41fba 100644 --- a/src/renderer/widgets/Transfer/lib/xcm-transfer-utils.ts +++ b/src/renderer/widgets/Transfer/lib/xcm-transfer-utils.ts @@ -12,6 +12,10 @@ function getXcmTransferType(api: ApiPromise, type: XcmTransferType): Transaction return TransactionType.XTOKENS_TRANSFER_MULTIASSET; } + if (type === XcmTransferType.XCMPALLET_TRANSFER_ASSETS) { + return TransactionType.POLKADOT_XCM_TRANSFER_ASSETS; + } + if (type === XcmTransferType.XCMPALLET_TELEPORT) { return api.tx.xcmPallet ? TransactionType.XCM_TELEPORT : TransactionType.POLKADOT_XCM_TELEPORT; } diff --git a/webpack/webpack.renderer.shared.ts b/webpack/webpack.renderer.shared.ts index 0f8192ae5c..ff7570179e 100644 --- a/webpack/webpack.renderer.shared.ts +++ b/webpack/webpack.renderer.shared.ts @@ -2,6 +2,7 @@ import { resolve } from 'path'; import { default as CopyWebpackPlugin } from 'copy-webpack-plugin'; import { default as CssMinimizerPlugin } from 'css-minimizer-webpack-plugin'; +import { default as FaviconsWebpackPlugin } from 'favicons-webpack-plugin'; import { default as HtmlWebpackPlugin } from 'html-webpack-plugin'; import { default as MiniCssExtractPlugin } from 'mini-css-extract-plugin'; import { default as TerserPlugin } from 'terser-webpack-plugin'; @@ -14,8 +15,8 @@ import { sharedConfig } from './webpack.shared'; const { FOLDERS } = APP_CONFIG; -export const sharedRendererConfig = (mode: 'development' | 'production') => - merge(sharedConfig, { +export const sharedRendererConfig = (mode: 'development' | 'production') => { + return merge(sharedConfig, { mode, stats: 'errors-only', target: 'web', @@ -94,6 +95,27 @@ export const sharedRendererConfig = (mode: 'development' | 'production') => isDevelopment: mode === 'development', }), + new FaviconsWebpackPlugin({ + manifest: resolve(FOLDERS.APP_ROOT, './manifest.webmanifest'), + logo: + mode === 'development' + ? resolve(FOLDERS.APP_ROOT, './favicon.dev.png') + : resolve(FOLDERS.APP_ROOT, './favicon.png'), + mode: 'webapp', + inject: true, + favicons: { + icons: { + android: true, + appleIcon: true, + appleStartup: true, + favicons: true, + windows: true, + yandex: true, + }, + }, + }), + mode === 'production' ? new MiniCssExtractPlugin({ filename: '[name].[contenthash].css' }) : null, ].filter((plugin) => plugin !== null), }); +};