diff --git a/.vscode/settings.json b/.vscode/settings.json index 774e8317..2ff71441 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -20,6 +20,7 @@ "depluralizes", "Eterna", "exif", + "exifr", "exiftool", "favicons", "Favoriting", diff --git a/package.json b/package.json index 5245c331..c038909c 100644 --- a/package.json +++ b/package.json @@ -12,9 +12,9 @@ "@ai-sdk/openai": "^1.3.23", "@aws-sdk/client-s3": "3.864.0", "@aws-sdk/s3-request-presigner": "3.864.0", - "@radix-ui/react-dialog": "^1.1.14", - "@radix-ui/react-dropdown-menu": "^2.1.15", - "@radix-ui/react-tooltip": "^1.2.7", + "@radix-ui/react-dialog": "^1.1.15", + "@radix-ui/react-dropdown-menu": "^2.1.16", + "@radix-ui/react-tooltip": "^1.2.8", "@radix-ui/react-visually-hidden": "^1.2.3", "@upstash/ratelimit": "^2.0.6", "@upstash/redis": "^1.35.3", @@ -28,6 +28,7 @@ "culori": "^4.0.2", "date-fns": "^4.1.0", "date-fns-tz": "^3.2.0", + "exifr": "^7.1.3", "extract-colors": "^4.2.1", "fast-average-color": "^9.5.0", "fast-deep-equal": "^3.1.3", @@ -43,7 +44,7 @@ "sanitize-html": "^2.17.0", "sharp": "^0.34.3", "sonner": "^2.0.7", - "swr": "^2.3.4", + "swr": "^2.3.6", "ts-exif-parser": "^0.2.2", "use-debounce": "^10.0.5", "viewerjs": "^1.11.7" @@ -55,15 +56,15 @@ "@stylistic/eslint-plugin": "^5.2.3", "@tailwindcss/container-queries": "^0.1.1", "@tailwindcss/forms": "^0.5.10", - "@tailwindcss/postcss": "^4.1.11", + "@tailwindcss/postcss": "^4.1.12", "@testing-library/dom": "^10.4.1", - "@testing-library/jest-dom": "^6.6.4", + "@testing-library/jest-dom": "^6.7.0", "@testing-library/react": "^16.3.0", "@types/culori": "^4.0.0", "@types/jest": "^30.0.0", - "@types/node": "^24.2.1", + "@types/node": "^24.3.0", "@types/pg": "^8.15.5", - "@types/react": "19.1.9", + "@types/react": "19.1.10", "@types/react-dom": "19.1.7", "@types/sanitize-html": "^2.16.0", "cross-fetch": "^4.1.0", @@ -73,7 +74,7 @@ "jest": "^30.0.5", "jest-environment-jsdom": "^30.0.5", "postcss": "8.5.6", - "tailwindcss": "4.1.11", + "tailwindcss": "4.1.12", "ts-node": "^10.9.2", "typescript": "5.9.2" }, diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 5bc3ca89..6e2bf391 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -18,17 +18,17 @@ importers: specifier: 3.864.0 version: 3.864.0 '@radix-ui/react-dialog': - specifier: ^1.1.14 - version: 1.1.14(@types/react-dom@19.1.7(@types/react@19.1.9))(@types/react@19.1.9)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + specifier: ^1.1.15 + version: 1.1.15(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) '@radix-ui/react-dropdown-menu': - specifier: ^2.1.15 - version: 2.1.15(@types/react-dom@19.1.7(@types/react@19.1.9))(@types/react@19.1.9)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + specifier: ^2.1.16 + version: 2.1.16(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) '@radix-ui/react-tooltip': - specifier: ^1.2.7 - version: 1.2.7(@types/react-dom@19.1.7(@types/react@19.1.9))(@types/react@19.1.9)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + specifier: ^1.2.8 + version: 1.2.8(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) '@radix-ui/react-visually-hidden': specifier: ^1.2.3 - version: 1.2.3(@types/react-dom@19.1.7(@types/react@19.1.9))(@types/react@19.1.9)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + version: 1.2.3(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) '@upstash/ratelimit': specifier: ^2.0.6 version: 2.0.6(@upstash/redis@1.35.3) @@ -55,7 +55,7 @@ importers: version: 2.1.1 cmdk: specifier: ^1.1.1 - version: 1.1.1(@types/react-dom@19.1.7(@types/react@19.1.9))(@types/react@19.1.9)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + version: 1.1.1(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) culori: specifier: ^4.0.2 version: 4.0.2 @@ -65,6 +65,9 @@ importers: date-fns-tz: specifier: ^3.2.0 version: 3.2.0(date-fns@4.1.0) + exifr: + specifier: ^7.1.3 + version: 7.1.3 extract-colors: specifier: ^4.2.1 version: 4.2.1 @@ -111,8 +114,8 @@ importers: specifier: ^2.0.7 version: 2.0.7(react-dom@19.1.1(react@19.1.1))(react@19.1.1) swr: - specifier: ^2.3.4 - version: 2.3.4(react@19.1.1) + specifier: ^2.3.6 + version: 2.3.6(react@19.1.1) ts-exif-parser: specifier: ^0.2.2 version: 0.2.2 @@ -137,22 +140,22 @@ importers: version: 5.2.3(eslint@9.33.0(jiti@2.5.1)) '@tailwindcss/container-queries': specifier: ^0.1.1 - version: 0.1.1(tailwindcss@4.1.11) + version: 0.1.1(tailwindcss@4.1.12) '@tailwindcss/forms': specifier: ^0.5.10 - version: 0.5.10(tailwindcss@4.1.11) + version: 0.5.10(tailwindcss@4.1.12) '@tailwindcss/postcss': - specifier: ^4.1.11 - version: 4.1.11 + specifier: ^4.1.12 + version: 4.1.12 '@testing-library/dom': specifier: ^10.4.1 version: 10.4.1 '@testing-library/jest-dom': - specifier: ^6.6.4 - version: 6.6.4 + specifier: ^6.7.0 + version: 6.7.0 '@testing-library/react': specifier: ^16.3.0 - version: 16.3.0(@testing-library/dom@10.4.1)(@types/react-dom@19.1.7(@types/react@19.1.9))(@types/react@19.1.9)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + version: 16.3.0(@testing-library/dom@10.4.1)(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) '@types/culori': specifier: ^4.0.0 version: 4.0.0 @@ -160,17 +163,17 @@ importers: specifier: ^30.0.0 version: 30.0.0 '@types/node': - specifier: ^24.2.1 - version: 24.2.1 + specifier: ^24.3.0 + version: 24.3.0 '@types/pg': specifier: ^8.15.5 version: 8.15.5 '@types/react': - specifier: 19.1.9 - version: 19.1.9 + specifier: 19.1.10 + version: 19.1.10 '@types/react-dom': specifier: 19.1.7 - version: 19.1.7(@types/react@19.1.9) + version: 19.1.7(@types/react@19.1.10) '@types/sanitize-html': specifier: ^2.16.0 version: 2.16.0 @@ -188,7 +191,7 @@ importers: version: 5.2.0(eslint@9.33.0(jiti@2.5.1)) jest: specifier: ^30.0.5 - version: 30.0.5(@types/node@24.2.1)(ts-node@10.9.2(@types/node@24.2.1)(typescript@5.9.2)) + version: 30.0.5(@types/node@24.3.0)(ts-node@10.9.2(@types/node@24.3.0)(typescript@5.9.2)) jest-environment-jsdom: specifier: ^30.0.5 version: 30.0.5 @@ -196,11 +199,11 @@ importers: specifier: 8.5.6 version: 8.5.6 tailwindcss: - specifier: 4.1.11 - version: 4.1.11 + specifier: 4.1.12 + version: 4.1.12 ts-node: specifier: ^10.9.2 - version: 10.9.2(@types/node@24.2.1)(typescript@5.9.2) + version: 10.9.2(@types/node@24.3.0)(typescript@5.9.2) typescript: specifier: 5.9.2 version: 5.9.2 @@ -950,6 +953,9 @@ packages: '@jridgewell/gen-mapping@0.3.12': resolution: {integrity: sha512-OuLGC46TjB5BbN1dH8JULVVZY4WTdkF7tV9Ys6wLL1rubZnCMstOhNHueU5bLCrnRuDhKPDM4g6sw4Bel5Gzqg==} + '@jridgewell/remapping@2.3.5': + resolution: {integrity: sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==} + '@jridgewell/resolve-uri@3.1.2': resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==} engines: {node: '>=6.0.0'} @@ -1057,8 +1063,8 @@ packages: '@polka/url@1.0.0-next.29': resolution: {integrity: sha512-wwQAWhWSuHaag8c4q/KN/vCoeOJYshAIvMQwD4GpSb3OiZklFfvAgmj0VCBBImRpuF/aFgIRzllXlVX93Jevww==} - '@radix-ui/primitive@1.1.2': - resolution: {integrity: sha512-XnbHrrprsNqZKQhStrSwgRUQzoCI1glLzdw79xiZPoofhGICeZRSQ3dIxAKH1gb3OHfNf4d6f+vAv3kil2eggA==} + '@radix-ui/primitive@1.1.3': + resolution: {integrity: sha512-JTF99U/6XIjCBo0wqkU5sK10glYe27MRRsfwoiq5zzOEZLHU3A3KCMa5X/azekYRCJ0HlwI0crAXS/5dEHTzDg==} '@radix-ui/react-arrow@1.1.7': resolution: {integrity: sha512-F+M1tLhO+mlQaOWspE8Wstg+z6PwxwRd8oQ8IXceWz92kfAmalTRf0EjrouQeo7QssEPfCn05B4Ihs1K9WQ/7w==} @@ -1104,8 +1110,8 @@ packages: '@types/react': optional: true - '@radix-ui/react-dialog@1.1.14': - resolution: {integrity: sha512-+CpweKjqpzTmwRwcYECQcNYbI8V9VSQt0SNFKeEBLgfucbsLssU6Ppq7wUdNXEGb573bMjFhVjKVll8rmV6zMw==} + '@radix-ui/react-dialog@1.1.15': + resolution: {integrity: sha512-TCglVRtzlffRNxRMEyR36DGBLJpeusFcgMVD9PZEzAKnUs1lKCgX5u9BmC2Yg+LL9MgZDugFFs1Vl+Jp4t/PGw==} peerDependencies: '@types/react': '*' '@types/react-dom': '*' @@ -1126,8 +1132,8 @@ packages: '@types/react': optional: true - '@radix-ui/react-dismissable-layer@1.1.10': - resolution: {integrity: sha512-IM1zzRV4W3HtVgftdQiiOmA0AdJlCtMLe00FXaHwgt3rAnNsIyDqshvkIW3hj/iu5hu8ERP7KIYki6NkqDxAwQ==} + '@radix-ui/react-dismissable-layer@1.1.11': + resolution: {integrity: sha512-Nqcp+t5cTB8BinFkZgXiMJniQH0PsUt2k51FUhbdfeKvc4ACcG2uQniY/8+h1Yv6Kza4Q7lD7PQV0z0oicE0Mg==} peerDependencies: '@types/react': '*' '@types/react-dom': '*' @@ -1139,8 +1145,8 @@ packages: '@types/react-dom': optional: true - '@radix-ui/react-dropdown-menu@2.1.15': - resolution: {integrity: sha512-mIBnOjgwo9AH3FyKaSWoSu/dYj6VdhJ7frEPiGTeXCdUFHjl9h3mFh2wwhEtINOmYXWhdpf1rY2minFsmaNgVQ==} + '@radix-ui/react-dropdown-menu@2.1.16': + resolution: {integrity: sha512-1PLGQEynI/3OX/ftV54COn+3Sud/Mn8vALg2rWnBLnRaGtJDduNW/22XjlGgPdpcIbiQxjKtb7BkcjP00nqfJw==} peerDependencies: '@types/react': '*' '@types/react-dom': '*' @@ -1152,8 +1158,8 @@ packages: '@types/react-dom': optional: true - '@radix-ui/react-focus-guards@1.1.2': - resolution: {integrity: sha512-fyjAACV62oPV925xFCrH8DR5xWhg9KYtJT4s3u54jxp+L/hbpTY2kIeEFFbFe+a/HCE94zGQMZLIpVTPVZDhaA==} + '@radix-ui/react-focus-guards@1.1.3': + resolution: {integrity: sha512-0rFg/Rj2Q62NCm62jZw0QX7a3sz6QCQU0LpZdNrJX8byRGaGVTqbrW9jAoIAHyMQqsNpeZ81YgSizOt5WXq0Pw==} peerDependencies: '@types/react': '*' react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc @@ -1183,8 +1189,8 @@ packages: '@types/react': optional: true - '@radix-ui/react-menu@2.1.15': - resolution: {integrity: sha512-tVlmA3Vb9n8SZSd+YSbuFR66l87Wiy4du+YE+0hzKQEANA+7cWKH1WgqcEX4pXqxUFQKrWQGHdvEfw00TjFiew==} + '@radix-ui/react-menu@2.1.16': + resolution: {integrity: sha512-72F2T+PLlphrqLcAotYPp0uJMr5SjP5SL01wfEspJbru5Zs5vQaSHb4VB3ZMJPimgHHCHG7gMOeOB9H3Hdmtxg==} peerDependencies: '@types/react': '*' '@types/react-dom': '*' @@ -1196,8 +1202,8 @@ packages: '@types/react-dom': optional: true - '@radix-ui/react-popper@1.2.7': - resolution: {integrity: sha512-IUFAccz1JyKcf/RjB552PlWwxjeCJB8/4KxT7EhBHOJM+mN7LdW+B3kacJXILm32xawcMMjb2i0cIZpo+f9kiQ==} + '@radix-ui/react-popper@1.2.8': + resolution: {integrity: sha512-0NJQ4LFFUuWkE7Oxf0htBKS6zLkkjBH+hM1uk7Ng705ReR8m/uelduy1DBo0PyBXPKVnBA6YBlU94MBGXrSBCw==} peerDependencies: '@types/react': '*' '@types/react-dom': '*' @@ -1222,8 +1228,8 @@ packages: '@types/react-dom': optional: true - '@radix-ui/react-presence@1.1.4': - resolution: {integrity: sha512-ueDqRbdc4/bkaQT3GIpLQssRlFgWaL/U2z/S31qRwwLWoxHLgry3SIfCwhxeQNbirEUXFa+lq3RL3oBYXtcmIA==} + '@radix-ui/react-presence@1.1.5': + resolution: {integrity: sha512-/jfEwNDdQVBCNvjkGit4h6pMOzq8bHkopq458dPt2lMjx+eBQUohZNG9A7DtO/O5ukSbxuaNGXMjHicgwy6rQQ==} peerDependencies: '@types/react': '*' '@types/react-dom': '*' @@ -1248,8 +1254,8 @@ packages: '@types/react-dom': optional: true - '@radix-ui/react-roving-focus@1.1.10': - resolution: {integrity: sha512-dT9aOXUen9JSsxnMPv/0VqySQf5eDQ6LCk5Sw28kamz8wSOW2bJdlX2Bg5VUIIcV+6XlHpWTIuTPCf/UNIyq8Q==} + '@radix-ui/react-roving-focus@1.1.11': + resolution: {integrity: sha512-7A6S9jSgm/S+7MdtNDSb+IU859vQqJ/QAtcYQcfFC6W8RS4IxIZDldLR0xqCFZ6DCyrQLjLPsxtTNch5jVA4lA==} peerDependencies: '@types/react': '*' '@types/react-dom': '*' @@ -1270,8 +1276,8 @@ packages: '@types/react': optional: true - '@radix-ui/react-tooltip@1.2.7': - resolution: {integrity: sha512-Ap+fNYwKTYJ9pzqW+Xe2HtMRbQ/EeWkj2qykZ6SuEV4iS/o1bZI5ssJbk4D2r8XuDuOBVz/tIx2JObtuqU+5Zw==} + '@radix-ui/react-tooltip@1.2.8': + resolution: {integrity: sha512-tY7sVt1yL9ozIxvmbtN5qtmH2krXcBCfjEiCgKGLqunJHvgvZG2Pcl2oQ3kbcZARb1BGEHdkLzcYGO8ynVlieg==} peerDependencies: '@types/react': '*' '@types/react-dom': '*' @@ -1608,65 +1614,65 @@ packages: peerDependencies: tailwindcss: '>=3.0.0 || >= 3.0.0-alpha.1 || >= 4.0.0-alpha.20 || >= 4.0.0-beta.1' - '@tailwindcss/node@4.1.11': - resolution: {integrity: sha512-yzhzuGRmv5QyU9qLNg4GTlYI6STedBWRE7NjxP45CsFYYq9taI0zJXZBMqIC/c8fViNLhmrbpSFS57EoxUmD6Q==} + '@tailwindcss/node@4.1.12': + resolution: {integrity: sha512-3hm9brwvQkZFe++SBt+oLjo4OLDtkvlE8q2WalaD/7QWaeM7KEJbAiY/LJZUaCs7Xa8aUu4xy3uoyX4q54UVdQ==} - '@tailwindcss/oxide-android-arm64@4.1.11': - resolution: {integrity: sha512-3IfFuATVRUMZZprEIx9OGDjG3Ou3jG4xQzNTvjDoKmU9JdmoCohQJ83MYd0GPnQIu89YoJqvMM0G3uqLRFtetg==} + '@tailwindcss/oxide-android-arm64@4.1.12': + resolution: {integrity: sha512-oNY5pq+1gc4T6QVTsZKwZaGpBb2N1H1fsc1GD4o7yinFySqIuRZ2E4NvGasWc6PhYJwGK2+5YT1f9Tp80zUQZQ==} engines: {node: '>= 10'} cpu: [arm64] os: [android] - '@tailwindcss/oxide-darwin-arm64@4.1.11': - resolution: {integrity: sha512-ESgStEOEsyg8J5YcMb1xl8WFOXfeBmrhAwGsFxxB2CxY9evy63+AtpbDLAyRkJnxLy2WsD1qF13E97uQyP1lfQ==} + '@tailwindcss/oxide-darwin-arm64@4.1.12': + resolution: {integrity: sha512-cq1qmq2HEtDV9HvZlTtrj671mCdGB93bVY6J29mwCyaMYCP/JaUBXxrQQQm7Qn33AXXASPUb2HFZlWiiHWFytw==} engines: {node: '>= 10'} cpu: [arm64] os: [darwin] - '@tailwindcss/oxide-darwin-x64@4.1.11': - resolution: {integrity: sha512-EgnK8kRchgmgzG6jE10UQNaH9Mwi2n+yw1jWmof9Vyg2lpKNX2ioe7CJdf9M5f8V9uaQxInenZkOxnTVL3fhAw==} + '@tailwindcss/oxide-darwin-x64@4.1.12': + resolution: {integrity: sha512-6UCsIeFUcBfpangqlXay9Ffty9XhFH1QuUFn0WV83W8lGdX8cD5/+2ONLluALJD5+yJ7k8mVtwy3zMZmzEfbLg==} engines: {node: '>= 10'} cpu: [x64] os: [darwin] - '@tailwindcss/oxide-freebsd-x64@4.1.11': - resolution: {integrity: sha512-xdqKtbpHs7pQhIKmqVpxStnY1skuNh4CtbcyOHeX1YBE0hArj2romsFGb6yUmzkq/6M24nkxDqU8GYrKrz+UcA==} + '@tailwindcss/oxide-freebsd-x64@4.1.12': + resolution: {integrity: sha512-JOH/f7j6+nYXIrHobRYCtoArJdMJh5zy5lr0FV0Qu47MID/vqJAY3r/OElPzx1C/wdT1uS7cPq+xdYYelny1ww==} engines: {node: '>= 10'} cpu: [x64] os: [freebsd] - '@tailwindcss/oxide-linux-arm-gnueabihf@4.1.11': - resolution: {integrity: sha512-ryHQK2eyDYYMwB5wZL46uoxz2zzDZsFBwfjssgB7pzytAeCCa6glsiJGjhTEddq/4OsIjsLNMAiMlHNYnkEEeg==} + '@tailwindcss/oxide-linux-arm-gnueabihf@4.1.12': + resolution: {integrity: sha512-v4Ghvi9AU1SYgGr3/j38PD8PEe6bRfTnNSUE3YCMIRrrNigCFtHZ2TCm8142X8fcSqHBZBceDx+JlFJEfNg5zQ==} engines: {node: '>= 10'} cpu: [arm] os: [linux] - '@tailwindcss/oxide-linux-arm64-gnu@4.1.11': - resolution: {integrity: sha512-mYwqheq4BXF83j/w75ewkPJmPZIqqP1nhoghS9D57CLjsh3Nfq0m4ftTotRYtGnZd3eCztgbSPJ9QhfC91gDZQ==} + '@tailwindcss/oxide-linux-arm64-gnu@4.1.12': + resolution: {integrity: sha512-YP5s1LmetL9UsvVAKusHSyPlzSRqYyRB0f+Kl/xcYQSPLEw/BvGfxzbH+ihUciePDjiXwHh+p+qbSP3SlJw+6g==} engines: {node: '>= 10'} cpu: [arm64] os: [linux] - '@tailwindcss/oxide-linux-arm64-musl@4.1.11': - resolution: {integrity: sha512-m/NVRFNGlEHJrNVk3O6I9ggVuNjXHIPoD6bqay/pubtYC9QIdAMpS+cswZQPBLvVvEF6GtSNONbDkZrjWZXYNQ==} + '@tailwindcss/oxide-linux-arm64-musl@4.1.12': + resolution: {integrity: sha512-V8pAM3s8gsrXcCv6kCHSuwyb/gPsd863iT+v1PGXC4fSL/OJqsKhfK//v8P+w9ThKIoqNbEnsZqNy+WDnwQqCA==} engines: {node: '>= 10'} cpu: [arm64] os: [linux] - '@tailwindcss/oxide-linux-x64-gnu@4.1.11': - resolution: {integrity: sha512-YW6sblI7xukSD2TdbbaeQVDysIm/UPJtObHJHKxDEcW2exAtY47j52f8jZXkqE1krdnkhCMGqP3dbniu1Te2Fg==} + '@tailwindcss/oxide-linux-x64-gnu@4.1.12': + resolution: {integrity: sha512-xYfqYLjvm2UQ3TZggTGrwxjYaLB62b1Wiysw/YE3Yqbh86sOMoTn0feF98PonP7LtjsWOWcXEbGqDL7zv0uW8Q==} engines: {node: '>= 10'} cpu: [x64] os: [linux] - '@tailwindcss/oxide-linux-x64-musl@4.1.11': - resolution: {integrity: sha512-e3C/RRhGunWYNC3aSF7exsQkdXzQ/M+aYuZHKnw4U7KQwTJotnWsGOIVih0s2qQzmEzOFIJ3+xt7iq67K/p56Q==} + '@tailwindcss/oxide-linux-x64-musl@4.1.12': + resolution: {integrity: sha512-ha0pHPamN+fWZY7GCzz5rKunlv9L5R8kdh+YNvP5awe3LtuXb5nRi/H27GeL2U+TdhDOptU7T6Is7mdwh5Ar3A==} engines: {node: '>= 10'} cpu: [x64] os: [linux] - '@tailwindcss/oxide-wasm32-wasi@4.1.11': - resolution: {integrity: sha512-Xo1+/GU0JEN/C/dvcammKHzeM6NqKovG+6921MR6oadee5XPBaKOumrJCXvopJ/Qb5TH7LX/UAywbqrP4lax0g==} + '@tailwindcss/oxide-wasm32-wasi@4.1.12': + resolution: {integrity: sha512-4tSyu3dW+ktzdEpuk6g49KdEangu3eCYoqPhWNsZgUhyegEda3M9rG0/j1GV/JjVVsj+lG7jWAyrTlLzd/WEBg==} engines: {node: '>=14.0.0'} cpu: [wasm32] bundledDependencies: @@ -1677,31 +1683,31 @@ packages: - '@emnapi/wasi-threads' - tslib - '@tailwindcss/oxide-win32-arm64-msvc@4.1.11': - resolution: {integrity: sha512-UgKYx5PwEKrac3GPNPf6HVMNhUIGuUh4wlDFR2jYYdkX6pL/rn73zTq/4pzUm8fOjAn5L8zDeHp9iXmUGOXZ+w==} + '@tailwindcss/oxide-win32-arm64-msvc@4.1.12': + resolution: {integrity: sha512-iGLyD/cVP724+FGtMWslhcFyg4xyYyM+5F4hGvKA7eifPkXHRAUDFaimu53fpNg9X8dfP75pXx/zFt/jlNF+lg==} engines: {node: '>= 10'} cpu: [arm64] os: [win32] - '@tailwindcss/oxide-win32-x64-msvc@4.1.11': - resolution: {integrity: sha512-YfHoggn1j0LK7wR82TOucWc5LDCguHnoS879idHekmmiR7g9HUtMw9MI0NHatS28u/Xlkfi9w5RJWgz2Dl+5Qg==} + '@tailwindcss/oxide-win32-x64-msvc@4.1.12': + resolution: {integrity: sha512-NKIh5rzw6CpEodv/++r0hGLlfgT/gFN+5WNdZtvh6wpU2BpGNgdjvj6H2oFc8nCM839QM1YOhjpgbAONUb4IxA==} engines: {node: '>= 10'} cpu: [x64] os: [win32] - '@tailwindcss/oxide@4.1.11': - resolution: {integrity: sha512-Q69XzrtAhuyfHo+5/HMgr1lAiPP/G40OMFAnws7xcFEYqcypZmdW8eGXaOUIeOl1dzPJBPENXgbjsOyhg2nkrg==} + '@tailwindcss/oxide@4.1.12': + resolution: {integrity: sha512-gM5EoKHW/ukmlEtphNwaGx45fGoEmP10v51t9unv55voWh6WrOL19hfuIdo2FjxIaZzw776/BUQg7Pck++cIVw==} engines: {node: '>= 10'} - '@tailwindcss/postcss@4.1.11': - resolution: {integrity: sha512-q/EAIIpF6WpLhKEuQSEVMZNMIY8KhWoAemZ9eylNAih9jxMGAYPPWBn3I9QL/2jZ+e7OEz/tZkX5HwbBR4HohA==} + '@tailwindcss/postcss@4.1.12': + resolution: {integrity: sha512-5PpLYhCAwf9SJEeIsSmCDLgyVfdBhdBpzX1OJ87anT9IVR0Z9pjM0FNixCAUAHGnMBGB8K99SwAheXrT0Kh6QQ==} '@testing-library/dom@10.4.1': resolution: {integrity: sha512-o4PXJQidqJl82ckFaXUeoAW+XysPLauYI43Abki5hABd853iMhitooc6znOnczgbTYmEP6U6/y1ZyKAIsvMKGg==} engines: {node: '>=18'} - '@testing-library/jest-dom@6.6.4': - resolution: {integrity: sha512-xDXgLjVunjHqczScfkCJ9iyjdNOVHvvCdqHSSxwM9L0l/wHkTRum67SDc020uAlCoqktJplgO2AAQeLP1wgqDQ==} + '@testing-library/jest-dom@6.7.0': + resolution: {integrity: sha512-RI2e97YZ7MRa+vxP4UUnMuMFL2buSsf0ollxUbTgrbPLKhMn8KVTx7raS6DYjC7v1NDVrioOvaShxsguLNISCA==} engines: {node: '>=14', npm: '>=6', yarn: '>=1'} '@testing-library/react@16.3.0': @@ -1779,8 +1785,8 @@ packages: '@types/json5@0.0.29': resolution: {integrity: sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==} - '@types/node@24.2.1': - resolution: {integrity: sha512-DRh5K+ka5eJic8CjH7td8QpYEV6Zo10gfRkjHCO3weqZHWDtAaSTFtl4+VMqOJ4N5jcuhZ9/l+yy8rVgw7BQeQ==} + '@types/node@24.3.0': + resolution: {integrity: sha512-aPTXCrfwnDLj4VvXrm+UUCQjNEvJgNA8s5F1cvwQU+3KNltTOkBm1j30uNLyqqPNe7gE3KFzImYoZEfLhp4Yow==} '@types/pg@8.15.5': resolution: {integrity: sha512-LF7lF6zWEKxuT3/OR8wAZGzkg4ENGXFNyiV/JeOt9z5B+0ZVwbql9McqX5c/WStFq1GaGso7H1AzP/qSzmlCKQ==} @@ -1790,8 +1796,8 @@ packages: peerDependencies: '@types/react': ^19.0.0 - '@types/react@19.1.9': - resolution: {integrity: sha512-WmdoynAX8Stew/36uTSVMcLJJ1KRh6L3IZRx1PZ7qJtBqT3dYTgyDTx8H1qoRghErydW7xw9mSJ3wS//tCRpFA==} + '@types/react@19.1.10': + resolution: {integrity: sha512-EhBeSYX0Y6ye8pNebpKrwFJq7BoQ8J5SO6NlvNwwHjSj6adXJViPQrKlsyPw7hLBLvckEMO1yxeGdR82YBBlDg==} '@types/sanitize-html@2.16.0': resolution: {integrity: sha512-l6rX1MUXje5ztPT0cAFtUayXF06DqPhRyfVXareEN5gGCFaP/iwsxIyKODr9XDhfxPpN6vXUFNfo5kZMXCxBtw==} @@ -2489,8 +2495,8 @@ packages: emoji-regex@9.2.2: resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==} - enhanced-resolve@5.18.2: - resolution: {integrity: sha512-6Jw4sE1maoRJo3q8MsSIn2onJFbLTOjY9hlx4DZXmOKvLRd1Ok2kXmAGXaafL2+ijsJZ1ClYbl/pmqr9+k4iUQ==} + enhanced-resolve@5.18.3: + resolution: {integrity: sha512-d4lC8xfavMeBjzGr2vECC3fsGXziXZQyJxD868h2M/mBI3PwAuODxAkLkq5HYuvrPYcUtiLzsTo8U3PgX3Ocww==} engines: {node: '>=10.13.0'} entities@4.5.0: @@ -2673,6 +2679,9 @@ packages: resolution: {integrity: sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==} engines: {node: '>=10'} + exifr@7.1.3: + resolution: {integrity: sha512-g/aje2noHivrRSLbAUtBPWFbxKdKhgj/xr1vATDdUXPOFYJlQ62Ft0oy+72V6XLIpDJfHs6gXLbBLAolqOXYRw==} + exit-x@0.2.2: resolution: {integrity: sha512-+I6B/IkJc1o/2tiURyz/ivu/O0nKNEArIUB5O7zBrlDVJr22SCLH3xTeEry428LvFhRzIA1g8izguxJ/gbNcVQ==} engines: {node: '>= 0.8.0'} @@ -3414,9 +3423,6 @@ packages: lodash.merge@4.6.2: resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==} - lodash@4.17.21: - resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==} - loose-envify@1.4.0: resolution: {integrity: sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==} hasBin: true @@ -4157,8 +4163,8 @@ packages: resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} engines: {node: '>= 0.4'} - swr@2.3.4: - resolution: {integrity: sha512-bYd2lrhc+VarcpkgWclcUi92wYCpOgMws9Sd1hG1ntAu0NEy+14CbotuFjshBU2kt9rYj9TSmDcybpxpeTU1fg==} + swr@2.3.6: + resolution: {integrity: sha512-wfHRmHWk/isGNMwlLGlZX5Gzz/uTgo0o2IRuTMcf4CPuPFJZlq0rDaKUx+ozB5nBOReNV1kiOyzMfj+MBMikLw==} peerDependencies: react: ^16.11.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 @@ -4169,8 +4175,8 @@ packages: resolution: {integrity: sha512-MeQTA1r0litLUf0Rp/iisCaL8761lKAZHaimlbGK4j0HysC4PLfqygQj9srcs0m2RdtDYnF8UuYyKpbjHYp7Jw==} engines: {node: ^14.18.0 || >=16.0.0} - tailwindcss@4.1.11: - resolution: {integrity: sha512-2E9TBm6MDD/xKYe+dvJZAmg3yxIEDNRc0jwlNyDg/4Fil2QcSLjFKGVff0lAf1jjeaArlG/M75Ey/EYr/OJtBA==} + tailwindcss@4.1.12: + resolution: {integrity: sha512-DzFtxOi+7NsFf7DBtI3BJsynR+0Yp6etH+nRPTbpWnS2pZBaSksv/JGctNwSWzbFjp0vxSqknaUylseZqMDGrA==} tapable@2.2.2: resolution: {integrity: sha512-Re10+NauLTMCudc7T5WLFLAwDhQ0JWdrMK+9B2M8zR5hRExKmsRDCBA7/aV/pNJFltmBFO5BAMlQFi/vq3nKOg==} @@ -4528,7 +4534,7 @@ snapshots: '@ai-sdk/provider-utils': 2.2.8(zod@3.25.76) '@ai-sdk/ui-utils': 1.2.11(zod@3.25.76) react: 19.1.1 - swr: 2.3.4(react@19.1.1) + swr: 2.3.6(react@19.1.1) throttleit: 2.1.0 optionalDependencies: zod: 3.25.76 @@ -5468,13 +5474,13 @@ snapshots: '@jest/console@30.0.5': dependencies: '@jest/types': 30.0.5 - '@types/node': 24.2.1 + '@types/node': 24.3.0 chalk: 4.1.2 jest-message-util: 30.0.5 jest-util: 30.0.5 slash: 3.0.0 - '@jest/core@30.0.5(ts-node@10.9.2(@types/node@24.2.1)(typescript@5.9.2))': + '@jest/core@30.0.5(ts-node@10.9.2(@types/node@24.3.0)(typescript@5.9.2))': dependencies: '@jest/console': 30.0.5 '@jest/pattern': 30.0.1 @@ -5482,14 +5488,14 @@ snapshots: '@jest/test-result': 30.0.5 '@jest/transform': 30.0.5 '@jest/types': 30.0.5 - '@types/node': 24.2.1 + '@types/node': 24.3.0 ansi-escapes: 4.3.2 chalk: 4.1.2 ci-info: 4.3.0 exit-x: 0.2.2 graceful-fs: 4.2.11 jest-changed-files: 30.0.5 - jest-config: 30.0.5(@types/node@24.2.1)(ts-node@10.9.2(@types/node@24.2.1)(typescript@5.9.2)) + jest-config: 30.0.5(@types/node@24.3.0)(ts-node@10.9.2(@types/node@24.3.0)(typescript@5.9.2)) jest-haste-map: 30.0.5 jest-message-util: 30.0.5 jest-regex-util: 30.0.1 @@ -5518,7 +5524,7 @@ snapshots: '@jest/fake-timers': 30.0.5 '@jest/types': 30.0.5 '@types/jsdom': 21.1.7 - '@types/node': 24.2.1 + '@types/node': 24.3.0 jest-mock: 30.0.5 jest-util: 30.0.5 jsdom: 26.1.0 @@ -5527,7 +5533,7 @@ snapshots: dependencies: '@jest/fake-timers': 30.0.5 '@jest/types': 30.0.5 - '@types/node': 24.2.1 + '@types/node': 24.3.0 jest-mock: 30.0.5 '@jest/expect-utils@30.0.5': @@ -5545,7 +5551,7 @@ snapshots: dependencies: '@jest/types': 30.0.5 '@sinonjs/fake-timers': 13.0.5 - '@types/node': 24.2.1 + '@types/node': 24.3.0 jest-message-util: 30.0.5 jest-mock: 30.0.5 jest-util: 30.0.5 @@ -5563,7 +5569,7 @@ snapshots: '@jest/pattern@30.0.1': dependencies: - '@types/node': 24.2.1 + '@types/node': 24.3.0 jest-regex-util: 30.0.1 '@jest/reporters@30.0.5': @@ -5574,7 +5580,7 @@ snapshots: '@jest/transform': 30.0.5 '@jest/types': 30.0.5 '@jridgewell/trace-mapping': 0.3.29 - '@types/node': 24.2.1 + '@types/node': 24.3.0 chalk: 4.1.2 collect-v8-coverage: 1.0.2 exit-x: 0.2.2 @@ -5651,7 +5657,7 @@ snapshots: '@jest/schemas': 30.0.5 '@types/istanbul-lib-coverage': 2.0.6 '@types/istanbul-reports': 3.0.4 - '@types/node': 24.2.1 + '@types/node': 24.3.0 '@types/yargs': 17.0.33 chalk: 4.1.2 @@ -5660,6 +5666,11 @@ snapshots: '@jridgewell/sourcemap-codec': 1.5.4 '@jridgewell/trace-mapping': 0.3.29 + '@jridgewell/remapping@2.3.5': + dependencies: + '@jridgewell/gen-mapping': 0.3.12 + '@jridgewell/trace-mapping': 0.3.29 + '@jridgewell/resolve-uri@3.1.2': {} '@jridgewell/sourcemap-codec@1.5.4': {} @@ -5743,294 +5754,294 @@ snapshots: '@polka/url@1.0.0-next.29': {} - '@radix-ui/primitive@1.1.2': {} + '@radix-ui/primitive@1.1.3': {} - '@radix-ui/react-arrow@1.1.7(@types/react-dom@19.1.7(@types/react@19.1.9))(@types/react@19.1.9)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)': + '@radix-ui/react-arrow@1.1.7(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)': dependencies: - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.7(@types/react@19.1.9))(@types/react@19.1.9)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) react: 19.1.1 react-dom: 19.1.1(react@19.1.1) optionalDependencies: - '@types/react': 19.1.9 - '@types/react-dom': 19.1.7(@types/react@19.1.9) + '@types/react': 19.1.10 + '@types/react-dom': 19.1.7(@types/react@19.1.10) - '@radix-ui/react-collection@1.1.7(@types/react-dom@19.1.7(@types/react@19.1.9))(@types/react@19.1.9)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)': + '@radix-ui/react-collection@1.1.7(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)': dependencies: - '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.1.9)(react@19.1.1) - '@radix-ui/react-context': 1.1.2(@types/react@19.1.9)(react@19.1.1) - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.7(@types/react@19.1.9))(@types/react@19.1.9)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) - '@radix-ui/react-slot': 1.2.3(@types/react@19.1.9)(react@19.1.1) + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.1.10)(react@19.1.1) + '@radix-ui/react-context': 1.1.2(@types/react@19.1.10)(react@19.1.1) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + '@radix-ui/react-slot': 1.2.3(@types/react@19.1.10)(react@19.1.1) react: 19.1.1 react-dom: 19.1.1(react@19.1.1) optionalDependencies: - '@types/react': 19.1.9 - '@types/react-dom': 19.1.7(@types/react@19.1.9) + '@types/react': 19.1.10 + '@types/react-dom': 19.1.7(@types/react@19.1.10) - '@radix-ui/react-compose-refs@1.1.2(@types/react@19.1.9)(react@19.1.1)': + '@radix-ui/react-compose-refs@1.1.2(@types/react@19.1.10)(react@19.1.1)': dependencies: react: 19.1.1 optionalDependencies: - '@types/react': 19.1.9 + '@types/react': 19.1.10 - '@radix-ui/react-context@1.1.2(@types/react@19.1.9)(react@19.1.1)': + '@radix-ui/react-context@1.1.2(@types/react@19.1.10)(react@19.1.1)': dependencies: react: 19.1.1 optionalDependencies: - '@types/react': 19.1.9 + '@types/react': 19.1.10 - '@radix-ui/react-dialog@1.1.14(@types/react-dom@19.1.7(@types/react@19.1.9))(@types/react@19.1.9)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)': + '@radix-ui/react-dialog@1.1.15(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)': dependencies: - '@radix-ui/primitive': 1.1.2 - '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.1.9)(react@19.1.1) - '@radix-ui/react-context': 1.1.2(@types/react@19.1.9)(react@19.1.1) - '@radix-ui/react-dismissable-layer': 1.1.10(@types/react-dom@19.1.7(@types/react@19.1.9))(@types/react@19.1.9)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) - '@radix-ui/react-focus-guards': 1.1.2(@types/react@19.1.9)(react@19.1.1) - '@radix-ui/react-focus-scope': 1.1.7(@types/react-dom@19.1.7(@types/react@19.1.9))(@types/react@19.1.9)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) - '@radix-ui/react-id': 1.1.1(@types/react@19.1.9)(react@19.1.1) - '@radix-ui/react-portal': 1.1.9(@types/react-dom@19.1.7(@types/react@19.1.9))(@types/react@19.1.9)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) - '@radix-ui/react-presence': 1.1.4(@types/react-dom@19.1.7(@types/react@19.1.9))(@types/react@19.1.9)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.7(@types/react@19.1.9))(@types/react@19.1.9)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) - '@radix-ui/react-slot': 1.2.3(@types/react@19.1.9)(react@19.1.1) - '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.1.9)(react@19.1.1) + '@radix-ui/primitive': 1.1.3 + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.1.10)(react@19.1.1) + '@radix-ui/react-context': 1.1.2(@types/react@19.1.10)(react@19.1.1) + '@radix-ui/react-dismissable-layer': 1.1.11(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + '@radix-ui/react-focus-guards': 1.1.3(@types/react@19.1.10)(react@19.1.1) + '@radix-ui/react-focus-scope': 1.1.7(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + '@radix-ui/react-id': 1.1.1(@types/react@19.1.10)(react@19.1.1) + '@radix-ui/react-portal': 1.1.9(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + '@radix-ui/react-presence': 1.1.5(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + '@radix-ui/react-slot': 1.2.3(@types/react@19.1.10)(react@19.1.1) + '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.1.10)(react@19.1.1) aria-hidden: 1.2.6 react: 19.1.1 react-dom: 19.1.1(react@19.1.1) - react-remove-scroll: 2.7.1(@types/react@19.1.9)(react@19.1.1) + react-remove-scroll: 2.7.1(@types/react@19.1.10)(react@19.1.1) optionalDependencies: - '@types/react': 19.1.9 - '@types/react-dom': 19.1.7(@types/react@19.1.9) + '@types/react': 19.1.10 + '@types/react-dom': 19.1.7(@types/react@19.1.10) - '@radix-ui/react-direction@1.1.1(@types/react@19.1.9)(react@19.1.1)': + '@radix-ui/react-direction@1.1.1(@types/react@19.1.10)(react@19.1.1)': dependencies: react: 19.1.1 optionalDependencies: - '@types/react': 19.1.9 + '@types/react': 19.1.10 - '@radix-ui/react-dismissable-layer@1.1.10(@types/react-dom@19.1.7(@types/react@19.1.9))(@types/react@19.1.9)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)': + '@radix-ui/react-dismissable-layer@1.1.11(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)': dependencies: - '@radix-ui/primitive': 1.1.2 - '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.1.9)(react@19.1.1) - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.7(@types/react@19.1.9))(@types/react@19.1.9)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) - '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.1.9)(react@19.1.1) - '@radix-ui/react-use-escape-keydown': 1.1.1(@types/react@19.1.9)(react@19.1.1) + '@radix-ui/primitive': 1.1.3 + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.1.10)(react@19.1.1) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.1.10)(react@19.1.1) + '@radix-ui/react-use-escape-keydown': 1.1.1(@types/react@19.1.10)(react@19.1.1) react: 19.1.1 react-dom: 19.1.1(react@19.1.1) optionalDependencies: - '@types/react': 19.1.9 - '@types/react-dom': 19.1.7(@types/react@19.1.9) + '@types/react': 19.1.10 + '@types/react-dom': 19.1.7(@types/react@19.1.10) - '@radix-ui/react-dropdown-menu@2.1.15(@types/react-dom@19.1.7(@types/react@19.1.9))(@types/react@19.1.9)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)': + '@radix-ui/react-dropdown-menu@2.1.16(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)': dependencies: - '@radix-ui/primitive': 1.1.2 - '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.1.9)(react@19.1.1) - '@radix-ui/react-context': 1.1.2(@types/react@19.1.9)(react@19.1.1) - '@radix-ui/react-id': 1.1.1(@types/react@19.1.9)(react@19.1.1) - '@radix-ui/react-menu': 2.1.15(@types/react-dom@19.1.7(@types/react@19.1.9))(@types/react@19.1.9)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.7(@types/react@19.1.9))(@types/react@19.1.9)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) - '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.1.9)(react@19.1.1) + '@radix-ui/primitive': 1.1.3 + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.1.10)(react@19.1.1) + '@radix-ui/react-context': 1.1.2(@types/react@19.1.10)(react@19.1.1) + '@radix-ui/react-id': 1.1.1(@types/react@19.1.10)(react@19.1.1) + '@radix-ui/react-menu': 2.1.16(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.1.10)(react@19.1.1) react: 19.1.1 react-dom: 19.1.1(react@19.1.1) optionalDependencies: - '@types/react': 19.1.9 - '@types/react-dom': 19.1.7(@types/react@19.1.9) + '@types/react': 19.1.10 + '@types/react-dom': 19.1.7(@types/react@19.1.10) - '@radix-ui/react-focus-guards@1.1.2(@types/react@19.1.9)(react@19.1.1)': + '@radix-ui/react-focus-guards@1.1.3(@types/react@19.1.10)(react@19.1.1)': dependencies: react: 19.1.1 optionalDependencies: - '@types/react': 19.1.9 + '@types/react': 19.1.10 - '@radix-ui/react-focus-scope@1.1.7(@types/react-dom@19.1.7(@types/react@19.1.9))(@types/react@19.1.9)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)': + '@radix-ui/react-focus-scope@1.1.7(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)': dependencies: - '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.1.9)(react@19.1.1) - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.7(@types/react@19.1.9))(@types/react@19.1.9)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) - '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.1.9)(react@19.1.1) + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.1.10)(react@19.1.1) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.1.10)(react@19.1.1) react: 19.1.1 react-dom: 19.1.1(react@19.1.1) optionalDependencies: - '@types/react': 19.1.9 - '@types/react-dom': 19.1.7(@types/react@19.1.9) + '@types/react': 19.1.10 + '@types/react-dom': 19.1.7(@types/react@19.1.10) - '@radix-ui/react-id@1.1.1(@types/react@19.1.9)(react@19.1.1)': + '@radix-ui/react-id@1.1.1(@types/react@19.1.10)(react@19.1.1)': dependencies: - '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.1.9)(react@19.1.1) + '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.1.10)(react@19.1.1) react: 19.1.1 optionalDependencies: - '@types/react': 19.1.9 + '@types/react': 19.1.10 - '@radix-ui/react-menu@2.1.15(@types/react-dom@19.1.7(@types/react@19.1.9))(@types/react@19.1.9)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)': + '@radix-ui/react-menu@2.1.16(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)': dependencies: - '@radix-ui/primitive': 1.1.2 - '@radix-ui/react-collection': 1.1.7(@types/react-dom@19.1.7(@types/react@19.1.9))(@types/react@19.1.9)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) - '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.1.9)(react@19.1.1) - '@radix-ui/react-context': 1.1.2(@types/react@19.1.9)(react@19.1.1) - '@radix-ui/react-direction': 1.1.1(@types/react@19.1.9)(react@19.1.1) - '@radix-ui/react-dismissable-layer': 1.1.10(@types/react-dom@19.1.7(@types/react@19.1.9))(@types/react@19.1.9)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) - '@radix-ui/react-focus-guards': 1.1.2(@types/react@19.1.9)(react@19.1.1) - '@radix-ui/react-focus-scope': 1.1.7(@types/react-dom@19.1.7(@types/react@19.1.9))(@types/react@19.1.9)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) - '@radix-ui/react-id': 1.1.1(@types/react@19.1.9)(react@19.1.1) - '@radix-ui/react-popper': 1.2.7(@types/react-dom@19.1.7(@types/react@19.1.9))(@types/react@19.1.9)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) - '@radix-ui/react-portal': 1.1.9(@types/react-dom@19.1.7(@types/react@19.1.9))(@types/react@19.1.9)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) - '@radix-ui/react-presence': 1.1.4(@types/react-dom@19.1.7(@types/react@19.1.9))(@types/react@19.1.9)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.7(@types/react@19.1.9))(@types/react@19.1.9)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) - '@radix-ui/react-roving-focus': 1.1.10(@types/react-dom@19.1.7(@types/react@19.1.9))(@types/react@19.1.9)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) - '@radix-ui/react-slot': 1.2.3(@types/react@19.1.9)(react@19.1.1) - '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.1.9)(react@19.1.1) + '@radix-ui/primitive': 1.1.3 + '@radix-ui/react-collection': 1.1.7(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.1.10)(react@19.1.1) + '@radix-ui/react-context': 1.1.2(@types/react@19.1.10)(react@19.1.1) + '@radix-ui/react-direction': 1.1.1(@types/react@19.1.10)(react@19.1.1) + '@radix-ui/react-dismissable-layer': 1.1.11(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + '@radix-ui/react-focus-guards': 1.1.3(@types/react@19.1.10)(react@19.1.1) + '@radix-ui/react-focus-scope': 1.1.7(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + '@radix-ui/react-id': 1.1.1(@types/react@19.1.10)(react@19.1.1) + '@radix-ui/react-popper': 1.2.8(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + '@radix-ui/react-portal': 1.1.9(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + '@radix-ui/react-presence': 1.1.5(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + '@radix-ui/react-roving-focus': 1.1.11(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + '@radix-ui/react-slot': 1.2.3(@types/react@19.1.10)(react@19.1.1) + '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.1.10)(react@19.1.1) aria-hidden: 1.2.6 react: 19.1.1 react-dom: 19.1.1(react@19.1.1) - react-remove-scroll: 2.7.1(@types/react@19.1.9)(react@19.1.1) + react-remove-scroll: 2.7.1(@types/react@19.1.10)(react@19.1.1) optionalDependencies: - '@types/react': 19.1.9 - '@types/react-dom': 19.1.7(@types/react@19.1.9) + '@types/react': 19.1.10 + '@types/react-dom': 19.1.7(@types/react@19.1.10) - '@radix-ui/react-popper@1.2.7(@types/react-dom@19.1.7(@types/react@19.1.9))(@types/react@19.1.9)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)': + '@radix-ui/react-popper@1.2.8(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)': dependencies: '@floating-ui/react-dom': 2.1.5(react-dom@19.1.1(react@19.1.1))(react@19.1.1) - '@radix-ui/react-arrow': 1.1.7(@types/react-dom@19.1.7(@types/react@19.1.9))(@types/react@19.1.9)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) - '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.1.9)(react@19.1.1) - '@radix-ui/react-context': 1.1.2(@types/react@19.1.9)(react@19.1.1) - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.7(@types/react@19.1.9))(@types/react@19.1.9)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) - '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.1.9)(react@19.1.1) - '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.1.9)(react@19.1.1) - '@radix-ui/react-use-rect': 1.1.1(@types/react@19.1.9)(react@19.1.1) - '@radix-ui/react-use-size': 1.1.1(@types/react@19.1.9)(react@19.1.1) + '@radix-ui/react-arrow': 1.1.7(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.1.10)(react@19.1.1) + '@radix-ui/react-context': 1.1.2(@types/react@19.1.10)(react@19.1.1) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.1.10)(react@19.1.1) + '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.1.10)(react@19.1.1) + '@radix-ui/react-use-rect': 1.1.1(@types/react@19.1.10)(react@19.1.1) + '@radix-ui/react-use-size': 1.1.1(@types/react@19.1.10)(react@19.1.1) '@radix-ui/rect': 1.1.1 react: 19.1.1 react-dom: 19.1.1(react@19.1.1) optionalDependencies: - '@types/react': 19.1.9 - '@types/react-dom': 19.1.7(@types/react@19.1.9) + '@types/react': 19.1.10 + '@types/react-dom': 19.1.7(@types/react@19.1.10) - '@radix-ui/react-portal@1.1.9(@types/react-dom@19.1.7(@types/react@19.1.9))(@types/react@19.1.9)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)': + '@radix-ui/react-portal@1.1.9(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)': dependencies: - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.7(@types/react@19.1.9))(@types/react@19.1.9)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) - '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.1.9)(react@19.1.1) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.1.10)(react@19.1.1) react: 19.1.1 react-dom: 19.1.1(react@19.1.1) optionalDependencies: - '@types/react': 19.1.9 - '@types/react-dom': 19.1.7(@types/react@19.1.9) + '@types/react': 19.1.10 + '@types/react-dom': 19.1.7(@types/react@19.1.10) - '@radix-ui/react-presence@1.1.4(@types/react-dom@19.1.7(@types/react@19.1.9))(@types/react@19.1.9)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)': + '@radix-ui/react-presence@1.1.5(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)': dependencies: - '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.1.9)(react@19.1.1) - '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.1.9)(react@19.1.1) + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.1.10)(react@19.1.1) + '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.1.10)(react@19.1.1) react: 19.1.1 react-dom: 19.1.1(react@19.1.1) optionalDependencies: - '@types/react': 19.1.9 - '@types/react-dom': 19.1.7(@types/react@19.1.9) + '@types/react': 19.1.10 + '@types/react-dom': 19.1.7(@types/react@19.1.10) - '@radix-ui/react-primitive@2.1.3(@types/react-dom@19.1.7(@types/react@19.1.9))(@types/react@19.1.9)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)': + '@radix-ui/react-primitive@2.1.3(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)': dependencies: - '@radix-ui/react-slot': 1.2.3(@types/react@19.1.9)(react@19.1.1) + '@radix-ui/react-slot': 1.2.3(@types/react@19.1.10)(react@19.1.1) react: 19.1.1 react-dom: 19.1.1(react@19.1.1) optionalDependencies: - '@types/react': 19.1.9 - '@types/react-dom': 19.1.7(@types/react@19.1.9) + '@types/react': 19.1.10 + '@types/react-dom': 19.1.7(@types/react@19.1.10) - '@radix-ui/react-roving-focus@1.1.10(@types/react-dom@19.1.7(@types/react@19.1.9))(@types/react@19.1.9)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)': + '@radix-ui/react-roving-focus@1.1.11(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)': dependencies: - '@radix-ui/primitive': 1.1.2 - '@radix-ui/react-collection': 1.1.7(@types/react-dom@19.1.7(@types/react@19.1.9))(@types/react@19.1.9)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) - '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.1.9)(react@19.1.1) - '@radix-ui/react-context': 1.1.2(@types/react@19.1.9)(react@19.1.1) - '@radix-ui/react-direction': 1.1.1(@types/react@19.1.9)(react@19.1.1) - '@radix-ui/react-id': 1.1.1(@types/react@19.1.9)(react@19.1.1) - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.7(@types/react@19.1.9))(@types/react@19.1.9)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) - '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.1.9)(react@19.1.1) - '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.1.9)(react@19.1.1) + '@radix-ui/primitive': 1.1.3 + '@radix-ui/react-collection': 1.1.7(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.1.10)(react@19.1.1) + '@radix-ui/react-context': 1.1.2(@types/react@19.1.10)(react@19.1.1) + '@radix-ui/react-direction': 1.1.1(@types/react@19.1.10)(react@19.1.1) + '@radix-ui/react-id': 1.1.1(@types/react@19.1.10)(react@19.1.1) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.1.10)(react@19.1.1) + '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.1.10)(react@19.1.1) react: 19.1.1 react-dom: 19.1.1(react@19.1.1) optionalDependencies: - '@types/react': 19.1.9 - '@types/react-dom': 19.1.7(@types/react@19.1.9) + '@types/react': 19.1.10 + '@types/react-dom': 19.1.7(@types/react@19.1.10) - '@radix-ui/react-slot@1.2.3(@types/react@19.1.9)(react@19.1.1)': + '@radix-ui/react-slot@1.2.3(@types/react@19.1.10)(react@19.1.1)': dependencies: - '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.1.9)(react@19.1.1) + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.1.10)(react@19.1.1) react: 19.1.1 optionalDependencies: - '@types/react': 19.1.9 + '@types/react': 19.1.10 - '@radix-ui/react-tooltip@1.2.7(@types/react-dom@19.1.7(@types/react@19.1.9))(@types/react@19.1.9)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)': + '@radix-ui/react-tooltip@1.2.8(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)': dependencies: - '@radix-ui/primitive': 1.1.2 - '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.1.9)(react@19.1.1) - '@radix-ui/react-context': 1.1.2(@types/react@19.1.9)(react@19.1.1) - '@radix-ui/react-dismissable-layer': 1.1.10(@types/react-dom@19.1.7(@types/react@19.1.9))(@types/react@19.1.9)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) - '@radix-ui/react-id': 1.1.1(@types/react@19.1.9)(react@19.1.1) - '@radix-ui/react-popper': 1.2.7(@types/react-dom@19.1.7(@types/react@19.1.9))(@types/react@19.1.9)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) - '@radix-ui/react-portal': 1.1.9(@types/react-dom@19.1.7(@types/react@19.1.9))(@types/react@19.1.9)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) - '@radix-ui/react-presence': 1.1.4(@types/react-dom@19.1.7(@types/react@19.1.9))(@types/react@19.1.9)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.7(@types/react@19.1.9))(@types/react@19.1.9)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) - '@radix-ui/react-slot': 1.2.3(@types/react@19.1.9)(react@19.1.1) - '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.1.9)(react@19.1.1) - '@radix-ui/react-visually-hidden': 1.2.3(@types/react-dom@19.1.7(@types/react@19.1.9))(@types/react@19.1.9)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + '@radix-ui/primitive': 1.1.3 + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.1.10)(react@19.1.1) + '@radix-ui/react-context': 1.1.2(@types/react@19.1.10)(react@19.1.1) + '@radix-ui/react-dismissable-layer': 1.1.11(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + '@radix-ui/react-id': 1.1.1(@types/react@19.1.10)(react@19.1.1) + '@radix-ui/react-popper': 1.2.8(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + '@radix-ui/react-portal': 1.1.9(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + '@radix-ui/react-presence': 1.1.5(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + '@radix-ui/react-slot': 1.2.3(@types/react@19.1.10)(react@19.1.1) + '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.1.10)(react@19.1.1) + '@radix-ui/react-visually-hidden': 1.2.3(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) react: 19.1.1 react-dom: 19.1.1(react@19.1.1) optionalDependencies: - '@types/react': 19.1.9 - '@types/react-dom': 19.1.7(@types/react@19.1.9) + '@types/react': 19.1.10 + '@types/react-dom': 19.1.7(@types/react@19.1.10) - '@radix-ui/react-use-callback-ref@1.1.1(@types/react@19.1.9)(react@19.1.1)': + '@radix-ui/react-use-callback-ref@1.1.1(@types/react@19.1.10)(react@19.1.1)': dependencies: react: 19.1.1 optionalDependencies: - '@types/react': 19.1.9 + '@types/react': 19.1.10 - '@radix-ui/react-use-controllable-state@1.2.2(@types/react@19.1.9)(react@19.1.1)': + '@radix-ui/react-use-controllable-state@1.2.2(@types/react@19.1.10)(react@19.1.1)': dependencies: - '@radix-ui/react-use-effect-event': 0.0.2(@types/react@19.1.9)(react@19.1.1) - '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.1.9)(react@19.1.1) + '@radix-ui/react-use-effect-event': 0.0.2(@types/react@19.1.10)(react@19.1.1) + '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.1.10)(react@19.1.1) react: 19.1.1 optionalDependencies: - '@types/react': 19.1.9 + '@types/react': 19.1.10 - '@radix-ui/react-use-effect-event@0.0.2(@types/react@19.1.9)(react@19.1.1)': + '@radix-ui/react-use-effect-event@0.0.2(@types/react@19.1.10)(react@19.1.1)': dependencies: - '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.1.9)(react@19.1.1) + '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.1.10)(react@19.1.1) react: 19.1.1 optionalDependencies: - '@types/react': 19.1.9 + '@types/react': 19.1.10 - '@radix-ui/react-use-escape-keydown@1.1.1(@types/react@19.1.9)(react@19.1.1)': + '@radix-ui/react-use-escape-keydown@1.1.1(@types/react@19.1.10)(react@19.1.1)': dependencies: - '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.1.9)(react@19.1.1) + '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.1.10)(react@19.1.1) react: 19.1.1 optionalDependencies: - '@types/react': 19.1.9 + '@types/react': 19.1.10 - '@radix-ui/react-use-layout-effect@1.1.1(@types/react@19.1.9)(react@19.1.1)': + '@radix-ui/react-use-layout-effect@1.1.1(@types/react@19.1.10)(react@19.1.1)': dependencies: react: 19.1.1 optionalDependencies: - '@types/react': 19.1.9 + '@types/react': 19.1.10 - '@radix-ui/react-use-rect@1.1.1(@types/react@19.1.9)(react@19.1.1)': + '@radix-ui/react-use-rect@1.1.1(@types/react@19.1.10)(react@19.1.1)': dependencies: '@radix-ui/rect': 1.1.1 react: 19.1.1 optionalDependencies: - '@types/react': 19.1.9 + '@types/react': 19.1.10 - '@radix-ui/react-use-size@1.1.1(@types/react@19.1.9)(react@19.1.1)': + '@radix-ui/react-use-size@1.1.1(@types/react@19.1.10)(react@19.1.1)': dependencies: - '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.1.9)(react@19.1.1) + '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.1.10)(react@19.1.1) react: 19.1.1 optionalDependencies: - '@types/react': 19.1.9 + '@types/react': 19.1.10 - '@radix-ui/react-visually-hidden@1.2.3(@types/react-dom@19.1.7(@types/react@19.1.9))(@types/react@19.1.9)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)': + '@radix-ui/react-visually-hidden@1.2.3(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)': dependencies: - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.7(@types/react@19.1.9))(@types/react@19.1.9)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) react: 19.1.1 react-dom: 19.1.1(react@19.1.1) optionalDependencies: - '@types/react': 19.1.9 - '@types/react-dom': 19.1.7(@types/react@19.1.9) + '@types/react': 19.1.10 + '@types/react-dom': 19.1.7(@types/react@19.1.10) '@radix-ui/rect@1.1.1': {} @@ -6398,86 +6409,86 @@ snapshots: dependencies: tslib: 2.8.1 - '@tailwindcss/container-queries@0.1.1(tailwindcss@4.1.11)': + '@tailwindcss/container-queries@0.1.1(tailwindcss@4.1.12)': dependencies: - tailwindcss: 4.1.11 + tailwindcss: 4.1.12 - '@tailwindcss/forms@0.5.10(tailwindcss@4.1.11)': + '@tailwindcss/forms@0.5.10(tailwindcss@4.1.12)': dependencies: mini-svg-data-uri: 1.4.4 - tailwindcss: 4.1.11 + tailwindcss: 4.1.12 - '@tailwindcss/node@4.1.11': + '@tailwindcss/node@4.1.12': dependencies: - '@ampproject/remapping': 2.3.0 - enhanced-resolve: 5.18.2 + '@jridgewell/remapping': 2.3.5 + enhanced-resolve: 5.18.3 jiti: 2.5.1 lightningcss: 1.30.1 magic-string: 0.30.17 source-map-js: 1.2.1 - tailwindcss: 4.1.11 + tailwindcss: 4.1.12 - '@tailwindcss/oxide-android-arm64@4.1.11': + '@tailwindcss/oxide-android-arm64@4.1.12': optional: true - '@tailwindcss/oxide-darwin-arm64@4.1.11': + '@tailwindcss/oxide-darwin-arm64@4.1.12': optional: true - '@tailwindcss/oxide-darwin-x64@4.1.11': + '@tailwindcss/oxide-darwin-x64@4.1.12': optional: true - '@tailwindcss/oxide-freebsd-x64@4.1.11': + '@tailwindcss/oxide-freebsd-x64@4.1.12': optional: true - '@tailwindcss/oxide-linux-arm-gnueabihf@4.1.11': + '@tailwindcss/oxide-linux-arm-gnueabihf@4.1.12': optional: true - '@tailwindcss/oxide-linux-arm64-gnu@4.1.11': + '@tailwindcss/oxide-linux-arm64-gnu@4.1.12': optional: true - '@tailwindcss/oxide-linux-arm64-musl@4.1.11': + '@tailwindcss/oxide-linux-arm64-musl@4.1.12': optional: true - '@tailwindcss/oxide-linux-x64-gnu@4.1.11': + '@tailwindcss/oxide-linux-x64-gnu@4.1.12': optional: true - '@tailwindcss/oxide-linux-x64-musl@4.1.11': + '@tailwindcss/oxide-linux-x64-musl@4.1.12': optional: true - '@tailwindcss/oxide-wasm32-wasi@4.1.11': + '@tailwindcss/oxide-wasm32-wasi@4.1.12': optional: true - '@tailwindcss/oxide-win32-arm64-msvc@4.1.11': + '@tailwindcss/oxide-win32-arm64-msvc@4.1.12': optional: true - '@tailwindcss/oxide-win32-x64-msvc@4.1.11': + '@tailwindcss/oxide-win32-x64-msvc@4.1.12': optional: true - '@tailwindcss/oxide@4.1.11': + '@tailwindcss/oxide@4.1.12': dependencies: detect-libc: 2.0.4 tar: 7.4.3 optionalDependencies: - '@tailwindcss/oxide-android-arm64': 4.1.11 - '@tailwindcss/oxide-darwin-arm64': 4.1.11 - '@tailwindcss/oxide-darwin-x64': 4.1.11 - '@tailwindcss/oxide-freebsd-x64': 4.1.11 - '@tailwindcss/oxide-linux-arm-gnueabihf': 4.1.11 - '@tailwindcss/oxide-linux-arm64-gnu': 4.1.11 - '@tailwindcss/oxide-linux-arm64-musl': 4.1.11 - '@tailwindcss/oxide-linux-x64-gnu': 4.1.11 - '@tailwindcss/oxide-linux-x64-musl': 4.1.11 - '@tailwindcss/oxide-wasm32-wasi': 4.1.11 - '@tailwindcss/oxide-win32-arm64-msvc': 4.1.11 - '@tailwindcss/oxide-win32-x64-msvc': 4.1.11 + '@tailwindcss/oxide-android-arm64': 4.1.12 + '@tailwindcss/oxide-darwin-arm64': 4.1.12 + '@tailwindcss/oxide-darwin-x64': 4.1.12 + '@tailwindcss/oxide-freebsd-x64': 4.1.12 + '@tailwindcss/oxide-linux-arm-gnueabihf': 4.1.12 + '@tailwindcss/oxide-linux-arm64-gnu': 4.1.12 + '@tailwindcss/oxide-linux-arm64-musl': 4.1.12 + '@tailwindcss/oxide-linux-x64-gnu': 4.1.12 + '@tailwindcss/oxide-linux-x64-musl': 4.1.12 + '@tailwindcss/oxide-wasm32-wasi': 4.1.12 + '@tailwindcss/oxide-win32-arm64-msvc': 4.1.12 + '@tailwindcss/oxide-win32-x64-msvc': 4.1.12 - '@tailwindcss/postcss@4.1.11': + '@tailwindcss/postcss@4.1.12': dependencies: '@alloc/quick-lru': 5.2.0 - '@tailwindcss/node': 4.1.11 - '@tailwindcss/oxide': 4.1.11 + '@tailwindcss/node': 4.1.12 + '@tailwindcss/oxide': 4.1.12 postcss: 8.5.6 - tailwindcss: 4.1.11 + tailwindcss: 4.1.12 '@testing-library/dom@10.4.1': dependencies: @@ -6490,25 +6501,24 @@ snapshots: picocolors: 1.1.1 pretty-format: 27.5.1 - '@testing-library/jest-dom@6.6.4': + '@testing-library/jest-dom@6.7.0': dependencies: '@adobe/css-tools': 4.4.3 aria-query: 5.3.2 css.escape: 1.5.1 dom-accessibility-api: 0.6.3 - lodash: 4.17.21 picocolors: 1.1.1 redent: 3.0.0 - '@testing-library/react@16.3.0(@testing-library/dom@10.4.1)(@types/react-dom@19.1.7(@types/react@19.1.9))(@types/react@19.1.9)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)': + '@testing-library/react@16.3.0(@testing-library/dom@10.4.1)(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)': dependencies: '@babel/runtime': 7.28.2 '@testing-library/dom': 10.4.1 react: 19.1.1 react-dom: 19.1.1(react@19.1.1) optionalDependencies: - '@types/react': 19.1.9 - '@types/react-dom': 19.1.7(@types/react@19.1.9) + '@types/react': 19.1.10 + '@types/react-dom': 19.1.7(@types/react@19.1.10) '@tsconfig/node10@1.0.11': {} @@ -6569,7 +6579,7 @@ snapshots: '@types/jsdom@21.1.7': dependencies: - '@types/node': 24.2.1 + '@types/node': 24.3.0 '@types/tough-cookie': 4.0.5 parse5: 7.3.0 @@ -6577,21 +6587,21 @@ snapshots: '@types/json5@0.0.29': {} - '@types/node@24.2.1': + '@types/node@24.3.0': dependencies: undici-types: 7.10.0 '@types/pg@8.15.5': dependencies: - '@types/node': 24.2.1 + '@types/node': 24.3.0 pg-protocol: 1.10.3 pg-types: 2.2.0 - '@types/react-dom@19.1.7(@types/react@19.1.9)': + '@types/react-dom@19.1.7(@types/react@19.1.10)': dependencies: - '@types/react': 19.1.9 + '@types/react': 19.1.10 - '@types/react@19.1.9': + '@types/react@19.1.10': dependencies: csstype: 3.1.3 @@ -7092,12 +7102,12 @@ snapshots: clsx@2.1.1: {} - cmdk@1.1.1(@types/react-dom@19.1.7(@types/react@19.1.9))(@types/react@19.1.9)(react-dom@19.1.1(react@19.1.1))(react@19.1.1): + cmdk@1.1.1(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@19.1.1(react@19.1.1))(react@19.1.1): dependencies: - '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.1.9)(react@19.1.1) - '@radix-ui/react-dialog': 1.1.14(@types/react-dom@19.1.7(@types/react@19.1.9))(@types/react@19.1.9)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) - '@radix-ui/react-id': 1.1.1(@types/react@19.1.9)(react@19.1.1) - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.7(@types/react@19.1.9))(@types/react@19.1.9)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.1.10)(react@19.1.1) + '@radix-ui/react-dialog': 1.1.15(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + '@radix-ui/react-id': 1.1.1(@types/react@19.1.10)(react@19.1.1) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) react: 19.1.1 react-dom: 19.1.1(react@19.1.1) transitivePeerDependencies: @@ -7272,7 +7282,7 @@ snapshots: emoji-regex@9.2.2: {} - enhanced-resolve@5.18.2: + enhanced-resolve@5.18.3: dependencies: graceful-fs: 4.2.11 tapable: 2.2.2 @@ -7603,6 +7613,8 @@ snapshots: signal-exit: 3.0.7 strip-final-newline: 2.0.0 + exifr@7.1.3: {} + exit-x@0.2.2: {} expect@30.0.5: @@ -8075,7 +8087,7 @@ snapshots: '@jest/expect': 30.0.5 '@jest/test-result': 30.0.5 '@jest/types': 30.0.5 - '@types/node': 24.2.1 + '@types/node': 24.3.0 chalk: 4.1.2 co: 4.6.0 dedent: 1.6.0 @@ -8095,15 +8107,15 @@ snapshots: - babel-plugin-macros - supports-color - jest-cli@30.0.5(@types/node@24.2.1)(ts-node@10.9.2(@types/node@24.2.1)(typescript@5.9.2)): + jest-cli@30.0.5(@types/node@24.3.0)(ts-node@10.9.2(@types/node@24.3.0)(typescript@5.9.2)): dependencies: - '@jest/core': 30.0.5(ts-node@10.9.2(@types/node@24.2.1)(typescript@5.9.2)) + '@jest/core': 30.0.5(ts-node@10.9.2(@types/node@24.3.0)(typescript@5.9.2)) '@jest/test-result': 30.0.5 '@jest/types': 30.0.5 chalk: 4.1.2 exit-x: 0.2.2 import-local: 3.2.0 - jest-config: 30.0.5(@types/node@24.2.1)(ts-node@10.9.2(@types/node@24.2.1)(typescript@5.9.2)) + jest-config: 30.0.5(@types/node@24.3.0)(ts-node@10.9.2(@types/node@24.3.0)(typescript@5.9.2)) jest-util: 30.0.5 jest-validate: 30.0.5 yargs: 17.7.2 @@ -8114,7 +8126,7 @@ snapshots: - supports-color - ts-node - jest-config@30.0.5(@types/node@24.2.1)(ts-node@10.9.2(@types/node@24.2.1)(typescript@5.9.2)): + jest-config@30.0.5(@types/node@24.3.0)(ts-node@10.9.2(@types/node@24.3.0)(typescript@5.9.2)): dependencies: '@babel/core': 7.28.0 '@jest/get-type': 30.0.1 @@ -8141,8 +8153,8 @@ snapshots: slash: 3.0.0 strip-json-comments: 3.1.1 optionalDependencies: - '@types/node': 24.2.1 - ts-node: 10.9.2(@types/node@24.2.1)(typescript@5.9.2) + '@types/node': 24.3.0 + ts-node: 10.9.2(@types/node@24.3.0)(typescript@5.9.2) transitivePeerDependencies: - babel-plugin-macros - supports-color @@ -8171,7 +8183,7 @@ snapshots: '@jest/environment': 30.0.5 '@jest/environment-jsdom-abstract': 30.0.5(jsdom@26.1.0) '@types/jsdom': 21.1.7 - '@types/node': 24.2.1 + '@types/node': 24.3.0 jsdom: 26.1.0 transitivePeerDependencies: - bufferutil @@ -8183,7 +8195,7 @@ snapshots: '@jest/environment': 30.0.5 '@jest/fake-timers': 30.0.5 '@jest/types': 30.0.5 - '@types/node': 24.2.1 + '@types/node': 24.3.0 jest-mock: 30.0.5 jest-util: 30.0.5 jest-validate: 30.0.5 @@ -8191,7 +8203,7 @@ snapshots: jest-haste-map@30.0.5: dependencies: '@jest/types': 30.0.5 - '@types/node': 24.2.1 + '@types/node': 24.3.0 anymatch: 3.1.3 fb-watchman: 2.0.2 graceful-fs: 4.2.11 @@ -8230,7 +8242,7 @@ snapshots: jest-mock@30.0.5: dependencies: '@jest/types': 30.0.5 - '@types/node': 24.2.1 + '@types/node': 24.3.0 jest-util: 30.0.5 jest-pnp-resolver@1.2.3(jest-resolve@30.0.5): @@ -8264,7 +8276,7 @@ snapshots: '@jest/test-result': 30.0.5 '@jest/transform': 30.0.5 '@jest/types': 30.0.5 - '@types/node': 24.2.1 + '@types/node': 24.3.0 chalk: 4.1.2 emittery: 0.13.1 exit-x: 0.2.2 @@ -8293,7 +8305,7 @@ snapshots: '@jest/test-result': 30.0.5 '@jest/transform': 30.0.5 '@jest/types': 30.0.5 - '@types/node': 24.2.1 + '@types/node': 24.3.0 chalk: 4.1.2 cjs-module-lexer: 2.1.0 collect-v8-coverage: 1.0.2 @@ -8340,7 +8352,7 @@ snapshots: jest-util@30.0.5: dependencies: '@jest/types': 30.0.5 - '@types/node': 24.2.1 + '@types/node': 24.3.0 chalk: 4.1.2 ci-info: 4.3.0 graceful-fs: 4.2.11 @@ -8359,7 +8371,7 @@ snapshots: dependencies: '@jest/test-result': 30.0.5 '@jest/types': 30.0.5 - '@types/node': 24.2.1 + '@types/node': 24.3.0 ansi-escapes: 4.3.2 chalk: 4.1.2 emittery: 0.13.1 @@ -8368,18 +8380,18 @@ snapshots: jest-worker@30.0.5: dependencies: - '@types/node': 24.2.1 + '@types/node': 24.3.0 '@ungap/structured-clone': 1.3.0 jest-util: 30.0.5 merge-stream: 2.0.0 supports-color: 8.1.1 - jest@30.0.5(@types/node@24.2.1)(ts-node@10.9.2(@types/node@24.2.1)(typescript@5.9.2)): + jest@30.0.5(@types/node@24.3.0)(ts-node@10.9.2(@types/node@24.3.0)(typescript@5.9.2)): dependencies: - '@jest/core': 30.0.5(ts-node@10.9.2(@types/node@24.2.1)(typescript@5.9.2)) + '@jest/core': 30.0.5(ts-node@10.9.2(@types/node@24.3.0)(typescript@5.9.2)) '@jest/types': 30.0.5 import-local: 3.2.0 - jest-cli: 30.0.5(@types/node@24.2.1)(ts-node@10.9.2(@types/node@24.2.1)(typescript@5.9.2)) + jest-cli: 30.0.5(@types/node@24.3.0)(ts-node@10.9.2(@types/node@24.3.0)(typescript@5.9.2)) transitivePeerDependencies: - '@types/node' - babel-plugin-macros @@ -8534,8 +8546,6 @@ snapshots: lodash.merge@4.6.2: {} - lodash@4.17.21: {} - loose-envify@1.4.0: dependencies: js-tokens: 4.0.0 @@ -8907,32 +8917,32 @@ snapshots: react-is@18.3.1: {} - react-remove-scroll-bar@2.3.8(@types/react@19.1.9)(react@19.1.1): + react-remove-scroll-bar@2.3.8(@types/react@19.1.10)(react@19.1.1): dependencies: react: 19.1.1 - react-style-singleton: 2.2.3(@types/react@19.1.9)(react@19.1.1) + react-style-singleton: 2.2.3(@types/react@19.1.10)(react@19.1.1) tslib: 2.8.1 optionalDependencies: - '@types/react': 19.1.9 + '@types/react': 19.1.10 - react-remove-scroll@2.7.1(@types/react@19.1.9)(react@19.1.1): + react-remove-scroll@2.7.1(@types/react@19.1.10)(react@19.1.1): dependencies: react: 19.1.1 - react-remove-scroll-bar: 2.3.8(@types/react@19.1.9)(react@19.1.1) - react-style-singleton: 2.2.3(@types/react@19.1.9)(react@19.1.1) + react-remove-scroll-bar: 2.3.8(@types/react@19.1.10)(react@19.1.1) + react-style-singleton: 2.2.3(@types/react@19.1.10)(react@19.1.1) tslib: 2.8.1 - use-callback-ref: 1.3.3(@types/react@19.1.9)(react@19.1.1) - use-sidecar: 1.1.3(@types/react@19.1.9)(react@19.1.1) + use-callback-ref: 1.3.3(@types/react@19.1.10)(react@19.1.1) + use-sidecar: 1.1.3(@types/react@19.1.10)(react@19.1.1) optionalDependencies: - '@types/react': 19.1.9 + '@types/react': 19.1.10 - react-style-singleton@2.2.3(@types/react@19.1.9)(react@19.1.1): + react-style-singleton@2.2.3(@types/react@19.1.10)(react@19.1.1): dependencies: get-nonce: 1.0.1 react: 19.1.1 tslib: 2.8.1 optionalDependencies: - '@types/react': 19.1.9 + '@types/react': 19.1.10 react@19.1.1: {} @@ -9275,7 +9285,7 @@ snapshots: supports-preserve-symlinks-flag@1.0.0: {} - swr@2.3.4(react@19.1.1): + swr@2.3.6(react@19.1.1): dependencies: dequal: 2.0.3 react: 19.1.1 @@ -9287,7 +9297,7 @@ snapshots: dependencies: '@pkgr/core': 0.2.9 - tailwindcss@4.1.11: {} + tailwindcss@4.1.12: {} tapable@2.2.2: {} @@ -9345,14 +9355,14 @@ snapshots: dependencies: sax: 1.2.4 - ts-node@10.9.2(@types/node@24.2.1)(typescript@5.9.2): + ts-node@10.9.2(@types/node@24.3.0)(typescript@5.9.2): dependencies: '@cspotcode/source-map-support': 0.8.1 '@tsconfig/node10': 1.0.11 '@tsconfig/node12': 1.0.11 '@tsconfig/node14': 1.0.3 '@tsconfig/node16': 1.0.4 - '@types/node': 24.2.1 + '@types/node': 24.3.0 acorn: 8.15.0 acorn-walk: 8.3.4 arg: 4.1.3 @@ -9466,24 +9476,24 @@ snapshots: dependencies: punycode: 2.3.1 - use-callback-ref@1.3.3(@types/react@19.1.9)(react@19.1.1): + use-callback-ref@1.3.3(@types/react@19.1.10)(react@19.1.1): dependencies: react: 19.1.1 tslib: 2.8.1 optionalDependencies: - '@types/react': 19.1.9 + '@types/react': 19.1.10 use-debounce@10.0.5(react@19.1.1): dependencies: react: 19.1.1 - use-sidecar@1.1.3(@types/react@19.1.9)(react@19.1.1): + use-sidecar@1.1.3(@types/react@19.1.10)(react@19.1.1): dependencies: detect-node-es: 1.1.0 react: 19.1.1 tslib: 2.8.1 optionalDependencies: - '@types/react': 19.1.9 + '@types/react': 19.1.10 use-sync-external-store@1.5.0(react@19.1.1): dependencies: diff --git a/src/photo/PhotoEditPageClient.tsx b/src/photo/PhotoEditPageClient.tsx index 5336440a..5ad64c03 100644 --- a/src/photo/PhotoEditPageClient.tsx +++ b/src/photo/PhotoEditPageClient.tsx @@ -37,8 +37,8 @@ export default function PhotoEditPageClient({ setIsPending, updatedTitle, setUpdatedTitle, - hasTextContent, - setHasTextContent, + shouldConfirmAiTextGeneration, + setShouldConfirmAiTextGeneration, aiContent, } = usePhotoFormParent({ photoForm, @@ -59,7 +59,10 @@ export default function PhotoEditPageClient({ accessory={
{hasAiTextGeneration && - } + } diff --git a/src/photo/UploadPageClient.tsx b/src/photo/UploadPageClient.tsx index f17de457..d9837739 100644 --- a/src/photo/UploadPageClient.tsx +++ b/src/photo/UploadPageClient.tsx @@ -38,10 +38,11 @@ export default function UploadPageClient({ setIsPending, updatedTitle, setUpdatedTitle, - hasTextContent, - setHasTextContent, + shouldConfirmAiTextGeneration, + setShouldConfirmAiTextGeneration, aiContent, } = usePhotoFormParent({ + photoForm: formDataFromExif, textFieldsToAutoGenerate, imageThumbnailBase64, }); @@ -61,7 +62,10 @@ export default function UploadPageClient({ : blobId} breadcrumbEllipsis accessory={hasAiTextGeneration && - } + } isLoading={pending} > ); diff --git a/src/photo/actions.ts b/src/photo/actions.ts index 29d7ac2a..c23312af 100644 --- a/src/photo/actions.ts +++ b/src/photo/actions.ts @@ -49,7 +49,7 @@ import { import { TAG_FAVS, isPhotoFav, isTagFavs } from '@/tag'; import { convertPhotoToPhotoDbInsert, Photo } from '.'; import { runAuthenticatedAdminServerAction } from '@/auth/server'; -import { AiImageQuery, getAiImageQuery } from './ai'; +import { AiImageQuery, getAiImageQuery, getAiTextFieldsToGenerate } from './ai'; import { streamOpenAiImageQuery } from '@/platforms/openai'; import { AI_TEXT_AUTO_GENERATED_FIELDS, @@ -96,8 +96,8 @@ export const createPhotoAction = async (formData: FormData) => // - addUploadsAction const addUpload = async ({ url, - title, - tags, + title: _title, + tags: _tags, favorite, hidden, excludeFromFeeds, @@ -138,24 +138,30 @@ const addUpload = async ({ onStreamUpdate?.('Generating AI text'); } + const title = _title || formDataFromExif.title; + const caption = formDataFromExif.caption; + const tags = _tags || formDataFromExif.tags; + const { title: aiTitle, - caption, + caption: aiCaption, tags: aiTags, semanticDescription, } = await generateAiImageQueries( imageResizedBase64, - Boolean(title) - ? AI_TEXT_AUTO_GENERATED_FIELDS - .filter(field => field !== 'title') - : AI_TEXT_AUTO_GENERATED_FIELDS, + getAiTextFieldsToGenerate( + AI_TEXT_AUTO_GENERATED_FIELDS, + Boolean(title), + Boolean(caption), + Boolean(tags), + ), title, ); const form: Partial = { ...formDataFromExif, title: title || aiTitle, - caption, + caption: caption || aiCaption, tags: tags || aiTags, excludeFromFeeds, hidden, @@ -190,9 +196,7 @@ const addUpload = async ({ }; export const addUploadAction = async (args: Parameters[0]) => - runAuthenticatedAdminServerAction(async () => { - await addUpload(args); - }); + runAuthenticatedAdminServerAction(() => addUpload(args)); export const addUploadsAction = async ({ uploadUrls, @@ -536,7 +540,7 @@ export const syncPhotoAction = async (photoId: string, isBatch?: boolean) => const formDataFromPhoto = convertPhotoToFormData(photo); - // Don't overwrite manually configured fujifilm meta with null data + // Don't overwrite manually configured meta with null data FIELDS_TO_NOT_OVERWRITE_WITH_NULL_DATA_ON_SYNC.forEach(field => { if (!formDataFromExif[field] && formDataFromPhoto[field]) { delete formDataFromExif[field]; diff --git a/src/photo/ai/index.ts b/src/photo/ai/index.ts index d0288863..3e07ce5f 100644 --- a/src/photo/ai/index.ts +++ b/src/photo/ai/index.ts @@ -40,6 +40,21 @@ export const parseAiAutoGeneratedFieldsString = ( } }; +export const getAiTextFieldsToGenerate = ( + textFieldsToGenerate: AiAutoGeneratedField[], + excludeTitle?: boolean, + excludeCaption?: boolean, + excludeTags?: boolean, + excludeSemantic?: boolean, +): AiAutoGeneratedField[] => { + return textFieldsToGenerate.filter(field => + !(excludeTitle && field === 'title') && + !(excludeCaption && field === 'caption') && + !(excludeTags && field === 'tags') && + !(excludeSemantic && field === 'semantic'), + ); +}; + export type AiImageQuery = 'title' | 'caption' | diff --git a/src/photo/color/server.ts b/src/photo/color/server.ts index c35e2c15..e5be7b35 100644 --- a/src/photo/color/server.ts +++ b/src/photo/color/server.ts @@ -61,7 +61,7 @@ const getColorDataFromImageUrl = async ( url: string, isBatch?: boolean, ): Promise => { - const ai = AI_CONTENT_GENERATION_ENABLED + const ai = AI_CONTENT_GENERATION_ENABLED ? await getColorFromAI(url, isBatch) : undefined; const average = await getAverageColorFromImageUrl(url); @@ -95,7 +95,7 @@ export const getColorFieldsForPhotoDbInsert = async ( ...args: Parameters ) => { const { colorData, ...rest } = await getColorFieldsForImageUrl(...args) ?? {}; - if (colorData) { + if (colorData !== undefined) { return { colorData: JSON.stringify(colorData), ...rest, @@ -109,10 +109,12 @@ export const getColorFieldsForPhotoForm = async ( ) => { const { colorSort, ...rest } = await getColorFieldsForPhotoDbInsert(...args) ?? {}; - return { - colorSort: `${colorSort}`, - ...rest, - }; + if (colorSort !== undefined) { + return { + colorSort: `${colorSort}`, + ...rest, + }; + } }; export const getColorFromAI = async ( diff --git a/src/photo/form/PhotoForm.tsx b/src/photo/form/PhotoForm.tsx index 907890df..831def02 100644 --- a/src/photo/form/PhotoForm.tsx +++ b/src/photo/form/PhotoForm.tsx @@ -14,7 +14,6 @@ import { FormMeta, PhotoFormData, convertFormKeysToLabels, - formHasTextContent, getChangedFormFields, getFormErrors, isFormValid, @@ -65,7 +64,7 @@ export default function PhotoForm({ aiContent, shouldStripGpsData, onTitleChange, - onTextContentChange, + onFormDataChange, onFormStatusChange, }: { type?: 'create' | 'edit' @@ -78,7 +77,7 @@ export default function PhotoForm({ aiContent?: AiContent shouldStripGpsData?: boolean onTitleChange?: (updatedTitle: string) => void - onTextContentChange?: (hasContent: boolean) => void, + onFormDataChange?: (formData: Partial) => void, onFormStatusChange?: (pending: boolean) => void }) { const [formData, setFormData] = @@ -188,8 +187,8 @@ export default function PhotoForm({ [aiContent?.semanticDescription]); useEffect(() => { - onTextContentChange?.(formHasTextContent(formData)); - }, [onTextContentChange, formData]); + onFormDataChange?.(formData); + }, [onFormDataChange, formData]); const isFieldGeneratingAi = (key: keyof PhotoFormData) => { switch (key) { diff --git a/src/photo/form/index.ts b/src/photo/form/index.ts index 10283f93..116e139e 100644 --- a/src/photo/form/index.ts +++ b/src/photo/form/index.ts @@ -85,6 +85,7 @@ const FORM_METADATA = ( label: 'title', capitalize: true, validateStringMaxLength: STRING_MAX_LENGTH_SHORT, + shouldNotOverwriteWithNullDataOnSync: true, }, caption: { label: 'caption', @@ -245,12 +246,12 @@ export const isFormValid = (formData: Partial) => (!validateStringMaxLength || (formData[key]?.length ?? 0) <= validateStringMaxLength), ); -export const formHasTextContent = ({ +export const formHasExistingAiTextContent = ({ title, caption, tags, semanticDescription, -}: Partial) => +}: Partial = {}) => Boolean(title || caption || tags || semanticDescription); // CREATE FORM DATA: FROM PHOTO diff --git a/src/photo/form/server.ts b/src/photo/form/server.ts index 5ea2a7e3..5d034716 100644 --- a/src/photo/form/server.ts +++ b/src/photo/form/server.ts @@ -15,38 +15,55 @@ import type { ExifData } from 'ts-exif-parser'; export const convertExifToFormData = ( data: ExifData, + dataExifr?: any, film?: FujifilmSimulation, recipeData?: FujifilmRecipe, -): Omit< - Record, - 'takenAt' | 'takenAtNaive' -> => ({ - aspectRatio: getAspectRatioFromExif(data).toString(), - make: data.tags?.Make, - model: data.tags?.Model, - focalLength: data.tags?.FocalLength?.toString(), - focalLengthIn35MmFormat: data.tags?.FocalLengthIn35mmFormat?.toString(), - lensMake: data.tags?.LensMake, - lensModel: data.tags?.LensModel, - fNumber: ( - data.tags?.FNumber?.toString() || - convertApertureValueToFNumber(data.tags?.ApertureValue) - ), - iso: data.tags?.ISO?.toString() || data.tags?.ISOSpeed?.toString(), - exposureTime: data.tags?.ExposureTime?.toString(), - exposureCompensation: data.tags?.ExposureCompensation?.toString(), - latitude: - !GEO_PRIVACY_ENABLED ? data.tags?.GPSLatitude?.toString() : undefined, - longitude: - !GEO_PRIVACY_ENABLED ? data.tags?.GPSLongitude?.toString() : undefined, - film, - recipeData: JSON.stringify(recipeData), - ...data.tags?.DateTimeOriginal && { - takenAt: convertTimestampWithOffsetToPostgresString( - data.tags.DateTimeOriginal, - getOffsetFromExif(data), +): Partial> => { + let title: string | undefined = dataExifr?.title?.value; + let caption: string | undefined; + const description: string | undefined = + data.tags?.ImageDescription || + dataExifr?.ImageDescription || + dataExifr?.description?.value; + const tags: string[] | undefined = dataExifr?.subject; + + if (title && title !== description) { + caption = description; + } else { + title = description; + } + + return { + aspectRatio: getAspectRatioFromExif(data).toString(), + make: data.tags?.Make, + model: data.tags?.Model, + focalLength: data.tags?.FocalLength?.toString(), + focalLengthIn35MmFormat: data.tags?.FocalLengthIn35mmFormat?.toString(), + lensMake: data.tags?.LensMake, + lensModel: data.tags?.LensModel, + fNumber: ( + data.tags?.FNumber?.toString() || + convertApertureValueToFNumber(data.tags?.ApertureValue) ), - takenAtNaive: - convertTimestampToNaivePostgresString(data.tags.DateTimeOriginal), - }, -}); + iso: data.tags?.ISO?.toString() || data.tags?.ISOSpeed?.toString(), + exposureTime: data.tags?.ExposureTime?.toString(), + exposureCompensation: data.tags?.ExposureCompensation?.toString(), + latitude: + !GEO_PRIVACY_ENABLED ? data.tags?.GPSLatitude?.toString() : undefined, + longitude: + !GEO_PRIVACY_ENABLED ? data.tags?.GPSLongitude?.toString() : undefined, + film, + recipeData: JSON.stringify(recipeData), + ...data.tags?.DateTimeOriginal && { + takenAt: convertTimestampWithOffsetToPostgresString( + data.tags.DateTimeOriginal, + getOffsetFromExif(data), + ), + takenAtNaive: + convertTimestampToNaivePostgresString(data.tags.DateTimeOriginal), + }, + ...title && { title }, + ...caption && { caption }, + ...Array.isArray(tags) && { tags: tags.join(', ') }, + }; +}; diff --git a/src/photo/form/usePhotoFormParent.ts b/src/photo/form/usePhotoFormParent.ts index 3ab89b9b..bf3715ee 100644 --- a/src/photo/form/usePhotoFormParent.ts +++ b/src/photo/form/usePhotoFormParent.ts @@ -1,11 +1,11 @@ -import { useState } from 'react'; -import { PhotoFormData, formHasTextContent } from '.'; +import { useCallback, useMemo, useState } from 'react'; +import { PhotoFormData, formHasExistingAiTextContent } from '.'; import useAiImageQueries from '../ai/useAiImageQueries'; -import { AiAutoGeneratedField } from '../ai'; +import { AiAutoGeneratedField, getAiTextFieldsToGenerate } from '../ai'; export default function usePhotoFormParent({ photoForm, - textFieldsToAutoGenerate, + textFieldsToAutoGenerate: _textFieldsToAutoGenerate = [], imageThumbnailBase64, }: { photoForm?: Partial @@ -14,8 +14,29 @@ export default function usePhotoFormParent({ }) { const [pending, setIsPending] = useState(false); const [updatedTitle, setUpdatedTitle] = useState(''); - const [hasTextContent, setHasTextContent] = - useState(photoForm ? formHasTextContent(photoForm) : false); + const [shouldConfirmAiTextGeneration, _setShouldConfirmAiTextGeneration] = + useState(formHasExistingAiTextContent(photoForm)); + + const setShouldConfirmAiTextGeneration = useCallback( + (updatedFormData: Partial) => { + _setShouldConfirmAiTextGeneration( + formHasExistingAiTextContent(updatedFormData), + ); + }, []); + + // Don't auto-generate titles when they can be captured from EXIF data + const textFieldsToAutoGenerate = useMemo(() => + getAiTextFieldsToGenerate( + _textFieldsToAutoGenerate, + Boolean(photoForm?.title), + Boolean(photoForm?.caption), + Boolean(photoForm?.tags), + ), [ + _textFieldsToAutoGenerate, + photoForm?.title, + photoForm?.caption, + photoForm?.tags, + ]); const aiContent = useAiImageQueries( textFieldsToAutoGenerate, @@ -27,8 +48,8 @@ export default function usePhotoFormParent({ setIsPending, updatedTitle, setUpdatedTitle, - hasTextContent, - setHasTextContent, + shouldConfirmAiTextGeneration, + setShouldConfirmAiTextGeneration, aiContent, }; } diff --git a/src/photo/index.ts b/src/photo/index.ts index acaa63cd..ca177686 100644 --- a/src/photo/index.ts +++ b/src/photo/index.ts @@ -68,6 +68,10 @@ export interface PhotoExif { recipeData?: string takenAt?: string takenAtNaive?: string + // Photo meta potentially located in EXIF/XMP data + title?: string + caption?: string + tags?: string[] } // Raw db insert @@ -76,7 +80,6 @@ export interface PhotoDbInsert extends PhotoExif { url: string extension: string blurData?: string - title?: string caption?: string semanticDescription?: string tags?: string[] diff --git a/src/photo/server.ts b/src/photo/server.ts index c2f5627a..6d6aa8eb 100644 --- a/src/photo/server.ts +++ b/src/photo/server.ts @@ -26,6 +26,7 @@ import { import { PhotoDbInsert } from '.'; import { convertExifToFormData } from './form/server'; import { getColorFieldsForPhotoForm } from './color/server'; +import exifr from 'exifr'; const IMAGE_WIDTH_RESIZE = 200; const IMAGE_WIDTH_BLUR = 200; @@ -58,6 +59,7 @@ export const extractImageDataFromBlobPath = async ( const extension = getExtensionFromStorageUrl(url); let exifData: ExifData | undefined; + let exifrData: any | undefined; let film: FujifilmSimulation | undefined; let recipe: FujifilmRecipe | undefined; let blurData: string | undefined; @@ -80,6 +82,7 @@ export const extractImageDataFromBlobPath = async ( // Data for form parser.enableBinaryFields(false); exifData = parser.parse(); + exifrData = await exifr.parse(fileBytes, { xmp: true }); // Capture film simulation for Fujifilm cameras if (isExifForFujifilm(exifData)) { @@ -126,7 +129,7 @@ export const extractImageDataFromBlobPath = async ( url, }, ...generateBlurData && { blurData }, - ...convertExifToFormData(exifData, film, recipe), + ...convertExifToFormData(exifData, exifrData, film, recipe), ...colorFields, }, },