Fork of atp.tools as a universal profile for people on the ATmosphere

add login

Natalie B. 5464df28 b6b31bfd

+11
env.d.ts
··· 1 1 /// <reference types="@atcute/bluesky/lexicons" /> 2 + interface ImportMetaEnv { 3 + readonly VITE_DEV_SERVER_PORT?: string; 4 + readonly VITE_CLIENT_URI: string; 5 + readonly VITE_OAUTH_CLIENT_ID: string; 6 + readonly VITE_OAUTH_REDIRECT_URI: string; 7 + readonly VITE_OAUTH_SCOPE: string; 8 + } 9 + 10 + interface ImportMeta { 11 + readonly env: ImportMetaEnv; 12 + }
+8 -6
package.json
··· 13 13 "@atcute/bluesky-richtext-segmenter": "^1.0.5", 14 14 "@atcute/client": "^2.0.7", 15 15 "@atcute/oauth-browser-client": "^1.0.9", 16 - "@radix-ui/react-dialog": "^1.1.4", 16 + "@radix-ui/react-avatar": "^1.1.3", 17 + "@radix-ui/react-dialog": "^1.1.6", 18 + "@radix-ui/react-dropdown-menu": "^2.1.6", 17 19 "@radix-ui/react-popover": "^1.1.6", 18 - "@radix-ui/react-progress": "^1.1.1", 19 - "@radix-ui/react-separator": "^1.1.1", 20 - "@radix-ui/react-slot": "^1.1.1", 21 - "@radix-ui/react-tabs": "^1.1.2", 22 - "@radix-ui/react-tooltip": "^1.1.6", 20 + "@radix-ui/react-progress": "^1.1.2", 21 + "@radix-ui/react-separator": "^1.1.2", 22 + "@radix-ui/react-slot": "^1.1.2", 23 + "@radix-ui/react-tabs": "^1.1.3", 24 + "@radix-ui/react-tooltip": "^1.1.8", 23 25 "@tanstack/react-router": "^1.97.3", 24 26 "@tsparticles/confetti": "^3.7.1", 25 27 "class-variance-authority": "^0.7.1",
+581 -618
pnpm-lock.yaml
··· 19 19 version: 2.0.7 20 20 '@atcute/oauth-browser-client': 21 21 specifier: ^1.0.9 22 - version: 1.0.9 22 + version: 1.0.13 23 + '@radix-ui/react-avatar': 24 + specifier: ^1.1.3 25 + version: 1.1.3(react-dom@19.0.0(react@19.0.0))(react@19.0.0) 23 26 '@radix-ui/react-dialog': 24 - specifier: ^1.1.4 25 - version: 1.1.4(react-dom@19.0.0(react@19.0.0))(react@19.0.0) 27 + specifier: ^1.1.6 28 + version: 1.1.6(react-dom@19.0.0(react@19.0.0))(react@19.0.0) 29 + '@radix-ui/react-dropdown-menu': 30 + specifier: ^2.1.6 31 + version: 2.1.6(react-dom@19.0.0(react@19.0.0))(react@19.0.0) 26 32 '@radix-ui/react-popover': 27 33 specifier: ^1.1.6 28 34 version: 1.1.6(react-dom@19.0.0(react@19.0.0))(react@19.0.0) 29 35 '@radix-ui/react-progress': 30 - specifier: ^1.1.1 31 - version: 1.1.1(react-dom@19.0.0(react@19.0.0))(react@19.0.0) 36 + specifier: ^1.1.2 37 + version: 1.1.2(react-dom@19.0.0(react@19.0.0))(react@19.0.0) 32 38 '@radix-ui/react-separator': 33 - specifier: ^1.1.1 34 - version: 1.1.1(react-dom@19.0.0(react@19.0.0))(react@19.0.0) 35 - '@radix-ui/react-slot': 36 - specifier: ^1.1.1 37 - version: 1.1.1(react@19.0.0) 38 - '@radix-ui/react-tabs': 39 39 specifier: ^1.1.2 40 40 version: 1.1.2(react-dom@19.0.0(react@19.0.0))(react@19.0.0) 41 + '@radix-ui/react-slot': 42 + specifier: ^1.1.2 43 + version: 1.1.2(react@19.0.0) 44 + '@radix-ui/react-tabs': 45 + specifier: ^1.1.3 46 + version: 1.1.3(react-dom@19.0.0(react@19.0.0))(react@19.0.0) 41 47 '@radix-ui/react-tooltip': 42 - specifier: ^1.1.6 43 - version: 1.1.6(react-dom@19.0.0(react@19.0.0))(react@19.0.0) 48 + specifier: ^1.1.8 49 + version: 1.1.8(react-dom@19.0.0(react@19.0.0))(react@19.0.0) 44 50 '@tanstack/react-router': 45 51 specifier: ^1.97.3 46 - version: 1.97.3(react-dom@19.0.0(react@19.0.0))(react@19.0.0) 52 + version: 1.104.1(react-dom@19.0.0(react@19.0.0))(react@19.0.0) 47 53 '@tsparticles/confetti': 48 54 specifier: ^3.7.1 49 - version: 3.7.1 55 + version: 3.8.1 50 56 class-variance-authority: 51 57 specifier: ^0.7.1 52 58 version: 0.7.1 ··· 58 64 version: 5.0.1 59 65 html-to-image: 60 66 specifier: ^1.11.11 61 - version: 1.11.11 67 + version: 1.11.13 62 68 lexicons: 63 69 specifier: link:@atcute/bluesky/lexicons 64 70 version: link:@atcute/bluesky/lexicons ··· 83 89 devDependencies: 84 90 '@preact/preset-vite': 85 91 specifier: ^2.9.4 86 - version: 2.9.4(@babel/core@7.26.0)(preact@10.25.4)(vite@6.0.7(@types/node@22.10.7)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0)) 92 + version: 2.10.1(@babel/core@7.26.8)(preact@10.25.4)(vite@6.1.0(@types/node@22.13.4)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0)) 87 93 '@tanstack/router-devtools': 88 94 specifier: ^1.97.3 89 - version: 1.97.3(@tanstack/react-router@1.97.3(react-dom@19.0.0(react@19.0.0))(react@19.0.0))(csstype@3.1.3)(react-dom@19.0.0(react@19.0.0))(react@19.0.0) 95 + version: 1.104.3(@tanstack/react-router@1.104.1(react-dom@19.0.0(react@19.0.0))(react@19.0.0))(csstype@3.1.3)(react-dom@19.0.0(react@19.0.0))(react@19.0.0) 90 96 '@tanstack/router-plugin': 91 97 specifier: ^1.97.3 92 - version: 1.97.3(@tanstack/react-router@1.97.3(react-dom@19.0.0(react@19.0.0))(react@19.0.0))(vite@6.0.7(@types/node@22.10.7)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0)) 98 + version: 1.104.1(@tanstack/react-router@1.104.1(react-dom@19.0.0(react@19.0.0))(react@19.0.0))(vite@6.1.0(@types/node@22.13.4)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0)) 93 99 '@types/node': 94 100 specifier: ^22.10.7 95 - version: 22.10.7 101 + version: 22.13.4 96 102 autoprefixer: 97 103 specifier: ^10.4.20 98 - version: 10.4.20(postcss@8.5.1) 104 + version: 10.4.20(postcss@8.5.2) 99 105 postcss: 100 106 specifier: ^8.5.1 101 - version: 8.5.1 107 + version: 8.5.2 102 108 tailwindcss: 103 109 specifier: ^3.4.17 104 110 version: 3.4.17 ··· 107 113 version: 5.6.3 108 114 vite: 109 115 specifier: ^6.0.7 110 - version: 6.0.7(@types/node@22.10.7)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0) 116 + version: 6.1.0(@types/node@22.13.4)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0) 111 117 112 118 packages: 113 119 ··· 133 139 '@atcute/client@2.0.7': 134 140 resolution: {integrity: sha512-bvNahrCGvhZw/EIx0HU/GOoKZEnUaAppbuZh7cu+VsOFA2tdFLnZJed9Hagh5Yz/eUX7QUh5NB4dRTRUdggSLQ==} 135 141 136 - '@atcute/oauth-browser-client@1.0.9': 137 - resolution: {integrity: sha512-7B4cBm9x/S6gtBgxPktCT6GY8GUze6XlCGUASqppU+bh6x5Z3QtfpPCg4jpd+bagzCdqpgb4VNhmCLcVqoO++g==} 142 + '@atcute/oauth-browser-client@1.0.13': 143 + resolution: {integrity: sha512-JxQKl9Vo1V8poxvR9uKS8bkBv8t53DIH4lCbaih6yn9u7fM62ZC/0x/9KoGWSNqpp3R3U0y/DOQQfdC9Y4GEGQ==} 138 144 139 145 '@babel/code-frame@7.26.2': 140 146 resolution: {integrity: sha512-RJlIHRueQgwWitWgF8OdFYGZX328Ax5BCemNGlqHfplnRT9ESi8JkFlvaVYbS+UubVY6dpv87Fs2u5M29iNFVQ==} 141 147 engines: {node: '>=6.9.0'} 142 148 143 - '@babel/compat-data@7.26.5': 144 - resolution: {integrity: sha512-XvcZi1KWf88RVbF9wn8MN6tYFloU5qX8KjuF3E1PVBmJ9eypXfs4GRiJwLuTZL0iSnJUKn1BFPa5BPZZJyFzPg==} 149 + '@babel/compat-data@7.26.8': 150 + resolution: {integrity: sha512-oH5UPLMWR3L2wEFLnFJ1TZXqHufiTKAiLfqw5zkhS4dKXLJ10yVztfil/twG8EDTA4F/tvVNw9nOl4ZMslB8rQ==} 145 151 engines: {node: '>=6.9.0'} 146 152 147 - '@babel/core@7.26.0': 148 - resolution: {integrity: sha512-i1SLeK+DzNnQ3LL/CswPCa/E5u4lh1k6IAEphON8F+cXt0t9euTshDru0q7/IqMa1PMPz5RnHuHscF8/ZJsStg==} 153 + '@babel/core@7.26.8': 154 + resolution: {integrity: sha512-l+lkXCHS6tQEc5oUpK28xBOZ6+HwaH7YwoYQbLFiYb4nS2/l1tKnZEtEWkD0GuiYdvArf9qBS0XlQGXzPMsNqQ==} 149 155 engines: {node: '>=6.9.0'} 150 156 151 - '@babel/generator@7.26.5': 152 - resolution: {integrity: sha512-2caSP6fN9I7HOe6nqhtft7V4g7/V/gfDsC3Ag4W7kEzzvRGKqiv0pu0HogPiZ3KaVSoNDhUws6IJjDjpfmYIXw==} 157 + '@babel/generator@7.26.8': 158 + resolution: {integrity: sha512-ef383X5++iZHWAXX0SXQR6ZyQhw/0KtTkrTz61WXRhFM6dhpHulO/RJz79L8S6ugZHJkOOkUrUdxgdF2YiPFnA==} 153 159 engines: {node: '>=6.9.0'} 154 160 155 161 '@babel/helper-annotate-as-pure@7.25.9': ··· 186 192 resolution: {integrity: sha512-e/zv1co8pp55dNdEcCynfj9X7nyUKUXoUEwfXqaZt0omVOmDe9oOTdKStH4GmAw6zxMFs50ZayuMfHDKlO7Tfw==} 187 193 engines: {node: '>=6.9.0'} 188 194 189 - '@babel/helpers@7.26.0': 190 - resolution: {integrity: sha512-tbhNuIxNcVb21pInl3ZSjksLCvgdZy9KwJ8brv993QtIVKJBBkYXz4q4ZbAv31GdnC+R90np23L5FbEBlthAEw==} 195 + '@babel/helpers@7.26.7': 196 + resolution: {integrity: sha512-8NHiL98vsi0mbPQmYAGWwfcFaOy4j2HY49fXJCfuDcdE7fMIsH9a7GdaeXpIBsbT7307WU8KCMp5pUVDNL4f9A==} 191 197 engines: {node: '>=6.9.0'} 192 198 193 - '@babel/parser@7.26.5': 194 - resolution: {integrity: sha512-SRJ4jYmXRqV1/Xc+TIVG84WjHBXKlxO9sHQnA2Pf12QQEAp1LOh6kDzNHXcUnbH1QI0FDoPPVOt+vyUDucxpaw==} 199 + '@babel/parser@7.26.8': 200 + resolution: {integrity: sha512-TZIQ25pkSoaKEYYaHbbxkfL36GNsQ6iFiBbeuzAkLnXayKR1yP1zFe+NxuZWWsUyvt8icPU9CCq0sgWGXR1GEw==} 195 201 engines: {node: '>=6.0.0'} 196 202 hasBin: true 197 203 ··· 223 229 resolution: {integrity: sha512-AOPI3D+a8dXnja+iwsUqGRjr1BbZIe771sXdapOtYI531gSqpi92vXivKcq2asu/DFpdl1ceFAKZyRzK2PCVcQ==} 224 230 engines: {node: '>=6.9.0'} 225 231 226 - '@babel/template@7.25.9': 227 - resolution: {integrity: sha512-9DGttpmPvIxBb/2uwpVo3dqJ+O6RooAFOS+lB+xDqoE2PVCE8nfoHMdZLpfCQRLwvohzXISPZcgxt80xLfsuwg==} 232 + '@babel/template@7.26.8': 233 + resolution: {integrity: sha512-iNKaX3ZebKIsCvJ+0jd6embf+Aulaa3vNBqZ41kM7iTWjx5qzWKXGHiJUW3+nTpQ18SG11hdF8OAzKrpXkb96Q==} 228 234 engines: {node: '>=6.9.0'} 229 235 230 - '@babel/traverse@7.26.5': 231 - resolution: {integrity: sha512-rkOSPOw+AXbgtwUga3U4u8RpoK9FEFWBNAlTpcnkLFjL5CT+oyHNuUUC/xx6XefEJ16r38r8Bc/lfp6rYuHeJQ==} 236 + '@babel/traverse@7.26.8': 237 + resolution: {integrity: sha512-nic9tRkjYH0oB2dzr/JoGIm+4Q6SuYeLEiIiZDwBscRMYFJ+tMAz98fuel9ZnbXViA2I0HVSSRRK8DW5fjXStA==} 232 238 engines: {node: '>=6.9.0'} 233 239 234 - '@babel/types@7.26.5': 235 - resolution: {integrity: sha512-L6mZmwFDK6Cjh1nRCLXpa6no13ZIioJDz7mdkzHv399pThrTa/k0nUlNaenOeh2kWu/iaOQYElEpKPUswUa9Vg==} 240 + '@babel/types@7.26.8': 241 + resolution: {integrity: sha512-eUuWapzEGWFEpHFxgEaBG8e3n6S8L3MSu0oda755rOfabWPnh0Our1AozNFVUxGFIhbKgd1ksprsoDGMinTOTA==} 236 242 engines: {node: '>=6.9.0'} 237 243 238 244 '@esbuild/aix-ppc64@0.23.1': ··· 582 588 resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==} 583 589 engines: {node: '>=14'} 584 590 585 - '@preact/preset-vite@2.9.4': 586 - resolution: {integrity: sha512-PpPnUlKUsbWZ2oBuAkAMnezhIYGsR7xi2EZcPjeTAjF1DhGl00IcPD1ZeXRFKp38i7Hk4kEdFlwpJ1525cAzpg==} 591 + '@preact/preset-vite@2.10.1': 592 + resolution: {integrity: sha512-59lyGBXNfZIr5OOuBUB4/IB8AqF/ULbvYnyItgK/2BJnsGJqaeaJobRVtMp1129obHQuj8oZ/dVxB9inmH8Xig==} 587 593 peerDependencies: 588 594 '@babel/core': 7.x 589 595 vite: 2.x || 3.x || 4.x || 5.x || 6.x ··· 599 605 '@prefresh/utils@1.2.0': 600 606 resolution: {integrity: sha512-KtC/fZw+oqtwOLUFM9UtiitB0JsVX0zLKNyRTA332sqREqSALIIQQxdUCS1P3xR/jT1e2e8/5rwH6gdcMLEmsQ==} 601 607 602 - '@prefresh/vite@2.4.6': 603 - resolution: {integrity: sha512-miYbTl2J1YNaQJWyWHJzyIpNh7vKUuXC1qCDRzPeWjhQ+9bxeXkUBGDGd9I1f37R5GQYi1S65AN5oR0BR2WzvQ==} 608 + '@prefresh/vite@2.4.7': 609 + resolution: {integrity: sha512-zmCEDWSFHl5A7PciXa/fe+OUjoGi4iiCQclpWfpIg7LjxwWrtlUT4DfxDBcQwHfTyipS/XDm8x7WYrkiTW0q+w==} 604 610 peerDependencies: 605 611 preact: ^10.4.0 606 612 vite: '>=2.0.0' ··· 608 614 '@radix-ui/primitive@1.1.1': 609 615 resolution: {integrity: sha512-SJ31y+Q/zAyShtXJc8x83i9TYdbAfHZ++tUZnvjJJqFjzsdUnKsxPL6IEtBlxKkU7yzer//GQtZSV4GbldL3YA==} 610 616 611 - '@radix-ui/react-arrow@1.1.1': 612 - resolution: {integrity: sha512-NaVpZfmv8SKeZbn4ijN2V3jlHA9ngBG16VnIIm22nUR0Yk8KUALyBxT3KYEUnNuch9sTE8UTsS3whzBgKOL30w==} 617 + '@radix-ui/react-arrow@1.1.2': 618 + resolution: {integrity: sha512-G+KcpzXHq24iH0uGG/pF8LyzpFJYGD4RfLjCIBfGdSLXvjLHST31RUiRVrupIBMvIppMgSzQ6l66iAxl03tdlg==} 613 619 peerDependencies: 614 620 '@types/react': '*' 615 621 '@types/react-dom': '*' ··· 621 627 '@types/react-dom': 622 628 optional: true 623 629 624 - '@radix-ui/react-arrow@1.1.2': 625 - resolution: {integrity: sha512-G+KcpzXHq24iH0uGG/pF8LyzpFJYGD4RfLjCIBfGdSLXvjLHST31RUiRVrupIBMvIppMgSzQ6l66iAxl03tdlg==} 630 + '@radix-ui/react-avatar@1.1.3': 631 + resolution: {integrity: sha512-Paen00T4P8L8gd9bNsRMw7Cbaz85oxiv+hzomsRZgFm2byltPFDtfcoqlWJ8GyZlIBWgLssJlzLCnKU0G0302g==} 626 632 peerDependencies: 627 633 '@types/react': '*' 628 634 '@types/react-dom': '*' ··· 634 640 '@types/react-dom': 635 641 optional: true 636 642 637 - '@radix-ui/react-collection@1.1.1': 638 - resolution: {integrity: sha512-LwT3pSho9Dljg+wY2KN2mrrh6y3qELfftINERIzBUO9e0N+t0oMTyn3k9iv+ZqgrwGkRnLpNJrsMv9BZlt2yuA==} 643 + '@radix-ui/react-collection@1.1.2': 644 + resolution: {integrity: sha512-9z54IEKRxIa9VityapoEYMuByaG42iSy1ZXlY2KcuLSEtq8x4987/N6m15ppoMffgZX72gER2uHe1D9Y6Unlcw==} 639 645 peerDependencies: 640 646 '@types/react': '*' 641 647 '@types/react-dom': '*' ··· 665 671 '@types/react': 666 672 optional: true 667 673 668 - '@radix-ui/react-dialog@1.1.4': 669 - resolution: {integrity: sha512-Ur7EV1IwQGCyaAuyDRiOLA5JIUZxELJljF+MbM/2NC0BYwfuRrbpS30BiQBJrVruscgUkieKkqXYDOoByaxIoA==} 674 + '@radix-ui/react-dialog@1.1.6': 675 + resolution: {integrity: sha512-/IVhJV5AceX620DUJ4uYVMymzsipdKBzo3edo+omeskCKGm9FRHM0ebIdbPnlQVJqyuHbuBltQUOG2mOTq2IYw==} 670 676 peerDependencies: 671 677 '@types/react': '*' 672 678 '@types/react-dom': '*' ··· 687 693 '@types/react': 688 694 optional: true 689 695 690 - '@radix-ui/react-dismissable-layer@1.1.3': 691 - resolution: {integrity: sha512-onrWn/72lQoEucDmJnr8uczSNTujT0vJnA/X5+3AkChVPowr8n1yvIKIabhWyMQeMvvmdpsvcyDqx3X1LEXCPg==} 696 + '@radix-ui/react-dismissable-layer@1.1.5': 697 + resolution: {integrity: sha512-E4TywXY6UsXNRhFrECa5HAvE5/4BFcGyfTyK36gP+pAW1ed7UTK4vKwdr53gAJYwqbfCWC6ATvJa3J3R/9+Qrg==} 692 698 peerDependencies: 693 699 '@types/react': '*' 694 700 '@types/react-dom': '*' ··· 700 706 '@types/react-dom': 701 707 optional: true 702 708 703 - '@radix-ui/react-dismissable-layer@1.1.5': 704 - resolution: {integrity: sha512-E4TywXY6UsXNRhFrECa5HAvE5/4BFcGyfTyK36gP+pAW1ed7UTK4vKwdr53gAJYwqbfCWC6ATvJa3J3R/9+Qrg==} 709 + '@radix-ui/react-dropdown-menu@2.1.6': 710 + resolution: {integrity: sha512-no3X7V5fD487wab/ZYSHXq3H37u4NVeLDKI/Ks724X/eEFSSEFYZxWgsIlr1UBeEyDaM29HM5x9p1Nv8DuTYPA==} 705 711 peerDependencies: 706 712 '@types/react': '*' 707 713 '@types/react-dom': '*' ··· 722 728 '@types/react': 723 729 optional: true 724 730 725 - '@radix-ui/react-focus-scope@1.1.1': 726 - resolution: {integrity: sha512-01omzJAYRxXdG2/he/+xy+c8a8gCydoQ1yOxnWNcRhrrBW5W+RQJ22EK1SaO8tb3WoUsuEw7mJjBozPzihDFjA==} 727 - peerDependencies: 728 - '@types/react': '*' 729 - '@types/react-dom': '*' 730 - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc 731 - react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc 732 - peerDependenciesMeta: 733 - '@types/react': 734 - optional: true 735 - '@types/react-dom': 736 - optional: true 737 - 738 731 '@radix-ui/react-focus-scope@1.1.2': 739 732 resolution: {integrity: sha512-zxwE80FCU7lcXUGWkdt6XpTTCKPitG1XKOwViTxHVKIJhZl9MvIl2dVHeZENCWD9+EdWv05wlaEkRXUykU27RA==} 740 733 peerDependencies: ··· 757 750 '@types/react': 758 751 optional: true 759 752 760 - '@radix-ui/react-popover@1.1.6': 761 - resolution: {integrity: sha512-NQouW0x4/GnkFJ/pRqsIS3rM/k97VzKnVb2jB7Gq7VEGPy5g7uNV1ykySFt7eWSp3i2uSGFwaJcvIRJBAHmmFg==} 753 + '@radix-ui/react-menu@2.1.6': 754 + resolution: {integrity: sha512-tBBb5CXDJW3t2mo9WlO7r6GTmWV0F0uzHZVFmlRmYpiSK1CDU5IKojP1pm7oknpBOrFZx/YgBRW9oorPO2S/Lg==} 762 755 peerDependencies: 763 756 '@types/react': '*' 764 757 '@types/react-dom': '*' ··· 770 763 '@types/react-dom': 771 764 optional: true 772 765 773 - '@radix-ui/react-popper@1.2.1': 774 - resolution: {integrity: sha512-3kn5Me69L+jv82EKRuQCXdYyf1DqHwD2U/sxoNgBGCB7K9TRc3bQamQ+5EPM9EvyPdli0W41sROd+ZU1dTCztw==} 766 + '@radix-ui/react-popover@1.1.6': 767 + resolution: {integrity: sha512-NQouW0x4/GnkFJ/pRqsIS3rM/k97VzKnVb2jB7Gq7VEGPy5g7uNV1ykySFt7eWSp3i2uSGFwaJcvIRJBAHmmFg==} 775 768 peerDependencies: 776 769 '@types/react': '*' 777 770 '@types/react-dom': '*' ··· 796 789 '@types/react-dom': 797 790 optional: true 798 791 799 - '@radix-ui/react-portal@1.1.3': 800 - resolution: {integrity: sha512-NciRqhXnGojhT93RPyDaMPfLH3ZSl4jjIFbZQ1b/vxvZEdHsBZ49wP9w8L3HzUQwep01LcWtkUvm0OVB5JAHTw==} 801 - peerDependencies: 802 - '@types/react': '*' 803 - '@types/react-dom': '*' 804 - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc 805 - react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc 806 - peerDependenciesMeta: 807 - '@types/react': 808 - optional: true 809 - '@types/react-dom': 810 - optional: true 811 - 812 792 '@radix-ui/react-portal@1.1.4': 813 793 resolution: {integrity: sha512-sn2O9k1rPFYVyKd5LAJfo96JlSGVFpa1fS6UuBJfrZadudiw5tAmru+n1x7aMRQ84qDM71Zh1+SzK5QwU0tJfA==} 814 794 peerDependencies: ··· 835 815 '@types/react-dom': 836 816 optional: true 837 817 838 - '@radix-ui/react-primitive@2.0.1': 839 - resolution: {integrity: sha512-sHCWTtxwNn3L3fH8qAfnF3WbUZycW93SM1j3NFDzXBiz8D6F5UTTy8G1+WFEaiCdvCVRJWj6N2R4Xq6HdiHmDg==} 840 - peerDependencies: 841 - '@types/react': '*' 842 - '@types/react-dom': '*' 843 - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc 844 - react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc 845 - peerDependenciesMeta: 846 - '@types/react': 847 - optional: true 848 - '@types/react-dom': 849 - optional: true 850 - 851 818 '@radix-ui/react-primitive@2.0.2': 852 819 resolution: {integrity: sha512-Ec/0d38EIuvDF+GZjcMU/Ze6MxntVJYO/fRlCPhCaVUyPY9WTalHJw54tp9sXeJo3tlShWpy41vQRgLRGOuz+w==} 853 820 peerDependencies: ··· 861 828 '@types/react-dom': 862 829 optional: true 863 830 864 - '@radix-ui/react-progress@1.1.1': 865 - resolution: {integrity: sha512-6diOawA84f/eMxFHcWut0aE1C2kyE9dOyCTQOMRR2C/qPiXz/X0SaiA/RLbapQaXUCmy0/hLMf9meSccD1N0pA==} 831 + '@radix-ui/react-progress@1.1.2': 832 + resolution: {integrity: sha512-u1IgJFQ4zNAUTjGdDL5dcl/U8ntOR6jsnhxKb5RKp5Ozwl88xKR9EqRZOe/Mk8tnx0x5tNUe2F+MzsyjqMg0MA==} 866 833 peerDependencies: 867 834 '@types/react': '*' 868 835 '@types/react-dom': '*' ··· 874 841 '@types/react-dom': 875 842 optional: true 876 843 877 - '@radix-ui/react-roving-focus@1.1.1': 878 - resolution: {integrity: sha512-QE1RoxPGJ/Nm8Qmk0PxP8ojmoaS67i0s7hVssS7KuI2FQoc/uzVlZsqKfQvxPE6D8hICCPHJ4D88zNhT3OOmkw==} 844 + '@radix-ui/react-roving-focus@1.1.2': 845 + resolution: {integrity: sha512-zgMQWkNO169GtGqRvYrzb0Zf8NhMHS2DuEB/TiEmVnpr5OqPU3i8lfbxaAmC2J/KYuIQxyoQQ6DxepyXp61/xw==} 879 846 peerDependencies: 880 847 '@types/react': '*' 881 848 '@types/react-dom': '*' ··· 887 854 '@types/react-dom': 888 855 optional: true 889 856 890 - '@radix-ui/react-separator@1.1.1': 891 - resolution: {integrity: sha512-RRiNRSrD8iUiXriq/Y5n4/3iE8HzqgLHsusUSg5jVpU2+3tqcUFPJXHDymwEypunc2sWxDUS3UC+rkZRlHedsw==} 857 + '@radix-ui/react-separator@1.1.2': 858 + resolution: {integrity: sha512-oZfHcaAp2Y6KFBX6I5P1u7CQoy4lheCGiYj+pGFrHy8E/VNRb5E39TkTr3JrV520csPBTZjkuKFdEsjS5EUNKQ==} 892 859 peerDependencies: 893 860 '@types/react': '*' 894 861 '@types/react-dom': '*' ··· 898 865 '@types/react': 899 866 optional: true 900 867 '@types/react-dom': 901 - optional: true 902 - 903 - '@radix-ui/react-slot@1.1.1': 904 - resolution: {integrity: sha512-RApLLOcINYJA+dMVbOju7MYv1Mb2EBp2nH4HdDzXTSyaR5optlm6Otrz1euW3HbdOR8UmmFK06TD+A9frYWv+g==} 905 - peerDependencies: 906 - '@types/react': '*' 907 - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc 908 - peerDependenciesMeta: 909 - '@types/react': 910 868 optional: true 911 869 912 870 '@radix-ui/react-slot@1.1.2': ··· 918 876 '@types/react': 919 877 optional: true 920 878 921 - '@radix-ui/react-tabs@1.1.2': 922 - resolution: {integrity: sha512-9u/tQJMcC2aGq7KXpGivMm1mgq7oRJKXphDwdypPd/j21j/2znamPU8WkXgnhUaTrSFNIt8XhOyCAupg8/GbwQ==} 879 + '@radix-ui/react-tabs@1.1.3': 880 + resolution: {integrity: sha512-9mFyI30cuRDImbmFF6O2KUJdgEOsGh9Vmx9x/Dh9tOhL7BngmQPQfwW4aejKm5OHpfWIdmeV6ySyuxoOGjtNng==} 923 881 peerDependencies: 924 882 '@types/react': '*' 925 883 '@types/react-dom': '*' ··· 931 889 '@types/react-dom': 932 890 optional: true 933 891 934 - '@radix-ui/react-tooltip@1.1.6': 935 - resolution: {integrity: sha512-TLB5D8QLExS1uDn7+wH/bjEmRurNMTzNrtq7IjaS4kjion9NtzsTGkvR5+i7yc9q01Pi2KMM2cN3f8UG4IvvXA==} 892 + '@radix-ui/react-tooltip@1.1.8': 893 + resolution: {integrity: sha512-YAA2cu48EkJZdAMHC0dqo9kialOcRStbtiY4nJPaht7Ptrhcvpo+eDChaM6BIs8kL6a8Z5l5poiqLnXcNduOkA==} 936 894 peerDependencies: 937 895 '@types/react': '*' 938 896 '@types/react-dom': '*' ··· 998 956 '@types/react': 999 957 optional: true 1000 958 1001 - '@radix-ui/react-visually-hidden@1.1.1': 1002 - resolution: {integrity: sha512-vVfA2IZ9q/J+gEamvj761Oq1FpWgCDaNOOIfbPVp2MVPLEomUr5+Vf7kJGwQ24YxZSlQVar7Bes8kyTo5Dshpg==} 959 + '@radix-ui/react-visually-hidden@1.1.2': 960 + resolution: {integrity: sha512-1SzA4ns2M1aRlvxErqhLHsBHoS5eI5UUcI2awAMgGUp4LoaoWOKYmvqDY2s/tltuPkh3Yk77YF/r3IRj+Amx4Q==} 1003 961 peerDependencies: 1004 962 '@types/react': '*' 1005 963 '@types/react-dom': '*' ··· 1018 976 resolution: {integrity: sha512-iKnFXr7NkdZAIHiIWE+BX5ULi/ucVFYWD6TbAV+rZctiRTY2PL6tsIKhoIOaoskiWAkgu+VsbXgUVDNLHf+InQ==} 1019 977 engines: {node: '>= 8.0.0'} 1020 978 1021 - '@rollup/rollup-android-arm-eabi@4.30.1': 1022 - resolution: {integrity: sha512-pSWY+EVt3rJ9fQ3IqlrEUtXh3cGqGtPDH1FQlNZehO2yYxCHEX1SPsz1M//NXwYfbTlcKr9WObLnJX9FsS9K1Q==} 979 + '@rollup/rollup-android-arm-eabi@4.34.6': 980 + resolution: {integrity: sha512-+GcCXtOQoWuC7hhX1P00LqjjIiS/iOouHXhMdiDSnq/1DGTox4SpUvO52Xm+div6+106r+TcvOeo/cxvyEyTgg==} 1023 981 cpu: [arm] 1024 982 os: [android] 1025 983 1026 - '@rollup/rollup-android-arm64@4.30.1': 1027 - resolution: {integrity: sha512-/NA2qXxE3D/BRjOJM8wQblmArQq1YoBVJjrjoTSBS09jgUisq7bqxNHJ8kjCHeV21W/9WDGwJEWSN0KQ2mtD/w==} 984 + '@rollup/rollup-android-arm64@4.34.6': 985 + resolution: {integrity: sha512-E8+2qCIjciYUnCa1AiVF1BkRgqIGW9KzJeesQqVfyRITGQN+dFuoivO0hnro1DjT74wXLRZ7QF8MIbz+luGaJA==} 1028 986 cpu: [arm64] 1029 987 os: [android] 1030 988 1031 - '@rollup/rollup-darwin-arm64@4.30.1': 1032 - resolution: {integrity: sha512-r7FQIXD7gB0WJ5mokTUgUWPl0eYIH0wnxqeSAhuIwvnnpjdVB8cRRClyKLQr7lgzjctkbp5KmswWszlwYln03Q==} 989 + '@rollup/rollup-darwin-arm64@4.34.6': 990 + resolution: {integrity: sha512-z9Ib+OzqN3DZEjX7PDQMHEhtF+t6Mi2z/ueChQPLS/qUMKY7Ybn5A2ggFoKRNRh1q1T03YTQfBTQCJZiepESAg==} 1033 991 cpu: [arm64] 1034 992 os: [darwin] 1035 993 1036 - '@rollup/rollup-darwin-x64@4.30.1': 1037 - resolution: {integrity: sha512-x78BavIwSH6sqfP2xeI1hd1GpHL8J4W2BXcVM/5KYKoAD3nNsfitQhvWSw+TFtQTLZ9OmlF+FEInEHyubut2OA==} 994 + '@rollup/rollup-darwin-x64@4.34.6': 995 + resolution: {integrity: sha512-PShKVY4u0FDAR7jskyFIYVyHEPCPnIQY8s5OcXkdU8mz3Y7eXDJPdyM/ZWjkYdR2m0izD9HHWA8sGcXn+Qrsyg==} 1038 996 cpu: [x64] 1039 997 os: [darwin] 1040 998 1041 - '@rollup/rollup-freebsd-arm64@4.30.1': 1042 - resolution: {integrity: sha512-HYTlUAjbO1z8ywxsDFWADfTRfTIIy/oUlfIDmlHYmjUP2QRDTzBuWXc9O4CXM+bo9qfiCclmHk1x4ogBjOUpUQ==} 999 + '@rollup/rollup-freebsd-arm64@4.34.6': 1000 + resolution: {integrity: sha512-YSwyOqlDAdKqs0iKuqvRHLN4SrD2TiswfoLfvYXseKbL47ht1grQpq46MSiQAx6rQEN8o8URtpXARCpqabqxGQ==} 1043 1001 cpu: [arm64] 1044 1002 os: [freebsd] 1045 1003 1046 - '@rollup/rollup-freebsd-x64@4.30.1': 1047 - resolution: {integrity: sha512-1MEdGqogQLccphhX5myCJqeGNYTNcmTyaic9S7CG3JhwuIByJ7J05vGbZxsizQthP1xpVx7kd3o31eOogfEirw==} 1004 + '@rollup/rollup-freebsd-x64@4.34.6': 1005 + resolution: {integrity: sha512-HEP4CgPAY1RxXwwL5sPFv6BBM3tVeLnshF03HMhJYCNc6kvSqBgTMmsEjb72RkZBAWIqiPUyF1JpEBv5XT9wKQ==} 1048 1006 cpu: [x64] 1049 1007 os: [freebsd] 1050 1008 1051 - '@rollup/rollup-linux-arm-gnueabihf@4.30.1': 1052 - resolution: {integrity: sha512-PaMRNBSqCx7K3Wc9QZkFx5+CX27WFpAMxJNiYGAXfmMIKC7jstlr32UhTgK6T07OtqR+wYlWm9IxzennjnvdJg==} 1009 + '@rollup/rollup-linux-arm-gnueabihf@4.34.6': 1010 + resolution: {integrity: sha512-88fSzjC5xeH9S2Vg3rPgXJULkHcLYMkh8faix8DX4h4TIAL65ekwuQMA/g2CXq8W+NJC43V6fUpYZNjaX3+IIg==} 1053 1011 cpu: [arm] 1054 1012 os: [linux] 1055 1013 1056 - '@rollup/rollup-linux-arm-musleabihf@4.30.1': 1057 - resolution: {integrity: sha512-B8Rcyj9AV7ZlEFqvB5BubG5iO6ANDsRKlhIxySXcF1axXYUyqwBok+XZPgIYGBgs7LDXfWfifxhw0Ik57T0Yug==} 1014 + '@rollup/rollup-linux-arm-musleabihf@4.34.6': 1015 + resolution: {integrity: sha512-wM4ztnutBqYFyvNeR7Av+reWI/enK9tDOTKNF+6Kk2Q96k9bwhDDOlnCUNRPvromlVXo04riSliMBs/Z7RteEg==} 1058 1016 cpu: [arm] 1059 1017 os: [linux] 1060 1018 1061 - '@rollup/rollup-linux-arm64-gnu@4.30.1': 1062 - resolution: {integrity: sha512-hqVyueGxAj3cBKrAI4aFHLV+h0Lv5VgWZs9CUGqr1z0fZtlADVV1YPOij6AhcK5An33EXaxnDLmJdQikcn5NEw==} 1019 + '@rollup/rollup-linux-arm64-gnu@4.34.6': 1020 + resolution: {integrity: sha512-9RyprECbRa9zEjXLtvvshhw4CMrRa3K+0wcp3KME0zmBe1ILmvcVHnypZ/aIDXpRyfhSYSuN4EPdCCj5Du8FIA==} 1063 1021 cpu: [arm64] 1064 1022 os: [linux] 1065 1023 1066 - '@rollup/rollup-linux-arm64-musl@4.30.1': 1067 - resolution: {integrity: sha512-i4Ab2vnvS1AE1PyOIGp2kXni69gU2DAUVt6FSXeIqUCPIR3ZlheMW3oP2JkukDfu3PsexYRbOiJrY+yVNSk9oA==} 1024 + '@rollup/rollup-linux-arm64-musl@4.34.6': 1025 + resolution: {integrity: sha512-qTmklhCTyaJSB05S+iSovfo++EwnIEZxHkzv5dep4qoszUMX5Ca4WM4zAVUMbfdviLgCSQOu5oU8YoGk1s6M9Q==} 1068 1026 cpu: [arm64] 1069 1027 os: [linux] 1070 1028 1071 - '@rollup/rollup-linux-loongarch64-gnu@4.30.1': 1072 - resolution: {integrity: sha512-fARcF5g296snX0oLGkVxPmysetwUk2zmHcca+e9ObOovBR++9ZPOhqFUM61UUZ2EYpXVPN1redgqVoBB34nTpQ==} 1029 + '@rollup/rollup-linux-loongarch64-gnu@4.34.6': 1030 + resolution: {integrity: sha512-4Qmkaps9yqmpjY5pvpkfOerYgKNUGzQpFxV6rnS7c/JfYbDSU0y6WpbbredB5cCpLFGJEqYX40WUmxMkwhWCjw==} 1073 1031 cpu: [loong64] 1074 1032 os: [linux] 1075 1033 1076 - '@rollup/rollup-linux-powerpc64le-gnu@4.30.1': 1077 - resolution: {integrity: sha512-GLrZraoO3wVT4uFXh67ElpwQY0DIygxdv0BNW9Hkm3X34wu+BkqrDrkcsIapAY+N2ATEbvak0XQ9gxZtCIA5Rw==} 1034 + '@rollup/rollup-linux-powerpc64le-gnu@4.34.6': 1035 + resolution: {integrity: sha512-Zsrtux3PuaxuBTX/zHdLaFmcofWGzaWW1scwLU3ZbW/X+hSsFbz9wDIp6XvnT7pzYRl9MezWqEqKy7ssmDEnuQ==} 1078 1036 cpu: [ppc64] 1079 1037 os: [linux] 1080 1038 1081 - '@rollup/rollup-linux-riscv64-gnu@4.30.1': 1082 - resolution: {integrity: sha512-0WKLaAUUHKBtll0wvOmh6yh3S0wSU9+yas923JIChfxOaaBarmb/lBKPF0w/+jTVozFnOXJeRGZ8NvOxvk/jcw==} 1039 + '@rollup/rollup-linux-riscv64-gnu@4.34.6': 1040 + resolution: {integrity: sha512-aK+Zp+CRM55iPrlyKiU3/zyhgzWBxLVrw2mwiQSYJRobCURb781+XstzvA8Gkjg/hbdQFuDw44aUOxVQFycrAg==} 1083 1041 cpu: [riscv64] 1084 1042 os: [linux] 1085 1043 1086 - '@rollup/rollup-linux-s390x-gnu@4.30.1': 1087 - resolution: {integrity: sha512-GWFs97Ruxo5Bt+cvVTQkOJ6TIx0xJDD/bMAOXWJg8TCSTEK8RnFeOeiFTxKniTc4vMIaWvCplMAFBt9miGxgkA==} 1044 + '@rollup/rollup-linux-s390x-gnu@4.34.6': 1045 + resolution: {integrity: sha512-WoKLVrY9ogmaYPXwTH326+ErlCIgMmsoRSx6bO+l68YgJnlOXhygDYSZe/qbUJCSiCiZAQ+tKm88NcWuUXqOzw==} 1088 1046 cpu: [s390x] 1089 1047 os: [linux] 1090 1048 1091 - '@rollup/rollup-linux-x64-gnu@4.30.1': 1092 - resolution: {integrity: sha512-UtgGb7QGgXDIO+tqqJ5oZRGHsDLO8SlpE4MhqpY9Llpzi5rJMvrK6ZGhsRCST2abZdBqIBeXW6WPD5fGK5SDwg==} 1049 + '@rollup/rollup-linux-x64-gnu@4.34.6': 1050 + resolution: {integrity: sha512-Sht4aFvmA4ToHd2vFzwMFaQCiYm2lDFho5rPcvPBT5pCdC+GwHG6CMch4GQfmWTQ1SwRKS0dhDYb54khSrjDWw==} 1093 1051 cpu: [x64] 1094 1052 os: [linux] 1095 1053 1096 - '@rollup/rollup-linux-x64-musl@4.30.1': 1097 - resolution: {integrity: sha512-V9U8Ey2UqmQsBT+xTOeMzPzwDzyXmnAoO4edZhL7INkwQcaW1Ckv3WJX3qrrp/VHaDkEWIBWhRwP47r8cdrOow==} 1054 + '@rollup/rollup-linux-x64-musl@4.34.6': 1055 + resolution: {integrity: sha512-zmmpOQh8vXc2QITsnCiODCDGXFC8LMi64+/oPpPx5qz3pqv0s6x46ps4xoycfUiVZps5PFn1gksZzo4RGTKT+A==} 1098 1056 cpu: [x64] 1099 1057 os: [linux] 1100 1058 1101 - '@rollup/rollup-win32-arm64-msvc@4.30.1': 1102 - resolution: {integrity: sha512-WabtHWiPaFF47W3PkHnjbmWawnX/aE57K47ZDT1BXTS5GgrBUEpvOzq0FI0V/UYzQJgdb8XlhVNH8/fwV8xDjw==} 1059 + '@rollup/rollup-win32-arm64-msvc@4.34.6': 1060 + resolution: {integrity: sha512-3/q1qUsO/tLqGBaD4uXsB6coVGB3usxw3qyeVb59aArCgedSF66MPdgRStUd7vbZOsko/CgVaY5fo2vkvPLWiA==} 1103 1061 cpu: [arm64] 1104 1062 os: [win32] 1105 1063 1106 - '@rollup/rollup-win32-ia32-msvc@4.30.1': 1107 - resolution: {integrity: sha512-pxHAU+Zv39hLUTdQQHUVHf4P+0C47y/ZloorHpzs2SXMRqeAWmGghzAhfOlzFHHwjvgokdFAhC4V+6kC1lRRfw==} 1064 + '@rollup/rollup-win32-ia32-msvc@4.34.6': 1065 + resolution: {integrity: sha512-oLHxuyywc6efdKVTxvc0135zPrRdtYVjtVD5GUm55I3ODxhU/PwkQFD97z16Xzxa1Fz0AEe4W/2hzRtd+IfpOA==} 1108 1066 cpu: [ia32] 1109 1067 os: [win32] 1110 1068 1111 - '@rollup/rollup-win32-x64-msvc@4.30.1': 1112 - resolution: {integrity: sha512-D6qjsXGcvhTjv0kI4fU8tUuBDF/Ueee4SVX79VfNDXZa64TfCW1Slkb6Z7O1p7vflqZjcmOVdZlqf8gvJxc6og==} 1069 + '@rollup/rollup-win32-x64-msvc@4.34.6': 1070 + resolution: {integrity: sha512-0PVwmgzZ8+TZ9oGBmdZoQVXflbvuwzN/HRclujpl4N/q3i+y0lqLw8n1bXA8ru3sApDjlmONaNAuYr38y1Kr9w==} 1113 1071 cpu: [x64] 1114 1072 os: [win32] 1115 1073 1116 - '@tanstack/history@1.97.0': 1117 - resolution: {integrity: sha512-xFdpGJqwSLUJW5TYRNjRO5T41KjGkJeHWyhANZsNJ1KDm7uCVNkfLxNXeCI1XhIFbpzJmk13vo/mY0WJDe0A5g==} 1074 + '@tanstack/history@1.99.13': 1075 + resolution: {integrity: sha512-JMd7USmnp8zV8BRGIjALqzPxazvKtQ7PGXQC7n39HpbqdsmfV2ePCzieO84IvN+mwsTrXErpbjI4BfKCa+ZNCg==} 1118 1076 engines: {node: '>=12'} 1119 1077 1120 - '@tanstack/react-router@1.97.3': 1121 - resolution: {integrity: sha512-pTQZ27IAd9LTjc2O6V0VIS+E9hAKSraKYcMPYABzV/3maMUt39DKmqpBFFxWgAJ3bW++oYvHaDEJ7ZI71mezZQ==} 1078 + '@tanstack/react-router@1.104.1': 1079 + resolution: {integrity: sha512-c/l6TNRuUP6FTmHKyDwTGdxU0bCQhZM7QeKq/Utkyzj2i8awjWLILhBTsCXhLGY1JZtDl4dXixNgXGBiNo8Cnw==} 1122 1080 engines: {node: '>=12'} 1123 1081 peerDependencies: 1124 - react: '>=18' 1125 - react-dom: '>=18' 1082 + react: '>=18.0.0 || >=19.0.0' 1083 + react-dom: '>=18.0.0 || >=19.0.0' 1126 1084 1127 1085 '@tanstack/react-store@0.7.0': 1128 1086 resolution: {integrity: sha512-S/Rq17HaGOk+tQHV/yrePMnG1xbsKZIl/VsNWnNXt4XW+tTY8dTlvpJH2ZQ3GRALsusG5K6Q3unAGJ2pd9W/Ng==} ··· 1130 1088 react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 1131 1089 react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 1132 1090 1133 - '@tanstack/router-devtools@1.97.3': 1134 - resolution: {integrity: sha512-Ah78X3MhpxcAjGolrhYz/NkPrIpeJ20Nxf6RW7s6/L6GMQ8VGOAhOAJpUbt98KeJ+yvgb3ShznhL9Cc6vxQIQg==} 1091 + '@tanstack/router-core@1.104.1': 1092 + resolution: {integrity: sha512-8nP/V5paP+S/17rlw+B2F12R2bB9PixU/+qnD2QdCjK1ajnG4qA0pVN3VSTQe2oCKND6GPZpm2ikmQWumwss9Q==} 1093 + engines: {node: '>=12'} 1094 + 1095 + '@tanstack/router-devtools@1.104.3': 1096 + resolution: {integrity: sha512-30lN9Q26IJ9fcuYXk29jp381/6R6FFoMdvhJj2AYl4esNeJ4I0PfMdqmVRLHe/Q/WEgPp6XIZvZulZfbYeBYZA==} 1135 1097 engines: {node: '>=12'} 1136 1098 peerDependencies: 1137 - '@tanstack/react-router': ^1.97.3 1138 - react: '>=18' 1139 - react-dom: '>=18' 1099 + '@tanstack/react-router': ^1.104.1 1100 + csstype: ^3.0.10 1101 + react: '>=18.0.0 || >=19.0.0' 1102 + react-dom: '>=18.0.0 || >=19.0.0' 1103 + peerDependenciesMeta: 1104 + csstype: 1105 + optional: true 1140 1106 1141 - '@tanstack/router-generator@1.97.3': 1142 - resolution: {integrity: sha512-BRjnlU5ETjazVdM89uMlPzgN4w9T+ZM+eTq5iUxbdbNP6WB+Fqa4DB3LkQpGbKpjzNGFwiOE53zREMqfIycp1A==} 1107 + '@tanstack/router-generator@1.104.1': 1108 + resolution: {integrity: sha512-1z75mOOEZxNTKUSNOZk1/liTx6TidqXqcZTT/JI6gWoGxqx3EVnhv0iqK3CHxlzrIvrr3akRuVU1mjEY42BHRQ==} 1143 1109 engines: {node: '>=12'} 1144 1110 peerDependencies: 1145 - '@tanstack/react-router': ^1.97.3 1111 + '@tanstack/react-router': ^1.104.1 1146 1112 peerDependenciesMeta: 1147 1113 '@tanstack/react-router': 1148 1114 optional: true 1149 1115 1150 - '@tanstack/router-plugin@1.97.3': 1151 - resolution: {integrity: sha512-jrDS3UtOQ3cdJZE8IWgk8B04TrkzUlMPIO7QD5OJtM8Mosx2k9sMN59JVc4nYYCZ506qPwKj+nhHZlQg29mpZA==} 1116 + '@tanstack/router-plugin@1.104.1': 1117 + resolution: {integrity: sha512-TUkO9wg962XHsvAUOIWqc+8jxJ16CdBje59FEB9NpnX2wy/9c9AJ6iV5RfWUbSntni/HfTXE9uNd4oWSTwDrXg==} 1152 1118 engines: {node: '>=12'} 1153 1119 peerDependencies: 1154 1120 '@rsbuild/core': '>=1.0.2' 1121 + '@tanstack/react-router': ^1.104.1 1155 1122 vite: '>=5.0.0 || >=6.0.0' 1156 1123 webpack: '>=5.92.0' 1157 1124 peerDependenciesMeta: 1158 1125 '@rsbuild/core': 1126 + optional: true 1127 + '@tanstack/react-router': 1159 1128 optional: true 1160 1129 vite: 1161 1130 optional: true 1162 1131 webpack: 1163 1132 optional: true 1164 1133 1134 + '@tanstack/router-utils@1.102.2': 1135 + resolution: {integrity: sha512-Uwl2nbrxhCzviaHHBLNPhSC/OMpZLdOTxTJndUSsXTzWUP4IoQcVmngaIsxi9iriE3ArC1VXuanUAkfGmimNOQ==} 1136 + engines: {node: '>=12'} 1137 + 1165 1138 '@tanstack/store@0.7.0': 1166 1139 resolution: {integrity: sha512-CNIhdoUsmD2NolYuaIs8VfWM467RK6oIBAW4nPEKZhg1smZ+/CwtCdpURgp7nxSqOaV9oKkzdWD80+bC66F/Jg==} 1167 1140 1168 - '@tanstack/virtual-file-routes@1.97.0': 1169 - resolution: {integrity: sha512-UsLBb+ALvxbRTYMlx3WJ36oq13Ps4n8tcN8biFrtiCbA8TiS0sgSAOr0lPQpzQqZuVSjscPjX43ciKf33hvkQw==} 1141 + '@tanstack/virtual-file-routes@1.99.0': 1142 + resolution: {integrity: sha512-XvX8bfdo4CYiCW+ItVdBfCorh3PwQFqYqd7ll+XKWiWOJpqUGIG7VlziVavARZpUySiY2VBlHadiUYS7jhgjRg==} 1170 1143 engines: {node: '>=12'} 1171 1144 1172 - '@tsparticles/basic@3.7.1': 1173 - resolution: {integrity: sha512-oJMJ3qzYUROYaOEsaFXkVynxT2OTWBXbQ9MNc1bJi/bVc1VOU44VN7X/KmiZjD+w1U+Qalk6BeVvDRwpFshblw==} 1145 + '@tsparticles/basic@3.8.1': 1146 + resolution: {integrity: sha512-my114zRmekT/+I2cGuEnHxlX5G/jO0iVtNnsxxlsgspXUTSY+fDixmrNF4UgFkuaIwd9Bv/yH+7S/4HE4qte7A==} 1174 1147 1175 - '@tsparticles/confetti@3.7.1': 1176 - resolution: {integrity: sha512-wYRCIi0l6PyjWm5LgxKqB4viMg/H1F3QFdBVI4zpNelypEHvnGyLw69gfhdnsiHjy2YO9/M5LOoJ2MSZllLcKg==} 1148 + '@tsparticles/confetti@3.8.1': 1149 + resolution: {integrity: sha512-ahtLeGiPwTXiWFAEnJHTOIFteYwjRJDpPEr4ohMSEHWD8Y0HkgtLQMzWgWMGYH/Q+ibi6DR5RGhXq6ndWkj/ag==} 1177 1150 1178 - '@tsparticles/engine@3.7.1': 1179 - resolution: {integrity: sha512-GYzBgq/oOE9YJdOL1++MoawWmYg4AvVct6CIrJGx84ZRb3U2owYmLsRGabYl0qX1CWWOvUG569043RJmyp/vQA==} 1151 + '@tsparticles/engine@3.8.1': 1152 + resolution: {integrity: sha512-S8h10nuZfElY7oih//NUHnT5qf4v3/dnsU8CMs7dz5lBEGr3amrYrXk0V+YKPTIQwfdmJHUaSBoAqFiv4aEGIA==} 1180 1153 1181 - '@tsparticles/move-base@3.7.1': 1182 - resolution: {integrity: sha512-LPtMHwJHhzwfRIcSAk814fY9NcRiICwaEbapaJSYyP1DwscSXqOWoyAEWwzV9hMgAcPdsED6nGeg8RCXGm58lw==} 1154 + '@tsparticles/move-base@3.8.1': 1155 + resolution: {integrity: sha512-DNFRL1QT8ZQYLg3fIk74EbHJq5HGOq9CM2bCci9dDcdymvN4L7aWVFQavRiWDbi3y1EUW3+jeHSMbD3qHAfOeA==} 1183 1156 1184 - '@tsparticles/plugin-emitters@3.7.1': 1185 - resolution: {integrity: sha512-WV5Uwxp/Ckqv5kZynTj6mj13jYbQCArNLFv8ks+zjdlteoyT5EhQl4rg+TalaySCb1zCd6Fu2Scp35l3JJgbnw==} 1157 + '@tsparticles/plugin-emitters@3.8.1': 1158 + resolution: {integrity: sha512-PGldE3OHs1hsZM6a8qHpXvKIMhaWAqZNwq8v7FwgJGxikXVvYtkKSaWslTpID3hYvtB6+whKig2uWURmq2TUsg==} 1186 1159 1187 - '@tsparticles/plugin-hex-color@3.7.1': 1188 - resolution: {integrity: sha512-7xu3MV8EdNNejjYyEmrq5fCDdYAcqz/9VatLpnwtwR5Q5t2qI0tD4CrcGaFfC/rTAVJacfiJe02UV/hlj03KKA==} 1160 + '@tsparticles/plugin-hex-color@3.8.1': 1161 + resolution: {integrity: sha512-AmgB7XIYBCvg5HcqYb19YpcjEx2k4DpU2e24n0rradDDeqKKcz7EWI/08FlAnDb5HUs1em63vaAanl1vdm3+OA==} 1189 1162 1190 - '@tsparticles/plugin-hsl-color@3.7.1': 1191 - resolution: {integrity: sha512-zzAI1CuoCMBJhgeYZ5Rq42nGbPg35ZzIs11eQegjsWG5Msm5QKSj60qPzERnoUcCc4HCKtIWP7rYMz6h3xpoEg==} 1163 + '@tsparticles/plugin-hsl-color@3.8.1': 1164 + resolution: {integrity: sha512-Ja6oEX6yu0064e4a+Fv1TBJiG5y0hqWwoOKSqf/Ra/zo01ageOEvDVX70FOVSrP+iEPGPznKVNcZs1tEOOvO0g==} 1192 1165 1193 - '@tsparticles/plugin-motion@3.7.1': 1194 - resolution: {integrity: sha512-CJVXQVcwURpcEin1xC5abPgaBQCJQ/SfP7zGBQJrfsaGz8t6YTbZdfuK6Yc0M8j8gTldlgl4dXjQCejFmSCNmQ==} 1166 + '@tsparticles/plugin-motion@3.8.1': 1167 + resolution: {integrity: sha512-UL/C1OKlysSdNf4ZMz8va1IaGbFuAAZE2hbkEE8B9It0N6Su3SyZtfssSDDQGAU4UQLmwRFd1HQ1M452X7d5+A==} 1195 1168 1196 - '@tsparticles/plugin-rgb-color@3.7.1': 1197 - resolution: {integrity: sha512-taEraTpCYR6jpjflqBL95tN0zFU8JrAChXTt8mxVn7gddxoNMHI/LGymEPRCweLukwV6GQyAGOkeGEdWDPtYTA==} 1169 + '@tsparticles/plugin-rgb-color@3.8.1': 1170 + resolution: {integrity: sha512-xNLqnaFUYjU+7dCHQXjZdM4UojUAVorPVmXlYmkh1xmujLljEaFTwCg1UJVlNq+fXENIFkeaf3/XT0U/q0ZBTA==} 1198 1171 1199 - '@tsparticles/shape-cards@3.7.1': 1200 - resolution: {integrity: sha512-MzXPlEH5lY9xR0j8kHaIPWzxEjvaYAxufUevi4ya5ju4qLGZB1tLAABr0h8qRMESPf1ALiVISNhdTxbDclaHFA==} 1172 + '@tsparticles/shape-cards@3.8.1': 1173 + resolution: {integrity: sha512-RpShXeYERR23mxoMOMQfCuewZveH0+3c4IvJCJFzXLadGTLdfbZyhCZVv1+v2nS9rDAacnRK7hJRwM2qOph4TA==} 1201 1174 1202 - '@tsparticles/shape-circle@3.7.1': 1203 - resolution: {integrity: sha512-kmOWaUuFwuTtcCFYjuyJbdA5qDqWdGsharLalYnIczkLu2c1I8jJo/OmGePKhWn62ocu7mqKMomfElkIcw2AsA==} 1175 + '@tsparticles/shape-circle@3.8.1': 1176 + resolution: {integrity: sha512-dM/f+qcpd8/KfviuVuKiTS8KLDE/T7xxHK7EI2S49yPW6yrJJBXdL7T4N9/n/6PF+Wslcl+kf/eTDjEAI3WjNQ==} 1204 1177 1205 - '@tsparticles/shape-emoji@3.7.1': 1206 - resolution: {integrity: sha512-mX18c/xhYVljS/r5Xbowzclw+1YwhtWoQFOOfkmjjZppA+RjgcwSKLvH6E20PaH1yVTjBOfSF+3POKpwsULzTg==} 1178 + '@tsparticles/shape-emoji@3.8.1': 1179 + resolution: {integrity: sha512-xiXNZ/afdecengUXhOqgUwR+vysgaseVpzEjoGoliOMWq4WHWv+S6ujNfes2oz3x736mTlvKdXcEWRncSXaKWw==} 1207 1180 1208 - '@tsparticles/shape-heart@3.7.1': 1209 - resolution: {integrity: sha512-g7HxUIgz2hzn47n3/LC3Q81NxrgvWoNIgqBdcVD1S3C+h/JnRHRDnQWhSpFD/bcZJFRxn4DGHnvV42H9u2hqfA==} 1181 + '@tsparticles/shape-heart@3.8.1': 1182 + resolution: {integrity: sha512-mUk3ZMp/f7FXDL3LseaDCTDaJSnWdja/MGwUOaGPNoyr0GwjeRxYUB0aSo+clpUiFEjJKAuzbgnGOc+AXokpvw==} 1210 1183 1211 - '@tsparticles/shape-image@3.7.1': 1212 - resolution: {integrity: sha512-eDzfkQhqLY6fb9QH2Vo9TGfdJBFFpYnojhxQxc7IdzIwOFMD3JK4B52RVl9oowR+rNE8dNp6P2L+eMAF4yld0g==} 1184 + '@tsparticles/shape-image@3.8.1': 1185 + resolution: {integrity: sha512-7Yi25uLXvcY5A6TzyVBjYPsTmeTrE+0a2YO8kdp3O7V9NRGCSfXKnPRFp+lNOTiQRRvOG+SSzx2G18dfc/jwQg==} 1213 1186 1214 - '@tsparticles/shape-polygon@3.7.1': 1215 - resolution: {integrity: sha512-5FrRfpYC3qnvV2nXBLE4Q0v+SMNWJO8xgzh6MBFwfptvqH4EOrqc/58eS5x0jlf+evwf9LjPgeGkOTcwaHHcYQ==} 1187 + '@tsparticles/shape-polygon@3.8.1': 1188 + resolution: {integrity: sha512-1pAx85NJbgmsOngl+ZAYH8vxwPJmoddjWCbWTD0wlp/x+2NRjn1iaGBKObPKLgwVzsAXb9qNHMsUX/x0C54svw==} 1216 1189 1217 - '@tsparticles/shape-square@3.7.1': 1218 - resolution: {integrity: sha512-7VCqbRwinjBZ+Ryme27rOtl+jKrET8qDthqZLrAoj3WONBqyt+R9q6SXAJ9WodqEX68IBvcluqbFY5qDZm8iAQ==} 1190 + '@tsparticles/shape-square@3.8.1': 1191 + resolution: {integrity: sha512-4cjDt6542dkc15zxG1VYT7ScgPXM3+5VGtwMfh5CYNBx+GZZ3R+XUo1Q66JadcqKcNdHXfMWbXCMxs0GaiTtSw==} 1219 1192 1220 - '@tsparticles/shape-star@3.7.1': 1221 - resolution: {integrity: sha512-3G4oipioyWKLEQYT11Sx3k6AObu3dbv/A5LRqGGTQm5IR6UACa+INwykZYI0a+MdJJMb83E0e4Fn3hlZbi0/8w==} 1193 + '@tsparticles/shape-star@3.8.1': 1194 + resolution: {integrity: sha512-wBxnawqan/ocguNxY6cOEXF+YVnLIUmGBlnVGYx/7U9E2UHuHEKkoumob4fUflKISjvj5eQLpm/E1eUfYMd6RA==} 1222 1195 1223 - '@tsparticles/updater-color@3.7.1': 1224 - resolution: {integrity: sha512-QimV3yn17dcdJx7PpTwLtw9BhkQ0q8qFF035OdcZpnynBPAO/hg0zvSMpMGoeuDVFH02wWBy4h2/BYCv6wh6Sw==} 1196 + '@tsparticles/updater-color@3.8.1': 1197 + resolution: {integrity: sha512-HKrZzrF8YJ+TD+FdIwaWOPV565bkBhe+Ewj7CwKblG7H/SG+C6n1xIYobXkGP5pYkkQ+Cm1UV/Aq0Ih7sa+rJg==} 1225 1198 1226 - '@tsparticles/updater-life@3.7.1': 1227 - resolution: {integrity: sha512-NY5gUrgO5AsARNC0usP9PKahXf7JCxbP/H1vzTfA0SJw4veANfWTldOvhIlcm2CHVP5P1b827p0hWsBHECwz7A==} 1199 + '@tsparticles/updater-life@3.8.1': 1200 + resolution: {integrity: sha512-5rCFFKD7js1lKgTpKOLo2OfmisWp4qqMVUVR4bNPeR0Ne/dcwDbKDzWyYS2AMsvWv/gcTTtWiarRfAiVQ5HtNg==} 1228 1201 1229 - '@tsparticles/updater-opacity@3.7.1': 1230 - resolution: {integrity: sha512-YcyviCooTv7SAKw7sxd84CfJqZ7dYPSdYZzCpedV6TKIObRiwLqXlyLXQGJ3YltghKQSCSolmVy8woWBCDm1qA==} 1202 + '@tsparticles/updater-opacity@3.8.1': 1203 + resolution: {integrity: sha512-41dJ0T7df7AUFFkV9yU0buUfUwh+hLYcViXxkDy+6CJiiNCNZ4H404w1DTpBQLL4fbxUcDk9BXZLV7gkE2OfAw==} 1231 1204 1232 - '@tsparticles/updater-out-modes@3.7.1': 1233 - resolution: {integrity: sha512-Cb5sWquRtUYLSiFpmBjjYKRdpNV52diCo9+qMtK1oVlldDBhUwqO+1TQjdlaA2yl5DURlY9ZfOHXvY+IT7CHCw==} 1205 + '@tsparticles/updater-out-modes@3.8.1': 1206 + resolution: {integrity: sha512-BY8WqQwoDFpgPybwTzBU2GnxtRkjWnGStqBnR53x5+f1j7geTSY6WjcOvl1W+IkjtwtjiifriwBl41EbqMrjdQ==} 1234 1207 1235 - '@tsparticles/updater-roll@3.7.1': 1236 - resolution: {integrity: sha512-gHLRqpTGVGPJBEAIPUiYVembIn5bcaTXXxsUJEM/IN+GIOvj2uZZGZ4r2aFTA6WugqEbJsJdblDSvMfouyz7Ug==} 1208 + '@tsparticles/updater-roll@3.8.1': 1209 + resolution: {integrity: sha512-KYFTfMr8/M5pYBJFUFVrkogJURtKO5ogNSocOCf0v2QLMsbT5+OKNO7CLtxPZD98vTGRD3CHlt53/PF0tSesDA==} 1237 1210 1238 - '@tsparticles/updater-rotate@3.7.1': 1239 - resolution: {integrity: sha512-toVHwl+h6SvtA8dyxSA2kMH2QdDA71vehuAa+HoRqf1y06h5kxyYiMKZFHCqDJ6lFfRPs47MjrC9dD2bDz14MQ==} 1211 + '@tsparticles/updater-rotate@3.8.1': 1212 + resolution: {integrity: sha512-gpI07H1+diuuUdhJsQ1RlfHSD3fzBJrjyuwGuoXgHmvKzak6EWKpYfUMOraH4Dm41m/4kJZelle4nST+NpIuoA==} 1240 1213 1241 - '@tsparticles/updater-size@3.7.1': 1242 - resolution: {integrity: sha512-+Y0H0PnDJVIsJ+zHTyubYu1jtRFmVnY1dAv3VCjScIDw6bcpL/ol+HrtHTGIX0WbMyUfjCyALfAoaXi/Wm8VcQ==} 1214 + '@tsparticles/updater-size@3.8.1': 1215 + resolution: {integrity: sha512-SC2ZxewtpwKadCalotK6x2YanxRO3hTMW1Rxzx9V2rcjAIgh/Nw49Vuithy2TDq8RtTc9rHDAPic2vMQ/lYQwA==} 1243 1216 1244 - '@tsparticles/updater-tilt@3.7.1': 1245 - resolution: {integrity: sha512-pSOXoXPre1VPKC5nC5GW0L9jw63w1dVdsDdggEau7MP9xO7trko9L/KyayBX12Y4Ief1ca12Incxxr67hw7GGA==} 1217 + '@tsparticles/updater-tilt@3.8.1': 1218 + resolution: {integrity: sha512-qMVd/sjrAds8m6vXFH5YKN8zrQR9SLdn5N5EvHx/JuKpOut4NhG85u8AEJL6ct1g7hY8Zj9kfi/dDSSovkaHhw==} 1246 1219 1247 - '@tsparticles/updater-wobble@3.7.1': 1248 - resolution: {integrity: sha512-YIlNg4L0w4egQJhPLpgcvcfv9+X621+cQsrdN9sSmajxhhwtEQvQUvFUzGTcvpjVi+GcBNp0t4sCKEzoP8iaYw==} 1220 + '@tsparticles/updater-wobble@3.8.1': 1221 + resolution: {integrity: sha512-PkjVgeSkW0EebJQ9PdpwSMWU2fAvKsVSuH4KGmodYlgGkH0/zvKjMOPMEI6YRAor1/vF1soFyLYp9Vax7Ae13g==} 1249 1222 1250 1223 '@types/babel__core@7.20.5': 1251 1224 resolution: {integrity: sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==} ··· 1286 1259 '@types/d3-timer@3.0.2': 1287 1260 resolution: {integrity: sha512-Ps3T8E8dZDam6fUyNiMkekK3XUsaUEik+idO9/YjPtfj2qruF8tFBXS7XhtE4iIXBLxhmLjP3SXpLhVf21I9Lw==} 1288 1261 1289 - '@types/diff@6.0.0': 1290 - resolution: {integrity: sha512-dhVCYGv3ZSbzmQaBSagrv1WJ6rXCdkyTcDyoNu1MD8JohI7pR7k8wdZEm+mvdxRKXyHVwckFzWU1vJc+Z29MlA==} 1291 - 1292 1262 '@types/estree@1.0.6': 1293 1263 resolution: {integrity: sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==} 1294 1264 1295 - '@types/node@22.10.7': 1296 - resolution: {integrity: sha512-V09KvXxFiutGp6B7XkpaDXlNadZxrzajcY50EuoLIpQ6WWYCSvf19lVIazzfIzQvhUN2HjX12spLojTnhuKlGg==} 1265 + '@types/gensync@1.0.4': 1266 + resolution: {integrity: sha512-C3YYeRQWp2fmq9OryX+FoDy8nXS6scQ7dPptD8LnFDAUNcKWJjXQKDNJD3HVm+kOUsXhTOkpi69vI4EuAr95bA==} 1267 + 1268 + '@types/node@22.13.4': 1269 + resolution: {integrity: sha512-ywP2X0DYtX3y08eFVx5fNIw7/uIv8hYUKgXoK8oayJlLnKcRfEYCxWMVE1XagUdVtCJlZT1AU4LXEABW+L1Peg==} 1297 1270 1298 1271 acorn@8.14.0: 1299 1272 resolution: {integrity: sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA==} ··· 1316 1289 resolution: {integrity: sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==} 1317 1290 engines: {node: '>=12'} 1318 1291 1292 + ansis@3.14.0: 1293 + resolution: {integrity: sha512-R1LnSpYZWMDEFoAyCrfgToVz4ES25luDpjlZsUlD5GXdPWb91U+TZGkxWAOvt+7zWRY/ctOxhtTx5HUtL3qmbA==} 1294 + engines: {node: '>=14'} 1295 + 1319 1296 any-promise@1.3.0: 1320 1297 resolution: {integrity: sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==} 1321 1298 ··· 1337 1314 peerDependencies: 1338 1315 postcss: ^8.1.0 1339 1316 1340 - babel-dead-code-elimination@1.0.8: 1341 - resolution: {integrity: sha512-og6HQERk0Cmm+nTT4Od2wbPtgABXFMPaHACjbKLulZIFMkYyXZLkUGuAxdgpMJBrxyt/XFpSz++lNzjbcMnPkQ==} 1317 + babel-dead-code-elimination@1.0.9: 1318 + resolution: {integrity: sha512-JLIhax/xullfInZjtu13UJjaLHDeTzt3vOeomaSUdO/nAMEL/pWC/laKrSvWylXMnVWyL5bpmG9njqBZlUQOdg==} 1342 1319 1343 1320 babel-plugin-transform-hook-names@1.0.2: 1344 1321 resolution: {integrity: sha512-5gafyjyyBTTdX/tQQ0hRgu4AhNHG/hqWi0ZZmg2xvs2FgRkJXzDNKBZCyoYqgFkovfDrgM8OoKg8karoUvWeCw==} ··· 1371 1348 resolution: {integrity: sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==} 1372 1349 engines: {node: '>= 6'} 1373 1350 1374 - caniuse-lite@1.0.30001695: 1375 - resolution: {integrity: sha512-vHyLade6wTgI2u1ec3WQBxv+2BrTERV28UXQu9LO6lZ9pYeMk34vjXFLOxo1A4UBA8XTL4njRQZdno/yYaSmWw==} 1376 - 1377 - chalk@5.4.1: 1378 - resolution: {integrity: sha512-zgVZuo2WcZgfUEmsn6eO3kINexW8RAE4maiQ8QNs8CtpPCSyMiYsULR3HQYkm3w8FIA3SberyMJMSldGsW+U3w==} 1379 - engines: {node: ^12.17.0 || ^14.13 || >=16.0.0} 1351 + caniuse-lite@1.0.30001699: 1352 + resolution: {integrity: sha512-b+uH5BakXZ9Do9iK+CkDmctUSEqZl+SP056vc5usa0PL+ev5OHw003rZXcnjNDv3L8P5j6rwT6C0BPKSikW08w==} 1380 1353 1381 1354 chokidar@3.6.0: 1382 1355 resolution: {integrity: sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==} ··· 1510 1483 eastasianwidth@0.2.0: 1511 1484 resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==} 1512 1485 1513 - electron-to-chromium@1.5.83: 1514 - resolution: {integrity: sha512-LcUDPqSt+V0QmI47XLzZrz5OqILSMGsPFkDYus22rIbgorSvBYEFqq854ltTmUdHkY92FSdAAvsh4jWEULMdfQ==} 1486 + electron-to-chromium@1.5.99: 1487 + resolution: {integrity: sha512-77c/+fCyL2U+aOyqfIFi89wYLBeSTCs55xCZL0oFH0KjqsvSvyh6AdQ+UIl1vgpnQQE6g+/KK8hOIupH6VwPtg==} 1515 1488 1516 1489 emoji-regex@8.0.0: 1517 1490 resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} ··· 1554 1527 resolution: {integrity: sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==} 1555 1528 engines: {node: '>=8.6.0'} 1556 1529 1557 - fastq@1.18.0: 1558 - resolution: {integrity: sha512-QKHXPW0hD8g4UET03SdOdunzSouc9N4AuHdsX8XNcTsuz+yYFILVNIX4l9yHABMhiEI9Db0JTTIpu0wB+Y1QQw==} 1530 + fastq@1.19.0: 1531 + resolution: {integrity: sha512-7SFSRCNjBQIZH/xZR3iy5iQYR8aGBE0h3VG6/cwlbrpdciNYBMotQav8c1XI3HjHH+NikUpP53nPdlZSdWmFzA==} 1559 1532 1560 1533 fill-range@7.1.1: 1561 1534 resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==} ··· 1584 1557 resolution: {integrity: sha512-FJhYRoDaiatfEkUK8HKlicmu/3SGFD51q3itKDGoSTysQJBnfOcxU5GxnhE1E6soB76MbT0MBtnKJuXyAx+96Q==} 1585 1558 engines: {node: '>=6'} 1586 1559 1587 - get-tsconfig@4.8.1: 1588 - resolution: {integrity: sha512-k9PN+cFBmaLWtVz29SkUoqU5O0slLuHJXt/2P+tMVFT+phsSGXGkp9t3rQIqdz0e+06EHNGs3oM6ZX1s2zHxRg==} 1560 + get-tsconfig@4.10.0: 1561 + resolution: {integrity: sha512-kGzZ3LWWQcGIAmg6iWvXn0ei6WDtV26wzHRMwDSzmAbcXrTEXxHy6IehI6/4eT6VRKyMP1eF1VqwrVUmE/LR7A==} 1589 1562 1590 1563 glob-parent@5.1.2: 1591 1564 resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} ··· 1616 1589 resolution: {integrity: sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==} 1617 1590 hasBin: true 1618 1591 1619 - html-to-image@1.11.11: 1620 - resolution: {integrity: sha512-9gux8QhvjRO/erSnDPv28noDZcPZmYE7e1vFsBLKLlRlKDSqNJYebj6Qz1TGd5lsRV+X+xYyjCKjuZdABinWjA==} 1592 + html-to-image@1.11.13: 1593 + resolution: {integrity: sha512-cuOPoI7WApyhBElTTb9oqsawRvZ0rHhaHwghRLlTuffoD1B2aDemlCruLeZrUIIdvG7gs9xeELEPm6PhuASqrg==} 1621 1594 1622 1595 internmap@2.0.3: 1623 1596 resolution: {integrity: sha512-5Hh7Y1wQbvY5ooGgPbDaL5iYLAPzMTUrjMulskHLH6wnv/A+1q5rgEaiuqEjB+oxGXIVZs1FF+R/KPN3ZSQYYg==} ··· 1698 1671 peerDependencies: 1699 1672 react: ^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0 1700 1673 1701 - magic-string@0.30.5: 1702 - resolution: {integrity: sha512-7xlpfBaQaP/T6Vh8MO/EqXSW5En6INHEvEXQiuff7Gku0PWjU3uf6w/j9o7O+SpB5fOAkrI5HeoNgwjEO0pFsA==} 1703 - engines: {node: '>=12'} 1674 + magic-string@0.30.17: 1675 + resolution: {integrity: sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA==} 1704 1676 1705 1677 merge2@1.4.1: 1706 1678 resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} ··· 1820 1792 postcss-value-parser@4.2.0: 1821 1793 resolution: {integrity: sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==} 1822 1794 1823 - postcss@8.5.1: 1824 - resolution: {integrity: sha512-6oz2beyjc5VMn/KV1pPw8fliQkhBXrVn1Z3TVyqZxU8kZpzEKhBdmCFqI6ZbmGtamQvQGuU1sgPTk8ZrXDD7jQ==} 1795 + postcss@8.5.2: 1796 + resolution: {integrity: sha512-MjOadfU3Ys9KYoX0AdkBlFEF1Vx37uCCeN4ZHnmwm9FfpbsGWMZeBLMmmpY+6Ocqod7mkdZ0DT31OlbsFrLlkA==} 1825 1797 engines: {node: ^10 || ^12 || >=14} 1826 1798 1827 1799 preact@10.25.4: 1828 1800 resolution: {integrity: sha512-jLdZDb+Q+odkHJ+MpW/9U5cODzqnB+fy2EiHSZES7ldV5LK7yjlVzTp7R8Xy6W6y75kfK8iWYtFVH7lvjwrCMA==} 1829 1801 1830 - prettier@3.4.2: 1831 - resolution: {integrity: sha512-e9MewbtFo+Fevyuxn/4rrcDAaq0IYxPGLvObpQjiZBMAzB9IGmzlnG9RZy3FFas+eBMu2vA0CszMeduow5dIuQ==} 1802 + prettier@3.5.1: 1803 + resolution: {integrity: sha512-hPpFQvHwL3Qv5AdRvBFMhnKo4tYxp0ReXiPn2bxkiohEX6mBeBwEpBSQTkD458RaaDKQMYSp4hX4UtfUTA5wDw==} 1832 1804 engines: {node: '>=14'} 1833 1805 hasBin: true 1834 1806 ··· 1859 1831 '@types/react': 1860 1832 optional: true 1861 1833 1862 - react-remove-scroll@2.6.2: 1863 - resolution: {integrity: sha512-KmONPx5fnlXYJQqC62Q+lwIeAk64ws/cUw6omIumRzMRPqgnYqhSSti99nbj0Ry13bv7dF+BKn7NB+OqkdZGTw==} 1864 - engines: {node: '>=10'} 1865 - peerDependencies: 1866 - '@types/react': '*' 1867 - react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc 1868 - peerDependenciesMeta: 1869 - '@types/react': 1870 - optional: true 1871 - 1872 1834 react-remove-scroll@2.6.3: 1873 1835 resolution: {integrity: sha512-pnAi91oOk8g8ABQKGF5/M9qxmmOPxaAnopyTHYfqYEwJhyFrbbBtHuSgtKEoH0jpcxx5o3hXqH1mNd9/Oi+8iQ==} 1874 1836 engines: {node: '>=10'} ··· 1937 1899 resolution: {integrity: sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==} 1938 1900 engines: {iojs: '>=1.0.0', node: '>=0.10.0'} 1939 1901 1940 - rollup@4.30.1: 1941 - resolution: {integrity: sha512-mlJ4glW020fPuLi7DkM/lN97mYEZGWeqBnrljzN0gs7GLctqX3lNWxKQ7Gl712UAX+6fog/L3jh4gb7R6aVi3w==} 1902 + rollup@4.34.6: 1903 + resolution: {integrity: sha512-wc2cBWqJgkU3Iz5oztRkQbfVkbxoz5EhnCGOrnJvnLnQ7O0WhQUYyv18qQI79O8L7DdHrrlJNeCHd4VGpnaXKQ==} 1942 1904 engines: {node: '>=18.0.0', npm: '>=8.0.0'} 1943 1905 hasBin: true 1944 1906 ··· 1963 1925 signal-exit@4.1.0: 1964 1926 resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==} 1965 1927 engines: {node: '>=14'} 1928 + 1929 + simple-code-frame@1.3.0: 1930 + resolution: {integrity: sha512-MB4pQmETUBlNs62BBeRjIFGeuy/x6gGKh7+eRUemn1rCFhqo7K+4slPqsyizCbcbYLnaYqaoZ2FWsZ/jN06D8w==} 1966 1931 1967 1932 simple-icons@13.21.0: 1968 1933 resolution: {integrity: sha512-LI5pVJPBv6oc79OMsffwb6kEqnmB8P1Cjg1crNUlhsxPETQ5UzbCKQdxU+7MW6+DD1qfPkla/vSKlLD4IfyXpQ==} ··· 2054 2019 undici-types@6.20.0: 2055 2020 resolution: {integrity: sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg==} 2056 2021 2057 - unplugin@1.16.1: 2058 - resolution: {integrity: sha512-4/u/j4FrCKdi17jaxuJA0jClGxB1AvU2hw/IuayPc4ay1XGaJs/rbb4v5WKwAjNifjmXK9PIFyuPiaK8azyR9w==} 2059 - engines: {node: '>=14.0.0'} 2022 + unplugin@2.2.0: 2023 + resolution: {integrity: sha512-m1ekpSwuOT5hxkJeZGRxO7gXbXT3gF26NjQ7GdVHoLoF8/nopLcd/QfPigpCy7i51oFHiRJg/CyHhj4vs2+KGw==} 2024 + engines: {node: '>=18.12.0'} 2060 2025 2061 2026 update-browserslist-db@1.1.2: 2062 2027 resolution: {integrity: sha512-PPypAm5qvlD7XMZC3BujecnaOxwhrtoFR+Dqkk5Aa/6DssiH0ibKoketaj9w8LP7Bont1rYeoV5plxD7RTEPRg==} ··· 2095 2060 victory-vendor@36.9.2: 2096 2061 resolution: {integrity: sha512-PnpQQMuxlwYdocC8fIJqVXvkeViHYzotI+NJrCuav0ZYFoq912ZHBk3mCeuj+5/VpodOjPe1z0Fk2ihgzlXqjQ==} 2097 2062 2098 - vite@6.0.7: 2099 - resolution: {integrity: sha512-RDt8r/7qx9940f8FcOIAH9PTViRrghKaK2K1jY3RaAURrEUbm9Du1mJ72G+jlhtG3WwodnfzY8ORQZbBavZEAQ==} 2063 + vite-prerender-plugin@0.5.6: 2064 + resolution: {integrity: sha512-ELG0pflVXWNVGaHme8g0rZB7xFnytf1U6fYLep3NUC4knGmOHtEc2R7DIlnCKeYGUGkzfMcvJOasK4C0dulKbQ==} 2065 + 2066 + vite@6.1.0: 2067 + resolution: {integrity: sha512-RjjMipCKVoR4hVfPY6GQTgveinjNuyLw+qruksLDvA5ktI1150VmcMBKmQaEWJhg/j6Uaf6dNCNA0AfdzUb/hQ==} 2100 2068 engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0} 2101 2069 hasBin: true 2102 2070 peerDependencies: ··· 2159 2127 engines: {node: '>= 14'} 2160 2128 hasBin: true 2161 2129 2162 - zod@3.24.1: 2163 - resolution: {integrity: sha512-muH7gBL9sI1nciMZV67X5fTKKBLtwpZ5VBp1vsOQzj1MhrBZ4wlVCm3gedKZWLp0Oyel8sIGfeiz54Su+OVT+A==} 2130 + zod@3.24.2: 2131 + resolution: {integrity: sha512-lY7CDW43ECgW9u1TcT3IoXHflywfVqDYze4waEz812jR/bZ8FHDsl7pFQoSZTz5N+2NqRXs8GBwnAwo3ZNxqhQ==} 2164 2132 2165 2133 snapshots: 2166 2134 ··· 2182 2150 2183 2151 '@atcute/client@2.0.7': {} 2184 2152 2185 - '@atcute/oauth-browser-client@1.0.9': 2153 + '@atcute/oauth-browser-client@1.0.13': 2186 2154 dependencies: 2187 2155 '@atcute/client': 2.0.7 2188 2156 ··· 2192 2160 js-tokens: 4.0.0 2193 2161 picocolors: 1.1.1 2194 2162 2195 - '@babel/compat-data@7.26.5': {} 2163 + '@babel/compat-data@7.26.8': {} 2196 2164 2197 - '@babel/core@7.26.0': 2165 + '@babel/core@7.26.8': 2198 2166 dependencies: 2199 2167 '@ampproject/remapping': 2.3.0 2200 2168 '@babel/code-frame': 7.26.2 2201 - '@babel/generator': 7.26.5 2169 + '@babel/generator': 7.26.8 2202 2170 '@babel/helper-compilation-targets': 7.26.5 2203 - '@babel/helper-module-transforms': 7.26.0(@babel/core@7.26.0) 2204 - '@babel/helpers': 7.26.0 2205 - '@babel/parser': 7.26.5 2206 - '@babel/template': 7.25.9 2207 - '@babel/traverse': 7.26.5 2208 - '@babel/types': 7.26.5 2171 + '@babel/helper-module-transforms': 7.26.0(@babel/core@7.26.8) 2172 + '@babel/helpers': 7.26.7 2173 + '@babel/parser': 7.26.8 2174 + '@babel/template': 7.26.8 2175 + '@babel/traverse': 7.26.8 2176 + '@babel/types': 7.26.8 2177 + '@types/gensync': 1.0.4 2209 2178 convert-source-map: 2.0.0 2210 2179 debug: 4.4.0 2211 2180 gensync: 1.0.0-beta.2 ··· 2214 2183 transitivePeerDependencies: 2215 2184 - supports-color 2216 2185 2217 - '@babel/generator@7.26.5': 2186 + '@babel/generator@7.26.8': 2218 2187 dependencies: 2219 - '@babel/parser': 7.26.5 2220 - '@babel/types': 7.26.5 2188 + '@babel/parser': 7.26.8 2189 + '@babel/types': 7.26.8 2221 2190 '@jridgewell/gen-mapping': 0.3.8 2222 2191 '@jridgewell/trace-mapping': 0.3.25 2223 2192 jsesc: 3.1.0 2224 2193 2225 2194 '@babel/helper-annotate-as-pure@7.25.9': 2226 2195 dependencies: 2227 - '@babel/types': 7.26.5 2196 + '@babel/types': 7.26.8 2228 2197 2229 2198 '@babel/helper-compilation-targets@7.26.5': 2230 2199 dependencies: 2231 - '@babel/compat-data': 7.26.5 2200 + '@babel/compat-data': 7.26.8 2232 2201 '@babel/helper-validator-option': 7.25.9 2233 2202 browserslist: 4.24.4 2234 2203 lru-cache: 5.1.1 ··· 2236 2205 2237 2206 '@babel/helper-module-imports@7.25.9': 2238 2207 dependencies: 2239 - '@babel/traverse': 7.26.5 2240 - '@babel/types': 7.26.5 2208 + '@babel/traverse': 7.26.8 2209 + '@babel/types': 7.26.8 2241 2210 transitivePeerDependencies: 2242 2211 - supports-color 2243 2212 2244 - '@babel/helper-module-transforms@7.26.0(@babel/core@7.26.0)': 2213 + '@babel/helper-module-transforms@7.26.0(@babel/core@7.26.8)': 2245 2214 dependencies: 2246 - '@babel/core': 7.26.0 2215 + '@babel/core': 7.26.8 2247 2216 '@babel/helper-module-imports': 7.25.9 2248 2217 '@babel/helper-validator-identifier': 7.25.9 2249 - '@babel/traverse': 7.26.5 2218 + '@babel/traverse': 7.26.8 2250 2219 transitivePeerDependencies: 2251 2220 - supports-color 2252 2221 ··· 2258 2227 2259 2228 '@babel/helper-validator-option@7.25.9': {} 2260 2229 2261 - '@babel/helpers@7.26.0': 2230 + '@babel/helpers@7.26.7': 2262 2231 dependencies: 2263 - '@babel/template': 7.25.9 2264 - '@babel/types': 7.26.5 2232 + '@babel/template': 7.26.8 2233 + '@babel/types': 7.26.8 2265 2234 2266 - '@babel/parser@7.26.5': 2235 + '@babel/parser@7.26.8': 2267 2236 dependencies: 2268 - '@babel/types': 7.26.5 2237 + '@babel/types': 7.26.8 2269 2238 2270 - '@babel/plugin-syntax-jsx@7.25.9(@babel/core@7.26.0)': 2239 + '@babel/plugin-syntax-jsx@7.25.9(@babel/core@7.26.8)': 2271 2240 dependencies: 2272 - '@babel/core': 7.26.0 2241 + '@babel/core': 7.26.8 2273 2242 '@babel/helper-plugin-utils': 7.26.5 2274 2243 2275 - '@babel/plugin-syntax-typescript@7.25.9(@babel/core@7.26.0)': 2244 + '@babel/plugin-syntax-typescript@7.25.9(@babel/core@7.26.8)': 2276 2245 dependencies: 2277 - '@babel/core': 7.26.0 2246 + '@babel/core': 7.26.8 2278 2247 '@babel/helper-plugin-utils': 7.26.5 2279 2248 2280 - '@babel/plugin-transform-react-jsx-development@7.25.9(@babel/core@7.26.0)': 2249 + '@babel/plugin-transform-react-jsx-development@7.25.9(@babel/core@7.26.8)': 2281 2250 dependencies: 2282 - '@babel/core': 7.26.0 2283 - '@babel/plugin-transform-react-jsx': 7.25.9(@babel/core@7.26.0) 2251 + '@babel/core': 7.26.8 2252 + '@babel/plugin-transform-react-jsx': 7.25.9(@babel/core@7.26.8) 2284 2253 transitivePeerDependencies: 2285 2254 - supports-color 2286 2255 2287 - '@babel/plugin-transform-react-jsx@7.25.9(@babel/core@7.26.0)': 2256 + '@babel/plugin-transform-react-jsx@7.25.9(@babel/core@7.26.8)': 2288 2257 dependencies: 2289 - '@babel/core': 7.26.0 2258 + '@babel/core': 7.26.8 2290 2259 '@babel/helper-annotate-as-pure': 7.25.9 2291 2260 '@babel/helper-module-imports': 7.25.9 2292 2261 '@babel/helper-plugin-utils': 7.26.5 2293 - '@babel/plugin-syntax-jsx': 7.25.9(@babel/core@7.26.0) 2294 - '@babel/types': 7.26.5 2262 + '@babel/plugin-syntax-jsx': 7.25.9(@babel/core@7.26.8) 2263 + '@babel/types': 7.26.8 2295 2264 transitivePeerDependencies: 2296 2265 - supports-color 2297 2266 ··· 2299 2268 dependencies: 2300 2269 regenerator-runtime: 0.14.1 2301 2270 2302 - '@babel/template@7.25.9': 2271 + '@babel/template@7.26.8': 2303 2272 dependencies: 2304 2273 '@babel/code-frame': 7.26.2 2305 - '@babel/parser': 7.26.5 2306 - '@babel/types': 7.26.5 2274 + '@babel/parser': 7.26.8 2275 + '@babel/types': 7.26.8 2307 2276 2308 - '@babel/traverse@7.26.5': 2277 + '@babel/traverse@7.26.8': 2309 2278 dependencies: 2310 2279 '@babel/code-frame': 7.26.2 2311 - '@babel/generator': 7.26.5 2312 - '@babel/parser': 7.26.5 2313 - '@babel/template': 7.25.9 2314 - '@babel/types': 7.26.5 2280 + '@babel/generator': 7.26.8 2281 + '@babel/parser': 7.26.8 2282 + '@babel/template': 7.26.8 2283 + '@babel/types': 7.26.8 2315 2284 debug: 4.4.0 2316 2285 globals: 11.12.0 2317 2286 transitivePeerDependencies: 2318 2287 - supports-color 2319 2288 2320 - '@babel/types@7.26.5': 2289 + '@babel/types@7.26.8': 2321 2290 dependencies: 2322 2291 '@babel/helper-string-parser': 7.25.9 2323 2292 '@babel/helper-validator-identifier': 7.25.9 ··· 2522 2491 '@nodelib/fs.walk@1.2.8': 2523 2492 dependencies: 2524 2493 '@nodelib/fs.scandir': 2.1.5 2525 - fastq: 1.18.0 2494 + fastq: 1.19.0 2526 2495 2527 2496 '@pkgjs/parseargs@0.11.0': 2528 2497 optional: true 2529 2498 2530 - '@preact/preset-vite@2.9.4(@babel/core@7.26.0)(preact@10.25.4)(vite@6.0.7(@types/node@22.10.7)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0))': 2499 + '@preact/preset-vite@2.10.1(@babel/core@7.26.8)(preact@10.25.4)(vite@6.1.0(@types/node@22.13.4)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0))': 2531 2500 dependencies: 2532 - '@babel/code-frame': 7.26.2 2533 - '@babel/core': 7.26.0 2534 - '@babel/plugin-transform-react-jsx': 7.25.9(@babel/core@7.26.0) 2535 - '@babel/plugin-transform-react-jsx-development': 7.25.9(@babel/core@7.26.0) 2536 - '@prefresh/vite': 2.4.6(preact@10.25.4)(vite@6.0.7(@types/node@22.10.7)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0)) 2501 + '@babel/core': 7.26.8 2502 + '@babel/plugin-transform-react-jsx': 7.25.9(@babel/core@7.26.8) 2503 + '@babel/plugin-transform-react-jsx-development': 7.25.9(@babel/core@7.26.8) 2504 + '@prefresh/vite': 2.4.7(preact@10.25.4)(vite@6.1.0(@types/node@22.13.4)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0)) 2537 2505 '@rollup/pluginutils': 4.2.1 2538 - babel-plugin-transform-hook-names: 1.0.2(@babel/core@7.26.0) 2506 + babel-plugin-transform-hook-names: 1.0.2(@babel/core@7.26.8) 2539 2507 debug: 4.4.0 2540 2508 kolorist: 1.8.0 2541 - magic-string: 0.30.5 2542 - node-html-parser: 6.1.13 2543 - source-map: 0.7.4 2544 - stack-trace: 1.0.0-pre2 2545 - vite: 6.0.7(@types/node@22.10.7)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0) 2509 + vite: 6.1.0(@types/node@22.13.4)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0) 2510 + vite-prerender-plugin: 0.5.6 2546 2511 transitivePeerDependencies: 2547 2512 - preact 2548 2513 - supports-color ··· 2555 2520 2556 2521 '@prefresh/utils@1.2.0': {} 2557 2522 2558 - '@prefresh/vite@2.4.6(preact@10.25.4)(vite@6.0.7(@types/node@22.10.7)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0))': 2523 + '@prefresh/vite@2.4.7(preact@10.25.4)(vite@6.1.0(@types/node@22.13.4)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0))': 2559 2524 dependencies: 2560 - '@babel/core': 7.26.0 2525 + '@babel/core': 7.26.8 2561 2526 '@prefresh/babel-plugin': 0.5.1 2562 2527 '@prefresh/core': 1.5.3(preact@10.25.4) 2563 2528 '@prefresh/utils': 1.2.0 2564 2529 '@rollup/pluginutils': 4.2.1 2565 2530 preact: 10.25.4 2566 - vite: 6.0.7(@types/node@22.10.7)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0) 2531 + vite: 6.1.0(@types/node@22.13.4)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0) 2567 2532 transitivePeerDependencies: 2568 2533 - supports-color 2569 2534 2570 2535 '@radix-ui/primitive@1.1.1': {} 2571 2536 2572 - '@radix-ui/react-arrow@1.1.1(react-dom@19.0.0(react@19.0.0))(react@19.0.0)': 2537 + '@radix-ui/react-arrow@1.1.2(react-dom@19.0.0(react@19.0.0))(react@19.0.0)': 2573 2538 dependencies: 2574 - '@radix-ui/react-primitive': 2.0.1(react-dom@19.0.0(react@19.0.0))(react@19.0.0) 2539 + '@radix-ui/react-primitive': 2.0.2(react-dom@19.0.0(react@19.0.0))(react@19.0.0) 2575 2540 react: 19.0.0 2576 2541 react-dom: 19.0.0(react@19.0.0) 2577 2542 2578 - '@radix-ui/react-arrow@1.1.2(react-dom@19.0.0(react@19.0.0))(react@19.0.0)': 2543 + '@radix-ui/react-avatar@1.1.3(react-dom@19.0.0(react@19.0.0))(react@19.0.0)': 2579 2544 dependencies: 2545 + '@radix-ui/react-context': 1.1.1(react@19.0.0) 2580 2546 '@radix-ui/react-primitive': 2.0.2(react-dom@19.0.0(react@19.0.0))(react@19.0.0) 2547 + '@radix-ui/react-use-callback-ref': 1.1.0(react@19.0.0) 2548 + '@radix-ui/react-use-layout-effect': 1.1.0(react@19.0.0) 2581 2549 react: 19.0.0 2582 2550 react-dom: 19.0.0(react@19.0.0) 2583 2551 2584 - '@radix-ui/react-collection@1.1.1(react-dom@19.0.0(react@19.0.0))(react@19.0.0)': 2552 + '@radix-ui/react-collection@1.1.2(react-dom@19.0.0(react@19.0.0))(react@19.0.0)': 2585 2553 dependencies: 2586 2554 '@radix-ui/react-compose-refs': 1.1.1(react@19.0.0) 2587 2555 '@radix-ui/react-context': 1.1.1(react@19.0.0) 2588 - '@radix-ui/react-primitive': 2.0.1(react-dom@19.0.0(react@19.0.0))(react@19.0.0) 2589 - '@radix-ui/react-slot': 1.1.1(react@19.0.0) 2556 + '@radix-ui/react-primitive': 2.0.2(react-dom@19.0.0(react@19.0.0))(react@19.0.0) 2557 + '@radix-ui/react-slot': 1.1.2(react@19.0.0) 2590 2558 react: 19.0.0 2591 2559 react-dom: 19.0.0(react@19.0.0) 2592 2560 ··· 2598 2566 dependencies: 2599 2567 react: 19.0.0 2600 2568 2601 - '@radix-ui/react-dialog@1.1.4(react-dom@19.0.0(react@19.0.0))(react@19.0.0)': 2569 + '@radix-ui/react-dialog@1.1.6(react-dom@19.0.0(react@19.0.0))(react@19.0.0)': 2602 2570 dependencies: 2603 2571 '@radix-ui/primitive': 1.1.1 2604 2572 '@radix-ui/react-compose-refs': 1.1.1(react@19.0.0) 2605 2573 '@radix-ui/react-context': 1.1.1(react@19.0.0) 2606 - '@radix-ui/react-dismissable-layer': 1.1.3(react-dom@19.0.0(react@19.0.0))(react@19.0.0) 2574 + '@radix-ui/react-dismissable-layer': 1.1.5(react-dom@19.0.0(react@19.0.0))(react@19.0.0) 2607 2575 '@radix-ui/react-focus-guards': 1.1.1(react@19.0.0) 2608 - '@radix-ui/react-focus-scope': 1.1.1(react-dom@19.0.0(react@19.0.0))(react@19.0.0) 2576 + '@radix-ui/react-focus-scope': 1.1.2(react-dom@19.0.0(react@19.0.0))(react@19.0.0) 2609 2577 '@radix-ui/react-id': 1.1.0(react@19.0.0) 2610 - '@radix-ui/react-portal': 1.1.3(react-dom@19.0.0(react@19.0.0))(react@19.0.0) 2578 + '@radix-ui/react-portal': 1.1.4(react-dom@19.0.0(react@19.0.0))(react@19.0.0) 2611 2579 '@radix-ui/react-presence': 1.1.2(react-dom@19.0.0(react@19.0.0))(react@19.0.0) 2612 - '@radix-ui/react-primitive': 2.0.1(react-dom@19.0.0(react@19.0.0))(react@19.0.0) 2613 - '@radix-ui/react-slot': 1.1.1(react@19.0.0) 2580 + '@radix-ui/react-primitive': 2.0.2(react-dom@19.0.0(react@19.0.0))(react@19.0.0) 2581 + '@radix-ui/react-slot': 1.1.2(react@19.0.0) 2614 2582 '@radix-ui/react-use-controllable-state': 1.1.0(react@19.0.0) 2615 2583 aria-hidden: 1.2.4 2616 2584 react: 19.0.0 2617 2585 react-dom: 19.0.0(react@19.0.0) 2618 - react-remove-scroll: 2.6.2(react@19.0.0) 2586 + react-remove-scroll: 2.6.3(react@19.0.0) 2619 2587 2620 2588 '@radix-ui/react-direction@1.1.0(react@19.0.0)': 2621 2589 dependencies: 2622 2590 react: 19.0.0 2623 2591 2624 - '@radix-ui/react-dismissable-layer@1.1.3(react-dom@19.0.0(react@19.0.0))(react@19.0.0)': 2592 + '@radix-ui/react-dismissable-layer@1.1.5(react-dom@19.0.0(react@19.0.0))(react@19.0.0)': 2625 2593 dependencies: 2626 2594 '@radix-ui/primitive': 1.1.1 2627 2595 '@radix-ui/react-compose-refs': 1.1.1(react@19.0.0) 2628 - '@radix-ui/react-primitive': 2.0.1(react-dom@19.0.0(react@19.0.0))(react@19.0.0) 2596 + '@radix-ui/react-primitive': 2.0.2(react-dom@19.0.0(react@19.0.0))(react@19.0.0) 2629 2597 '@radix-ui/react-use-callback-ref': 1.1.0(react@19.0.0) 2630 2598 '@radix-ui/react-use-escape-keydown': 1.1.0(react@19.0.0) 2631 2599 react: 19.0.0 2632 2600 react-dom: 19.0.0(react@19.0.0) 2633 2601 2634 - '@radix-ui/react-dismissable-layer@1.1.5(react-dom@19.0.0(react@19.0.0))(react@19.0.0)': 2602 + '@radix-ui/react-dropdown-menu@2.1.6(react-dom@19.0.0(react@19.0.0))(react@19.0.0)': 2635 2603 dependencies: 2636 2604 '@radix-ui/primitive': 1.1.1 2637 2605 '@radix-ui/react-compose-refs': 1.1.1(react@19.0.0) 2606 + '@radix-ui/react-context': 1.1.1(react@19.0.0) 2607 + '@radix-ui/react-id': 1.1.0(react@19.0.0) 2608 + '@radix-ui/react-menu': 2.1.6(react-dom@19.0.0(react@19.0.0))(react@19.0.0) 2638 2609 '@radix-ui/react-primitive': 2.0.2(react-dom@19.0.0(react@19.0.0))(react@19.0.0) 2639 - '@radix-ui/react-use-callback-ref': 1.1.0(react@19.0.0) 2640 - '@radix-ui/react-use-escape-keydown': 1.1.0(react@19.0.0) 2610 + '@radix-ui/react-use-controllable-state': 1.1.0(react@19.0.0) 2641 2611 react: 19.0.0 2642 2612 react-dom: 19.0.0(react@19.0.0) 2643 2613 ··· 2645 2615 dependencies: 2646 2616 react: 19.0.0 2647 2617 2648 - '@radix-ui/react-focus-scope@1.1.1(react-dom@19.0.0(react@19.0.0))(react@19.0.0)': 2649 - dependencies: 2650 - '@radix-ui/react-compose-refs': 1.1.1(react@19.0.0) 2651 - '@radix-ui/react-primitive': 2.0.1(react-dom@19.0.0(react@19.0.0))(react@19.0.0) 2652 - '@radix-ui/react-use-callback-ref': 1.1.0(react@19.0.0) 2653 - react: 19.0.0 2654 - react-dom: 19.0.0(react@19.0.0) 2655 - 2656 2618 '@radix-ui/react-focus-scope@1.1.2(react-dom@19.0.0(react@19.0.0))(react@19.0.0)': 2657 2619 dependencies: 2658 2620 '@radix-ui/react-compose-refs': 1.1.1(react@19.0.0) ··· 2666 2628 '@radix-ui/react-use-layout-effect': 1.1.0(react@19.0.0) 2667 2629 react: 19.0.0 2668 2630 2669 - '@radix-ui/react-popover@1.1.6(react-dom@19.0.0(react@19.0.0))(react@19.0.0)': 2631 + '@radix-ui/react-menu@2.1.6(react-dom@19.0.0(react@19.0.0))(react@19.0.0)': 2670 2632 dependencies: 2671 2633 '@radix-ui/primitive': 1.1.1 2634 + '@radix-ui/react-collection': 1.1.2(react-dom@19.0.0(react@19.0.0))(react@19.0.0) 2672 2635 '@radix-ui/react-compose-refs': 1.1.1(react@19.0.0) 2673 2636 '@radix-ui/react-context': 1.1.1(react@19.0.0) 2637 + '@radix-ui/react-direction': 1.1.0(react@19.0.0) 2674 2638 '@radix-ui/react-dismissable-layer': 1.1.5(react-dom@19.0.0(react@19.0.0))(react@19.0.0) 2675 2639 '@radix-ui/react-focus-guards': 1.1.1(react@19.0.0) 2676 2640 '@radix-ui/react-focus-scope': 1.1.2(react-dom@19.0.0(react@19.0.0))(react@19.0.0) ··· 2679 2643 '@radix-ui/react-portal': 1.1.4(react-dom@19.0.0(react@19.0.0))(react@19.0.0) 2680 2644 '@radix-ui/react-presence': 1.1.2(react-dom@19.0.0(react@19.0.0))(react@19.0.0) 2681 2645 '@radix-ui/react-primitive': 2.0.2(react-dom@19.0.0(react@19.0.0))(react@19.0.0) 2646 + '@radix-ui/react-roving-focus': 1.1.2(react-dom@19.0.0(react@19.0.0))(react@19.0.0) 2682 2647 '@radix-ui/react-slot': 1.1.2(react@19.0.0) 2683 - '@radix-ui/react-use-controllable-state': 1.1.0(react@19.0.0) 2648 + '@radix-ui/react-use-callback-ref': 1.1.0(react@19.0.0) 2684 2649 aria-hidden: 1.2.4 2685 2650 react: 19.0.0 2686 2651 react-dom: 19.0.0(react@19.0.0) 2687 2652 react-remove-scroll: 2.6.3(react@19.0.0) 2688 2653 2689 - '@radix-ui/react-popper@1.2.1(react-dom@19.0.0(react@19.0.0))(react@19.0.0)': 2654 + '@radix-ui/react-popover@1.1.6(react-dom@19.0.0(react@19.0.0))(react@19.0.0)': 2690 2655 dependencies: 2691 - '@floating-ui/react-dom': 2.1.2(react-dom@19.0.0(react@19.0.0))(react@19.0.0) 2692 - '@radix-ui/react-arrow': 1.1.1(react-dom@19.0.0(react@19.0.0))(react@19.0.0) 2656 + '@radix-ui/primitive': 1.1.1 2693 2657 '@radix-ui/react-compose-refs': 1.1.1(react@19.0.0) 2694 2658 '@radix-ui/react-context': 1.1.1(react@19.0.0) 2695 - '@radix-ui/react-primitive': 2.0.1(react-dom@19.0.0(react@19.0.0))(react@19.0.0) 2696 - '@radix-ui/react-use-callback-ref': 1.1.0(react@19.0.0) 2697 - '@radix-ui/react-use-layout-effect': 1.1.0(react@19.0.0) 2698 - '@radix-ui/react-use-rect': 1.1.0(react@19.0.0) 2699 - '@radix-ui/react-use-size': 1.1.0(react@19.0.0) 2700 - '@radix-ui/rect': 1.1.0 2659 + '@radix-ui/react-dismissable-layer': 1.1.5(react-dom@19.0.0(react@19.0.0))(react@19.0.0) 2660 + '@radix-ui/react-focus-guards': 1.1.1(react@19.0.0) 2661 + '@radix-ui/react-focus-scope': 1.1.2(react-dom@19.0.0(react@19.0.0))(react@19.0.0) 2662 + '@radix-ui/react-id': 1.1.0(react@19.0.0) 2663 + '@radix-ui/react-popper': 1.2.2(react-dom@19.0.0(react@19.0.0))(react@19.0.0) 2664 + '@radix-ui/react-portal': 1.1.4(react-dom@19.0.0(react@19.0.0))(react@19.0.0) 2665 + '@radix-ui/react-presence': 1.1.2(react-dom@19.0.0(react@19.0.0))(react@19.0.0) 2666 + '@radix-ui/react-primitive': 2.0.2(react-dom@19.0.0(react@19.0.0))(react@19.0.0) 2667 + '@radix-ui/react-slot': 1.1.2(react@19.0.0) 2668 + '@radix-ui/react-use-controllable-state': 1.1.0(react@19.0.0) 2669 + aria-hidden: 1.2.4 2701 2670 react: 19.0.0 2702 2671 react-dom: 19.0.0(react@19.0.0) 2672 + react-remove-scroll: 2.6.3(react@19.0.0) 2703 2673 2704 2674 '@radix-ui/react-popper@1.2.2(react-dom@19.0.0(react@19.0.0))(react@19.0.0)': 2705 2675 dependencies: ··· 2716 2686 react: 19.0.0 2717 2687 react-dom: 19.0.0(react@19.0.0) 2718 2688 2719 - '@radix-ui/react-portal@1.1.3(react-dom@19.0.0(react@19.0.0))(react@19.0.0)': 2720 - dependencies: 2721 - '@radix-ui/react-primitive': 2.0.1(react-dom@19.0.0(react@19.0.0))(react@19.0.0) 2722 - '@radix-ui/react-use-layout-effect': 1.1.0(react@19.0.0) 2723 - react: 19.0.0 2724 - react-dom: 19.0.0(react@19.0.0) 2725 - 2726 2689 '@radix-ui/react-portal@1.1.4(react-dom@19.0.0(react@19.0.0))(react@19.0.0)': 2727 2690 dependencies: 2728 2691 '@radix-ui/react-primitive': 2.0.2(react-dom@19.0.0(react@19.0.0))(react@19.0.0) ··· 2737 2700 react: 19.0.0 2738 2701 react-dom: 19.0.0(react@19.0.0) 2739 2702 2740 - '@radix-ui/react-primitive@2.0.1(react-dom@19.0.0(react@19.0.0))(react@19.0.0)': 2741 - dependencies: 2742 - '@radix-ui/react-slot': 1.1.1(react@19.0.0) 2743 - react: 19.0.0 2744 - react-dom: 19.0.0(react@19.0.0) 2745 - 2746 2703 '@radix-ui/react-primitive@2.0.2(react-dom@19.0.0(react@19.0.0))(react@19.0.0)': 2747 2704 dependencies: 2748 2705 '@radix-ui/react-slot': 1.1.2(react@19.0.0) 2749 2706 react: 19.0.0 2750 2707 react-dom: 19.0.0(react@19.0.0) 2751 2708 2752 - '@radix-ui/react-progress@1.1.1(react-dom@19.0.0(react@19.0.0))(react@19.0.0)': 2709 + '@radix-ui/react-progress@1.1.2(react-dom@19.0.0(react@19.0.0))(react@19.0.0)': 2753 2710 dependencies: 2754 2711 '@radix-ui/react-context': 1.1.1(react@19.0.0) 2755 - '@radix-ui/react-primitive': 2.0.1(react-dom@19.0.0(react@19.0.0))(react@19.0.0) 2712 + '@radix-ui/react-primitive': 2.0.2(react-dom@19.0.0(react@19.0.0))(react@19.0.0) 2756 2713 react: 19.0.0 2757 2714 react-dom: 19.0.0(react@19.0.0) 2758 2715 2759 - '@radix-ui/react-roving-focus@1.1.1(react-dom@19.0.0(react@19.0.0))(react@19.0.0)': 2716 + '@radix-ui/react-roving-focus@1.1.2(react-dom@19.0.0(react@19.0.0))(react@19.0.0)': 2760 2717 dependencies: 2761 2718 '@radix-ui/primitive': 1.1.1 2762 - '@radix-ui/react-collection': 1.1.1(react-dom@19.0.0(react@19.0.0))(react@19.0.0) 2719 + '@radix-ui/react-collection': 1.1.2(react-dom@19.0.0(react@19.0.0))(react@19.0.0) 2763 2720 '@radix-ui/react-compose-refs': 1.1.1(react@19.0.0) 2764 2721 '@radix-ui/react-context': 1.1.1(react@19.0.0) 2765 2722 '@radix-ui/react-direction': 1.1.0(react@19.0.0) 2766 2723 '@radix-ui/react-id': 1.1.0(react@19.0.0) 2767 - '@radix-ui/react-primitive': 2.0.1(react-dom@19.0.0(react@19.0.0))(react@19.0.0) 2724 + '@radix-ui/react-primitive': 2.0.2(react-dom@19.0.0(react@19.0.0))(react@19.0.0) 2768 2725 '@radix-ui/react-use-callback-ref': 1.1.0(react@19.0.0) 2769 2726 '@radix-ui/react-use-controllable-state': 1.1.0(react@19.0.0) 2770 2727 react: 19.0.0 2771 2728 react-dom: 19.0.0(react@19.0.0) 2772 2729 2773 - '@radix-ui/react-separator@1.1.1(react-dom@19.0.0(react@19.0.0))(react@19.0.0)': 2730 + '@radix-ui/react-separator@1.1.2(react-dom@19.0.0(react@19.0.0))(react@19.0.0)': 2774 2731 dependencies: 2775 - '@radix-ui/react-primitive': 2.0.1(react-dom@19.0.0(react@19.0.0))(react@19.0.0) 2732 + '@radix-ui/react-primitive': 2.0.2(react-dom@19.0.0(react@19.0.0))(react@19.0.0) 2776 2733 react: 19.0.0 2777 2734 react-dom: 19.0.0(react@19.0.0) 2778 - 2779 - '@radix-ui/react-slot@1.1.1(react@19.0.0)': 2780 - dependencies: 2781 - '@radix-ui/react-compose-refs': 1.1.1(react@19.0.0) 2782 - react: 19.0.0 2783 2735 2784 2736 '@radix-ui/react-slot@1.1.2(react@19.0.0)': 2785 2737 dependencies: 2786 2738 '@radix-ui/react-compose-refs': 1.1.1(react@19.0.0) 2787 2739 react: 19.0.0 2788 2740 2789 - '@radix-ui/react-tabs@1.1.2(react-dom@19.0.0(react@19.0.0))(react@19.0.0)': 2741 + '@radix-ui/react-tabs@1.1.3(react-dom@19.0.0(react@19.0.0))(react@19.0.0)': 2790 2742 dependencies: 2791 2743 '@radix-ui/primitive': 1.1.1 2792 2744 '@radix-ui/react-context': 1.1.1(react@19.0.0) 2793 2745 '@radix-ui/react-direction': 1.1.0(react@19.0.0) 2794 2746 '@radix-ui/react-id': 1.1.0(react@19.0.0) 2795 2747 '@radix-ui/react-presence': 1.1.2(react-dom@19.0.0(react@19.0.0))(react@19.0.0) 2796 - '@radix-ui/react-primitive': 2.0.1(react-dom@19.0.0(react@19.0.0))(react@19.0.0) 2797 - '@radix-ui/react-roving-focus': 1.1.1(react-dom@19.0.0(react@19.0.0))(react@19.0.0) 2748 + '@radix-ui/react-primitive': 2.0.2(react-dom@19.0.0(react@19.0.0))(react@19.0.0) 2749 + '@radix-ui/react-roving-focus': 1.1.2(react-dom@19.0.0(react@19.0.0))(react@19.0.0) 2798 2750 '@radix-ui/react-use-controllable-state': 1.1.0(react@19.0.0) 2799 2751 react: 19.0.0 2800 2752 react-dom: 19.0.0(react@19.0.0) 2801 2753 2802 - '@radix-ui/react-tooltip@1.1.6(react-dom@19.0.0(react@19.0.0))(react@19.0.0)': 2754 + '@radix-ui/react-tooltip@1.1.8(react-dom@19.0.0(react@19.0.0))(react@19.0.0)': 2803 2755 dependencies: 2804 2756 '@radix-ui/primitive': 1.1.1 2805 2757 '@radix-ui/react-compose-refs': 1.1.1(react@19.0.0) 2806 2758 '@radix-ui/react-context': 1.1.1(react@19.0.0) 2807 - '@radix-ui/react-dismissable-layer': 1.1.3(react-dom@19.0.0(react@19.0.0))(react@19.0.0) 2759 + '@radix-ui/react-dismissable-layer': 1.1.5(react-dom@19.0.0(react@19.0.0))(react@19.0.0) 2808 2760 '@radix-ui/react-id': 1.1.0(react@19.0.0) 2809 - '@radix-ui/react-popper': 1.2.1(react-dom@19.0.0(react@19.0.0))(react@19.0.0) 2810 - '@radix-ui/react-portal': 1.1.3(react-dom@19.0.0(react@19.0.0))(react@19.0.0) 2761 + '@radix-ui/react-popper': 1.2.2(react-dom@19.0.0(react@19.0.0))(react@19.0.0) 2762 + '@radix-ui/react-portal': 1.1.4(react-dom@19.0.0(react@19.0.0))(react@19.0.0) 2811 2763 '@radix-ui/react-presence': 1.1.2(react-dom@19.0.0(react@19.0.0))(react@19.0.0) 2812 - '@radix-ui/react-primitive': 2.0.1(react-dom@19.0.0(react@19.0.0))(react@19.0.0) 2813 - '@radix-ui/react-slot': 1.1.1(react@19.0.0) 2764 + '@radix-ui/react-primitive': 2.0.2(react-dom@19.0.0(react@19.0.0))(react@19.0.0) 2765 + '@radix-ui/react-slot': 1.1.2(react@19.0.0) 2814 2766 '@radix-ui/react-use-controllable-state': 1.1.0(react@19.0.0) 2815 - '@radix-ui/react-visually-hidden': 1.1.1(react-dom@19.0.0(react@19.0.0))(react@19.0.0) 2767 + '@radix-ui/react-visually-hidden': 1.1.2(react-dom@19.0.0(react@19.0.0))(react@19.0.0) 2816 2768 react: 19.0.0 2817 2769 react-dom: 19.0.0(react@19.0.0) 2818 2770 ··· 2844 2796 '@radix-ui/react-use-layout-effect': 1.1.0(react@19.0.0) 2845 2797 react: 19.0.0 2846 2798 2847 - '@radix-ui/react-visually-hidden@1.1.1(react-dom@19.0.0(react@19.0.0))(react@19.0.0)': 2799 + '@radix-ui/react-visually-hidden@1.1.2(react-dom@19.0.0(react@19.0.0))(react@19.0.0)': 2848 2800 dependencies: 2849 - '@radix-ui/react-primitive': 2.0.1(react-dom@19.0.0(react@19.0.0))(react@19.0.0) 2801 + '@radix-ui/react-primitive': 2.0.2(react-dom@19.0.0(react@19.0.0))(react@19.0.0) 2850 2802 react: 19.0.0 2851 2803 react-dom: 19.0.0(react@19.0.0) 2852 2804 ··· 2857 2809 estree-walker: 2.0.2 2858 2810 picomatch: 2.3.1 2859 2811 2860 - '@rollup/rollup-android-arm-eabi@4.30.1': 2812 + '@rollup/rollup-android-arm-eabi@4.34.6': 2861 2813 optional: true 2862 2814 2863 - '@rollup/rollup-android-arm64@4.30.1': 2815 + '@rollup/rollup-android-arm64@4.34.6': 2864 2816 optional: true 2865 2817 2866 - '@rollup/rollup-darwin-arm64@4.30.1': 2818 + '@rollup/rollup-darwin-arm64@4.34.6': 2867 2819 optional: true 2868 2820 2869 - '@rollup/rollup-darwin-x64@4.30.1': 2821 + '@rollup/rollup-darwin-x64@4.34.6': 2870 2822 optional: true 2871 2823 2872 - '@rollup/rollup-freebsd-arm64@4.30.1': 2824 + '@rollup/rollup-freebsd-arm64@4.34.6': 2873 2825 optional: true 2874 2826 2875 - '@rollup/rollup-freebsd-x64@4.30.1': 2827 + '@rollup/rollup-freebsd-x64@4.34.6': 2876 2828 optional: true 2877 2829 2878 - '@rollup/rollup-linux-arm-gnueabihf@4.30.1': 2830 + '@rollup/rollup-linux-arm-gnueabihf@4.34.6': 2879 2831 optional: true 2880 2832 2881 - '@rollup/rollup-linux-arm-musleabihf@4.30.1': 2833 + '@rollup/rollup-linux-arm-musleabihf@4.34.6': 2882 2834 optional: true 2883 2835 2884 - '@rollup/rollup-linux-arm64-gnu@4.30.1': 2836 + '@rollup/rollup-linux-arm64-gnu@4.34.6': 2885 2837 optional: true 2886 2838 2887 - '@rollup/rollup-linux-arm64-musl@4.30.1': 2839 + '@rollup/rollup-linux-arm64-musl@4.34.6': 2888 2840 optional: true 2889 2841 2890 - '@rollup/rollup-linux-loongarch64-gnu@4.30.1': 2842 + '@rollup/rollup-linux-loongarch64-gnu@4.34.6': 2891 2843 optional: true 2892 2844 2893 - '@rollup/rollup-linux-powerpc64le-gnu@4.30.1': 2845 + '@rollup/rollup-linux-powerpc64le-gnu@4.34.6': 2894 2846 optional: true 2895 2847 2896 - '@rollup/rollup-linux-riscv64-gnu@4.30.1': 2848 + '@rollup/rollup-linux-riscv64-gnu@4.34.6': 2897 2849 optional: true 2898 2850 2899 - '@rollup/rollup-linux-s390x-gnu@4.30.1': 2851 + '@rollup/rollup-linux-s390x-gnu@4.34.6': 2900 2852 optional: true 2901 2853 2902 - '@rollup/rollup-linux-x64-gnu@4.30.1': 2854 + '@rollup/rollup-linux-x64-gnu@4.34.6': 2903 2855 optional: true 2904 2856 2905 - '@rollup/rollup-linux-x64-musl@4.30.1': 2857 + '@rollup/rollup-linux-x64-musl@4.34.6': 2906 2858 optional: true 2907 2859 2908 - '@rollup/rollup-win32-arm64-msvc@4.30.1': 2860 + '@rollup/rollup-win32-arm64-msvc@4.34.6': 2909 2861 optional: true 2910 2862 2911 - '@rollup/rollup-win32-ia32-msvc@4.30.1': 2863 + '@rollup/rollup-win32-ia32-msvc@4.34.6': 2912 2864 optional: true 2913 2865 2914 - '@rollup/rollup-win32-x64-msvc@4.30.1': 2866 + '@rollup/rollup-win32-x64-msvc@4.34.6': 2915 2867 optional: true 2916 2868 2917 - '@tanstack/history@1.97.0': {} 2869 + '@tanstack/history@1.99.13': {} 2918 2870 2919 - '@tanstack/react-router@1.97.3(react-dom@19.0.0(react@19.0.0))(react@19.0.0)': 2871 + '@tanstack/react-router@1.104.1(react-dom@19.0.0(react@19.0.0))(react@19.0.0)': 2920 2872 dependencies: 2921 - '@tanstack/history': 1.97.0 2873 + '@tanstack/history': 1.99.13 2922 2874 '@tanstack/react-store': 0.7.0(react-dom@19.0.0(react@19.0.0))(react@19.0.0) 2875 + '@tanstack/router-core': 1.104.1 2923 2876 jsesc: 3.1.0 2924 2877 react: 19.0.0 2925 2878 react-dom: 19.0.0(react@19.0.0) ··· 2933 2886 react-dom: 19.0.0(react@19.0.0) 2934 2887 use-sync-external-store: 1.4.0(react@19.0.0) 2935 2888 2936 - '@tanstack/router-devtools@1.97.3(@tanstack/react-router@1.97.3(react-dom@19.0.0(react@19.0.0))(react@19.0.0))(csstype@3.1.3)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)': 2889 + '@tanstack/router-core@1.104.1': 2937 2890 dependencies: 2938 - '@tanstack/react-router': 1.97.3(react-dom@19.0.0(react@19.0.0))(react@19.0.0) 2891 + '@tanstack/history': 1.99.13 2892 + '@tanstack/store': 0.7.0 2893 + 2894 + '@tanstack/router-devtools@1.104.3(@tanstack/react-router@1.104.1(react-dom@19.0.0(react@19.0.0))(react@19.0.0))(csstype@3.1.3)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)': 2895 + dependencies: 2896 + '@tanstack/react-router': 1.104.1(react-dom@19.0.0(react@19.0.0))(react@19.0.0) 2939 2897 clsx: 2.1.1 2940 2898 goober: 2.1.16(csstype@3.1.3) 2941 2899 react: 19.0.0 2942 2900 react-dom: 19.0.0(react@19.0.0) 2943 - transitivePeerDependencies: 2944 - - csstype 2901 + optionalDependencies: 2902 + csstype: 3.1.3 2945 2903 2946 - '@tanstack/router-generator@1.97.3(@tanstack/react-router@1.97.3(react-dom@19.0.0(react@19.0.0))(react@19.0.0))': 2904 + '@tanstack/router-generator@1.104.1(@tanstack/react-router@1.104.1(react-dom@19.0.0(react@19.0.0))(react@19.0.0))': 2947 2905 dependencies: 2948 - '@tanstack/virtual-file-routes': 1.97.0 2949 - prettier: 3.4.2 2906 + '@tanstack/virtual-file-routes': 1.99.0 2907 + prettier: 3.5.1 2950 2908 tsx: 4.19.2 2951 - zod: 3.24.1 2909 + zod: 3.24.2 2952 2910 optionalDependencies: 2953 - '@tanstack/react-router': 1.97.3(react-dom@19.0.0(react@19.0.0))(react@19.0.0) 2911 + '@tanstack/react-router': 1.104.1(react-dom@19.0.0(react@19.0.0))(react@19.0.0) 2954 2912 2955 - '@tanstack/router-plugin@1.97.3(@tanstack/react-router@1.97.3(react-dom@19.0.0(react@19.0.0))(react@19.0.0))(vite@6.0.7(@types/node@22.10.7)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0))': 2913 + '@tanstack/router-plugin@1.104.1(@tanstack/react-router@1.104.1(react-dom@19.0.0(react@19.0.0))(react@19.0.0))(vite@6.1.0(@types/node@22.13.4)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0))': 2956 2914 dependencies: 2957 - '@babel/core': 7.26.0 2958 - '@babel/generator': 7.26.5 2959 - '@babel/parser': 7.26.5 2960 - '@babel/plugin-syntax-jsx': 7.25.9(@babel/core@7.26.0) 2961 - '@babel/plugin-syntax-typescript': 7.25.9(@babel/core@7.26.0) 2962 - '@babel/template': 7.25.9 2963 - '@babel/traverse': 7.26.5 2964 - '@babel/types': 7.26.5 2965 - '@tanstack/router-generator': 1.97.3(@tanstack/react-router@1.97.3(react-dom@19.0.0(react@19.0.0))(react@19.0.0)) 2966 - '@tanstack/virtual-file-routes': 1.97.0 2915 + '@babel/core': 7.26.8 2916 + '@babel/plugin-syntax-jsx': 7.25.9(@babel/core@7.26.8) 2917 + '@babel/plugin-syntax-typescript': 7.25.9(@babel/core@7.26.8) 2918 + '@babel/template': 7.26.8 2919 + '@babel/traverse': 7.26.8 2920 + '@babel/types': 7.26.8 2921 + '@tanstack/router-generator': 1.104.1(@tanstack/react-router@1.104.1(react-dom@19.0.0(react@19.0.0))(react@19.0.0)) 2922 + '@tanstack/router-utils': 1.102.2 2923 + '@tanstack/virtual-file-routes': 1.99.0 2967 2924 '@types/babel__core': 7.20.5 2968 - '@types/babel__generator': 7.6.8 2969 2925 '@types/babel__template': 7.4.4 2970 2926 '@types/babel__traverse': 7.20.6 2971 - '@types/diff': 6.0.0 2972 - babel-dead-code-elimination: 1.0.8 2973 - chalk: 5.4.1 2927 + babel-dead-code-elimination: 1.0.9 2974 2928 chokidar: 3.6.0 2975 - diff: 7.0.0 2976 - unplugin: 1.16.1 2977 - zod: 3.24.1 2929 + unplugin: 2.2.0 2930 + zod: 3.24.2 2978 2931 optionalDependencies: 2979 - vite: 6.0.7(@types/node@22.10.7)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0) 2932 + '@tanstack/react-router': 1.104.1(react-dom@19.0.0(react@19.0.0))(react@19.0.0) 2933 + vite: 6.1.0(@types/node@22.13.4)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0) 2980 2934 transitivePeerDependencies: 2981 - - '@tanstack/react-router' 2982 2935 - supports-color 2983 2936 2937 + '@tanstack/router-utils@1.102.2': 2938 + dependencies: 2939 + '@babel/generator': 7.26.8 2940 + '@babel/parser': 7.26.8 2941 + ansis: 3.14.0 2942 + diff: 7.0.0 2943 + 2984 2944 '@tanstack/store@0.7.0': {} 2985 2945 2986 - '@tanstack/virtual-file-routes@1.97.0': {} 2946 + '@tanstack/virtual-file-routes@1.99.0': {} 2987 2947 2988 - '@tsparticles/basic@3.7.1': 2948 + '@tsparticles/basic@3.8.1': 2989 2949 dependencies: 2990 - '@tsparticles/engine': 3.7.1 2991 - '@tsparticles/move-base': 3.7.1 2992 - '@tsparticles/plugin-hex-color': 3.7.1 2993 - '@tsparticles/plugin-hsl-color': 3.7.1 2994 - '@tsparticles/plugin-rgb-color': 3.7.1 2995 - '@tsparticles/shape-circle': 3.7.1 2996 - '@tsparticles/updater-color': 3.7.1 2997 - '@tsparticles/updater-opacity': 3.7.1 2998 - '@tsparticles/updater-out-modes': 3.7.1 2999 - '@tsparticles/updater-size': 3.7.1 2950 + '@tsparticles/engine': 3.8.1 2951 + '@tsparticles/move-base': 3.8.1 2952 + '@tsparticles/plugin-hex-color': 3.8.1 2953 + '@tsparticles/plugin-hsl-color': 3.8.1 2954 + '@tsparticles/plugin-rgb-color': 3.8.1 2955 + '@tsparticles/shape-circle': 3.8.1 2956 + '@tsparticles/updater-color': 3.8.1 2957 + '@tsparticles/updater-opacity': 3.8.1 2958 + '@tsparticles/updater-out-modes': 3.8.1 2959 + '@tsparticles/updater-size': 3.8.1 3000 2960 3001 - '@tsparticles/confetti@3.7.1': 2961 + '@tsparticles/confetti@3.8.1': 3002 2962 dependencies: 3003 - '@tsparticles/basic': 3.7.1 3004 - '@tsparticles/engine': 3.7.1 3005 - '@tsparticles/plugin-emitters': 3.7.1 3006 - '@tsparticles/plugin-motion': 3.7.1 3007 - '@tsparticles/shape-cards': 3.7.1 3008 - '@tsparticles/shape-emoji': 3.7.1 3009 - '@tsparticles/shape-heart': 3.7.1 3010 - '@tsparticles/shape-image': 3.7.1 3011 - '@tsparticles/shape-polygon': 3.7.1 3012 - '@tsparticles/shape-square': 3.7.1 3013 - '@tsparticles/shape-star': 3.7.1 3014 - '@tsparticles/updater-life': 3.7.1 3015 - '@tsparticles/updater-roll': 3.7.1 3016 - '@tsparticles/updater-rotate': 3.7.1 3017 - '@tsparticles/updater-tilt': 3.7.1 3018 - '@tsparticles/updater-wobble': 3.7.1 2963 + '@tsparticles/basic': 3.8.1 2964 + '@tsparticles/engine': 3.8.1 2965 + '@tsparticles/plugin-emitters': 3.8.1 2966 + '@tsparticles/plugin-motion': 3.8.1 2967 + '@tsparticles/shape-cards': 3.8.1 2968 + '@tsparticles/shape-emoji': 3.8.1 2969 + '@tsparticles/shape-heart': 3.8.1 2970 + '@tsparticles/shape-image': 3.8.1 2971 + '@tsparticles/shape-polygon': 3.8.1 2972 + '@tsparticles/shape-square': 3.8.1 2973 + '@tsparticles/shape-star': 3.8.1 2974 + '@tsparticles/updater-life': 3.8.1 2975 + '@tsparticles/updater-roll': 3.8.1 2976 + '@tsparticles/updater-rotate': 3.8.1 2977 + '@tsparticles/updater-tilt': 3.8.1 2978 + '@tsparticles/updater-wobble': 3.8.1 3019 2979 3020 - '@tsparticles/engine@3.7.1': {} 2980 + '@tsparticles/engine@3.8.1': {} 3021 2981 3022 - '@tsparticles/move-base@3.7.1': 2982 + '@tsparticles/move-base@3.8.1': 3023 2983 dependencies: 3024 - '@tsparticles/engine': 3.7.1 2984 + '@tsparticles/engine': 3.8.1 3025 2985 3026 - '@tsparticles/plugin-emitters@3.7.1': 2986 + '@tsparticles/plugin-emitters@3.8.1': 3027 2987 dependencies: 3028 - '@tsparticles/engine': 3.7.1 2988 + '@tsparticles/engine': 3.8.1 3029 2989 3030 - '@tsparticles/plugin-hex-color@3.7.1': 2990 + '@tsparticles/plugin-hex-color@3.8.1': 3031 2991 dependencies: 3032 - '@tsparticles/engine': 3.7.1 2992 + '@tsparticles/engine': 3.8.1 3033 2993 3034 - '@tsparticles/plugin-hsl-color@3.7.1': 2994 + '@tsparticles/plugin-hsl-color@3.8.1': 3035 2995 dependencies: 3036 - '@tsparticles/engine': 3.7.1 2996 + '@tsparticles/engine': 3.8.1 3037 2997 3038 - '@tsparticles/plugin-motion@3.7.1': 2998 + '@tsparticles/plugin-motion@3.8.1': 3039 2999 dependencies: 3040 - '@tsparticles/engine': 3.7.1 3000 + '@tsparticles/engine': 3.8.1 3041 3001 3042 - '@tsparticles/plugin-rgb-color@3.7.1': 3002 + '@tsparticles/plugin-rgb-color@3.8.1': 3043 3003 dependencies: 3044 - '@tsparticles/engine': 3.7.1 3004 + '@tsparticles/engine': 3.8.1 3045 3005 3046 - '@tsparticles/shape-cards@3.7.1': 3006 + '@tsparticles/shape-cards@3.8.1': 3047 3007 dependencies: 3048 - '@tsparticles/engine': 3.7.1 3008 + '@tsparticles/engine': 3.8.1 3049 3009 3050 - '@tsparticles/shape-circle@3.7.1': 3010 + '@tsparticles/shape-circle@3.8.1': 3051 3011 dependencies: 3052 - '@tsparticles/engine': 3.7.1 3012 + '@tsparticles/engine': 3.8.1 3053 3013 3054 - '@tsparticles/shape-emoji@3.7.1': 3014 + '@tsparticles/shape-emoji@3.8.1': 3055 3015 dependencies: 3056 - '@tsparticles/engine': 3.7.1 3016 + '@tsparticles/engine': 3.8.1 3057 3017 3058 - '@tsparticles/shape-heart@3.7.1': 3018 + '@tsparticles/shape-heart@3.8.1': 3059 3019 dependencies: 3060 - '@tsparticles/engine': 3.7.1 3020 + '@tsparticles/engine': 3.8.1 3061 3021 3062 - '@tsparticles/shape-image@3.7.1': 3022 + '@tsparticles/shape-image@3.8.1': 3063 3023 dependencies: 3064 - '@tsparticles/engine': 3.7.1 3024 + '@tsparticles/engine': 3.8.1 3065 3025 3066 - '@tsparticles/shape-polygon@3.7.1': 3026 + '@tsparticles/shape-polygon@3.8.1': 3067 3027 dependencies: 3068 - '@tsparticles/engine': 3.7.1 3028 + '@tsparticles/engine': 3.8.1 3069 3029 3070 - '@tsparticles/shape-square@3.7.1': 3030 + '@tsparticles/shape-square@3.8.1': 3071 3031 dependencies: 3072 - '@tsparticles/engine': 3.7.1 3032 + '@tsparticles/engine': 3.8.1 3073 3033 3074 - '@tsparticles/shape-star@3.7.1': 3034 + '@tsparticles/shape-star@3.8.1': 3075 3035 dependencies: 3076 - '@tsparticles/engine': 3.7.1 3036 + '@tsparticles/engine': 3.8.1 3077 3037 3078 - '@tsparticles/updater-color@3.7.1': 3038 + '@tsparticles/updater-color@3.8.1': 3079 3039 dependencies: 3080 - '@tsparticles/engine': 3.7.1 3040 + '@tsparticles/engine': 3.8.1 3081 3041 3082 - '@tsparticles/updater-life@3.7.1': 3042 + '@tsparticles/updater-life@3.8.1': 3083 3043 dependencies: 3084 - '@tsparticles/engine': 3.7.1 3044 + '@tsparticles/engine': 3.8.1 3085 3045 3086 - '@tsparticles/updater-opacity@3.7.1': 3046 + '@tsparticles/updater-opacity@3.8.1': 3087 3047 dependencies: 3088 - '@tsparticles/engine': 3.7.1 3048 + '@tsparticles/engine': 3.8.1 3089 3049 3090 - '@tsparticles/updater-out-modes@3.7.1': 3050 + '@tsparticles/updater-out-modes@3.8.1': 3091 3051 dependencies: 3092 - '@tsparticles/engine': 3.7.1 3052 + '@tsparticles/engine': 3.8.1 3093 3053 3094 - '@tsparticles/updater-roll@3.7.1': 3054 + '@tsparticles/updater-roll@3.8.1': 3095 3055 dependencies: 3096 - '@tsparticles/engine': 3.7.1 3056 + '@tsparticles/engine': 3.8.1 3097 3057 3098 - '@tsparticles/updater-rotate@3.7.1': 3058 + '@tsparticles/updater-rotate@3.8.1': 3099 3059 dependencies: 3100 - '@tsparticles/engine': 3.7.1 3060 + '@tsparticles/engine': 3.8.1 3101 3061 3102 - '@tsparticles/updater-size@3.7.1': 3062 + '@tsparticles/updater-size@3.8.1': 3103 3063 dependencies: 3104 - '@tsparticles/engine': 3.7.1 3064 + '@tsparticles/engine': 3.8.1 3105 3065 3106 - '@tsparticles/updater-tilt@3.7.1': 3066 + '@tsparticles/updater-tilt@3.8.1': 3107 3067 dependencies: 3108 - '@tsparticles/engine': 3.7.1 3068 + '@tsparticles/engine': 3.8.1 3109 3069 3110 - '@tsparticles/updater-wobble@3.7.1': 3070 + '@tsparticles/updater-wobble@3.8.1': 3111 3071 dependencies: 3112 - '@tsparticles/engine': 3.7.1 3072 + '@tsparticles/engine': 3.8.1 3113 3073 3114 3074 '@types/babel__core@7.20.5': 3115 3075 dependencies: 3116 - '@babel/parser': 7.26.5 3117 - '@babel/types': 7.26.5 3076 + '@babel/parser': 7.26.8 3077 + '@babel/types': 7.26.8 3118 3078 '@types/babel__generator': 7.6.8 3119 3079 '@types/babel__template': 7.4.4 3120 3080 '@types/babel__traverse': 7.20.6 3121 3081 3122 3082 '@types/babel__generator@7.6.8': 3123 3083 dependencies: 3124 - '@babel/types': 7.26.5 3084 + '@babel/types': 7.26.8 3125 3085 3126 3086 '@types/babel__template@7.4.4': 3127 3087 dependencies: 3128 - '@babel/parser': 7.26.5 3129 - '@babel/types': 7.26.5 3088 + '@babel/parser': 7.26.8 3089 + '@babel/types': 7.26.8 3130 3090 3131 3091 '@types/babel__traverse@7.20.6': 3132 3092 dependencies: 3133 - '@babel/types': 7.26.5 3093 + '@babel/types': 7.26.8 3134 3094 3135 3095 '@types/d3-array@3.2.1': {} 3136 3096 ··· 3156 3116 3157 3117 '@types/d3-timer@3.0.2': {} 3158 3118 3159 - '@types/diff@6.0.0': {} 3119 + '@types/estree@1.0.6': {} 3160 3120 3161 - '@types/estree@1.0.6': {} 3121 + '@types/gensync@1.0.4': {} 3162 3122 3163 - '@types/node@22.10.7': 3123 + '@types/node@22.13.4': 3164 3124 dependencies: 3165 3125 undici-types: 6.20.0 3166 3126 ··· 3176 3136 3177 3137 ansi-styles@6.2.1: {} 3178 3138 3139 + ansis@3.14.0: {} 3140 + 3179 3141 any-promise@1.3.0: {} 3180 3142 3181 3143 anymatch@3.1.3: ··· 3189 3151 dependencies: 3190 3152 tslib: 2.8.1 3191 3153 3192 - autoprefixer@10.4.20(postcss@8.5.1): 3154 + autoprefixer@10.4.20(postcss@8.5.2): 3193 3155 dependencies: 3194 3156 browserslist: 4.24.4 3195 - caniuse-lite: 1.0.30001695 3157 + caniuse-lite: 1.0.30001699 3196 3158 fraction.js: 4.3.7 3197 3159 normalize-range: 0.1.2 3198 3160 picocolors: 1.1.1 3199 - postcss: 8.5.1 3161 + postcss: 8.5.2 3200 3162 postcss-value-parser: 4.2.0 3201 3163 3202 - babel-dead-code-elimination@1.0.8: 3164 + babel-dead-code-elimination@1.0.9: 3203 3165 dependencies: 3204 - '@babel/core': 7.26.0 3205 - '@babel/parser': 7.26.5 3206 - '@babel/traverse': 7.26.5 3207 - '@babel/types': 7.26.5 3166 + '@babel/core': 7.26.8 3167 + '@babel/parser': 7.26.8 3168 + '@babel/traverse': 7.26.8 3169 + '@babel/types': 7.26.8 3208 3170 transitivePeerDependencies: 3209 3171 - supports-color 3210 3172 3211 - babel-plugin-transform-hook-names@1.0.2(@babel/core@7.26.0): 3173 + babel-plugin-transform-hook-names@1.0.2(@babel/core@7.26.8): 3212 3174 dependencies: 3213 - '@babel/core': 7.26.0 3175 + '@babel/core': 7.26.8 3214 3176 3215 3177 balanced-match@1.0.2: {} 3216 3178 ··· 3228 3190 3229 3191 browserslist@4.24.4: 3230 3192 dependencies: 3231 - caniuse-lite: 1.0.30001695 3232 - electron-to-chromium: 1.5.83 3193 + caniuse-lite: 1.0.30001699 3194 + electron-to-chromium: 1.5.99 3233 3195 node-releases: 2.0.19 3234 3196 update-browserslist-db: 1.1.2(browserslist@4.24.4) 3235 3197 3236 3198 camelcase-css@2.0.1: {} 3237 3199 3238 - caniuse-lite@1.0.30001695: {} 3239 - 3240 - chalk@5.4.1: {} 3200 + caniuse-lite@1.0.30001699: {} 3241 3201 3242 3202 chokidar@3.6.0: 3243 3203 dependencies: ··· 3364 3324 3365 3325 eastasianwidth@0.2.0: {} 3366 3326 3367 - electron-to-chromium@1.5.83: {} 3327 + electron-to-chromium@1.5.99: {} 3368 3328 3369 3329 emoji-regex@8.0.0: {} 3370 3330 ··· 3445 3405 merge2: 1.4.1 3446 3406 micromatch: 4.0.8 3447 3407 3448 - fastq@1.18.0: 3408 + fastq@1.19.0: 3449 3409 dependencies: 3450 3410 reusify: 1.0.4 3451 3411 ··· 3469 3429 3470 3430 get-nonce@1.0.1: {} 3471 3431 3472 - get-tsconfig@4.8.1: 3432 + get-tsconfig@4.10.0: 3473 3433 dependencies: 3474 3434 resolve-pkg-maps: 1.0.0 3475 3435 ··· 3502 3462 3503 3463 he@1.2.0: {} 3504 3464 3505 - html-to-image@1.11.11: {} 3465 + html-to-image@1.11.13: {} 3506 3466 3507 3467 internmap@2.0.3: {} 3508 3468 ··· 3562 3522 dependencies: 3563 3523 react: 19.0.0 3564 3524 3565 - magic-string@0.30.5: 3525 + magic-string@0.30.17: 3566 3526 dependencies: 3567 3527 '@jridgewell/sourcemap-codec': 1.5.0 3568 3528 ··· 3627 3587 3628 3588 pirates@4.0.6: {} 3629 3589 3630 - postcss-import@15.1.0(postcss@8.5.1): 3590 + postcss-import@15.1.0(postcss@8.5.2): 3631 3591 dependencies: 3632 - postcss: 8.5.1 3592 + postcss: 8.5.2 3633 3593 postcss-value-parser: 4.2.0 3634 3594 read-cache: 1.0.0 3635 3595 resolve: 1.22.10 3636 3596 3637 - postcss-js@4.0.1(postcss@8.5.1): 3597 + postcss-js@4.0.1(postcss@8.5.2): 3638 3598 dependencies: 3639 3599 camelcase-css: 2.0.1 3640 - postcss: 8.5.1 3600 + postcss: 8.5.2 3641 3601 3642 - postcss-load-config@4.0.2(postcss@8.5.1): 3602 + postcss-load-config@4.0.2(postcss@8.5.2): 3643 3603 dependencies: 3644 3604 lilconfig: 3.1.3 3645 3605 yaml: 2.7.0 3646 3606 optionalDependencies: 3647 - postcss: 8.5.1 3607 + postcss: 8.5.2 3648 3608 3649 - postcss-nested@6.2.0(postcss@8.5.1): 3609 + postcss-nested@6.2.0(postcss@8.5.2): 3650 3610 dependencies: 3651 - postcss: 8.5.1 3611 + postcss: 8.5.2 3652 3612 postcss-selector-parser: 6.1.2 3653 3613 3654 3614 postcss-selector-parser@6.1.2: ··· 3658 3618 3659 3619 postcss-value-parser@4.2.0: {} 3660 3620 3661 - postcss@8.5.1: 3621 + postcss@8.5.2: 3662 3622 dependencies: 3663 3623 nanoid: 3.3.8 3664 3624 picocolors: 1.1.1 ··· 3666 3626 3667 3627 preact@10.25.4: {} 3668 3628 3669 - prettier@3.4.2: {} 3629 + prettier@3.5.1: {} 3670 3630 3671 3631 prop-types@15.8.1: 3672 3632 dependencies: ··· 3690 3650 react: 19.0.0 3691 3651 react-style-singleton: 2.2.3(react@19.0.0) 3692 3652 tslib: 2.8.1 3693 - 3694 - react-remove-scroll@2.6.2(react@19.0.0): 3695 - dependencies: 3696 - react: 19.0.0 3697 - react-remove-scroll-bar: 2.3.8(react@19.0.0) 3698 - react-style-singleton: 2.2.3(react@19.0.0) 3699 - tslib: 2.8.1 3700 - use-callback-ref: 1.3.3(react@19.0.0) 3701 - use-sidecar: 1.1.3(react@19.0.0) 3702 3653 3703 3654 react-remove-scroll@2.6.3(react@19.0.0): 3704 3655 dependencies: ··· 3771 3722 3772 3723 reusify@1.0.4: {} 3773 3724 3774 - rollup@4.30.1: 3725 + rollup@4.34.6: 3775 3726 dependencies: 3776 3727 '@types/estree': 1.0.6 3777 3728 optionalDependencies: 3778 - '@rollup/rollup-android-arm-eabi': 4.30.1 3779 - '@rollup/rollup-android-arm64': 4.30.1 3780 - '@rollup/rollup-darwin-arm64': 4.30.1 3781 - '@rollup/rollup-darwin-x64': 4.30.1 3782 - '@rollup/rollup-freebsd-arm64': 4.30.1 3783 - '@rollup/rollup-freebsd-x64': 4.30.1 3784 - '@rollup/rollup-linux-arm-gnueabihf': 4.30.1 3785 - '@rollup/rollup-linux-arm-musleabihf': 4.30.1 3786 - '@rollup/rollup-linux-arm64-gnu': 4.30.1 3787 - '@rollup/rollup-linux-arm64-musl': 4.30.1 3788 - '@rollup/rollup-linux-loongarch64-gnu': 4.30.1 3789 - '@rollup/rollup-linux-powerpc64le-gnu': 4.30.1 3790 - '@rollup/rollup-linux-riscv64-gnu': 4.30.1 3791 - '@rollup/rollup-linux-s390x-gnu': 4.30.1 3792 - '@rollup/rollup-linux-x64-gnu': 4.30.1 3793 - '@rollup/rollup-linux-x64-musl': 4.30.1 3794 - '@rollup/rollup-win32-arm64-msvc': 4.30.1 3795 - '@rollup/rollup-win32-ia32-msvc': 4.30.1 3796 - '@rollup/rollup-win32-x64-msvc': 4.30.1 3729 + '@rollup/rollup-android-arm-eabi': 4.34.6 3730 + '@rollup/rollup-android-arm64': 4.34.6 3731 + '@rollup/rollup-darwin-arm64': 4.34.6 3732 + '@rollup/rollup-darwin-x64': 4.34.6 3733 + '@rollup/rollup-freebsd-arm64': 4.34.6 3734 + '@rollup/rollup-freebsd-x64': 4.34.6 3735 + '@rollup/rollup-linux-arm-gnueabihf': 4.34.6 3736 + '@rollup/rollup-linux-arm-musleabihf': 4.34.6 3737 + '@rollup/rollup-linux-arm64-gnu': 4.34.6 3738 + '@rollup/rollup-linux-arm64-musl': 4.34.6 3739 + '@rollup/rollup-linux-loongarch64-gnu': 4.34.6 3740 + '@rollup/rollup-linux-powerpc64le-gnu': 4.34.6 3741 + '@rollup/rollup-linux-riscv64-gnu': 4.34.6 3742 + '@rollup/rollup-linux-s390x-gnu': 4.34.6 3743 + '@rollup/rollup-linux-x64-gnu': 4.34.6 3744 + '@rollup/rollup-linux-x64-musl': 4.34.6 3745 + '@rollup/rollup-win32-arm64-msvc': 4.34.6 3746 + '@rollup/rollup-win32-ia32-msvc': 4.34.6 3747 + '@rollup/rollup-win32-x64-msvc': 4.34.6 3797 3748 fsevents: 2.3.3 3798 3749 3799 3750 run-parallel@1.2.0: ··· 3811 3762 shebang-regex@3.0.0: {} 3812 3763 3813 3764 signal-exit@4.1.0: {} 3765 + 3766 + simple-code-frame@1.3.0: 3767 + dependencies: 3768 + kolorist: 1.8.0 3814 3769 3815 3770 simple-icons@13.21.0: {} 3816 3771 ··· 3874 3829 normalize-path: 3.0.0 3875 3830 object-hash: 3.0.0 3876 3831 picocolors: 1.1.1 3877 - postcss: 8.5.1 3878 - postcss-import: 15.1.0(postcss@8.5.1) 3879 - postcss-js: 4.0.1(postcss@8.5.1) 3880 - postcss-load-config: 4.0.2(postcss@8.5.1) 3881 - postcss-nested: 6.2.0(postcss@8.5.1) 3832 + postcss: 8.5.2 3833 + postcss-import: 15.1.0(postcss@8.5.2) 3834 + postcss-js: 4.0.1(postcss@8.5.2) 3835 + postcss-load-config: 4.0.2(postcss@8.5.2) 3836 + postcss-nested: 6.2.0(postcss@8.5.2) 3882 3837 postcss-selector-parser: 6.1.2 3883 3838 resolve: 1.22.10 3884 3839 sucrase: 3.35.0 ··· 3908 3863 tsx@4.19.2: 3909 3864 dependencies: 3910 3865 esbuild: 0.23.1 3911 - get-tsconfig: 4.8.1 3866 + get-tsconfig: 4.10.0 3912 3867 optionalDependencies: 3913 3868 fsevents: 2.3.3 3914 3869 ··· 3916 3871 3917 3872 undici-types@6.20.0: {} 3918 3873 3919 - unplugin@1.16.1: 3874 + unplugin@2.2.0: 3920 3875 dependencies: 3921 3876 acorn: 8.14.0 3922 3877 webpack-virtual-modules: 0.6.2 ··· 3961 3916 d3-time: 3.1.0 3962 3917 d3-timer: 3.0.1 3963 3918 3964 - vite@6.0.7(@types/node@22.10.7)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0): 3919 + vite-prerender-plugin@0.5.6: 3920 + dependencies: 3921 + magic-string: 0.30.17 3922 + node-html-parser: 6.1.13 3923 + simple-code-frame: 1.3.0 3924 + source-map: 0.7.4 3925 + stack-trace: 1.0.0-pre2 3926 + 3927 + vite@6.1.0(@types/node@22.13.4)(jiti@1.21.7)(tsx@4.19.2)(yaml@2.7.0): 3965 3928 dependencies: 3966 3929 esbuild: 0.24.2 3967 - postcss: 8.5.1 3968 - rollup: 4.30.1 3930 + postcss: 8.5.2 3931 + rollup: 4.34.6 3969 3932 optionalDependencies: 3970 - '@types/node': 22.10.7 3933 + '@types/node': 22.13.4 3971 3934 fsevents: 2.3.3 3972 3935 jiti: 1.21.7 3973 3936 tsx: 4.19.2 ··· 3995 3958 3996 3959 yaml@2.7.0: {} 3997 3960 3998 - zod@3.24.1: {} 3961 + zod@3.24.2: {}
+12
public/oauth/client-metadata.json
··· 1 + { 2 + "redirect_uris": ["https://atp.tools/auth/callback"], 3 + "response_types": ["code"], 4 + "grant_types": ["authorization_code", "refresh_token"], 5 + "scope": "atproto transition:generic", 6 + "token_endpoint_auth_method": "none", 7 + "application_type": "web", 8 + "client_id": "https://atp.tools/oauth/client-metadata.json", 9 + "client_name": "atproto tools", 10 + "client_uri": "https://atp.tools", 11 + "dpop_bound_access_tokens": true 12 + }
+135
src/components/auth/accountsManagementModal.tsx
··· 1 + import { QtContext, resolveBskyUser } from "@/providers/qtprovider"; 2 + import { Avatar, AvatarImage, AvatarFallback } from "@/components/ui/avatar"; 3 + import { Trash2 } from "lucide-react"; 4 + import { useContext, useState, useEffect } from "preact/hooks"; 5 + import { Button } from "@/components/ui/button"; 6 + import { 7 + DialogFooter, 8 + DialogHeader, 9 + Dialog, 10 + DialogContent, 11 + DialogTitle, 12 + DialogDescription, 13 + } from "../ui/dialog"; 14 + export function AccountsManagementModal({ 15 + isOpen, 16 + onClose, 17 + }: { 18 + isOpen: boolean; 19 + onClose: () => void; 20 + }) { 21 + const qt = useContext(QtContext); 22 + const [userList, setUserList] = useState< 23 + Array<{ 24 + name: string; 25 + did: string; 26 + avatar: string; 27 + }> 28 + >([]); 29 + const [isDeleting, setIsDeleting] = useState(false); 30 + 31 + // Handle user list fetching 32 + useEffect(() => { 33 + async function fetchUsers() { 34 + if (!qt?.accounts.length) return; 35 + 36 + setUserList([]); // Reset list before fetching 37 + 38 + for (const did of qt.accounts) { 39 + try { 40 + const { data } = await resolveBskyUser(did, qt); 41 + if (data && data.displayName) { 42 + setUserList((prev) => [ 43 + ...prev, 44 + { 45 + name: data.displayName || "", 46 + did: did, 47 + avatar: data.avatar || "", 48 + }, 49 + ]); 50 + } 51 + } catch (err) { 52 + console.error(`Failed to fetch user data for ${did}:`, err); 53 + } 54 + } 55 + } 56 + 57 + if (isOpen) { 58 + fetchUsers(); 59 + } 60 + }, [isOpen, qt?.accounts]); 61 + 62 + const handleRemoveAccount = async (did: string) => { 63 + if (!qt?.client) return; 64 + setIsDeleting(true); 65 + try { 66 + await qt.client.logout(did as `did:${string}`); 67 + } catch (error) { 68 + console.error("Failed to remove account:", error); 69 + } finally { 70 + setIsDeleting(false); 71 + } 72 + }; 73 + 74 + return ( 75 + <Dialog 76 + open={isOpen} 77 + onOpenChange={(open) => { 78 + if (!isDeleting && !open) { 79 + onClose(); 80 + } 81 + }} 82 + > 83 + <DialogContent 84 + onInteractOutside={(e) => { 85 + if (isDeleting) { 86 + e.preventDefault(); 87 + } 88 + }} 89 + > 90 + <DialogHeader> 91 + <DialogTitle>Manage Accounts</DialogTitle> 92 + <DialogDescription> 93 + View and manage your connected accounts 94 + </DialogDescription> 95 + </DialogHeader> 96 + <div className="flex flex-col gap-4 py-4"> 97 + {userList.map((user) => ( 98 + <div 99 + key={user.did} 100 + className="flex items-center justify-between p-2 rounded-lg hover:bg-accent" 101 + > 102 + <div className="flex items-center gap-3"> 103 + <Avatar className="h-10 w-10 rounded-lg"> 104 + <AvatarImage src={user.avatar} alt={user.name} /> 105 + <AvatarFallback className="rounded-lg"> 106 + {user.name.slice(0, 2)} 107 + </AvatarFallback> 108 + </Avatar> 109 + <div className="grid flex-1 text-left text-sm leading-tight"> 110 + <span className="font-semibold">{user.name}</span> 111 + <span className="text-muted-foreground">{user.did}</span> 112 + </div> 113 + </div> 114 + <Button 115 + variant="ghost" 116 + size="icon" 117 + className="text-destructive hover:text-destructive hover:bg-destructive/10" 118 + disabled={isDeleting} 119 + onClick={() => handleRemoveAccount(user.did)} 120 + aria-label={`Remove account ${user.name}`} 121 + > 122 + <Trash2 className="h-4 w-4" /> 123 + </Button> 124 + </div> 125 + ))} 126 + </div> 127 + <DialogFooter> 128 + <Button variant="outline" disabled={isDeleting} onClick={onClose}> 129 + Close 130 + </Button> 131 + </DialogFooter> 132 + </DialogContent> 133 + </Dialog> 134 + ); 135 + }
+134
src/components/auth/navUser.tsx
··· 1 + import { AtSign, BadgeCheck, ChevronsUpDown, LogOut } from "lucide-react"; 2 + 3 + import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar"; 4 + import { 5 + DropdownMenu, 6 + DropdownMenuContent, 7 + DropdownMenuGroup, 8 + DropdownMenuItem, 9 + DropdownMenuLabel, 10 + DropdownMenuSeparator, 11 + DropdownMenuTrigger, 12 + } from "@/components/ui/dropdown-menu"; 13 + import { SidebarMenuButton, useSidebar } from "@/components/ui/sidebar"; 14 + import { QtContext, resolveBskyUser } from "@/providers/qtprovider"; 15 + import { useContext, useEffect, useState } from "preact/hooks"; 16 + import { Link, redirect } from "@tanstack/react-router"; 17 + import { UserSwitcher } from "./userSwitcher"; 18 + 19 + export function NavUser() { 20 + const { isMobile } = useSidebar(); 21 + let qt = useContext(QtContext); 22 + if (!qt) return null; 23 + 24 + const [user, setUser] = useState({ 25 + name: "John Doe", 26 + did: "", 27 + avatar: "https://example.com/avatar.jpg", 28 + }); 29 + 30 + useEffect(() => { 31 + async function fetchUser() { 32 + if (!qt?.client?.currentAgent) return; 33 + 34 + try { 35 + const { data } = await resolveBskyUser(qt.client.currentAgent.sub, qt); 36 + setUser({ 37 + name: data.displayName || data.handle, 38 + did: data.did, 39 + avatar: data.avatar || "", 40 + }); 41 + } catch (err) { 42 + console.error("Failed to fetch user data:", err); 43 + } 44 + } 45 + 46 + fetchUser(); 47 + }, [qt]); 48 + 49 + if (!user.did) 50 + return ( 51 + <Link to="/auth/login"> 52 + <SidebarMenuButton 53 + size="lg" 54 + className="data-[state=open]:bg-sidebar-accent data-[state=open]:text-sidebar-accent-foreground border" 55 + > 56 + <Avatar className="h-8 w-8 rounded-full"> 57 + <AvatarImage src={user.avatar} alt={user.name} /> 58 + <AvatarFallback className="rounded-lg"> 59 + <AtSign height={18} width={18} /> 60 + </AvatarFallback> 61 + </Avatar> 62 + Log in to @tools 63 + </SidebarMenuButton> 64 + </Link> 65 + ); 66 + 67 + return ( 68 + <> 69 + <DropdownMenu> 70 + <DropdownMenuTrigger asChild> 71 + <SidebarMenuButton 72 + size="lg" 73 + className="data-[state=open]:bg-sidebar-accent data-[state=open]:text-sidebar-accent-foreground border" 74 + > 75 + <Avatar className="h-8 w-8 rounded-full"> 76 + <AvatarImage src={user.avatar} alt={user.name} /> 77 + <AvatarFallback className="rounded-lg">CN</AvatarFallback> 78 + </Avatar> 79 + <div className="grid flex-1 text-left text-sm leading-tight"> 80 + <span className="truncate font-semibold">{user.name}</span> 81 + <span className="truncate text-muted-foreground">{user.did}</span> 82 + </div> 83 + <ChevronsUpDown className="ml-auto size-4" /> 84 + </SidebarMenuButton> 85 + </DropdownMenuTrigger> 86 + <DropdownMenuContent 87 + className="w-[--radix-dropdown-menu-trigger-width] min-w-56 rounded-lg" 88 + side={isMobile ? "bottom" : "right"} 89 + align="end" 90 + sideOffset={4} 91 + > 92 + <DropdownMenuLabel className="p-0 font-normal"> 93 + <div className="flex items-center gap-2 px-1 py-1.5 text-left text-sm"> 94 + <Avatar className="h-8 w-8 rounded-lg"> 95 + <AvatarImage src={user.avatar} alt={user.name} /> 96 + <AvatarFallback className="rounded-lg">CN</AvatarFallback> 97 + </Avatar> 98 + <div className="grid flex-1 text-left text-sm leading-tight"> 99 + <span className="truncate font-semibold">{user.name}</span> 100 + <span className="truncate text-muted-foreground"> 101 + {user.did} 102 + </span> 103 + </div> 104 + </div> 105 + </DropdownMenuLabel> 106 + <DropdownMenuSeparator /> 107 + <DropdownMenuGroup> 108 + <Link to="/at:/$handle" params={{ handle: user.did }}> 109 + <DropdownMenuItem className="cursor-pointer"> 110 + <BadgeCheck /> 111 + Profile 112 + </DropdownMenuItem> 113 + </Link> 114 + </DropdownMenuGroup> 115 + <DropdownMenuItem> 116 + <UserSwitcher /> 117 + </DropdownMenuItem> 118 + <DropdownMenuSeparator /> 119 + <DropdownMenuItem 120 + onClick={() => { 121 + qt.client.logout(user.did as `did:${string}`); 122 + redirect({ to: "/" }); 123 + // force reload in 250ms to avoid rollback 124 + setTimeout(() => window.location.reload(), 250); 125 + }} 126 + > 127 + <LogOut /> 128 + Log out 129 + </DropdownMenuItem> 130 + </DropdownMenuContent> 131 + </DropdownMenu> 132 + </> 133 + ); 134 + }
+136
src/components/auth/userSwitcher.tsx
··· 1 + import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar"; 2 + import { 3 + DropdownMenu, 4 + DropdownMenuContent, 5 + DropdownMenuGroup, 6 + DropdownMenuItem, 7 + DropdownMenuSeparator, 8 + DropdownMenuTrigger, 9 + } from "@/components/ui/dropdown-menu"; 10 + import { useSidebar } from "@/components/ui/sidebar"; 11 + import { QtContext, resolveBskyUser } from "@/providers/qtprovider"; 12 + import { ChevronRight, Trash2, User, User2, Users } from "lucide-react"; 13 + import { useContext, useEffect, useState } from "preact/hooks"; 14 + import { Button } from "../ui/button"; 15 + import { Link } from "@tanstack/react-router"; 16 + 17 + export function UserSwitcher() { 18 + const { isMobile } = useSidebar(); 19 + let qt = useContext(QtContext); 20 + if (!qt) return null; 21 + 22 + const [userList, setUserList] = useState< 23 + { name: string; did: string; avatar: string }[] 24 + >([]); 25 + 26 + const [isDeleting, setIsDeleting] = useState(false); 27 + 28 + const handleRemoveAccount = async (did: string) => { 29 + if (!qt?.client) return; 30 + setIsDeleting(true); 31 + try { 32 + await qt.client.logout(did as `did:${string}`); 33 + } catch (error) { 34 + console.error("Failed to remove account:", error); 35 + } finally { 36 + setIsDeleting(false); 37 + } 38 + }; 39 + 40 + const refreshUserList = async () => { 41 + setUserList([]); 42 + if (!qt?.client?.currentAgent?.sub) return; 43 + 44 + try { 45 + qt.accounts.forEach(async (did) => { 46 + let { data } = await resolveBskyUser(did, qt); 47 + if (data && data.displayName) 48 + setUserList((ulist) => [ 49 + ...(ulist || []), 50 + { 51 + name: data.displayName || "", 52 + did: did, 53 + avatar: data.avatar || "", 54 + }, 55 + ]); 56 + }); 57 + } catch (err) { 58 + console.error("Failed to fetch user data:", err); 59 + } 60 + }; 61 + 62 + useEffect(() => { 63 + refreshUserList(); 64 + }, [qt]); 65 + 66 + return ( 67 + <DropdownMenu> 68 + <DropdownMenuTrigger asChild> 69 + <div className="flex justify-between items-center w-full"> 70 + <div className="flex items-center gap-2"> 71 + <User /> 72 + Switch Accounts 73 + </div> 74 + <ChevronRight /> 75 + </div> 76 + </DropdownMenuTrigger> 77 + <DropdownMenuContent 78 + className="w-[--radix-dropdown-menu-trigger-width] min-w-56 rounded-lg" 79 + side={isMobile ? "bottom" : "right"} 80 + align="end" 81 + sideOffset={4} 82 + > 83 + <DropdownMenuGroup> 84 + {userList.map((user) => ( 85 + <DropdownMenuItem 86 + key={user.did} 87 + onClick={() => { 88 + qt.client.switchAccount(user.did as `did:${string}`); 89 + }} 90 + > 91 + <Avatar className="h-8 w-8 rounded-lg"> 92 + <AvatarImage src={user.avatar} alt={user.name} /> 93 + <AvatarFallback className="rounded-lg">CN</AvatarFallback> 94 + </Avatar> 95 + <div className="grid flex-1 text-left text-sm leading-tight"> 96 + <span className="truncate font-semibold">{user.name}</span> 97 + <span className="truncate text-muted-foreground"> 98 + {user.did} 99 + </span> 100 + </div> 101 + <Button 102 + variant="ghost" 103 + size="icon" 104 + className="text-destructive hover:text-destructive hover:bg-destructive/10" 105 + disabled={isDeleting} 106 + onClick={() => handleRemoveAccount(user.did)} 107 + aria-label={`Remove account ${user.name}`} 108 + > 109 + <Trash2 className="h-4 w-4" /> 110 + </Button> 111 + </DropdownMenuItem> 112 + ))} 113 + </DropdownMenuGroup> 114 + <DropdownMenuSeparator /> 115 + <DropdownMenuGroup> 116 + <DropdownMenuItem 117 + onClick={(event) => { 118 + event.preventDefault(); 119 + qt.openManagementModal(); 120 + console.log("Opening mgmt modal"); 121 + }} 122 + > 123 + <User2 /> 124 + Manage Accounts 125 + </DropdownMenuItem> 126 + <Link to="/auth/login" className="flex items-center gap-2"> 127 + <DropdownMenuItem> 128 + <Users /> 129 + Log in to another account 130 + </DropdownMenuItem> 131 + </Link> 132 + </DropdownMenuGroup> 133 + </DropdownMenuContent> 134 + </DropdownMenu> 135 + ); 136 + }
+2
src/components/sidebar.tsx
··· 18 18 import { Link } from "@tanstack/react-router"; 19 19 import { ForwardRefExoticComponent, ReactNode } from "preact/compat"; 20 20 import { FontPicker } from "./fontPicker"; 21 + import { NavUser } from "./auth/navUser"; 21 22 22 23 type BaseMenuItem = { 23 24 url: string; ··· 105 106 </SidebarGroup> 106 107 </SidebarContent> 107 108 <SidebarFooter> 109 + <NavUser /> 108 110 <div className="flex min-w-full"> 109 111 <FontPicker /> 110 112 <ColorToggle />
+48
src/components/ui/avatar.tsx
··· 1 + import * as React from "react" 2 + import * as AvatarPrimitive from "@radix-ui/react-avatar" 3 + 4 + import { cn } from "@/lib/utils" 5 + 6 + const Avatar = React.forwardRef< 7 + React.ElementRef<typeof AvatarPrimitive.Root>, 8 + React.ComponentPropsWithoutRef<typeof AvatarPrimitive.Root> 9 + >(({ className, ...props }, ref) => ( 10 + <AvatarPrimitive.Root 11 + ref={ref} 12 + className={cn( 13 + "relative flex h-10 w-10 shrink-0 overflow-hidden rounded-full", 14 + className 15 + )} 16 + {...props} 17 + /> 18 + )) 19 + Avatar.displayName = AvatarPrimitive.Root.displayName 20 + 21 + const AvatarImage = React.forwardRef< 22 + React.ElementRef<typeof AvatarPrimitive.Image>, 23 + React.ComponentPropsWithoutRef<typeof AvatarPrimitive.Image> 24 + >(({ className, ...props }, ref) => ( 25 + <AvatarPrimitive.Image 26 + ref={ref} 27 + className={cn("aspect-square h-full w-full", className)} 28 + {...props} 29 + /> 30 + )) 31 + AvatarImage.displayName = AvatarPrimitive.Image.displayName 32 + 33 + const AvatarFallback = React.forwardRef< 34 + React.ElementRef<typeof AvatarPrimitive.Fallback>, 35 + React.ComponentPropsWithoutRef<typeof AvatarPrimitive.Fallback> 36 + >(({ className, ...props }, ref) => ( 37 + <AvatarPrimitive.Fallback 38 + ref={ref} 39 + className={cn( 40 + "flex h-full w-full items-center justify-center rounded-full bg-muted", 41 + className 42 + )} 43 + {...props} 44 + /> 45 + )) 46 + AvatarFallback.displayName = AvatarPrimitive.Fallback.displayName 47 + 48 + export { Avatar, AvatarImage, AvatarFallback }
+29 -27
src/components/ui/dialog.tsx
··· 1 - import * as React from "react" 2 - import * as DialogPrimitive from "@radix-ui/react-dialog" 3 - import { X } from "lucide-react" 1 + "use client"; 4 2 5 - import { cn } from "@/lib/utils" 3 + import * as React from "react"; 4 + import * as DialogPrimitive from "@radix-ui/react-dialog"; 5 + import { X } from "lucide-react"; 6 6 7 - const Dialog = DialogPrimitive.Root 7 + import { cn } from "@/lib/utils"; 8 8 9 - const DialogTrigger = DialogPrimitive.Trigger 9 + const Dialog = DialogPrimitive.Root; 10 10 11 - const DialogPortal = DialogPrimitive.Portal 11 + const DialogTrigger = DialogPrimitive.Trigger; 12 12 13 - const DialogClose = DialogPrimitive.Close 13 + const DialogPortal = DialogPrimitive.Portal; 14 + 15 + const DialogClose = DialogPrimitive.Close; 14 16 15 17 const DialogOverlay = React.forwardRef< 16 18 React.ElementRef<typeof DialogPrimitive.Overlay>, ··· 20 22 ref={ref} 21 23 className={cn( 22 24 "fixed inset-0 z-50 bg-black/80 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0", 23 - className 25 + className, 24 26 )} 25 27 {...props} 26 28 /> 27 - )) 28 - DialogOverlay.displayName = DialogPrimitive.Overlay.displayName 29 + )); 30 + DialogOverlay.displayName = DialogPrimitive.Overlay.displayName; 29 31 30 32 const DialogContent = React.forwardRef< 31 33 React.ElementRef<typeof DialogPrimitive.Content>, ··· 37 39 ref={ref} 38 40 className={cn( 39 41 "fixed left-[50%] top-[50%] z-50 grid w-full max-w-lg translate-x-[-50%] translate-y-[-50%] gap-4 border bg-background p-6 shadow-lg duration-200 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[state=closed]:slide-out-to-left-1/2 data-[state=closed]:slide-out-to-top-[48%] data-[state=open]:slide-in-from-left-1/2 data-[state=open]:slide-in-from-top-[48%] sm:rounded-lg", 40 - className 42 + className, 41 43 )} 42 44 {...props} 43 45 > ··· 48 50 </DialogPrimitive.Close> 49 51 </DialogPrimitive.Content> 50 52 </DialogPortal> 51 - )) 52 - DialogContent.displayName = DialogPrimitive.Content.displayName 53 + )); 54 + DialogContent.displayName = DialogPrimitive.Content.displayName; 53 55 54 56 const DialogHeader = ({ 55 57 className, ··· 58 60 <div 59 61 className={cn( 60 62 "flex flex-col space-y-1.5 text-center sm:text-left", 61 - className 63 + className, 62 64 )} 63 65 {...props} 64 66 /> 65 - ) 66 - DialogHeader.displayName = "DialogHeader" 67 + ); 68 + DialogHeader.displayName = "DialogHeader"; 67 69 68 70 const DialogFooter = ({ 69 71 className, ··· 72 74 <div 73 75 className={cn( 74 76 "flex flex-col-reverse sm:flex-row sm:justify-end sm:space-x-2", 75 - className 77 + className, 76 78 )} 77 79 {...props} 78 80 /> 79 - ) 80 - DialogFooter.displayName = "DialogFooter" 81 + ); 82 + DialogFooter.displayName = "DialogFooter"; 81 83 82 84 const DialogTitle = React.forwardRef< 83 85 React.ElementRef<typeof DialogPrimitive.Title>, ··· 87 89 ref={ref} 88 90 className={cn( 89 91 "text-lg font-semibold leading-none tracking-tight", 90 - className 92 + className, 91 93 )} 92 94 {...props} 93 95 /> 94 - )) 95 - DialogTitle.displayName = DialogPrimitive.Title.displayName 96 + )); 97 + DialogTitle.displayName = DialogPrimitive.Title.displayName; 96 98 97 99 const DialogDescription = React.forwardRef< 98 100 React.ElementRef<typeof DialogPrimitive.Description>, ··· 103 105 className={cn("text-sm text-muted-foreground", className)} 104 106 {...props} 105 107 /> 106 - )) 107 - DialogDescription.displayName = DialogPrimitive.Description.displayName 108 + )); 109 + DialogDescription.displayName = DialogPrimitive.Description.displayName; 108 110 109 111 export { 110 112 Dialog, 111 113 DialogPortal, 112 114 DialogOverlay, 115 + DialogTrigger, 113 116 DialogClose, 114 - DialogTrigger, 115 117 DialogContent, 116 118 DialogHeader, 117 119 DialogFooter, 118 120 DialogTitle, 119 121 DialogDescription, 120 - } 122 + };
+200
src/components/ui/dropdown-menu.tsx
··· 1 + "use client" 2 + 3 + import * as React from "react" 4 + import * as DropdownMenuPrimitive from "@radix-ui/react-dropdown-menu" 5 + import { Check, ChevronRight, Circle } from "lucide-react" 6 + 7 + import { cn } from "@/lib/utils" 8 + 9 + const DropdownMenu = DropdownMenuPrimitive.Root 10 + 11 + const DropdownMenuTrigger = DropdownMenuPrimitive.Trigger 12 + 13 + const DropdownMenuGroup = DropdownMenuPrimitive.Group 14 + 15 + const DropdownMenuPortal = DropdownMenuPrimitive.Portal 16 + 17 + const DropdownMenuSub = DropdownMenuPrimitive.Sub 18 + 19 + const DropdownMenuRadioGroup = DropdownMenuPrimitive.RadioGroup 20 + 21 + const DropdownMenuSubTrigger = React.forwardRef< 22 + React.ElementRef<typeof DropdownMenuPrimitive.SubTrigger>, 23 + React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.SubTrigger> & { 24 + inset?: boolean 25 + } 26 + >(({ className, inset, children, ...props }, ref) => ( 27 + <DropdownMenuPrimitive.SubTrigger 28 + ref={ref} 29 + className={cn( 30 + "flex cursor-default gap-2 select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none focus:bg-accent data-[state=open]:bg-accent [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0", 31 + inset && "pl-8", 32 + className 33 + )} 34 + {...props} 35 + > 36 + {children} 37 + <ChevronRight className="ml-auto" /> 38 + </DropdownMenuPrimitive.SubTrigger> 39 + )) 40 + DropdownMenuSubTrigger.displayName = 41 + DropdownMenuPrimitive.SubTrigger.displayName 42 + 43 + const DropdownMenuSubContent = React.forwardRef< 44 + React.ElementRef<typeof DropdownMenuPrimitive.SubContent>, 45 + React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.SubContent> 46 + >(({ className, ...props }, ref) => ( 47 + <DropdownMenuPrimitive.SubContent 48 + ref={ref} 49 + className={cn( 50 + "z-50 min-w-[8rem] overflow-hidden rounded-md border bg-popover p-1 text-popover-foreground shadow-lg data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2", 51 + className 52 + )} 53 + {...props} 54 + /> 55 + )) 56 + DropdownMenuSubContent.displayName = 57 + DropdownMenuPrimitive.SubContent.displayName 58 + 59 + const DropdownMenuContent = React.forwardRef< 60 + React.ElementRef<typeof DropdownMenuPrimitive.Content>, 61 + React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Content> 62 + >(({ className, sideOffset = 4, ...props }, ref) => ( 63 + <DropdownMenuPrimitive.Portal> 64 + <DropdownMenuPrimitive.Content 65 + ref={ref} 66 + sideOffset={sideOffset} 67 + className={cn( 68 + "z-50 min-w-[8rem] overflow-hidden rounded-md border bg-popover p-1 text-popover-foreground shadow-md data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2", 69 + className 70 + )} 71 + {...props} 72 + /> 73 + </DropdownMenuPrimitive.Portal> 74 + )) 75 + DropdownMenuContent.displayName = DropdownMenuPrimitive.Content.displayName 76 + 77 + const DropdownMenuItem = React.forwardRef< 78 + React.ElementRef<typeof DropdownMenuPrimitive.Item>, 79 + React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Item> & { 80 + inset?: boolean 81 + } 82 + >(({ className, inset, ...props }, ref) => ( 83 + <DropdownMenuPrimitive.Item 84 + ref={ref} 85 + className={cn( 86 + "relative flex cursor-default select-none items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-none transition-colors focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0", 87 + inset && "pl-8", 88 + className 89 + )} 90 + {...props} 91 + /> 92 + )) 93 + DropdownMenuItem.displayName = DropdownMenuPrimitive.Item.displayName 94 + 95 + const DropdownMenuCheckboxItem = React.forwardRef< 96 + React.ElementRef<typeof DropdownMenuPrimitive.CheckboxItem>, 97 + React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.CheckboxItem> 98 + >(({ className, children, checked, ...props }, ref) => ( 99 + <DropdownMenuPrimitive.CheckboxItem 100 + ref={ref} 101 + className={cn( 102 + "relative flex cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none transition-colors focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50", 103 + className 104 + )} 105 + checked={checked} 106 + {...props} 107 + > 108 + <span className="absolute left-2 flex h-3.5 w-3.5 items-center justify-center"> 109 + <DropdownMenuPrimitive.ItemIndicator> 110 + <Check className="h-4 w-4" /> 111 + </DropdownMenuPrimitive.ItemIndicator> 112 + </span> 113 + {children} 114 + </DropdownMenuPrimitive.CheckboxItem> 115 + )) 116 + DropdownMenuCheckboxItem.displayName = 117 + DropdownMenuPrimitive.CheckboxItem.displayName 118 + 119 + const DropdownMenuRadioItem = React.forwardRef< 120 + React.ElementRef<typeof DropdownMenuPrimitive.RadioItem>, 121 + React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.RadioItem> 122 + >(({ className, children, ...props }, ref) => ( 123 + <DropdownMenuPrimitive.RadioItem 124 + ref={ref} 125 + className={cn( 126 + "relative flex cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none transition-colors focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50", 127 + className 128 + )} 129 + {...props} 130 + > 131 + <span className="absolute left-2 flex h-3.5 w-3.5 items-center justify-center"> 132 + <DropdownMenuPrimitive.ItemIndicator> 133 + <Circle className="h-2 w-2 fill-current" /> 134 + </DropdownMenuPrimitive.ItemIndicator> 135 + </span> 136 + {children} 137 + </DropdownMenuPrimitive.RadioItem> 138 + )) 139 + DropdownMenuRadioItem.displayName = DropdownMenuPrimitive.RadioItem.displayName 140 + 141 + const DropdownMenuLabel = React.forwardRef< 142 + React.ElementRef<typeof DropdownMenuPrimitive.Label>, 143 + React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Label> & { 144 + inset?: boolean 145 + } 146 + >(({ className, inset, ...props }, ref) => ( 147 + <DropdownMenuPrimitive.Label 148 + ref={ref} 149 + className={cn( 150 + "px-2 py-1.5 text-sm font-semibold", 151 + inset && "pl-8", 152 + className 153 + )} 154 + {...props} 155 + /> 156 + )) 157 + DropdownMenuLabel.displayName = DropdownMenuPrimitive.Label.displayName 158 + 159 + const DropdownMenuSeparator = React.forwardRef< 160 + React.ElementRef<typeof DropdownMenuPrimitive.Separator>, 161 + React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Separator> 162 + >(({ className, ...props }, ref) => ( 163 + <DropdownMenuPrimitive.Separator 164 + ref={ref} 165 + className={cn("-mx-1 my-1 h-px bg-muted", className)} 166 + {...props} 167 + /> 168 + )) 169 + DropdownMenuSeparator.displayName = DropdownMenuPrimitive.Separator.displayName 170 + 171 + const DropdownMenuShortcut = ({ 172 + className, 173 + ...props 174 + }: React.HTMLAttributes<HTMLSpanElement>) => { 175 + return ( 176 + <span 177 + className={cn("ml-auto text-xs tracking-widest opacity-60", className)} 178 + {...props} 179 + /> 180 + ) 181 + } 182 + DropdownMenuShortcut.displayName = "DropdownMenuShortcut" 183 + 184 + export { 185 + DropdownMenu, 186 + DropdownMenuTrigger, 187 + DropdownMenuContent, 188 + DropdownMenuItem, 189 + DropdownMenuCheckboxItem, 190 + DropdownMenuRadioItem, 191 + DropdownMenuLabel, 192 + DropdownMenuSeparator, 193 + DropdownMenuShortcut, 194 + DropdownMenuGroup, 195 + DropdownMenuPortal, 196 + DropdownMenuSub, 197 + DropdownMenuSubContent, 198 + DropdownMenuSubTrigger, 199 + DropdownMenuRadioGroup, 200 + }
+9 -9
src/components/ui/popover.tsx
··· 1 - import * as React from "react" 2 - import * as PopoverPrimitive from "@radix-ui/react-popover" 1 + import * as React from "react"; 2 + import * as PopoverPrimitive from "@radix-ui/react-popover"; 3 3 4 - import { cn } from "@/lib/utils" 4 + import { cn } from "@/lib/utils"; 5 5 6 - const Popover = PopoverPrimitive.Root 6 + const Popover = PopoverPrimitive.Root; 7 7 8 - const PopoverTrigger = PopoverPrimitive.Trigger 8 + const PopoverTrigger = PopoverPrimitive.Trigger; 9 9 10 10 const PopoverContent = React.forwardRef< 11 11 React.ElementRef<typeof PopoverPrimitive.Content>, ··· 18 18 sideOffset={sideOffset} 19 19 className={cn( 20 20 "z-50 w-72 rounded-md border bg-popover p-4 text-popover-foreground shadow-md outline-none data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2", 21 - className 21 + className, 22 22 )} 23 23 {...props} 24 24 /> 25 25 </PopoverPrimitive.Portal> 26 - )) 27 - PopoverContent.displayName = PopoverPrimitive.Content.displayName 26 + )); 27 + PopoverContent.displayName = PopoverPrimitive.Content.displayName; 28 28 29 - export { Popover, PopoverTrigger, PopoverContent } 29 + export { Popover, PopoverTrigger, PopoverContent };
+1 -1
src/index.css
··· 45 45 --card-foreground: 0 0% 98%; 46 46 --popover: 0 0% 3.9%; 47 47 --popover-foreground: 0 0% 98%; 48 - --primary: 0 0% 98%; 48 + --primary: 220 50% 80%; 49 49 --primary-foreground: 0 0% 9%; 50 50 --secondary: 0 0% 14.9%; 51 51 --secondary-foreground: 0 0% 98%;
+79
src/lib/userCache.ts
··· 1 + export interface CacheEntry { 2 + data: any; 3 + timestamp: number; 4 + } 5 + 6 + export interface UserCache { 7 + get(key: string): CacheEntry | undefined; 8 + set(key: string, value: CacheEntry): void; 9 + delete(key: string): void; 10 + clear(): void; 11 + clean(): void; 12 + } 13 + 14 + export class PersistentUserCache implements UserCache { 15 + private cache: Map<string, CacheEntry>; 16 + private readonly CACHE_KEY = "bsky_user_cache"; 17 + private readonly CACHE_DURATION = 24 * 60 * 60 * 1000; // 1 day 18 + 19 + constructor() { 20 + this.cache = new Map(); 21 + this.loadFromStorage(); 22 + } 23 + 24 + private loadFromStorage() { 25 + try { 26 + const stored = localStorage.getItem(this.CACHE_KEY); 27 + if (stored) { 28 + const parsed = JSON.parse(stored); 29 + this.cache = new Map(Object.entries(parsed)); 30 + } 31 + } catch (error) { 32 + console.warn("Failed to load cache from storage:", error); 33 + } 34 + } 35 + 36 + private saveToStorage() { 37 + try { 38 + const obj = Object.fromEntries(this.cache); 39 + localStorage.setItem(this.CACHE_KEY, JSON.stringify(obj)); 40 + } catch (error) { 41 + console.warn("Failed to save cache to storage:", error); 42 + } 43 + } 44 + 45 + get(key: string): CacheEntry | undefined { 46 + return this.cache.get(key); 47 + } 48 + 49 + set(key: string, value: CacheEntry) { 50 + this.cache.set(key, value); 51 + this.saveToStorage(); 52 + } 53 + 54 + delete(key: string) { 55 + this.cache.delete(key); 56 + this.saveToStorage(); 57 + } 58 + 59 + clear() { 60 + this.cache.clear(); 61 + this.saveToStorage(); 62 + } 63 + 64 + clean() { 65 + const now = Date.now(); 66 + let hasChanges = false; 67 + 68 + for (const [key, value] of this.cache.entries()) { 69 + if (now - value.timestamp > this.CACHE_DURATION) { 70 + this.cache.delete(key); 71 + hasChanges = true; 72 + } 73 + } 74 + 75 + if (hasChanges) { 76 + this.saveToStorage(); 77 + } 78 + } 79 + }
+235 -3
src/providers/qtprovider.tsx
··· 1 + import { AccountsManagementModal } from "@/components/auth/accountsManagementModal"; 2 + import { PersistentUserCache, UserCache } from "@/lib/userCache"; 1 3 import { XRPC, CredentialManager } from "@atcute/client"; 2 - import React from "preact/compat"; 4 + import { 5 + AuthorizationServerMetadata, 6 + configureOAuth, 7 + createAuthorizationUrl, 8 + deleteStoredSession, 9 + finalizeAuthorization, 10 + getSession, 11 + IdentityMetadata, 12 + OAuthUserAgent, 13 + resolveFromIdentity, 14 + } from "@atcute/oauth-browser-client"; 15 + import React, { useState, useEffect } from "preact/compat"; 3 16 4 - export const QtContext = React.createContext<QtClient | null>(null); 17 + configureOAuth({ 18 + metadata: { 19 + client_id: import.meta.env.VITE_OAUTH_CLIENT_ID, 20 + redirect_uri: import.meta.env.VITE_OAUTH_REDIRECT_URI, 21 + }, 22 + }); 23 + 24 + interface QtContextType { 25 + client: QtClient; 26 + currentAgent: OAuthUserAgent | null; 27 + accounts: `did:${string}`[]; 28 + isManagementModalOpen: boolean; 29 + openManagementModal: () => void; 30 + closeManagementModal: () => void; 31 + userCache: UserCache; 32 + } 33 + 34 + export const QtContext = React.createContext<QtContextType | null>(null); 5 35 6 36 export function useXrpc(): XRPC { 7 37 const client = React.useContext(QtContext); 8 38 if (!client) { 9 39 throw new Error("useXrpc must be used within a QtProvider"); 10 40 } 11 - return client.rpc; 41 + return client.client.rpc; 42 + } 43 + 44 + export function QtProvider({ children }: { children: React.ReactNode }) { 45 + const [client, setClient] = useState<QtClient | null>(null); 46 + const [currentAgent, setCurrentAgent] = useState<OAuthUserAgent | null>(null); 47 + const [accounts, setAccounts] = useState<`did:${string}`[]>([]); 48 + const [isLoading, setIsLoading] = useState(true); 49 + const [error, setError] = useState<Error | null>(null); 50 + const [isManagementModalOpen, setIsManagementModalOpen] = useState(false); 51 + const [userCache] = useState<UserCache>(() => new PersistentUserCache()); 52 + 53 + useEffect(() => { 54 + try { 55 + const newClient = new QtClient(); 56 + newClient.onStateChange = (agent, accounts) => { 57 + setCurrentAgent(agent); 58 + setAccounts(accounts); 59 + }; 60 + setClient(newClient); 61 + } catch (err) { 62 + setError( 63 + err instanceof Error ? err : new Error("Failed to initialize client"), 64 + ); 65 + } finally { 66 + setIsLoading(false); 67 + } 68 + }, []); 69 + 70 + if (isLoading) return <div>Loading...</div>; 71 + if (error) return <div>Error: {error.message}</div>; 72 + if (!client) return null; 73 + 74 + const value = { 75 + client, 76 + currentAgent, 77 + accounts, 78 + isManagementModalOpen, 79 + openManagementModal: () => setIsManagementModalOpen(true), 80 + closeManagementModal: () => setIsManagementModalOpen(false), 81 + userCache, 82 + }; 83 + 84 + return ( 85 + <QtContext.Provider value={value}> 86 + <div>{children}</div> 87 + <AccountsManagementModal 88 + isOpen={isManagementModalOpen} 89 + onClose={() => setIsManagementModalOpen(false)} 90 + /> 91 + </QtContext.Provider> 92 + ); 12 93 } 13 94 14 95 export class QtClient { 15 96 manager: CredentialManager; 16 97 rpc: XRPC; 98 + accounts: `did:${string}`[]; 99 + currentAgent: OAuthUserAgent | null; 100 + currentAgentDid: `did:${string}` | null; 101 + onStateChange?: ( 102 + agent: OAuthUserAgent | null, 103 + accounts: `did:${string}`[], 104 + ) => void; 105 + 17 106 constructor(service: URL = new URL("https://bsky.social")) { 18 107 this.manager = new CredentialManager({ service: service.toString() }); 19 108 this.rpc = new XRPC({ handler: this.manager }); 109 + this.accounts = 110 + (JSON.parse( 111 + localStorage.getItem("currentAccountList") as string, 112 + ) as `did:${string}`[]) || []; 113 + this.currentAgent = null; 114 + this.currentAgentDid = localStorage.getItem("currentAgentDid") as 115 + | `did:${string}` 116 + | null; 117 + 118 + this.attemptResumeSession(); 119 + } 120 + private updateState() { 121 + if (this.onStateChange) { 122 + this.onStateChange(this.currentAgent, this.accounts); 123 + } 124 + // Save currentAgentDid to localStorage whenever state updates 125 + if (this.currentAgent?.sub) { 126 + localStorage.setItem("currentAgentDid", this.currentAgent.sub); 127 + } else { 128 + localStorage.removeItem("currentAgentDid"); 129 + } 130 + if (this.accounts.length > 0) { 131 + localStorage.setItem("currentAccountList", JSON.stringify(this.accounts)); 132 + } else { 133 + localStorage.removeItem("currentAccountList"); 134 + } 20 135 } 21 136 getXrpcClient() { 22 137 return this.rpc; 23 138 } 139 + async resolveHandle(handle: string) { 140 + return await resolveFromIdentity(handle); 141 + } 142 + async getOAuthRedirectUri(meta: { 143 + identity: IdentityMetadata; 144 + metadata: AuthorizationServerMetadata; 145 + }) { 146 + return await createAuthorizationUrl({ 147 + metadata: meta.metadata, 148 + identity: meta.identity, 149 + scope: "atproto transition:generic", 150 + }); 151 + } 152 + 153 + async finalizeAuthorization(code: URLSearchParams) { 154 + const sess = await finalizeAuthorization(code); 155 + console.log("Logging in as ", sess.info.sub); 156 + const agent = new OAuthUserAgent(sess); 157 + this.currentAgent = agent; 158 + this.currentAgentDid = agent.sub; 159 + this.accounts.push(agent.sub); 160 + this.rpc = new XRPC({ handler: this.manager }); 161 + this.updateState(); 162 + console.log("Successfully logged in!"); 163 + } 164 + 165 + async attemptResumeSession() { 166 + console.log("Attempting resume session"); 167 + try { 168 + if (this.currentAgentDid) { 169 + await this.switchAccount(this.currentAgentDid); 170 + console.log("Session resumed successfully"); 171 + } else { 172 + for (const did of this.accounts) { 173 + try { 174 + await this.switchAccount(did); 175 + console.log(`Session resumed successfully for ${did}`); 176 + break; 177 + } catch (error) { 178 + console.error(`Error resuming session for ${did}:`, error); 179 + } 180 + } 181 + } 182 + console.log("No session to resume"); 183 + } catch (error) { 184 + console.error("Error resuming session:", error); 185 + } 186 + } 187 + 188 + async switchAccount(did: `did:${string}`) { 189 + const sess = await getSession(did); 190 + if (!sess) { 191 + throw new Error(`No session found for ${did}`); 192 + } 193 + const agent = new OAuthUserAgent(sess); 194 + this.currentAgent = agent; 195 + this.currentAgentDid = agent.sub; 196 + this.rpc = new XRPC({ handler: this.manager }); 197 + this.updateState(); 198 + } 199 + 200 + async logout(did: `did:${string}`) { 201 + const currentDid = this.currentAgent?.sub; 202 + await this.switchAccount(did); 203 + await this.currentAgent?.signOut(); 204 + deleteStoredSession(did); 205 + this.accounts = this.accounts.filter((a) => a !== did); 206 + this.currentAgentDid = currentDid !== did ? currentDid || null : null; // Update currentAgentDid 207 + if (currentDid && currentDid !== did) { 208 + await this.switchAccount(currentDid); 209 + } else { 210 + this.currentAgent = null; 211 + this.updateState(); 212 + } 213 + } 214 + } 215 + 216 + export async function resolveBskyUser(did: `did:${string}`, qt: QtContextType) { 217 + const context = qt; 218 + 219 + const cachedData = context.userCache.get(did); 220 + const now = Date.now(); 221 + 222 + if (cachedData && now - cachedData.timestamp < 5 * 60 * 1000) { 223 + return cachedData.data; 224 + } 225 + 226 + const response = await new QtClient(new URL("https://public.api.bsky.app")) 227 + .getXrpcClient() 228 + .get("app.bsky.actor.getProfile", { 229 + params: { actor: did }, 230 + }); 231 + 232 + context.userCache.set(did, { 233 + data: response, 234 + timestamp: now, 235 + }); 236 + 237 + return response; 238 + } 239 + 240 + export function useQt() { 241 + const client = React.useContext(QtContext); 242 + if (!client) { 243 + throw new Error("useQtState must be used within a QtProvider"); 244 + } 245 + return { 246 + currentAgent: client.currentAgent, 247 + accounts: client.accounts, 248 + }; 249 + } 250 + export function useUserCache() { 251 + const context = React.useContext(QtContext); 252 + if (!context) { 253 + throw new Error("useUserCache must be used within a QtProvider"); 254 + } 255 + return context.userCache; 24 256 }
+52
src/routeTree.gen.ts
··· 23 23 const IndexLazyImport = createFileRoute('/')() 24 24 const RnfgrerttIndexLazyImport = createFileRoute('/rnfgrertt/')() 25 25 const RnfgrerttTypingLazyImport = createFileRoute('/rnfgrertt/typing')() 26 + const AuthLoginLazyImport = createFileRoute('/auth/login')() 27 + const AuthCallbackLazyImport = createFileRoute('/auth/callback')() 26 28 const PdsUrlIndexLazyImport = createFileRoute('/pds/$url/')() 27 29 const AtHandleCollectionIndexLazyImport = createFileRoute( 28 30 '/at:/$handle/$collection/', ··· 73 75 import('./routes/rnfgrertt/typing.lazy').then((d) => d.Route), 74 76 ) 75 77 78 + const AuthLoginLazyRoute = AuthLoginLazyImport.update({ 79 + id: '/auth/login', 80 + path: '/auth/login', 81 + getParentRoute: () => rootRoute, 82 + } as any).lazy(() => import('./routes/auth/login.lazy').then((d) => d.Route)) 83 + 84 + const AuthCallbackLazyRoute = AuthCallbackLazyImport.update({ 85 + id: '/auth/callback', 86 + path: '/auth/callback', 87 + getParentRoute: () => rootRoute, 88 + } as any).lazy(() => import('./routes/auth/callback.lazy').then((d) => d.Route)) 89 + 76 90 const PdsUrlIndexLazyRoute = PdsUrlIndexLazyImport.update({ 77 91 id: '/pds/$url/', 78 92 path: '/pds/$url/', ··· 138 152 preLoaderRoute: typeof JetstreamLazyImport 139 153 parentRoute: typeof rootRoute 140 154 } 155 + '/auth/callback': { 156 + id: '/auth/callback' 157 + path: '/auth/callback' 158 + fullPath: '/auth/callback' 159 + preLoaderRoute: typeof AuthCallbackLazyImport 160 + parentRoute: typeof rootRoute 161 + } 162 + '/auth/login': { 163 + id: '/auth/login' 164 + path: '/auth/login' 165 + fullPath: '/auth/login' 166 + preLoaderRoute: typeof AuthLoginLazyImport 167 + parentRoute: typeof rootRoute 168 + } 141 169 '/rnfgrertt/typing': { 142 170 id: '/rnfgrertt/typing' 143 171 path: '/rnfgrertt/typing' ··· 190 218 '/about': typeof AboutLazyRoute 191 219 '/counter': typeof CounterLazyRoute 192 220 '/jetstream': typeof JetstreamLazyRoute 221 + '/auth/callback': typeof AuthCallbackLazyRoute 222 + '/auth/login': typeof AuthLoginLazyRoute 193 223 '/rnfgrertt/typing': typeof RnfgrerttTypingLazyRoute 194 224 '/rnfgrertt': typeof RnfgrerttIndexLazyRoute 195 225 '/at:/$handle': typeof AtHandleIndexRoute ··· 203 233 '/about': typeof AboutLazyRoute 204 234 '/counter': typeof CounterLazyRoute 205 235 '/jetstream': typeof JetstreamLazyRoute 236 + '/auth/callback': typeof AuthCallbackLazyRoute 237 + '/auth/login': typeof AuthLoginLazyRoute 206 238 '/rnfgrertt/typing': typeof RnfgrerttTypingLazyRoute 207 239 '/rnfgrertt': typeof RnfgrerttIndexLazyRoute 208 240 '/at:/$handle': typeof AtHandleIndexRoute ··· 217 249 '/about': typeof AboutLazyRoute 218 250 '/counter': typeof CounterLazyRoute 219 251 '/jetstream': typeof JetstreamLazyRoute 252 + '/auth/callback': typeof AuthCallbackLazyRoute 253 + '/auth/login': typeof AuthLoginLazyRoute 220 254 '/rnfgrertt/typing': typeof RnfgrerttTypingLazyRoute 221 255 '/rnfgrertt/': typeof RnfgrerttIndexLazyRoute 222 256 '/at:/$handle/': typeof AtHandleIndexRoute ··· 232 266 | '/about' 233 267 | '/counter' 234 268 | '/jetstream' 269 + | '/auth/callback' 270 + | '/auth/login' 235 271 | '/rnfgrertt/typing' 236 272 | '/rnfgrertt' 237 273 | '/at:/$handle' ··· 244 280 | '/about' 245 281 | '/counter' 246 282 | '/jetstream' 283 + | '/auth/callback' 284 + | '/auth/login' 247 285 | '/rnfgrertt/typing' 248 286 | '/rnfgrertt' 249 287 | '/at:/$handle' ··· 256 294 | '/about' 257 295 | '/counter' 258 296 | '/jetstream' 297 + | '/auth/callback' 298 + | '/auth/login' 259 299 | '/rnfgrertt/typing' 260 300 | '/rnfgrertt/' 261 301 | '/at:/$handle/' ··· 270 310 AboutLazyRoute: typeof AboutLazyRoute 271 311 CounterLazyRoute: typeof CounterLazyRoute 272 312 JetstreamLazyRoute: typeof JetstreamLazyRoute 313 + AuthCallbackLazyRoute: typeof AuthCallbackLazyRoute 314 + AuthLoginLazyRoute: typeof AuthLoginLazyRoute 273 315 RnfgrerttTypingLazyRoute: typeof RnfgrerttTypingLazyRoute 274 316 RnfgrerttIndexLazyRoute: typeof RnfgrerttIndexLazyRoute 275 317 AtHandleIndexRoute: typeof AtHandleIndexRoute ··· 283 325 AboutLazyRoute: AboutLazyRoute, 284 326 CounterLazyRoute: CounterLazyRoute, 285 327 JetstreamLazyRoute: JetstreamLazyRoute, 328 + AuthCallbackLazyRoute: AuthCallbackLazyRoute, 329 + AuthLoginLazyRoute: AuthLoginLazyRoute, 286 330 RnfgrerttTypingLazyRoute: RnfgrerttTypingLazyRoute, 287 331 RnfgrerttIndexLazyRoute: RnfgrerttIndexLazyRoute, 288 332 AtHandleIndexRoute: AtHandleIndexRoute, ··· 305 349 "/about", 306 350 "/counter", 307 351 "/jetstream", 352 + "/auth/callback", 353 + "/auth/login", 308 354 "/rnfgrertt/typing", 309 355 "/rnfgrertt/", 310 356 "/at:/$handle/", ··· 324 370 }, 325 371 "/jetstream": { 326 372 "filePath": "jetstream.lazy.tsx" 373 + }, 374 + "/auth/callback": { 375 + "filePath": "auth/callback.lazy.tsx" 376 + }, 377 + "/auth/login": { 378 + "filePath": "auth/login.lazy.tsx" 327 379 }, 328 380 "/rnfgrertt/typing": { 329 381 "filePath": "rnfgrertt/typing.lazy.tsx"
+3 -3
src/routes/__root.tsx
··· 4 4 SidebarProvider, 5 5 SidebarTrigger, 6 6 } from "@/components/ui/sidebar"; 7 - import { QtClient, QtContext } from "@/providers/qtprovider"; 7 + import { QtProvider } from "@/providers/qtprovider"; 8 8 import { ThemeProvider } from "@/providers/themeProvider"; 9 9 import { createRootRoute, Outlet } from "@tanstack/react-router"; 10 10 import { TanStackRouterDevtools } from "@tanstack/router-devtools"; ··· 14 14 component: () => ( 15 15 <> 16 16 <ThemeProvider> 17 - <QtContext.Provider value={new QtClient()}> 17 + <QtProvider> 18 18 <SidebarProvider> 19 19 <AppSidebar /> 20 20 <SidebarInset> ··· 22 22 <Outlet /> 23 23 </SidebarInset> 24 24 </SidebarProvider> 25 - </QtContext.Provider> 25 + </QtProvider> 26 26 </ThemeProvider> 27 27 {process.env.NODE_ENV === "development" && ( 28 28 <TanStackRouterDevtools position="bottom-right" />
+52
src/routes/auth/callback.lazy.tsx
··· 1 + import ShowError from "@/components/error"; 2 + import { Loader } from "@/components/ui/loader"; 3 + import { QtContext } from "@/providers/qtprovider"; 4 + import { createLazyFileRoute } from "@tanstack/react-router"; 5 + import { Check } from "lucide-react"; 6 + import { useContext, useEffect, useState } from "preact/hooks"; 7 + 8 + export const Route = createLazyFileRoute("/auth/callback")({ 9 + component: RouteComponent, 10 + }); 11 + 12 + function RouteComponent() { 13 + let qt = useContext(QtContext); 14 + const [error, setError] = useState<Error | null>(null); 15 + const [isDone, setIsDone] = useState<boolean>(false); 16 + if (!qt) return null; 17 + // do this once 18 + useEffect(() => { 19 + const handleAuthorization = async () => { 20 + try { 21 + const params = new URLSearchParams(location.hash.slice(1)); 22 + console.log(params); 23 + if (params) { 24 + await qt.client.finalizeAuthorization(params); 25 + } 26 + } catch (error) { 27 + console.error(error); 28 + setError(error as Error); 29 + } finally { 30 + setIsDone(true); 31 + setTimeout(() => { 32 + window.location.href = "/"; 33 + }, 200); 34 + } 35 + }; 36 + handleAuthorization(); 37 + }, []); 38 + return ( 39 + <div className="flex flex-col items-center justify-center h-full"> 40 + {error ? ( 41 + <ShowError error={error} /> 42 + ) : isDone ? ( 43 + <div className="flex flex-col items-center justify-center gap-4"> 44 + <Check className="text-green-500" height={64} width="full" /> 45 + <p className="text-lg">Done! Redirecting shortly...</p> 46 + </div> 47 + ) : ( 48 + <Loader /> 49 + )} 50 + </div> 51 + ); 52 + }
+61
src/routes/auth/login.lazy.tsx
··· 1 + import { Button } from "@/components/ui/button"; 2 + import { Input } from "@/components/ui/input"; 3 + import { QtContext } from "@/providers/qtprovider"; 4 + import { createLazyFileRoute } from "@tanstack/react-router"; 5 + import { AtSign } from "lucide-react"; 6 + import { useContext, useState } from "preact/hooks"; 7 + 8 + export const Route = createLazyFileRoute("/auth/login")({ 9 + component: RouteComponent, 10 + }); 11 + 12 + function RouteComponent() { 13 + // get xrpc 14 + let qt = useContext(QtContext); 15 + let [user, setUser] = useState(""); 16 + let [isResolving, setIsResolving] = useState(false); 17 + if (!qt) return null; 18 + const onRedirectIntent = async () => { 19 + setIsResolving(true); 20 + const resolved = await qt.client.resolveHandle(user); 21 + if (qt.accounts.includes(resolved.identity.id)) { 22 + // switch to user 23 + try { 24 + qt.client.switchAccount(resolved.identity.id); 25 + // redirect to dashboard 26 + window.location.href = "/"; 27 + return; 28 + } catch (error) { 29 + console.error(error); 30 + } 31 + } 32 + const uri = await qt.client.getOAuthRedirectUri(resolved); 33 + window.location.href = uri.toString(); 34 + setIsResolving(false); 35 + }; 36 + return ( 37 + <div className="max-h-[calc(100vh-5rem)] h-screen flex flex-col items-center justify-center"> 38 + <div className="max-w-md w-screen bg-card border py-6 px-6 gap-4 flex flex-col rounded-lg"> 39 + <AtSign height={64} width={64} className="text-blue-500" /> 40 + <p className="text-lg">Log in with your ATProto account</p> 41 + <form 42 + onSubmitCapture={onRedirectIntent} 43 + className="flex flex-col items-end gap-4" 44 + > 45 + <Input 46 + placeholder="alice.bsky.social" 47 + value={user} 48 + onChange={(e: Event) => { 49 + const target = e.target as HTMLInputElement; 50 + setUser(target.value); 51 + }} 52 + onSubmitCapture={onRedirectIntent} 53 + /> 54 + <Button onClick={onRedirectIntent} disabled={isResolving}> 55 + {isResolving ? "Loading..." : "Log In"} 56 + </Button> 57 + </form> 58 + </div> 59 + </div> 60 + ); 61 + }
+42 -1
vite.config.ts
··· 3 3 import preact from "@preact/preset-vite"; 4 4 import { TanStackRouterVite } from "@tanstack/router-plugin/vite"; 5 5 6 + import metadata from "./public/oauth/client-metadata.json" with { type: "json" }; 7 + 6 8 // https://vite.dev/config/ 7 9 export default defineConfig({ 8 - plugins: [TanStackRouterVite(), preact()], 10 + plugins: [ 11 + TanStackRouterVite(), 12 + preact(), 13 + { 14 + enforce: "pre", 15 + name: "oauth-config", 16 + config(_conf, { command }) { 17 + if (command === "build") { 18 + process.env.VITE_OAUTH_CLIENT_ID = metadata.client_id as string; 19 + process.env.VITE_OAUTH_REDIRECT_URI = ( 20 + metadata.redirect_uris as string[] 21 + )[0]; 22 + } else { 23 + const SERVER_HOST = "127.0.0.1"; 24 + const SERVER_PORT = 5173; 25 + 26 + const redirectUri = (() => { 27 + const url = new URL((metadata.redirect_uris as string[])[0]); 28 + return `http://${SERVER_HOST}:${SERVER_PORT}${url.pathname}`; 29 + })(); 30 + 31 + const clientId = 32 + `http://localhost` + 33 + `?redirect_uri=${encodeURIComponent(redirectUri)}` + 34 + `&scope=${encodeURIComponent(metadata.scope as string)}`; 35 + 36 + process.env.VITE_DEV_SERVER_PORT = "" + SERVER_PORT; 37 + process.env.VITE_OAUTH_CLIENT_ID = clientId; 38 + process.env.VITE_OAUTH_REDIRECT_URI = redirectUri; 39 + } 40 + 41 + process.env.VITE_CLIENT_URI = metadata.client_uri as string; 42 + process.env.VITE_OAUTH_SCOPE = metadata.scope as string; 43 + }, 44 + }, 45 + ], 9 46 resolve: { 10 47 alias: { 11 48 "@": path.resolve(__dirname, "./src"), 12 49 }, 50 + }, 51 + server: { 52 + host: "127.0.0.1", 53 + open: true, 13 54 }, 14 55 });