mirror of
https://github.com/IliesAllali/parenthese.git
synced 2026-11-06 23:32:08 +00:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1b13b093ba | ||
|
|
c1734501ae | ||
|
|
b444c1ad39 | ||
|
|
04dc7f0e88 | ||
|
|
1c78c043bd | ||
|
|
cd93a470b8 | ||
|
|
b39d1f68e8 | ||
|
|
d013c8b8fc | ||
|
|
3dfc8625e9 | ||
|
|
1a65f28b21 |
No files matched your search
@@ -72,7 +72,7 @@ jobs:
|
||||
|
||||
- uses: docker/setup-buildx-action@f87e5991a6d7451dcb8d9637bfbc97413f497069 # v4.4.1
|
||||
|
||||
- uses: docker/login-action@dbcb813823bdd20940b903addbd779551569679f # v4.6.0
|
||||
- uses: docker/login-action@81c6f93d4bc991e510b342a00b419b3bb4efc5c6 # v4.7.0
|
||||
with:
|
||||
registry: ghcr.io
|
||||
username: ${{ github.actor }}
|
||||
@@ -120,7 +120,7 @@ jobs:
|
||||
persist-credentials: false
|
||||
|
||||
# Tant que les paquets ne sont pas publics, le pull demande une connexion.
|
||||
- uses: docker/login-action@dbcb813823bdd20940b903addbd779551569679f # v4.6.0
|
||||
- uses: docker/login-action@81c6f93d4bc991e510b342a00b419b3bb4efc5c6 # v4.7.0
|
||||
with:
|
||||
registry: ghcr.io
|
||||
username: ${{ github.actor }}
|
||||
|
||||
@@ -2,6 +2,23 @@
|
||||
|
||||
Notable changes to Parenthèse. Dates are in YYYY-MM-DD format.
|
||||
|
||||
## 1.5.8 (2026-10-29)
|
||||
|
||||
### Family tabs
|
||||
|
||||
- A tab is named after the surname most of its members carry (birth name, otherwise current name), not after the person it starts from. When two tabs would share a name, the smaller one takes its next most common surname (#192).
|
||||
- Switching tabs keeps the person who joins the two families at the same place and zoom, only the families around change. Hovering a tab lights that person up in the tree (#192).
|
||||
- The tab bar follows the shape of the tree, grouped by branch, with a line between a tab and the one it comes from. The way-back badge sits where the way-in badge was (#192).
|
||||
|
||||
### Profile
|
||||
|
||||
- The age counts the birthday: with a full birth date, a person born in December is not a year older from January. Same for the age at death and the ages in the Life tab. With only a year, the age stays the difference between the years (#198).
|
||||
|
||||
### Dependencies
|
||||
|
||||
- `@node-rs/bcrypt` 2.0: the cost is passed as an option. Stored passwords still verify, new hashes are `$2b$` with the same cost (#197).
|
||||
- Minor updates for the frontend, the landing, the backend and the CI (#193, #194, #195, #196).
|
||||
|
||||
## 1.5.7 (2026-10-28)
|
||||
|
||||
### Phone
|
||||
|
||||
@@ -83,7 +83,7 @@ Only the first name, last name and birth year leave the server, and the panel sa
|
||||
|
||||
#### Sign in with your identity provider (OIDC)
|
||||
|
||||
*Experimental in 1.2.0: tested against a certified OpenID provider, feedback from real setups is welcome in the issues.*
|
||||
*Used with Pocket ID on a real setup (#153).*
|
||||
|
||||
Parenthèse can hand sign-in to an OpenID Connect provider you already run (Authentik, Authelia, Keycloak, Pocket ID, Zitadel…), so your family reuses one account and its two-factor settings. Create an OIDC application (confidential client, authorization code flow) whose redirect URI is the public address of Parenthèse followed by `/auth/oidc/callback`, then set in `.env`:
|
||||
|
||||
@@ -95,6 +95,8 @@ OIDC_REDIRECT_URI=https://tree.your-domain.com/auth/oidc/callback
|
||||
OIDC_PROVIDER_NAME=Authentik # shown on the button
|
||||
```
|
||||
|
||||
The `api` container talks to the provider itself, to read its configuration and exchange the sign-in code. If your Docker network is marked `internal`, give `api` a network that can reach the provider, not just `web`.
|
||||
|
||||
The sign-in screen then shows "Sign in with Authentik". On a first sign-in, Parenthèse links the provider account to the Parenthèse account with the same email, or creates one when `ALLOW_REGISTRATION` allows it. With registration closed, the provider only signs in people who already have an account (the first account of an empty instance is still accepted). Emails are only trusted when the provider marks them verified (`email_verified`); `OIDC_REQUIRE_VERIFIED_EMAIL=false` lifts that check, for a provider that doesn't send the claim and where nobody picks their own address. Once linked, an account stays tied to the provider's user id, not to the email.
|
||||
|
||||
`PASSWORD_LOGIN=false` removes Parenthèse passwords altogether: sign-in goes through the provider only (the API refuses to start without `OIDC_ISSUER`). Accounts created through the provider have no password; to delete one, its owner types their email instead. Accounts that already have a password are not linked to the provider by email: before switching, each owner opens their account and clicks « Se connecter aussi avec … » ("Also sign in with …"), then signs in with the provider once. `OIDC_SCOPES` (default `openid email profile`) and `OIDC_APP_URL` (where the app opens after sign-in, by default the origin of `OIDC_REDIRECT_URI`) rarely need changing.
|
||||
|
||||
Generated
+72
-120
@@ -12,11 +12,11 @@
|
||||
"@fastify/cors": "^11.3.0",
|
||||
"@fastify/jwt": "^10.2.5",
|
||||
"@fastify/rate-limit": "^11.2.0",
|
||||
"@node-rs/bcrypt": "^1.10.7",
|
||||
"@node-rs/bcrypt": "^2.0.0",
|
||||
"@prisma/adapter-pg": "^7.10.1",
|
||||
"@prisma/client": "^7.10.1",
|
||||
"blurhash": "^2.0.5",
|
||||
"dotenv": "^18.0.8",
|
||||
"dotenv": "^18.0.9",
|
||||
"fastify": "^5.12.7",
|
||||
"openid-client": "^6.8.8",
|
||||
"pg": "^8.23.1",
|
||||
@@ -62,17 +62,6 @@
|
||||
"@electric-sql/pglite": "0.4.3"
|
||||
}
|
||||
},
|
||||
"node_modules/@emnapi/core": {
|
||||
"version": "1.11.3",
|
||||
"resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.11.3.tgz",
|
||||
"integrity": "sha512-zLpS5asjEb7lq8jYLq37N6XKaE41DIexlY1rF/z4/tIl3wo13Sqm28fRyfIsKZD+NZ8mM5RoKkpW/rBcuoSZSg==",
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"dependencies": {
|
||||
"@emnapi/wasi-threads": "1.2.3",
|
||||
"tslib": "^2.4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@emnapi/runtime": {
|
||||
"version": "1.11.3",
|
||||
"resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.11.3.tgz",
|
||||
@@ -83,16 +72,6 @@
|
||||
"tslib": "^2.4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@emnapi/wasi-threads": {
|
||||
"version": "1.2.3",
|
||||
"resolved": "https://registry.npmjs.org/@emnapi/wasi-threads/-/wasi-threads-1.2.3.tgz",
|
||||
"integrity": "sha512-ELEBe8PsLvvJ6QMr0zLt8ffvOHW/dc1m3CEzNMg7aJUv3bMaoDtw2TXyDAwkYBuroxxuHEwhRTLJSe5sya547g==",
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"dependencies": {
|
||||
"tslib": "^2.4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/aix-ppc64": {
|
||||
"version": "0.28.2",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.28.2.tgz",
|
||||
@@ -1281,22 +1260,10 @@
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/@napi-rs/wasm-runtime": {
|
||||
"version": "0.2.12",
|
||||
"resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-0.2.12.tgz",
|
||||
"integrity": "sha512-ZVWUcfwY4E/yPitQJl481FjFo3K22D6qF0DuFH6Y/nbnE11GY5uguDxZMGXPQ8WQ0128MXQD7TnfHyK4oWoIJQ==",
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"dependencies": {
|
||||
"@emnapi/core": "^1.4.3",
|
||||
"@emnapi/runtime": "^1.4.3",
|
||||
"@tybys/wasm-util": "^0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@node-rs/bcrypt": {
|
||||
"version": "1.10.7",
|
||||
"resolved": "https://registry.npmjs.org/@node-rs/bcrypt/-/bcrypt-1.10.7.tgz",
|
||||
"integrity": "sha512-1wk0gHsUQC/ap0j6SJa2K34qNhomxXRcEe3T8cI5s+g6fgHBgLTN7U9LzWTG/HE6G4+2tWWLeCabk1wiYGEQSA==",
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@node-rs/bcrypt/-/bcrypt-2.0.0.tgz",
|
||||
"integrity": "sha512-perB+8PsvBsJeUJ0pE2GgOFAZZ3IXSfKhQ3Pkr+y/L5yZm6W727659g+ZtHmlhIi9obs3y2euUMjVqRB/DVlvA==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">= 10"
|
||||
@@ -1306,26 +1273,25 @@
|
||||
"url": "https://github.com/sponsors/Brooooooklyn"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"@node-rs/bcrypt-android-arm-eabi": "1.10.7",
|
||||
"@node-rs/bcrypt-android-arm64": "1.10.7",
|
||||
"@node-rs/bcrypt-darwin-arm64": "1.10.7",
|
||||
"@node-rs/bcrypt-darwin-x64": "1.10.7",
|
||||
"@node-rs/bcrypt-freebsd-x64": "1.10.7",
|
||||
"@node-rs/bcrypt-linux-arm-gnueabihf": "1.10.7",
|
||||
"@node-rs/bcrypt-linux-arm64-gnu": "1.10.7",
|
||||
"@node-rs/bcrypt-linux-arm64-musl": "1.10.7",
|
||||
"@node-rs/bcrypt-linux-x64-gnu": "1.10.7",
|
||||
"@node-rs/bcrypt-linux-x64-musl": "1.10.7",
|
||||
"@node-rs/bcrypt-wasm32-wasi": "1.10.7",
|
||||
"@node-rs/bcrypt-win32-arm64-msvc": "1.10.7",
|
||||
"@node-rs/bcrypt-win32-ia32-msvc": "1.10.7",
|
||||
"@node-rs/bcrypt-win32-x64-msvc": "1.10.7"
|
||||
"@node-rs/bcrypt-android-arm-eabi": "2.0.0",
|
||||
"@node-rs/bcrypt-android-arm64": "2.0.0",
|
||||
"@node-rs/bcrypt-darwin-arm64": "2.0.0",
|
||||
"@node-rs/bcrypt-darwin-x64": "2.0.0",
|
||||
"@node-rs/bcrypt-freebsd-x64": "2.0.0",
|
||||
"@node-rs/bcrypt-linux-arm-gnueabihf": "2.0.0",
|
||||
"@node-rs/bcrypt-linux-arm64-gnu": "2.0.0",
|
||||
"@node-rs/bcrypt-linux-arm64-musl": "2.0.0",
|
||||
"@node-rs/bcrypt-linux-x64-gnu": "2.0.0",
|
||||
"@node-rs/bcrypt-linux-x64-musl": "2.0.0",
|
||||
"@node-rs/bcrypt-win32-arm64-msvc": "2.0.0",
|
||||
"@node-rs/bcrypt-win32-ia32-msvc": "2.0.0",
|
||||
"@node-rs/bcrypt-win32-x64-msvc": "2.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@node-rs/bcrypt-android-arm-eabi": {
|
||||
"version": "1.10.7",
|
||||
"resolved": "https://registry.npmjs.org/@node-rs/bcrypt-android-arm-eabi/-/bcrypt-android-arm-eabi-1.10.7.tgz",
|
||||
"integrity": "sha512-8dO6/PcbeMZXS3VXGEtct9pDYdShp2WBOWlDvSbcRwVqyB580aCBh0BEFmKYtXLzLvUK8Wf+CG3U6sCdILW1lA==",
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@node-rs/bcrypt-android-arm-eabi/-/bcrypt-android-arm-eabi-2.0.0.tgz",
|
||||
"integrity": "sha512-BGxkS6uXxDphPoMWevOVCXd3A07x45o1p4uYoXTjcvG7K+6iZXaXzOL5ZrGMUP71BAJ6b89/QStjuhGlMmuxOQ==",
|
||||
"cpu": [
|
||||
"arm"
|
||||
],
|
||||
@@ -1339,9 +1305,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@node-rs/bcrypt-android-arm64": {
|
||||
"version": "1.10.7",
|
||||
"resolved": "https://registry.npmjs.org/@node-rs/bcrypt-android-arm64/-/bcrypt-android-arm64-1.10.7.tgz",
|
||||
"integrity": "sha512-UASFBS/CucEMHiCtL/2YYsAY01ZqVR1N7vSb94EOvG5iwW7BQO06kXXCTgj+Xbek9azxixrCUmo3WJnkJZ0hTQ==",
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@node-rs/bcrypt-android-arm64/-/bcrypt-android-arm64-2.0.0.tgz",
|
||||
"integrity": "sha512-aKS02ZDZ26mLM5resokCCXHFhmlixytN0G7GbR1Xm3kq76mL9munu7vS0xk/5OszEls69o7oHH+NDe8xWyolnQ==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
@@ -1355,9 +1321,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@node-rs/bcrypt-darwin-arm64": {
|
||||
"version": "1.10.7",
|
||||
"resolved": "https://registry.npmjs.org/@node-rs/bcrypt-darwin-arm64/-/bcrypt-darwin-arm64-1.10.7.tgz",
|
||||
"integrity": "sha512-DgzFdAt455KTuiJ/zYIyJcKFobjNDR/hnf9OS7pK5NRS13Nq4gLcSIIyzsgHwZHxsJWbLpHmFc1H23Y7IQoQBw==",
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@node-rs/bcrypt-darwin-arm64/-/bcrypt-darwin-arm64-2.0.0.tgz",
|
||||
"integrity": "sha512-gHKuT+80v2jAeJujfmJPbbDt5zzE/ne5x/eoG52Twyfx/1bCWAN+cZoDEnzuD0Yduw484bDFtgq5PKXBPV2PYw==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
@@ -1371,9 +1337,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@node-rs/bcrypt-darwin-x64": {
|
||||
"version": "1.10.7",
|
||||
"resolved": "https://registry.npmjs.org/@node-rs/bcrypt-darwin-x64/-/bcrypt-darwin-x64-1.10.7.tgz",
|
||||
"integrity": "sha512-SPWVfQ6sxSokoUWAKWD0EJauvPHqOGQTd7CxmYatcsUgJ/bruvEHxZ4bIwX1iDceC3FkOtmeHO0cPwR480n/xA==",
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@node-rs/bcrypt-darwin-x64/-/bcrypt-darwin-x64-2.0.0.tgz",
|
||||
"integrity": "sha512-v8xBU+AZshfQ5fDNUvUDQsmc1mYGASnHXD2yVxjuDvKu/gaEHEz5gHtTFqzkNR9NPdWx3YxJ1UiW8fwSuN4XCQ==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
@@ -1387,9 +1353,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@node-rs/bcrypt-freebsd-x64": {
|
||||
"version": "1.10.7",
|
||||
"resolved": "https://registry.npmjs.org/@node-rs/bcrypt-freebsd-x64/-/bcrypt-freebsd-x64-1.10.7.tgz",
|
||||
"integrity": "sha512-gpa+Ixs6GwEx6U6ehBpsQetzUpuAGuAFbOiuLB2oo4N58yU4AZz1VIcWyWAHrSWRs92O0SHtmo2YPrMrwfBbSw==",
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@node-rs/bcrypt-freebsd-x64/-/bcrypt-freebsd-x64-2.0.0.tgz",
|
||||
"integrity": "sha512-XSFyizSOH0CWw+60XL4xaeOIRn5F9bgd919EvaIXQcjV7mWuhWbtGc2Z1eOcI8o7Yzh6LSkcIbZJ4fT094S7ww==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
@@ -1403,9 +1369,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@node-rs/bcrypt-linux-arm-gnueabihf": {
|
||||
"version": "1.10.7",
|
||||
"resolved": "https://registry.npmjs.org/@node-rs/bcrypt-linux-arm-gnueabihf/-/bcrypt-linux-arm-gnueabihf-1.10.7.tgz",
|
||||
"integrity": "sha512-kYgJnTnpxrzl9sxYqzflobvMp90qoAlaX1oDL7nhNTj8OYJVDIk0jQgblj0bIkjmoPbBed53OJY/iu4uTS+wig==",
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@node-rs/bcrypt-linux-arm-gnueabihf/-/bcrypt-linux-arm-gnueabihf-2.0.0.tgz",
|
||||
"integrity": "sha512-YYXkdl4rQuTayFB7MeQva8/H5AVeaaIkzuTNtD0RDEjBSQCKYMalM23pP673ScCvBAWLuiYHtviMITdubiER6Q==",
|
||||
"cpu": [
|
||||
"arm"
|
||||
],
|
||||
@@ -1419,12 +1385,15 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@node-rs/bcrypt-linux-arm64-gnu": {
|
||||
"version": "1.10.7",
|
||||
"resolved": "https://registry.npmjs.org/@node-rs/bcrypt-linux-arm64-gnu/-/bcrypt-linux-arm64-gnu-1.10.7.tgz",
|
||||
"integrity": "sha512-7cEkK2RA+gBCj2tCVEI1rDSJV40oLbSq7bQ+PNMHNI6jCoXGmj9Uzo7mg7ZRbNZ7piIyNH5zlJqutjo8hh/tmA==",
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@node-rs/bcrypt-linux-arm64-gnu/-/bcrypt-linux-arm64-gnu-2.0.0.tgz",
|
||||
"integrity": "sha512-jLbuJ/MVa4xvFV5lmd71xx6DOfkQvpj4zR0X0AuOopofP0z6SmyA/zKQOrVrfDUCbBwAHoi22VD9umfU8HsrGA==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"libc": [
|
||||
"glibc"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
@@ -1435,12 +1404,15 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@node-rs/bcrypt-linux-arm64-musl": {
|
||||
"version": "1.10.7",
|
||||
"resolved": "https://registry.npmjs.org/@node-rs/bcrypt-linux-arm64-musl/-/bcrypt-linux-arm64-musl-1.10.7.tgz",
|
||||
"integrity": "sha512-X7DRVjshhwxUqzdUKDlF55cwzh+wqWJ2E/tILvZPboO3xaNO07Um568Vf+8cmKcz+tiZCGP7CBmKbBqjvKN/Pw==",
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@node-rs/bcrypt-linux-arm64-musl/-/bcrypt-linux-arm64-musl-2.0.0.tgz",
|
||||
"integrity": "sha512-31ORIUbGuBPGyqvZMppQc99l7hdKZrhDxtfsqFcWyeQ5ie4iR7QHv7FGXj+uTLQtJDFVBQQFpVIXTL4jNW7OPQ==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"libc": [
|
||||
"musl"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
@@ -1451,12 +1423,15 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@node-rs/bcrypt-linux-x64-gnu": {
|
||||
"version": "1.10.7",
|
||||
"resolved": "https://registry.npmjs.org/@node-rs/bcrypt-linux-x64-gnu/-/bcrypt-linux-x64-gnu-1.10.7.tgz",
|
||||
"integrity": "sha512-LXRZsvG65NggPD12hn6YxVgH0W3VR5fsE/o1/o2D5X0nxKcNQGeLWnRzs5cP8KpoFOuk1ilctXQJn8/wq+Gn/Q==",
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@node-rs/bcrypt-linux-x64-gnu/-/bcrypt-linux-x64-gnu-2.0.0.tgz",
|
||||
"integrity": "sha512-Kyo2iGkvtGDcfPcqjRQXS1DYDucpAMJbIw0aPmdiKFLAt8tdOeafK2+zfwuWq8/BDs/n9jKV2ajlda53AqFHMA==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"libc": [
|
||||
"glibc"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
@@ -1467,12 +1442,15 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@node-rs/bcrypt-linux-x64-musl": {
|
||||
"version": "1.10.7",
|
||||
"resolved": "https://registry.npmjs.org/@node-rs/bcrypt-linux-x64-musl/-/bcrypt-linux-x64-musl-1.10.7.tgz",
|
||||
"integrity": "sha512-tCjHmct79OfcO3g5q21ME7CNzLzpw1MAsUXCLHLGWH+V6pp/xTvMbIcLwzkDj6TI3mxK6kehTn40SEjBkZ3Rog==",
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@node-rs/bcrypt-linux-x64-musl/-/bcrypt-linux-x64-musl-2.0.0.tgz",
|
||||
"integrity": "sha512-NkQN7yL4yRQOPpK80SAgHDlYE352QJmnSP3oKp1SXHS/G92b1IwjGlTB2+9ZKIGEDdqxnyI3dRzP0P/Sabv9zg==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"libc": [
|
||||
"musl"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
@@ -1482,26 +1460,10 @@
|
||||
"node": ">= 10"
|
||||
}
|
||||
},
|
||||
"node_modules/@node-rs/bcrypt-wasm32-wasi": {
|
||||
"version": "1.10.7",
|
||||
"resolved": "https://registry.npmjs.org/@node-rs/bcrypt-wasm32-wasi/-/bcrypt-wasm32-wasi-1.10.7.tgz",
|
||||
"integrity": "sha512-4qXSihIKeVXYglfXZEq/QPtYtBUvR8d3S85k15Lilv3z5B6NSGQ9mYiNleZ7QHVLN2gEc5gmi7jM353DMH9GkA==",
|
||||
"cpu": [
|
||||
"wasm32"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"dependencies": {
|
||||
"@napi-rs/wasm-runtime": "^0.2.5"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=14.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@node-rs/bcrypt-win32-arm64-msvc": {
|
||||
"version": "1.10.7",
|
||||
"resolved": "https://registry.npmjs.org/@node-rs/bcrypt-win32-arm64-msvc/-/bcrypt-win32-arm64-msvc-1.10.7.tgz",
|
||||
"integrity": "sha512-FdfUQrqmDfvC5jFhntMBkk8EI+fCJTx/I1v7Rj+Ezlr9rez1j1FmuUnywbBj2Cg15/0BDhwYdbyZ5GCMFli2aQ==",
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@node-rs/bcrypt-win32-arm64-msvc/-/bcrypt-win32-arm64-msvc-2.0.0.tgz",
|
||||
"integrity": "sha512-7BzjgPzfE9GktBafMaOTQR5klfcQ4SnzLS5dPKKdXEJ/rHilKbqm8EBszhGimlBMkutIBd53OE7MAqFVhtgIZw==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
@@ -1515,9 +1477,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@node-rs/bcrypt-win32-ia32-msvc": {
|
||||
"version": "1.10.7",
|
||||
"resolved": "https://registry.npmjs.org/@node-rs/bcrypt-win32-ia32-msvc/-/bcrypt-win32-ia32-msvc-1.10.7.tgz",
|
||||
"integrity": "sha512-lZLf4Cx+bShIhU071p5BZft4OvP4PGhyp542EEsb3zk34U5GLsGIyCjOafcF/2DGewZL6u8/aqoxbSuROkgFXg==",
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@node-rs/bcrypt-win32-ia32-msvc/-/bcrypt-win32-ia32-msvc-2.0.0.tgz",
|
||||
"integrity": "sha512-nbbwy8LOd4NxSJ2HrLTrXq5zNy0B6+LtX9wberLp9+DOQZVBfZF7PHlH4KlXi9aHrOpZHoXZNGIhWANtOpJlNA==",
|
||||
"cpu": [
|
||||
"ia32"
|
||||
],
|
||||
@@ -1531,9 +1493,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@node-rs/bcrypt-win32-x64-msvc": {
|
||||
"version": "1.10.7",
|
||||
"resolved": "https://registry.npmjs.org/@node-rs/bcrypt-win32-x64-msvc/-/bcrypt-win32-x64-msvc-1.10.7.tgz",
|
||||
"integrity": "sha512-hdw7tGmN1DxVAMTzICLdaHpXjy+4rxaxnBMgI8seG1JL5e3VcRGsd1/1vVDogVp2cbsmgq+6d6yAY+D9lW/DCg==",
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@node-rs/bcrypt-win32-x64-msvc/-/bcrypt-win32-x64-msvc-2.0.0.tgz",
|
||||
"integrity": "sha512-9KdovFbXWVUhhdsUjtMR8WLw7+U4dCFMyYFRogmdpe+a4SMy8IcN8rv3azxmGYgtoH5wW63BQ0COKZq6C7O96g==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
@@ -2234,16 +2196,6 @@
|
||||
"devOptional": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@tybys/wasm-util": {
|
||||
"version": "0.10.4",
|
||||
"resolved": "https://registry.npmjs.org/@tybys/wasm-util/-/wasm-util-0.10.4.tgz",
|
||||
"integrity": "sha512-W3c4gRigFS0T/Ma4qIYF3GDAc5AQdHb1yL5znJT1Zv1YaD9Kitx656wBjvr19qbiosmZT8lWDM5BEMynUqX65A==",
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"dependencies": {
|
||||
"tslib": "^2.4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/chai": {
|
||||
"version": "5.2.3",
|
||||
"resolved": "https://registry.npmjs.org/@types/chai/-/chai-5.2.3.tgz",
|
||||
@@ -3364,9 +3316,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/dotenv": {
|
||||
"version": "18.0.8",
|
||||
"resolved": "https://registry.npmjs.org/dotenv/-/dotenv-18.0.8.tgz",
|
||||
"integrity": "sha512-2KDeoFoK/zRtcnbunCDlLG5VWVMcyqeQc6iK65o231nfNAcuGrKoqUQfJFUtBI+QlShk5HKIHxwebBtUl3rEfA==",
|
||||
"version": "18.0.9",
|
||||
"resolved": "https://registry.npmjs.org/dotenv/-/dotenv-18.0.9.tgz",
|
||||
"integrity": "sha512-3fVOW4cB02R066PUSwn8O4TJyz9NckQl7F81blIbaq9jKBm2tSmOKky7ZHIXzGvkVPXCSn6jkpziBPZdGFs8Tw==",
|
||||
"license": "BSD-2-Clause",
|
||||
"bin": {
|
||||
"dotenv": "dist/index.cjs"
|
||||
|
||||
@@ -21,11 +21,11 @@
|
||||
"@fastify/cors": "^11.3.0",
|
||||
"@fastify/jwt": "^10.2.5",
|
||||
"@fastify/rate-limit": "^11.2.0",
|
||||
"@node-rs/bcrypt": "^1.10.7",
|
||||
"@node-rs/bcrypt": "^2.0.0",
|
||||
"@prisma/adapter-pg": "^7.10.1",
|
||||
"@prisma/client": "^7.10.1",
|
||||
"blurhash": "^2.0.5",
|
||||
"dotenv": "^18.0.8",
|
||||
"dotenv": "^18.0.9",
|
||||
"fastify": "^5.12.7",
|
||||
"openid-client": "^6.8.8",
|
||||
"pg": "^8.23.1",
|
||||
|
||||
@@ -8,7 +8,7 @@ import { env } from '../config/env.js'
|
||||
const HASH_ROUNDS = 12
|
||||
|
||||
export async function hashPassword(value: string): Promise<string> {
|
||||
return hash(value, HASH_ROUNDS)
|
||||
return hash(value, { cost: HASH_ROUNDS })
|
||||
}
|
||||
|
||||
export async function verifyPassword(value: string, storedHash: string): Promise<boolean> {
|
||||
|
||||
Generated
+181
-96
@@ -8,10 +8,10 @@
|
||||
"name": "frontend",
|
||||
"version": "0.0.0",
|
||||
"dependencies": {
|
||||
"@lucide/icons": "^1.59.0",
|
||||
"@lucide/icons": "^1.61.0",
|
||||
"blurhash": "^2.0.5",
|
||||
"lucide-react": "^1.59.0",
|
||||
"posthog-js": "^1.438.12",
|
||||
"lucide-react": "^1.61.0",
|
||||
"posthog-js": "^1.438.21",
|
||||
"react": "^19.3.1",
|
||||
"react-dom": "^19.3.1"
|
||||
},
|
||||
@@ -26,7 +26,7 @@
|
||||
"eslint-plugin-react-refresh": "^0.5.7",
|
||||
"globals": "^17.13.0",
|
||||
"tailwindcss": "^4.3.3",
|
||||
"vite": "^8.3.4",
|
||||
"vite": "^8.3.5",
|
||||
"vitest": "^5.0.5"
|
||||
}
|
||||
},
|
||||
@@ -554,15 +554,15 @@
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@lucide/icons": {
|
||||
"version": "1.59.0",
|
||||
"resolved": "https://registry.npmjs.org/@lucide/icons/-/icons-1.59.0.tgz",
|
||||
"integrity": "sha512-olGAqAKEtttGTAyjz+pmKEppYLu7X0jUtpLwt6JBvl9TMZaHnG7q6ECWVXh7rvt1ZLAsRASsuvtE4JtWU0Q2Ow==",
|
||||
"version": "1.61.0",
|
||||
"resolved": "https://registry.npmjs.org/@lucide/icons/-/icons-1.61.0.tgz",
|
||||
"integrity": "sha512-YNm6W6kz5/zlr63oNCJJY3BjSYU01L6HbGvOkKH3NNmu2vKGkCxSHLPx55FdSU9aY7jwwdvCfgU2d5bq4mNLig==",
|
||||
"license": "ISC"
|
||||
},
|
||||
"node_modules/@oxc-project/types": {
|
||||
"version": "0.152.0",
|
||||
"resolved": "https://registry.npmjs.org/@oxc-project/types/-/types-0.152.0.tgz",
|
||||
"integrity": "sha512-oM/5rLBm2tPkg0iBgkH/FOeR3PCDpY19GTgAZjMFM8h9WI9VW7cLgzp6nwtarYKmovavIQZ+Fe/RKX/8C8O/Rw==",
|
||||
"version": "0.155.0",
|
||||
"resolved": "https://registry.npmjs.org/@oxc-project/types/-/types-0.155.0.tgz",
|
||||
"integrity": "sha512-SeE8JPwW1xs1tHeNycjUtUBdhorRa8o4jlvjwk49R7/Z291i+4DQa7JJIgOm/TaYQZx+QrPQbVJ/9c8dMIZN8Q==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"funding": {
|
||||
@@ -570,19 +570,20 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@posthog/browser-common": {
|
||||
"version": "0.9.5",
|
||||
"resolved": "https://registry.npmjs.org/@posthog/browser-common/-/browser-common-0.9.5.tgz",
|
||||
"integrity": "sha512-oXnBgZvM8UQ84IcBLfGP0WSGd9rA0PCGR37H8Pw0NszJRwxwbJnFXIUih0pvI/ze2eGmzkIEC9i3SwC+bMAgjQ==",
|
||||
"version": "0.9.11",
|
||||
"resolved": "https://registry.npmjs.org/@posthog/browser-common/-/browser-common-0.9.11.tgz",
|
||||
"integrity": "sha512-ZCwJIgiDBRoEAlrlYxaIIIAUfITmBDpWDQJp+IZmAcTyvJka5/ebEKu8uV+jSSA/RhpvDKKte1WmhLUbkIWQjA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@posthog/core": "^1.59.1",
|
||||
"@posthog/types": "^1.416.0"
|
||||
"@posthog/core": "^1.60.1",
|
||||
"@posthog/types": "^1.416.0",
|
||||
"preact": "^10.29.3"
|
||||
}
|
||||
},
|
||||
"node_modules/@posthog/core": {
|
||||
"version": "1.59.1",
|
||||
"resolved": "https://registry.npmjs.org/@posthog/core/-/core-1.59.1.tgz",
|
||||
"integrity": "sha512-P39YgzQVDh6oz6wAzQXEnoHgTYpM7gifonmVKq1scAJco79h31XmmNVurRq9tTmmyIrr1uX8FHT0riCsyfV9AQ==",
|
||||
"version": "1.60.1",
|
||||
"resolved": "https://registry.npmjs.org/@posthog/core/-/core-1.60.1.tgz",
|
||||
"integrity": "sha512-UpswaG2957O6Ywfx1aCeI8BbXcfoKduKwq1ytBml80AQuAmgK672OmhDcldA7wg4vGP49LpDTgxcNbLvZwQOqw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@posthog/types": "^1.416.0"
|
||||
@@ -595,9 +596,9 @@
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@rolldown/binding-android-arm-eabi": {
|
||||
"version": "1.2.12",
|
||||
"resolved": "https://registry.npmjs.org/@rolldown/binding-android-arm-eabi/-/binding-android-arm-eabi-1.2.12.tgz",
|
||||
"integrity": "sha512-dB/a1214qKfHMXCpgqR4OZT+jS4kTyEXbQGJPqzobt5EwH5rX080pxE37alt3RzvR1bf1Yz/yGqRfrYAxuPw0A==",
|
||||
"version": "1.2.15",
|
||||
"resolved": "https://registry.npmjs.org/@rolldown/binding-android-arm-eabi/-/binding-android-arm-eabi-1.2.15.tgz",
|
||||
"integrity": "sha512-aLcgK9gIJ3YRvrrtfSBbRa27F5WrpiTaPulnFpsHPxpUHgFlSgnU4854MHwoRGEBhfRJDWCS2WQ7lIjskE9Olw==",
|
||||
"cpu": [
|
||||
"arm"
|
||||
],
|
||||
@@ -612,9 +613,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@rolldown/binding-android-arm64": {
|
||||
"version": "1.2.12",
|
||||
"resolved": "https://registry.npmjs.org/@rolldown/binding-android-arm64/-/binding-android-arm64-1.2.12.tgz",
|
||||
"integrity": "sha512-7KHFgQ5VJxIHcLlrwrc3Xbds7oTNQT7Pgi9gQCJKrd2VGab/UksIOYp6VD8MzCstGxOKMgNamPwUCfxPdP1OHg==",
|
||||
"version": "1.2.15",
|
||||
"resolved": "https://registry.npmjs.org/@rolldown/binding-android-arm64/-/binding-android-arm64-1.2.15.tgz",
|
||||
"integrity": "sha512-xD7DdZCrbThKuxNg7ooQmvp07ys4J/pnSEMTG3/OdOWl6daC67m/Q4fL78sRHMxTH/N4fGUbYhcPM0MF5WFHkg==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
@@ -629,9 +630,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@rolldown/binding-darwin-arm64": {
|
||||
"version": "1.2.12",
|
||||
"resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-arm64/-/binding-darwin-arm64-1.2.12.tgz",
|
||||
"integrity": "sha512-3YIhqHD96nA5SaYNRBR16HnGv4oavZvXfD/ayHM+oYZ0WD/8lBAtf6zQua4kEyAvpqrluKXl0lnOBoiNby7x9w==",
|
||||
"version": "1.2.15",
|
||||
"resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-arm64/-/binding-darwin-arm64-1.2.15.tgz",
|
||||
"integrity": "sha512-m2WuQ6r0B4OTYxyPpNLtXaMRbRDUbG8YQV2Q3KTdSSK8Th6KHCnC8jVCJt8bvYeSB5WivkkNbc85mKadaSdOxA==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
@@ -646,9 +647,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@rolldown/binding-darwin-x64": {
|
||||
"version": "1.2.12",
|
||||
"resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-x64/-/binding-darwin-x64-1.2.12.tgz",
|
||||
"integrity": "sha512-UuuJ35MFw4gmFOrE9pEqIV+K3syIKveph+Qc1/ljHZVdoDW4pz/JHR/eMVom+TZGl/5OOvGJOWaOCVt3ZfqhxA==",
|
||||
"version": "1.2.15",
|
||||
"resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-x64/-/binding-darwin-x64-1.2.15.tgz",
|
||||
"integrity": "sha512-5RtnsHM36nodM9WbMy+zip0LGS/G+y5wro5RHrpOlr4ac24+1zSi9kiV2MP1myZeZ/ifEHfulQcWjnAXzc2C2A==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
@@ -663,9 +664,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@rolldown/binding-freebsd-x64": {
|
||||
"version": "1.2.12",
|
||||
"resolved": "https://registry.npmjs.org/@rolldown/binding-freebsd-x64/-/binding-freebsd-x64-1.2.12.tgz",
|
||||
"integrity": "sha512-uMvssit0a4W+/7D8CbHUvG719mH3R2jwXAlh/XcPvuHTE0g++LymF88DCGNX0HM2rBOn0xrzgXktIB6fLSJBTQ==",
|
||||
"version": "1.2.15",
|
||||
"resolved": "https://registry.npmjs.org/@rolldown/binding-freebsd-x64/-/binding-freebsd-x64-1.2.15.tgz",
|
||||
"integrity": "sha512-g3l09pyFqhu+135JKkbkwiKGQmwU5hUMUPJ4VdBADvuqR8d33L6H578rh8m7rtxbdp+VmX/+nzI7nvhSZlzpUQ==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
@@ -680,9 +681,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@rolldown/binding-linux-arm-gnueabihf": {
|
||||
"version": "1.2.12",
|
||||
"resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-1.2.12.tgz",
|
||||
"integrity": "sha512-XcFu0R0xWnwzSf4IQgFH1rJIckPN1pLy2R+4r9IDB7Yfu/ys9cVqfa4pBrMHj7a3gl8mIR4nRNPg0e5IvEVs6g==",
|
||||
"version": "1.2.15",
|
||||
"resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-1.2.15.tgz",
|
||||
"integrity": "sha512-nIe3VugI97nGQtspPxDqA4sXMUpeiocKIP/CqpY/u/vgbT+alX+cVxu1C/oVBPKg4feNTmYovE91v4DgXvXNwQ==",
|
||||
"cpu": [
|
||||
"arm"
|
||||
],
|
||||
@@ -697,13 +698,16 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@rolldown/binding-linux-arm64-gnu": {
|
||||
"version": "1.2.12",
|
||||
"resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-1.2.12.tgz",
|
||||
"integrity": "sha512-260UrKgn8tz39ak+SMDOirKzr7V04M9dWPw5llW00SwBivCZoWcRBKV1d8cXnRkUmSZA3BdiUmBHWk7734Ulpw==",
|
||||
"version": "1.2.15",
|
||||
"resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-1.2.15.tgz",
|
||||
"integrity": "sha512-iTBjXx+B5QSvgI89lJfmqh4wTh8NabR1YZIIN3hNx4zSG0EVfVqkOvLulNpG4251pbd6/IAmZ/LefVk1Y4rPhw==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"dev": true,
|
||||
"libc": [
|
||||
"glibc"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
@@ -714,13 +718,16 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@rolldown/binding-linux-arm64-musl": {
|
||||
"version": "1.2.12",
|
||||
"resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-musl/-/binding-linux-arm64-musl-1.2.12.tgz",
|
||||
"integrity": "sha512-5YK1I9SqDkbPgc1IA8BgDl34suqUS2q0KWnBrirm0E51YjOs6eo6dV6jbQfNE/argHRSvd0QUGgtpIoYx+WWpw==",
|
||||
"version": "1.2.15",
|
||||
"resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-musl/-/binding-linux-arm64-musl-1.2.15.tgz",
|
||||
"integrity": "sha512-uN26XOnVR7rqQupG3V9oAG2EGGatWjcJHOeDOHUFCh4TBWmP2tHTFoVN13aYbwfm0aHqJAEmcwhAu6sooIjfqQ==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"dev": true,
|
||||
"libc": [
|
||||
"musl"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
@@ -731,13 +738,16 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@rolldown/binding-linux-ppc64-gnu": {
|
||||
"version": "1.2.12",
|
||||
"resolved": "https://registry.npmjs.org/@rolldown/binding-linux-ppc64-gnu/-/binding-linux-ppc64-gnu-1.2.12.tgz",
|
||||
"integrity": "sha512-Rkcrmp7eFRg74yL5fXEU91JEWbdEPLevWwGtXpmhbjlD1StScbWTmO94Bhly+Mo+ketKYkdmM1vNUKeWSlx8cQ==",
|
||||
"version": "1.2.15",
|
||||
"resolved": "https://registry.npmjs.org/@rolldown/binding-linux-ppc64-gnu/-/binding-linux-ppc64-gnu-1.2.15.tgz",
|
||||
"integrity": "sha512-9nWkcdd+H+XhaA3fQIwpHnKIrfx/PQ6rO0pivr78Og07tXlUlctBBJoEYLPfhTmCR/QxEVdn6uPjHV5SymPhdw==",
|
||||
"cpu": [
|
||||
"ppc64"
|
||||
],
|
||||
"dev": true,
|
||||
"libc": [
|
||||
"glibc"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
@@ -748,13 +758,16 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@rolldown/binding-linux-s390x-gnu": {
|
||||
"version": "1.2.12",
|
||||
"resolved": "https://registry.npmjs.org/@rolldown/binding-linux-s390x-gnu/-/binding-linux-s390x-gnu-1.2.12.tgz",
|
||||
"integrity": "sha512-qvK4DuAsQc2BSjlx+Xr+IzOIvvxbGZqxFwdWfG6F518Erj0GGISyQbJ6pIappnOxlNPzNHvo/L0BwB30GZ+zVw==",
|
||||
"version": "1.2.15",
|
||||
"resolved": "https://registry.npmjs.org/@rolldown/binding-linux-s390x-gnu/-/binding-linux-s390x-gnu-1.2.15.tgz",
|
||||
"integrity": "sha512-Ggh0ciFjLwIusLSLz7LZYEaGdxOAUJXI+Qu5JCbhPJJHEt8vP+IjRATTJheiJsdzzTYgUiHUiw3X1Ea3ZpMBdA==",
|
||||
"cpu": [
|
||||
"s390x"
|
||||
],
|
||||
"dev": true,
|
||||
"libc": [
|
||||
"glibc"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
@@ -765,13 +778,16 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@rolldown/binding-linux-x64-gnu": {
|
||||
"version": "1.2.12",
|
||||
"resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-gnu/-/binding-linux-x64-gnu-1.2.12.tgz",
|
||||
"integrity": "sha512-Q9uLBO53Xd4QIq1WOycVQyPP1O4HhraEV2qqb3uTrnVw6QZih9duY4vNXOivL1xoUS1/z+W8eF4NMfl2a8Sdjw==",
|
||||
"version": "1.2.15",
|
||||
"resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-gnu/-/binding-linux-x64-gnu-1.2.15.tgz",
|
||||
"integrity": "sha512-FHg60rS6DBePAYZ9X9F67x+JObFdmgn6tupA1C/a3B+CufFmTD4mX+e8M75tCiAO3foR/6xwVBI0KQiI7sn/rw==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"libc": [
|
||||
"glibc"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
@@ -782,13 +798,16 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@rolldown/binding-linux-x64-musl": {
|
||||
"version": "1.2.12",
|
||||
"resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-musl/-/binding-linux-x64-musl-1.2.12.tgz",
|
||||
"integrity": "sha512-3IBxWFMjbOZskDPKv8Lf9BCnahlKuHthWkYnyIxOH/QcJrFcS4EmcenthApkwr/5+nEqZlLzeYbxeMaX7A5u4g==",
|
||||
"version": "1.2.15",
|
||||
"resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-musl/-/binding-linux-x64-musl-1.2.15.tgz",
|
||||
"integrity": "sha512-/cvV/7v5VGz/moiz0XKRj2dE8DzsKyhIu1KpOvJGPjRywg3yscON889UGvAe8zfiJLHup7VLjBduoGWi3HusWQ==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"libc": [
|
||||
"musl"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
@@ -799,9 +818,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@rolldown/binding-openharmony-arm64": {
|
||||
"version": "1.2.12",
|
||||
"resolved": "https://registry.npmjs.org/@rolldown/binding-openharmony-arm64/-/binding-openharmony-arm64-1.2.12.tgz",
|
||||
"integrity": "sha512-xtX61xg4LKPkPWilZU1ynKClz5Gj4bf74LML4r3eVLWumKnGjoEr1OSHQhMdbBDoYTi+yjrujvpZe2pUnqCrrA==",
|
||||
"version": "1.2.15",
|
||||
"resolved": "https://registry.npmjs.org/@rolldown/binding-openharmony-arm64/-/binding-openharmony-arm64-1.2.15.tgz",
|
||||
"integrity": "sha512-MyzC5Hrv/sm+Z7TSGKP/j8001RO2xQm1zOpCNVL4j0cY/VhBZviludA2YFQ7i4lH6ZAXxQm0lcMdBzM+99mE7w==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
@@ -816,9 +835,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@rolldown/binding-win32-arm64-msvc": {
|
||||
"version": "1.2.12",
|
||||
"resolved": "https://registry.npmjs.org/@rolldown/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-1.2.12.tgz",
|
||||
"integrity": "sha512-At7fPB6PCaIjzgIhEZFxuT+BBFqiQibJDT4d3PhiR3f4E7bbMZF4aKblbFfEM3sETRDd1YiQx/+U/g/B/ou5Ew==",
|
||||
"version": "1.2.15",
|
||||
"resolved": "https://registry.npmjs.org/@rolldown/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-1.2.15.tgz",
|
||||
"integrity": "sha512-+PgYiS+AH5omy6L45ZLxybasauJaj3M8buoT83D+nzPmCayXlxUV9hydhciCKVyIg0B/v0BtXPDE1uGqNwCPpg==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
@@ -833,9 +852,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@rolldown/binding-win32-x64-msvc": {
|
||||
"version": "1.2.12",
|
||||
"resolved": "https://registry.npmjs.org/@rolldown/binding-win32-x64-msvc/-/binding-win32-x64-msvc-1.2.12.tgz",
|
||||
"integrity": "sha512-WIw2haVKwjuYdXkHaoC0mF8Le71TuCBxjrdKqLbJGctbBABj+ClfmNvtbOnzpq3RokNo5+V1qhtSzJyXorsklQ==",
|
||||
"version": "1.2.15",
|
||||
"resolved": "https://registry.npmjs.org/@rolldown/binding-win32-x64-msvc/-/binding-win32-x64-msvc-1.2.15.tgz",
|
||||
"integrity": "sha512-HFZd2QNQYn1JbIi+Hpd7H+r/lkWxcfIu28nirZ6eCn2LafuvmExMlb/P96Sfx5tf7pPArw39IdhmCF8vmV+NhQ==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
@@ -1350,6 +1369,72 @@
|
||||
"node": ">=14.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@emnapi/core": {
|
||||
"version": "1.11.1",
|
||||
"dev": true,
|
||||
"inBundle": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"dependencies": {
|
||||
"@emnapi/wasi-threads": "1.2.2",
|
||||
"tslib": "^2.4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@emnapi/runtime": {
|
||||
"version": "1.11.1",
|
||||
"dev": true,
|
||||
"inBundle": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"dependencies": {
|
||||
"tslib": "^2.4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@emnapi/wasi-threads": {
|
||||
"version": "1.2.2",
|
||||
"dev": true,
|
||||
"inBundle": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"dependencies": {
|
||||
"tslib": "^2.4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@napi-rs/wasm-runtime": {
|
||||
"version": "1.1.4",
|
||||
"dev": true,
|
||||
"inBundle": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"dependencies": {
|
||||
"@tybys/wasm-util": "^0.10.1"
|
||||
},
|
||||
"funding": {
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/Brooooooklyn"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@emnapi/core": "^1.7.1",
|
||||
"@emnapi/runtime": "^1.7.1"
|
||||
}
|
||||
},
|
||||
"node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@tybys/wasm-util": {
|
||||
"version": "0.10.2",
|
||||
"dev": true,
|
||||
"inBundle": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"dependencies": {
|
||||
"tslib": "^2.4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/tslib": {
|
||||
"version": "2.8.1",
|
||||
"dev": true,
|
||||
"inBundle": true,
|
||||
"license": "0BSD",
|
||||
"optional": true
|
||||
},
|
||||
"node_modules/@tailwindcss/oxide-win32-arm64-msvc": {
|
||||
"version": "4.3.3",
|
||||
"resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-arm64-msvc/-/oxide-win32-arm64-msvc-4.3.3.tgz",
|
||||
@@ -2627,9 +2712,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/lucide-react": {
|
||||
"version": "1.59.0",
|
||||
"resolved": "https://registry.npmjs.org/lucide-react/-/lucide-react-1.59.0.tgz",
|
||||
"integrity": "sha512-5qgMyyCPU6OvnKpLS2t693+ZtiqA8oaSweWoUows0BLFKFf6V75m4+CptpmohZHpD5IuOVIBXHBBiv2vpLJmtw==",
|
||||
"version": "1.61.0",
|
||||
"resolved": "https://registry.npmjs.org/lucide-react/-/lucide-react-1.61.0.tgz",
|
||||
"integrity": "sha512-v2SQPPPNjnr+BlhL9Spuzmo5yR+hLkftfuE4E3jaxdNPgSH0hJKPcLJBP7yAta87jQNPsSERS59PJjCJ/CorBA==",
|
||||
"license": "ISC",
|
||||
"peerDependencies": {
|
||||
"@types/react": "*",
|
||||
@@ -2836,13 +2921,13 @@
|
||||
}
|
||||
},
|
||||
"node_modules/posthog-js": {
|
||||
"version": "1.438.12",
|
||||
"resolved": "https://registry.npmjs.org/posthog-js/-/posthog-js-1.438.12.tgz",
|
||||
"integrity": "sha512-hjhvrtqbk6pFlbtNEGk0FrWKKFdeXe/WWA/LppN0f+uDoHKR9/SZJOxUHSVCGYbGTJvNRoDjjQvZuTcq4oKSlg==",
|
||||
"version": "1.438.21",
|
||||
"resolved": "https://registry.npmjs.org/posthog-js/-/posthog-js-1.438.21.tgz",
|
||||
"integrity": "sha512-KFrb9SOhyWg65OYOJ6dIxog26AqyD3ETj5pin/dWBcGll3pqa3FnqoJxq5IkHC6dtms/YjRCj6cT06u9j+EkoA==",
|
||||
"license": "(Apache-2.0 AND MIT)",
|
||||
"dependencies": {
|
||||
"@posthog/browser-common": "^0.9.5",
|
||||
"@posthog/core": "^1.59.1",
|
||||
"@posthog/browser-common": "^0.9.11",
|
||||
"@posthog/core": "^1.60.1",
|
||||
"@posthog/types": "^1.416.0",
|
||||
"core-js": "^3.49.0",
|
||||
"dompurify": "^3.4.13",
|
||||
@@ -2950,13 +3035,13 @@
|
||||
}
|
||||
},
|
||||
"node_modules/rolldown": {
|
||||
"version": "1.2.12",
|
||||
"resolved": "https://registry.npmjs.org/rolldown/-/rolldown-1.2.12.tgz",
|
||||
"integrity": "sha512-8wafseiaG80xmXSfqidUNqZcylTlhmPZZt+za2m+js2sFZ8dTNlhIOV2WcbIPx2hgwPBJpEUGFAMZ9bgBBLTSQ==",
|
||||
"version": "1.2.15",
|
||||
"resolved": "https://registry.npmjs.org/rolldown/-/rolldown-1.2.15.tgz",
|
||||
"integrity": "sha512-6odND+fel5zVw3I4Yc2e69gvguDnX0CAAGiNDZSq4ik5WUcaLrkD2GLuog0XcODbor31hZ5ayEMgVDno+KPV5g==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@oxc-project/types": "=0.152.0",
|
||||
"@oxc-project/types": "=0.155.0",
|
||||
"@rolldown/pluginutils": "^1.0.0"
|
||||
},
|
||||
"bin": {
|
||||
@@ -2966,21 +3051,21 @@
|
||||
"node": "^20.19.0 || >=22.12.0"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"@rolldown/binding-android-arm-eabi": "1.2.12",
|
||||
"@rolldown/binding-android-arm64": "1.2.12",
|
||||
"@rolldown/binding-darwin-arm64": "1.2.12",
|
||||
"@rolldown/binding-darwin-x64": "1.2.12",
|
||||
"@rolldown/binding-freebsd-x64": "1.2.12",
|
||||
"@rolldown/binding-linux-arm-gnueabihf": "1.2.12",
|
||||
"@rolldown/binding-linux-arm64-gnu": "1.2.12",
|
||||
"@rolldown/binding-linux-arm64-musl": "1.2.12",
|
||||
"@rolldown/binding-linux-ppc64-gnu": "1.2.12",
|
||||
"@rolldown/binding-linux-s390x-gnu": "1.2.12",
|
||||
"@rolldown/binding-linux-x64-gnu": "1.2.12",
|
||||
"@rolldown/binding-linux-x64-musl": "1.2.12",
|
||||
"@rolldown/binding-openharmony-arm64": "1.2.12",
|
||||
"@rolldown/binding-win32-arm64-msvc": "1.2.12",
|
||||
"@rolldown/binding-win32-x64-msvc": "1.2.12"
|
||||
"@rolldown/binding-android-arm-eabi": "1.2.15",
|
||||
"@rolldown/binding-android-arm64": "1.2.15",
|
||||
"@rolldown/binding-darwin-arm64": "1.2.15",
|
||||
"@rolldown/binding-darwin-x64": "1.2.15",
|
||||
"@rolldown/binding-freebsd-x64": "1.2.15",
|
||||
"@rolldown/binding-linux-arm-gnueabihf": "1.2.15",
|
||||
"@rolldown/binding-linux-arm64-gnu": "1.2.15",
|
||||
"@rolldown/binding-linux-arm64-musl": "1.2.15",
|
||||
"@rolldown/binding-linux-ppc64-gnu": "1.2.15",
|
||||
"@rolldown/binding-linux-s390x-gnu": "1.2.15",
|
||||
"@rolldown/binding-linux-x64-gnu": "1.2.15",
|
||||
"@rolldown/binding-linux-x64-musl": "1.2.15",
|
||||
"@rolldown/binding-openharmony-arm64": "1.2.15",
|
||||
"@rolldown/binding-win32-arm64-msvc": "1.2.15",
|
||||
"@rolldown/binding-win32-x64-msvc": "1.2.15"
|
||||
}
|
||||
},
|
||||
"node_modules/scheduler": {
|
||||
@@ -3149,16 +3234,16 @@
|
||||
}
|
||||
},
|
||||
"node_modules/vite": {
|
||||
"version": "8.3.4",
|
||||
"resolved": "https://registry.npmjs.org/vite/-/vite-8.3.4.tgz",
|
||||
"integrity": "sha512-IftLE8phJhdNRIGNEV4JCCvfNScoZQVfcXaN8TQropWGJtOHcu+iAB9pHcuGvmEb/kddw0LBe/jS8ztdC6xdiQ==",
|
||||
"version": "8.3.5",
|
||||
"resolved": "https://registry.npmjs.org/vite/-/vite-8.3.5.tgz",
|
||||
"integrity": "sha512-z1YpjieJ9g0ebTmQpLBv/oq9E3F9EIlOe+7LahW8SrE3LTiG3udBRUXQOlYXP9b+IC2q2phHeVxj9xGlw34OEQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"lightningcss": "^1.33.0",
|
||||
"picomatch": "^4.0.7",
|
||||
"postcss": "^8.5.29",
|
||||
"rolldown": "~1.2.12",
|
||||
"postcss": "^8.5.30",
|
||||
"rolldown": "~1.2.14",
|
||||
"tinyglobby": "^0.2.17"
|
||||
},
|
||||
"bin": {
|
||||
@@ -3175,7 +3260,7 @@
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@types/node": "^20.19.0 || >=22.12.0",
|
||||
"@vitejs/devtools": "^0.7.1",
|
||||
"@vitejs/devtools": "^0.7.1 || ^0.8.0",
|
||||
"esbuild": "^0.27.0 || ^0.28.0",
|
||||
"jiti": ">=1.21.0",
|
||||
"less": "^4.0.0",
|
||||
|
||||
@@ -12,10 +12,10 @@
|
||||
"test:watch": "vitest"
|
||||
},
|
||||
"dependencies": {
|
||||
"@lucide/icons": "^1.59.0",
|
||||
"@lucide/icons": "^1.61.0",
|
||||
"blurhash": "^2.0.5",
|
||||
"lucide-react": "^1.59.0",
|
||||
"posthog-js": "^1.438.12",
|
||||
"lucide-react": "^1.61.0",
|
||||
"posthog-js": "^1.438.21",
|
||||
"react": "^19.3.1",
|
||||
"react-dom": "^19.3.1"
|
||||
},
|
||||
@@ -30,7 +30,7 @@
|
||||
"eslint-plugin-react-refresh": "^0.5.7",
|
||||
"globals": "^17.13.0",
|
||||
"tailwindcss": "^4.3.3",
|
||||
"vite": "^8.3.4",
|
||||
"vite": "^8.3.5",
|
||||
"vitest": "^5.0.5"
|
||||
}
|
||||
}
|
||||
@@ -119,3 +119,10 @@
|
||||
body:has(.expandable-search.expanded) .family-tabs { top: 80px; max-width: calc(100vw - 20px); }
|
||||
.family-tab { font-size: 14px; padding: 6px 12px 7px; }
|
||||
}
|
||||
|
||||
/* Trait d'union entre deux onglets voisins quand le second part du premier (planche A, variante 2) */
|
||||
.family-tabs { gap: 0; }
|
||||
.family-tab + .family-tab:not([style]) { margin-left: 6px; }
|
||||
.family-tab--suite { position: relative; }
|
||||
.family-tab--suite::before { content: ""; position: absolute; right: 100%; top: 50%; width: 10px; height: 1.3px; transform: translateY(-50%); background: #E3A590; pointer-events: none; }
|
||||
.family-tab--trait-on::before { background: #D2694A; }
|
||||
@@ -50,6 +50,33 @@ const centerX = (node) => node.x + node.width / 2
|
||||
const easeOutQuint = (t) => 1 - (1 - t) ** 5
|
||||
const prefersReducedMotion = () => typeof window !== 'undefined' && window.matchMedia?.('(prefers-reduced-motion: reduce)').matches
|
||||
|
||||
// Barre des familles rangée comme l'arbre (Patch, 28/10, planche A variante 2 « le trait d'union ») : chaque
|
||||
// famille juste après celle par laquelle on y entre, la famille de départ en tête. Les onglets d'une même branche
|
||||
// (sous-arbre d'un enfant direct de la famille de départ) se serrent à 10 px, 16 px entre les branches ; un trait
|
||||
// relie deux voisins quand le second part du premier (jamais vers la famille de départ, sa place en tête suffit).
|
||||
// Le trait qui mène à l'onglet ouvert est terracotta, les autres couleur fil.
|
||||
function barTabs(tabs, activeKey) {
|
||||
if (!tabs.length) return []
|
||||
const root = tabs[0]
|
||||
const kids = new Map()
|
||||
for (const tb of tabs.slice(1)) { const pk = tabs.some((x) => x.key === tb.parentKey) ? tb.parentKey : root.key; if (!kids.has(pk)) kids.set(pk, []); kids.get(pk).push(tb) }
|
||||
const order = []
|
||||
const visit = (tb) => { order.push(tb); for (const c of kids.get(tb.key) || []) visit(c) }
|
||||
visit(root)
|
||||
for (const tb of tabs) if (!order.includes(tb)) order.push(tb)
|
||||
const byKey = new Map(tabs.map((tb) => [tb.key, tb]))
|
||||
const pathTo = (tb) => { const out = []; for (let t = tb; t; t = byKey.get(t.parentKey)) out.unshift(t.key); return out }
|
||||
const branchOf = (tb) => { const p = pathTo(tb); return p[1] || p[0] }
|
||||
const active = byKey.get(activeKey) || root
|
||||
const lit = new Set(pathTo(active))
|
||||
return order.map((tb, i) => {
|
||||
const prev = order[i - 1]
|
||||
const gap = i === 0 ? 0 : (prev !== root && branchOf(tb) === branchOf(prev) ? 10 : 16)
|
||||
const trait = i > 0 && prev !== root && tb.parentKey === prev.key ? (lit.has(tb.key) ? 'on' : 'off') : null
|
||||
return { tb, gap, trait }
|
||||
})
|
||||
}
|
||||
|
||||
const Galaxy = ({ onPersonSelect, onMediaSelect, selectedPersonId, searchHighlightIds = [], graphRevision = 0, annotationHandlers = null, transformReadRef = null, zoomApiRef = null, focusPersonId = null, assetRevision = 0, reorderEnabled = false, onReorderSiblings = null, familyTabs = true, fullNames = false, annotationViewRef = null, onAnnotationsAnchored = null, selfPersonId = null, ghosts = null, initialFamilyKey = null, onFamilyChange = null }) => {
|
||||
const canvasRef = useRef(null)
|
||||
const layoutDataRef = useRef(null)
|
||||
@@ -94,7 +121,32 @@ const Galaxy = ({ onPersonSelect, onMediaSelect, selectedPersonId, searchHighlig
|
||||
setActiveKey(focusPersonId != null ? String(focusPersonId) : null)
|
||||
}, [focusPersonId])
|
||||
// Onglet choisi par la personne (barre, badge, recherche) : le lien d'arrivée ne s'impose plus
|
||||
const chooseTab = useCallback((key) => { linkFamilyRef.current = null; pendingFamilyRef.current = null; frameOnRef.current = null; setActiveKey(key) }, [])
|
||||
// Repère du changement d'onglet (Patch, 28/10 : « on perd un peu rapidement le fil ») : la personne qui relie
|
||||
// les deux familles garde sa place et son zoom à l'écran, seules les familles autour changent
|
||||
const anchorRef = useRef(null)
|
||||
const linkPeople = (key) => {
|
||||
const list = tabsCacheRef.current.tabs
|
||||
const target = list.find((tb) => tb.key === String(key)), cur = activeTabRef.current || list[0]
|
||||
return [target?.referenceId, ...(target?.hinges || []), cur?.referenceId, ...(cur?.hinges || [])].filter((x) => x != null).map(String)
|
||||
}
|
||||
const rememberAnchor = (key) => {
|
||||
const layout = layoutDataRef.current, t = transformRef.current
|
||||
if (!layout || !t) return
|
||||
const ids = linkPeople(key)
|
||||
const node = layout.children.find((n) => n._type === 'person' && ids.includes(String(n._data?.id)))
|
||||
anchorRef.current = node ? { id: String(node._data.id), sx: (node.x + node.width / 2) * t.scale + t.x, sy: (node.y + node.height / 2) * t.scale + t.y, scale: t.scale } : null
|
||||
}
|
||||
const chooseTab = useCallback((key) => { rememberAnchor(key); linkFamilyRef.current = null; pendingFamilyRef.current = null; frameOnRef.current = null; setActiveKey(key) }, [])
|
||||
// Survol d'un onglet : la personne par qui l'on y passe s'allume dans l'arbre affiché, sans texte (Patch : « que ça les suggère »)
|
||||
const hoverTab = (key) => {
|
||||
const layout = layoutDataRef.current
|
||||
if (!layout) return
|
||||
const present = new Set(layout.children.filter((n) => n._type === 'person').map((n) => String(n._data?.id)))
|
||||
const ids = linkPeople(key).filter((id) => present.has(id))
|
||||
searchHighlightSetRef.current = new Set([...searchHighlightIdsRef.current.map((id) => `p-${id}`), ...ids.map((id) => `p-${id}`)])
|
||||
needsRedrawRef.current = true
|
||||
}
|
||||
const leaveTab = () => { searchHighlightSetRef.current = new Set(searchHighlightIdsRef.current.map((id) => `p-${id}`)); needsRedrawRef.current = true }
|
||||
// Lu au calcul du cadrage et par le réordonnancement : la référence de l'arbre affiché
|
||||
const focusPersonIdRef = useRef(focusPersonId)
|
||||
// La barre défile quand les onglets débordent : l'onglet ouvert se met en vue (sans animation) et les bords
|
||||
@@ -630,7 +682,7 @@ const Galaxy = ({ onPersonSelect, onMediaSelect, selectedPersonId, searchHighlig
|
||||
const parent = tabsCacheRef.current.tabs.find((tb) => tb.key === tab.parentKey)
|
||||
for (const h of (tab.hinges || [tab.referenceId])) {
|
||||
const node = result.children.find((n) => n.id === `p-${h}`)
|
||||
if (parent && node) node._familyTab = { anchorId: node.id, label: parent.label, count: parent.count, tabKey: parent.key, place: 'above' }
|
||||
if (parent && node) node._familyTab = { anchorId: node.id, label: parent.label, count: parent.count, tabKey: parent.key, place: 'above', back: true }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -684,6 +736,15 @@ const Galaxy = ({ onPersonSelect, onMediaSelect, selectedPersonId, searchHighlig
|
||||
offsetY = cssH * (cssW < 768 ? 0.4 : 0.42) - (focusNode.y + focusNode.height / 2) * scale
|
||||
}
|
||||
|
||||
const anc = anchorRef.current
|
||||
anchorRef.current = null
|
||||
const ancNode = anc && personNodes.find((n) => String(n._data?.id) === anc.id)
|
||||
if (ancNode) {
|
||||
scale = anc.scale
|
||||
offsetX = anc.sx - (ancNode.x + ancNode.width / 2) * scale
|
||||
offsetY = anc.sy - (ancNode.y + ancNode.height / 2) * scale
|
||||
}
|
||||
|
||||
const init = { x: offsetX, y: offsetY, scale }
|
||||
initialTransformRef.current = init
|
||||
transformRef.current = init
|
||||
@@ -803,7 +864,9 @@ const Galaxy = ({ onPersonSelect, onMediaSelect, selectedPersonId, searchHighlig
|
||||
}, [selectedPersonId])
|
||||
|
||||
// Sync searchHighlightIds
|
||||
const searchHighlightIdsRef = useRef(searchHighlightIds)
|
||||
useEffect(() => {
|
||||
searchHighlightIdsRef.current = searchHighlightIds
|
||||
searchHighlightSetRef.current = new Set(searchHighlightIds.map(id => `p-${id}`))
|
||||
}, [searchHighlightIds])
|
||||
|
||||
@@ -1259,18 +1322,23 @@ const Galaxy = ({ onPersonSelect, onMediaSelect, selectedPersonId, searchHighlig
|
||||
)}
|
||||
{familyTabs && tabs.length > 1 && (
|
||||
<nav ref={tabsBarRef} onScroll={updateTabsEdges} className={`family-tabs${annotationHandlers ? ' family-tabs--lowered' : ''}${tabsEdges}`} aria-label={tr('Familles')}>
|
||||
{tabs.map((tb) => {
|
||||
{barTabs(tabs, activeKey).map(({ tb, gap, trait }) => {
|
||||
const active = tb.key === (tabs.some((x) => x.key === activeKey) ? activeKey : tabs[0].key)
|
||||
return (
|
||||
<button
|
||||
key={tb.key}
|
||||
type="button"
|
||||
className={`family-tab${active ? ' is-active' : ''}`}
|
||||
style={gap ? { marginLeft: gap } : undefined}
|
||||
className={`family-tab${active ? ' is-active' : ''}${trait ? ` family-tab--suite family-tab--trait-${trait}` : ''}`}
|
||||
aria-current={active ? 'page' : undefined}
|
||||
onClick={() => chooseTab(tb.key)}
|
||||
onMouseEnter={() => { if (!active) hoverTab(tb.key) }}
|
||||
onMouseLeave={leaveTab}
|
||||
onFocus={() => { if (!active) hoverTab(tb.key) }}
|
||||
onBlur={leaveTab}
|
||||
>
|
||||
<span className="family-tab-name">{tb.label ? tr('Famille {name}', { name: tb.label }) : tr('Famille')}</span>
|
||||
<span className="family-tab-count">{tb.count}</span>
|
||||
<span className="family-tab-count" title={tr('{n} personnes', { n: tb.count })}>{tb.count}</span>
|
||||
</button>
|
||||
)
|
||||
})}
|
||||
|
||||
@@ -18,6 +18,7 @@ import { t, dateLocale } from '../i18n/index.js'
|
||||
import { formatPlace } from '../utils/place.js'
|
||||
import { firstNameLabel, fullNameLabel, isFirstNameUnknown } from '../utils/personName.js'
|
||||
import { isYearOnly } from '../utils/dateInput.js'
|
||||
import { ageInYears } from '../utils/age.js'
|
||||
import DateField from './DateField.jsx'
|
||||
import { runOnce } from '../utils/saveOnLeave.js'
|
||||
import { normalizeSex, SEX_CHOICES } from '../utils/personSex.js'
|
||||
@@ -448,9 +449,9 @@ const PersonCard = ({
|
||||
const hasDeathYear = Number.isFinite(deathYearNumber)
|
||||
const age = hasBirthYear
|
||||
? person.isAlive
|
||||
? new Date().getFullYear() - birthYearNumber
|
||||
? ageInYears(person.birthDate ?? birthYearNumber)
|
||||
: hasDeathYear
|
||||
? deathYearNumber - birthYearNumber
|
||||
? ageInYears(person.birthDate ?? birthYearNumber, person.deathDate ?? deathYearNumber)
|
||||
: null
|
||||
: null
|
||||
|
||||
|
||||
@@ -127,6 +127,20 @@ function layoutOnce(graphData, referenceId, forcedSide, familyTabs = true) {
|
||||
const result = computeLayout(graphData, referenceId)
|
||||
const nodes = result.children
|
||||
const byId = new Map(nodes.map(n => [n.id, n]))
|
||||
// Nom d'une famille : celui que portent le plus ses membres (nom de naissance, sinon nom), pas celui de la seule
|
||||
// personne de référence. Ex. : 175 personnes dont 5 portent le nom de la référence. Égalité : le nom
|
||||
// de secours (celui de la référence) s'il est parmi les premiers, sinon le premier rencontré.
|
||||
const nomMajoritaire = (ids, secours = '') => {
|
||||
const n = new Map()
|
||||
for (const id of ids) {
|
||||
const d = byId.get(id)?._type === 'person' ? byId.get(id)._data : null
|
||||
const nom = (d?.birthName || d?.lastName || '').trim()
|
||||
if (nom) n.set(nom, (n.get(nom) || 0) + 1)
|
||||
}
|
||||
let best = '', max = 0
|
||||
for (const [nom, c] of n) if (c > max) { best = nom; max = c }
|
||||
return secours && n.get(secours) === max ? secours : (best || secours)
|
||||
}
|
||||
|
||||
// Chaînes de couples (composantes d'une rangée) telles que computeLayout les a ordonnées
|
||||
const chainOf = new Map()
|
||||
@@ -416,8 +430,8 @@ function layoutOnce(graphData, referenceId, forcedSide, familyTabs = true) {
|
||||
unplace(block.members)
|
||||
forgetExternal(snap.externalBefore, snap.externalAfter)
|
||||
const A = byId.get(id)
|
||||
const label = A._data?.birthName || byId.get(pcPersons[0])?._data?.lastName || A._data?.lastName || ''
|
||||
const members = new Set([...extra, ...nested].filter(m => !keep.has(m)))
|
||||
const label = nomMajoritaire(members, A._data?.birthName || byId.get(pcPersons[0])?._data?.lastName || A._data?.lastName || '')
|
||||
registerTab({ anchorId: pcPersons[0], pu: parentUnionOf.get(pcPersons[0]) || pu, label, count: members.size, members, hinges: pcPersons.slice(1), hingeEdges: [] })
|
||||
for (const x of pcPersons) byId.get(x)._familyTab = { anchorId: pcPersons[0], label, count: members.size, tabKey: pcPersons[0].replace(/^p-/, ''), place: 'above' }
|
||||
const saved = anchor
|
||||
@@ -461,7 +475,7 @@ function layoutOnce(graphData, referenceId, forcedSide, familyTabs = true) {
|
||||
anchor = saved
|
||||
if (block.width > FAMILY_TAB_PX && !familyTabs) {
|
||||
const A = byId.get(id)
|
||||
bigFamilies.push({ anchorId: id, label: A._data?.birthName || A._data?.lastName || '', count: [...block.members].filter(m => byId.get(m)?._type === 'person').length })
|
||||
bigFamilies.push({ anchorId: id, label: nomMajoritaire(block.members, A._data?.birthName || A._data?.lastName || ''), count: [...block.members].filter(m => byId.get(m)?._type === 'person').length })
|
||||
}
|
||||
if (block.width > FAMILY_TAB_PX && familyTabs) {
|
||||
// Trop large pour cet arbre : la famille devient un onglet et n'est pas dessinée ici. Sa construction ne
|
||||
@@ -474,8 +488,8 @@ function layoutOnce(graphData, referenceId, forcedSide, familyTabs = true) {
|
||||
forgetExternal(externalBefore, new Set(externalEdges))
|
||||
const A = byId.get(id)
|
||||
const partners = [byId.get(pu)?._data?.p1Key, byId.get(pu)?._data?.p2Key].map(k => byId.get(k)?._data).filter(Boolean)
|
||||
const label = A._data?.birthName || partners.find(d => d.lastName)?.lastName || A._data?.lastName || ''
|
||||
const members = new Set([...[...block.members].filter(m => byId.get(m)?._type === 'person'), ...nested])
|
||||
const label = nomMajoritaire(members, A._data?.birthName || partners.find(d => d.lastName)?.lastName || A._data?.lastName || '')
|
||||
registerTab({ anchorId: id, pu, label, count: members.size, members, hinges: [], hingeEdges: [[pu, id]] })
|
||||
A._familyTab = { anchorId: id, label, count: members.size, tabKey: id.replace(/^p-/, ''), place: 'above' }
|
||||
continue
|
||||
@@ -818,7 +832,7 @@ function layoutOnce(graphData, referenceId, forcedSide, familyTabs = true) {
|
||||
// la barre d'onglets ; un onglet est le même arbre recalculé avec le conjoint comme référence.
|
||||
const drawn = nodes.filter(n => n._type === 'person')
|
||||
result.families = [
|
||||
{ id: 'main', label: referenceNode?._data?.lastName || drawn[0]?._data?.lastName || '', count: drawn.length, referenceId: result.referenceId ?? null },
|
||||
{ id: 'main', label: nomMajoritaire(drawn.map(n => n.id), referenceNode?._data?.lastName || drawn[0]?._data?.lastName || ''), count: drawn.length, referenceId: result.referenceId ?? null },
|
||||
...tabs.map(tb => ({ id: tb.anchorId, anchorId: tb.anchorId, label: tb.label, count: tb.count, members: [...tb.members].map(m => m.replace(/^p-/, '')), hinges: [tb.anchorId, ...tb.hinges].map(m => m.replace(/^p-/, '')) })),
|
||||
...bigFamilies.map(f => ({ id: f.anchorId, anchorId: f.anchorId, label: f.label, count: f.count, members: [], drawn: true })),
|
||||
]
|
||||
@@ -925,14 +939,26 @@ export function familyTabsOf(graphData = null, referenceId = null) {
|
||||
// Deux onglets au même nom (homonymes, ou une branche sortie de sa propre lignée) : sauf le plus grand, chacun
|
||||
// prend les prénoms de sa charnière, ceux que porte la pastille qui y mène (Patch, 20/10 : « plusieurs fois
|
||||
// les mêmes familles »)
|
||||
const firstName = new Map((graphData?.persons || globalPersons).map(p => [String(p.id), p.firstName]))
|
||||
// 28/10 (Patch : « ptet le Joseph et Marie ») : l'onglet le plus petit prend d'abord le nom suivant le plus
|
||||
// porté chez lui et pas encore pris par un autre onglet ; les prénoms de la charnière ne servent qu'en dernier recours.
|
||||
const persons = graphData?.persons || globalPersons
|
||||
const firstName = new Map(persons.map(p => [String(p.id), p.firstName]))
|
||||
const familyName = new Map(persons.map(p => [String(p.id), (p.birthName || p.lastName || '').trim()]))
|
||||
const namesByCount = (tb) => {
|
||||
const n = new Map()
|
||||
for (const id of tb.personIds || []) { const nom = familyName.get(String(id).replace(/^p-/, '')); if (nom) n.set(nom, (n.get(nom) || 0) + 1) }
|
||||
return [...n].sort((x, y) => y[1] - x[1]).map(([nom]) => nom)
|
||||
}
|
||||
const byLabel = new Map()
|
||||
for (const tb of tabs) { if (!byLabel.has(tb.label)) byLabel.set(tb.label, []); byLabel.get(tb.label).push(tb) }
|
||||
const taken = new Set(tabs.map(tb => tb.label))
|
||||
for (const group of byLabel.values()) {
|
||||
if (group.length < 2) continue
|
||||
const biggest = group.reduce((a, b) => (b.count > a.count ? b : a))
|
||||
for (const tb of group) {
|
||||
for (const tb of [...group].sort((a, b) => b.count - a.count)) {
|
||||
if (tb === biggest) continue
|
||||
const next = namesByCount(tb).find(nom => !taken.has(nom))
|
||||
if (next) { tb.label = next; taken.add(next); continue }
|
||||
const names = [...new Set((tb.hinges || [tb.referenceId]).map(id => firstName.get(String(id))).filter(Boolean))].slice(0, 2)
|
||||
if (names.length) tb.label = `${tb.label} · ${names.join(' et ')}`
|
||||
}
|
||||
|
||||
@@ -697,7 +697,10 @@ function drawPersonNode(ctx, node, pos, nodeProgress, {
|
||||
// la charnière peut avoir des enfants dessous, jamais rien au-dessus que le fil de ses parents.
|
||||
if (withDetail && node._familyTab) {
|
||||
const tab = node._familyTab
|
||||
const text = `${tab.label ? t('Famille {name}', { name: tab.label }) : t('Famille')} · ${tab.count} ›`
|
||||
// Retour vers la famille d'où l'on vient : même place que la pastille de l'aller (la charnière ne bouge pas),
|
||||
// flèche retournée (Patch, 28/10, planche D)
|
||||
const name = tab.label ? t('Famille {name}', { name: tab.label }) : t('Famille')
|
||||
const text = tab.back ? `‹ ${name} · ${tab.count}` : `${name} · ${tab.count} ›`
|
||||
const py = cy - PERSON_R * personScale - RENVOI_CHILD_GAP
|
||||
familyPills.push({ text, cx, cy: py, anchorId: tab.anchorId, tabKey: tab.tabKey, alpha: nodeProgress * labelAlpha })
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
// Traductions anglaises, clé = texte français exact passé à t().
|
||||
export default {
|
||||
'Famille {name}': 'The {name} family',
|
||||
'{n} personnes': '{n} people',
|
||||
'Famille': 'Family',
|
||||
'Familles': 'Families',
|
||||
'Affichage': 'Display',
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
import { isYearOnly } from './dateInput.js'
|
||||
|
||||
// Âge en années révolues (#198) : l'anniversaire compte une fois passé, pas dès le 1er janvier.
|
||||
// Une année seule (rangée au 1er janvier) n'a pas de jour : on garde la différence des années.
|
||||
const partsOf = (value) => {
|
||||
if (value === null || value === undefined || value === '') return null
|
||||
if (Number.isFinite(value)) return { year: Number(value), md: null }
|
||||
const text = String(value).slice(0, 10)
|
||||
const m = text.match(/^(\d{4})(?:-(\d{2})-(\d{2}))?/)
|
||||
if (!m) return null
|
||||
return { year: Number(m[1]), md: m[2] && !isYearOnly(text) ? `${m[2]}-${m[3]}` : null }
|
||||
}
|
||||
|
||||
const today = () => {
|
||||
const now = new Date()
|
||||
return `${now.getFullYear()}-${String(now.getMonth() + 1).padStart(2, '0')}-${String(now.getDate()).padStart(2, '0')}`
|
||||
}
|
||||
|
||||
// end absent = aujourd'hui ; null si la naissance (ou la fin donnée) manque
|
||||
export function ageInYears(birth, end = today()) {
|
||||
const from = partsOf(birth)
|
||||
const to = partsOf(end)
|
||||
if (!from || !to) return null
|
||||
const age = to.year - from.year
|
||||
return from.md && to.md && to.md < from.md ? age - 1 : age
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
import { describe, expect, it } from 'vitest'
|
||||
import { ageInYears } from './age.js'
|
||||
|
||||
describe('ageInYears', () => {
|
||||
it("ne compte l'anniversaire qu'une fois passé (#198)", () => {
|
||||
expect(ageInYears('1980-12-15', '2026-10-29')).toBe(45)
|
||||
expect(ageInYears('1980-12-15', '2026-12-15')).toBe(46)
|
||||
expect(ageInYears('1980-03-02T00:00:00.000Z', '2026-10-29')).toBe(46)
|
||||
})
|
||||
|
||||
it('garde la différence des années pour une année seule', () => {
|
||||
expect(ageInYears('1980-01-01', '2026-10-29')).toBe(46)
|
||||
expect(ageInYears(1980, '2026-10-29')).toBe(46)
|
||||
expect(ageInYears('1920-05-10', 1995)).toBe(75)
|
||||
})
|
||||
|
||||
it('calcule un âge au décès au jour près', () => {
|
||||
expect(ageInYears('1920-05-10', '1995-05-09T00:00:00.000Z')).toBe(74)
|
||||
})
|
||||
|
||||
it('rend null sans naissance', () => {
|
||||
expect(ageInYears(null)).toBe(null)
|
||||
expect(ageInYears('', '2026-10-29')).toBe(null)
|
||||
})
|
||||
})
|
||||
@@ -8,6 +8,7 @@
|
||||
import { t, dateLocale } from '../i18n/index.js'
|
||||
import { firstNameLabel } from './personName.js'
|
||||
import { formatPlace } from './place.js'
|
||||
import { ageInYears } from './age.js'
|
||||
|
||||
const EVENT_LABELS = {
|
||||
baptism: t('Baptême'),
|
||||
@@ -90,7 +91,11 @@ export function describeDate(date, end, precision) {
|
||||
}
|
||||
}
|
||||
|
||||
const ageAt = (birthYear, year) => (birthYear && year && year > birthYear ? t('{age} ans', { age: year - birthYear }) : '')
|
||||
// Âge à une date, au jour près quand les deux dates sont complètes (#198), sinon à l'année
|
||||
const ageAt = (birth, end) => {
|
||||
const age = ageInYears(birth, end || null)
|
||||
return age > 0 ? t('{age} ans', { age }) : ''
|
||||
}
|
||||
const joinMeta = (...parts) => parts.filter(Boolean).join(' · ')
|
||||
|
||||
// Le prénom d'un proche, cliquable dans la frise : il ouvre sa fiche
|
||||
@@ -123,6 +128,7 @@ export function buildLifeTimeline(person, family = {}, life = null) {
|
||||
const lifeUnions = new Map((life?.unions || []).map((u) => [String(u.id), u]))
|
||||
const events = life?.events || []
|
||||
const birthYear = yearOf(person.birthDate) ?? person.birthYear ?? null
|
||||
const birthDate = person.birthDate || birthYear
|
||||
const deathYear = yearOf(person.deathDate) ?? person.deathYear ?? null
|
||||
const lastYear = deathYear ?? new Date().getFullYear()
|
||||
const within = (year) => year && (!birthYear || year >= birthYear) && year <= lastYear
|
||||
@@ -165,14 +171,14 @@ export function buildLifeTimeline(person, family = {}, life = null) {
|
||||
startDatePrecision: detail.startDatePrecision || null, startPlace: detail.startPlace || '',
|
||||
},
|
||||
meta: year
|
||||
? joinMeta(place, detail.startDatePrecision ? describeDate(detail.startDate, null, detail.startDatePrecision) : '', ageAt(birthYear, year))
|
||||
? joinMeta(place, detail.startDatePrecision ? describeDate(detail.startDate, null, detail.startDatePrecision) : '', ageAt(birthDate, detail.startDate || year))
|
||||
: joinMeta(place, t('date inconnue')),
|
||||
note: extra?.notes || '', sources: extra?.sources || '',
|
||||
...milestoneFields(extra, { type: 'marriage', unionId: union.id }),
|
||||
})
|
||||
const hasEndEvent = events.some((e) => String(e.unionId) === String(union.id) && ['divorce', 'annulment'].includes(e.type))
|
||||
if (union.endYear && !hasEndEvent) {
|
||||
out.push({ key: `union-end-${union.id}`, year: union.endYear, order: 3, kind: 'minor', title: t('Fin de l’union avec {name}', { name: union.partner?.firstName || partnerName }), meta: ageAt(birthYear, union.endYear) })
|
||||
out.push({ key: `union-end-${union.id}`, year: union.endYear, order: 3, kind: 'minor', title: t('Fin de l’union avec {name}', { name: union.partner?.firstName || partnerName }), meta: ageAt(birthDate, union.endYear) })
|
||||
}
|
||||
if (union.partner && within(yearOf(union.partner.deathDate) ?? union.partner.deathYear)) {
|
||||
const year2 = yearOf(union.partner.deathDate) ?? union.partner.deathYear
|
||||
@@ -190,7 +196,7 @@ export function buildLifeTimeline(person, family = {}, life = null) {
|
||||
}
|
||||
out.push({
|
||||
key: `event-${event.id}`, year, order: 1, kind: 'minor', title,
|
||||
meta: joinMeta(formatPlace(event.place || ''), year ? describeDate(event.date, event.dateEnd, event.datePrecision) : t('date inconnue'), ageAt(birthYear, year)),
|
||||
meta: joinMeta(formatPlace(event.place || ''), year ? describeDate(event.date, event.dateEnd, event.datePrecision) : t('date inconnue'), ageAt(birthDate, event.date || year)),
|
||||
note: event.notes || '', sources: event.sources || '',
|
||||
mediaIds: event.mediaIds || [],
|
||||
// Seuls les moments propres à la personne se modifient depuis l'onglet (pas ceux d'une union)
|
||||
@@ -219,7 +225,7 @@ export function buildLifeTimeline(person, family = {}, life = null) {
|
||||
out.push({
|
||||
key: 'death', year: deathYear, order: 9, kind: 'mile',
|
||||
title: place ? t('Décès à {place}', { place: place.split(',')[0] }) : t('Décès'),
|
||||
meta: deathYear ? joinMeta(describeDate(person.deathDate, details.deathDateEnd, details.deathDatePrecision), ageAt(birthYear, deathYear)) : t('date inconnue'),
|
||||
meta: deathYear ? joinMeta(describeDate(person.deathDate, details.deathDateEnd, details.deathDatePrecision), ageAt(birthDate, person.deathDate || deathYear)) : t('date inconnue'),
|
||||
note: extra?.notes || '', sources: extra?.sources || '',
|
||||
...milestoneFields(extra, { type: 'death' }),
|
||||
})
|
||||
|
||||
Generated
+173
-88
@@ -8,7 +8,7 @@
|
||||
"name": "landing",
|
||||
"version": "0.0.0",
|
||||
"dependencies": {
|
||||
"posthog-js": "^1.438.12",
|
||||
"posthog-js": "^1.438.21",
|
||||
"react": "^19.3.1",
|
||||
"react-dom": "^19.3.1"
|
||||
},
|
||||
@@ -16,7 +16,7 @@
|
||||
"@tailwindcss/vite": "^4.3.3",
|
||||
"@vitejs/plugin-react": "^6.1.2",
|
||||
"tailwindcss": "^4.3.3",
|
||||
"vite": "^8.3.4"
|
||||
"vite": "^8.3.5"
|
||||
}
|
||||
},
|
||||
"node_modules/@jridgewell/gen-mapping": {
|
||||
@@ -70,9 +70,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@oxc-project/types": {
|
||||
"version": "0.153.0",
|
||||
"resolved": "https://registry.npmjs.org/@oxc-project/types/-/types-0.153.0.tgz",
|
||||
"integrity": "sha512-jSNrRIyvPVLL5E1z/tS5zLAprosGz/FuI1PWwEOz59j3E4TTTzSpqKb/RDGqJhhW0QHYISGXxq582wGx6T11Tw==",
|
||||
"version": "0.155.0",
|
||||
"resolved": "https://registry.npmjs.org/@oxc-project/types/-/types-0.155.0.tgz",
|
||||
"integrity": "sha512-SeE8JPwW1xs1tHeNycjUtUBdhorRa8o4jlvjwk49R7/Z291i+4DQa7JJIgOm/TaYQZx+QrPQbVJ/9c8dMIZN8Q==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"funding": {
|
||||
@@ -80,19 +80,20 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@posthog/browser-common": {
|
||||
"version": "0.9.5",
|
||||
"resolved": "https://registry.npmjs.org/@posthog/browser-common/-/browser-common-0.9.5.tgz",
|
||||
"integrity": "sha512-oXnBgZvM8UQ84IcBLfGP0WSGd9rA0PCGR37H8Pw0NszJRwxwbJnFXIUih0pvI/ze2eGmzkIEC9i3SwC+bMAgjQ==",
|
||||
"version": "0.9.11",
|
||||
"resolved": "https://registry.npmjs.org/@posthog/browser-common/-/browser-common-0.9.11.tgz",
|
||||
"integrity": "sha512-ZCwJIgiDBRoEAlrlYxaIIIAUfITmBDpWDQJp+IZmAcTyvJka5/ebEKu8uV+jSSA/RhpvDKKte1WmhLUbkIWQjA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@posthog/core": "^1.59.1",
|
||||
"@posthog/types": "^1.416.0"
|
||||
"@posthog/core": "^1.60.1",
|
||||
"@posthog/types": "^1.416.0",
|
||||
"preact": "^10.29.3"
|
||||
}
|
||||
},
|
||||
"node_modules/@posthog/core": {
|
||||
"version": "1.59.1",
|
||||
"resolved": "https://registry.npmjs.org/@posthog/core/-/core-1.59.1.tgz",
|
||||
"integrity": "sha512-P39YgzQVDh6oz6wAzQXEnoHgTYpM7gifonmVKq1scAJco79h31XmmNVurRq9tTmmyIrr1uX8FHT0riCsyfV9AQ==",
|
||||
"version": "1.60.1",
|
||||
"resolved": "https://registry.npmjs.org/@posthog/core/-/core-1.60.1.tgz",
|
||||
"integrity": "sha512-UpswaG2957O6Ywfx1aCeI8BbXcfoKduKwq1ytBml80AQuAmgK672OmhDcldA7wg4vGP49LpDTgxcNbLvZwQOqw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@posthog/types": "^1.416.0"
|
||||
@@ -105,9 +106,9 @@
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@rolldown/binding-android-arm-eabi": {
|
||||
"version": "1.2.13",
|
||||
"resolved": "https://registry.npmjs.org/@rolldown/binding-android-arm-eabi/-/binding-android-arm-eabi-1.2.13.tgz",
|
||||
"integrity": "sha512-Vu/NICrgdRvUOeaJZIyB2FP63s6fO/4ud5l8dXmxDx9yDyn+mN0y+gsvsVviSli+T361Aqo0h46EuMoobrwawA==",
|
||||
"version": "1.2.15",
|
||||
"resolved": "https://registry.npmjs.org/@rolldown/binding-android-arm-eabi/-/binding-android-arm-eabi-1.2.15.tgz",
|
||||
"integrity": "sha512-aLcgK9gIJ3YRvrrtfSBbRa27F5WrpiTaPulnFpsHPxpUHgFlSgnU4854MHwoRGEBhfRJDWCS2WQ7lIjskE9Olw==",
|
||||
"cpu": [
|
||||
"arm"
|
||||
],
|
||||
@@ -122,9 +123,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@rolldown/binding-android-arm64": {
|
||||
"version": "1.2.13",
|
||||
"resolved": "https://registry.npmjs.org/@rolldown/binding-android-arm64/-/binding-android-arm64-1.2.13.tgz",
|
||||
"integrity": "sha512-6LEoIrGy5vvCd2boNnv2soPSUZj/PRvhp8R/t9KlX+mIZxThIE/ZqxrGXxmuNX0FuvQFvLdZr7S4HrYpYBVhEQ==",
|
||||
"version": "1.2.15",
|
||||
"resolved": "https://registry.npmjs.org/@rolldown/binding-android-arm64/-/binding-android-arm64-1.2.15.tgz",
|
||||
"integrity": "sha512-xD7DdZCrbThKuxNg7ooQmvp07ys4J/pnSEMTG3/OdOWl6daC67m/Q4fL78sRHMxTH/N4fGUbYhcPM0MF5WFHkg==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
@@ -139,9 +140,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@rolldown/binding-darwin-arm64": {
|
||||
"version": "1.2.13",
|
||||
"resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-arm64/-/binding-darwin-arm64-1.2.13.tgz",
|
||||
"integrity": "sha512-CaJSRzlQ6Q+zkDMVA9OkVxBjVoPRCDEE3v0FSJ9kIQBgRjFApA3Si4ijhbNVUji7ZJt+PfO0e46qy4nPInHUPA==",
|
||||
"version": "1.2.15",
|
||||
"resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-arm64/-/binding-darwin-arm64-1.2.15.tgz",
|
||||
"integrity": "sha512-m2WuQ6r0B4OTYxyPpNLtXaMRbRDUbG8YQV2Q3KTdSSK8Th6KHCnC8jVCJt8bvYeSB5WivkkNbc85mKadaSdOxA==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
@@ -156,9 +157,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@rolldown/binding-darwin-x64": {
|
||||
"version": "1.2.13",
|
||||
"resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-x64/-/binding-darwin-x64-1.2.13.tgz",
|
||||
"integrity": "sha512-e4r340I5hxSzJkD3YJBxgzq/rJ3wwxwdLLb2FPt1Zpyem20nrQPT11DDEEkazwxaHumH8wpglsp/Ozgj/wT6mw==",
|
||||
"version": "1.2.15",
|
||||
"resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-x64/-/binding-darwin-x64-1.2.15.tgz",
|
||||
"integrity": "sha512-5RtnsHM36nodM9WbMy+zip0LGS/G+y5wro5RHrpOlr4ac24+1zSi9kiV2MP1myZeZ/ifEHfulQcWjnAXzc2C2A==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
@@ -173,9 +174,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@rolldown/binding-freebsd-x64": {
|
||||
"version": "1.2.13",
|
||||
"resolved": "https://registry.npmjs.org/@rolldown/binding-freebsd-x64/-/binding-freebsd-x64-1.2.13.tgz",
|
||||
"integrity": "sha512-hoBWDZ4/K/mJKVMbsgUd1jfpA2DiOrJ54mpegObU9TBHBBrtX4FLIXJJQRDPZ/2Dn91GvPob+Z2hwKJzf4E5SQ==",
|
||||
"version": "1.2.15",
|
||||
"resolved": "https://registry.npmjs.org/@rolldown/binding-freebsd-x64/-/binding-freebsd-x64-1.2.15.tgz",
|
||||
"integrity": "sha512-g3l09pyFqhu+135JKkbkwiKGQmwU5hUMUPJ4VdBADvuqR8d33L6H578rh8m7rtxbdp+VmX/+nzI7nvhSZlzpUQ==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
@@ -190,9 +191,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@rolldown/binding-linux-arm-gnueabihf": {
|
||||
"version": "1.2.13",
|
||||
"resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-1.2.13.tgz",
|
||||
"integrity": "sha512-oF9fZu3vTWnTiVAkDFxU9PJLt1nh20K9RRpuHsR7ZnE2L7XookBbDBVLojCVSLGbvtSlxeUNnjAj6DbNsKyzbg==",
|
||||
"version": "1.2.15",
|
||||
"resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-1.2.15.tgz",
|
||||
"integrity": "sha512-nIe3VugI97nGQtspPxDqA4sXMUpeiocKIP/CqpY/u/vgbT+alX+cVxu1C/oVBPKg4feNTmYovE91v4DgXvXNwQ==",
|
||||
"cpu": [
|
||||
"arm"
|
||||
],
|
||||
@@ -207,13 +208,16 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@rolldown/binding-linux-arm64-gnu": {
|
||||
"version": "1.2.13",
|
||||
"resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-1.2.13.tgz",
|
||||
"integrity": "sha512-DTpb/+jMiqWMPgphn4ksW1zW+XLJ6dJJ9FMvnIk9I291LhCctMPhMYJrP5t9p6C9qa3KXadDdUEZHBaPh3kNxQ==",
|
||||
"version": "1.2.15",
|
||||
"resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-1.2.15.tgz",
|
||||
"integrity": "sha512-iTBjXx+B5QSvgI89lJfmqh4wTh8NabR1YZIIN3hNx4zSG0EVfVqkOvLulNpG4251pbd6/IAmZ/LefVk1Y4rPhw==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"dev": true,
|
||||
"libc": [
|
||||
"glibc"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
@@ -224,13 +228,16 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@rolldown/binding-linux-arm64-musl": {
|
||||
"version": "1.2.13",
|
||||
"resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-musl/-/binding-linux-arm64-musl-1.2.13.tgz",
|
||||
"integrity": "sha512-xU+Kvv9N2A3SY35zFh1FWWNjxbadE/BKeqnkXe7vScU4GZsw757BlVmDLITZEq8DPpk6m7uoDYkK7P+x/uU5Ow==",
|
||||
"version": "1.2.15",
|
||||
"resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-musl/-/binding-linux-arm64-musl-1.2.15.tgz",
|
||||
"integrity": "sha512-uN26XOnVR7rqQupG3V9oAG2EGGatWjcJHOeDOHUFCh4TBWmP2tHTFoVN13aYbwfm0aHqJAEmcwhAu6sooIjfqQ==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"dev": true,
|
||||
"libc": [
|
||||
"musl"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
@@ -241,13 +248,16 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@rolldown/binding-linux-ppc64-gnu": {
|
||||
"version": "1.2.13",
|
||||
"resolved": "https://registry.npmjs.org/@rolldown/binding-linux-ppc64-gnu/-/binding-linux-ppc64-gnu-1.2.13.tgz",
|
||||
"integrity": "sha512-XMk/hnhh25oQ756Lclb1Q11h4ll0xC0Esa5w4Vzp+mAE2S3AGJgeM0SonrIgY8fHhjarb6hcoTuwoFG0VVP2ig==",
|
||||
"version": "1.2.15",
|
||||
"resolved": "https://registry.npmjs.org/@rolldown/binding-linux-ppc64-gnu/-/binding-linux-ppc64-gnu-1.2.15.tgz",
|
||||
"integrity": "sha512-9nWkcdd+H+XhaA3fQIwpHnKIrfx/PQ6rO0pivr78Og07tXlUlctBBJoEYLPfhTmCR/QxEVdn6uPjHV5SymPhdw==",
|
||||
"cpu": [
|
||||
"ppc64"
|
||||
],
|
||||
"dev": true,
|
||||
"libc": [
|
||||
"glibc"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
@@ -258,13 +268,16 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@rolldown/binding-linux-s390x-gnu": {
|
||||
"version": "1.2.13",
|
||||
"resolved": "https://registry.npmjs.org/@rolldown/binding-linux-s390x-gnu/-/binding-linux-s390x-gnu-1.2.13.tgz",
|
||||
"integrity": "sha512-U1BoTHYmlywE2n3HUWjzZ+8EQsKr+OwpxYuDWaubx42tUL8QSL7nOqRz/NVHanibbFP3M1Rxuprz/wNcbMKjqw==",
|
||||
"version": "1.2.15",
|
||||
"resolved": "https://registry.npmjs.org/@rolldown/binding-linux-s390x-gnu/-/binding-linux-s390x-gnu-1.2.15.tgz",
|
||||
"integrity": "sha512-Ggh0ciFjLwIusLSLz7LZYEaGdxOAUJXI+Qu5JCbhPJJHEt8vP+IjRATTJheiJsdzzTYgUiHUiw3X1Ea3ZpMBdA==",
|
||||
"cpu": [
|
||||
"s390x"
|
||||
],
|
||||
"dev": true,
|
||||
"libc": [
|
||||
"glibc"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
@@ -275,13 +288,16 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@rolldown/binding-linux-x64-gnu": {
|
||||
"version": "1.2.13",
|
||||
"resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-gnu/-/binding-linux-x64-gnu-1.2.13.tgz",
|
||||
"integrity": "sha512-J4cm80Pc6wEwV5AZ42o62sIQgDk+Y7R2s646jIwuvO+4V46QB58N4vVuMPWCBaNgursXLpmUWJV//WQAkPvHBQ==",
|
||||
"version": "1.2.15",
|
||||
"resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-gnu/-/binding-linux-x64-gnu-1.2.15.tgz",
|
||||
"integrity": "sha512-FHg60rS6DBePAYZ9X9F67x+JObFdmgn6tupA1C/a3B+CufFmTD4mX+e8M75tCiAO3foR/6xwVBI0KQiI7sn/rw==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"libc": [
|
||||
"glibc"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
@@ -292,13 +308,16 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@rolldown/binding-linux-x64-musl": {
|
||||
"version": "1.2.13",
|
||||
"resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-musl/-/binding-linux-x64-musl-1.2.13.tgz",
|
||||
"integrity": "sha512-W0euZS40U4V6JkmEnVCIX9mcsL6cbXQ4X8c2w+MMOIjFg68TXUW+u3RT+2e1t1pv9mg/EP3pDtK3POXdQ7Rxyw==",
|
||||
"version": "1.2.15",
|
||||
"resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-musl/-/binding-linux-x64-musl-1.2.15.tgz",
|
||||
"integrity": "sha512-/cvV/7v5VGz/moiz0XKRj2dE8DzsKyhIu1KpOvJGPjRywg3yscON889UGvAe8zfiJLHup7VLjBduoGWi3HusWQ==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"libc": [
|
||||
"musl"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
@@ -309,9 +328,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@rolldown/binding-openharmony-arm64": {
|
||||
"version": "1.2.13",
|
||||
"resolved": "https://registry.npmjs.org/@rolldown/binding-openharmony-arm64/-/binding-openharmony-arm64-1.2.13.tgz",
|
||||
"integrity": "sha512-do/AF/4n9MRshia3a5aXoy8xM2c6mgfT6D7H/dY6my5z+hfCIR4ab7mk4IRj++nsEQpKy39kd0DQnDq+r692tw==",
|
||||
"version": "1.2.15",
|
||||
"resolved": "https://registry.npmjs.org/@rolldown/binding-openharmony-arm64/-/binding-openharmony-arm64-1.2.15.tgz",
|
||||
"integrity": "sha512-MyzC5Hrv/sm+Z7TSGKP/j8001RO2xQm1zOpCNVL4j0cY/VhBZviludA2YFQ7i4lH6ZAXxQm0lcMdBzM+99mE7w==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
@@ -326,9 +345,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@rolldown/binding-win32-arm64-msvc": {
|
||||
"version": "1.2.13",
|
||||
"resolved": "https://registry.npmjs.org/@rolldown/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-1.2.13.tgz",
|
||||
"integrity": "sha512-6FtUf2cJZobutJdxnGYX8z0vtbgqU0b2v8vfBhkXb9wp2MppMFtkunE+IaOntyi01rkIQoPW2GHABtfzsC0BRQ==",
|
||||
"version": "1.2.15",
|
||||
"resolved": "https://registry.npmjs.org/@rolldown/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-1.2.15.tgz",
|
||||
"integrity": "sha512-+PgYiS+AH5omy6L45ZLxybasauJaj3M8buoT83D+nzPmCayXlxUV9hydhciCKVyIg0B/v0BtXPDE1uGqNwCPpg==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
@@ -343,9 +362,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@rolldown/binding-win32-x64-msvc": {
|
||||
"version": "1.2.13",
|
||||
"resolved": "https://registry.npmjs.org/@rolldown/binding-win32-x64-msvc/-/binding-win32-x64-msvc-1.2.13.tgz",
|
||||
"integrity": "sha512-UKhFaZTeTcbKrb3iU82m17jVcPEAoqDkCN5MBqgPyZSwp/cQmib21crTS0DdH7T1B7wZRWEI89YQAOJMet5yhg==",
|
||||
"version": "1.2.15",
|
||||
"resolved": "https://registry.npmjs.org/@rolldown/binding-win32-x64-msvc/-/binding-win32-x64-msvc-1.2.15.tgz",
|
||||
"integrity": "sha512-HFZd2QNQYn1JbIi+Hpd7H+r/lkWxcfIu28nirZ6eCn2LafuvmExMlb/P96Sfx5tf7pPArw39IdhmCF8vmV+NhQ==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
@@ -850,6 +869,72 @@
|
||||
"node": ">=14.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@emnapi/core": {
|
||||
"version": "1.11.1",
|
||||
"dev": true,
|
||||
"inBundle": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"dependencies": {
|
||||
"@emnapi/wasi-threads": "1.2.2",
|
||||
"tslib": "^2.4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@emnapi/runtime": {
|
||||
"version": "1.11.1",
|
||||
"dev": true,
|
||||
"inBundle": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"dependencies": {
|
||||
"tslib": "^2.4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@emnapi/wasi-threads": {
|
||||
"version": "1.2.2",
|
||||
"dev": true,
|
||||
"inBundle": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"dependencies": {
|
||||
"tslib": "^2.4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@napi-rs/wasm-runtime": {
|
||||
"version": "1.1.4",
|
||||
"dev": true,
|
||||
"inBundle": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"dependencies": {
|
||||
"@tybys/wasm-util": "^0.10.1"
|
||||
},
|
||||
"funding": {
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/Brooooooklyn"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@emnapi/core": "^1.7.1",
|
||||
"@emnapi/runtime": "^1.7.1"
|
||||
}
|
||||
},
|
||||
"node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@tybys/wasm-util": {
|
||||
"version": "0.10.2",
|
||||
"dev": true,
|
||||
"inBundle": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"dependencies": {
|
||||
"tslib": "^2.4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/tslib": {
|
||||
"version": "2.8.1",
|
||||
"dev": true,
|
||||
"inBundle": true,
|
||||
"license": "0BSD",
|
||||
"optional": true
|
||||
},
|
||||
"node_modules/@tailwindcss/oxide-win32-arm64-msvc": {
|
||||
"version": "4.3.3",
|
||||
"resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-arm64-msvc/-/oxide-win32-arm64-msvc-4.3.3.tgz",
|
||||
@@ -1348,13 +1433,13 @@
|
||||
}
|
||||
},
|
||||
"node_modules/posthog-js": {
|
||||
"version": "1.438.12",
|
||||
"resolved": "https://registry.npmjs.org/posthog-js/-/posthog-js-1.438.12.tgz",
|
||||
"integrity": "sha512-hjhvrtqbk6pFlbtNEGk0FrWKKFdeXe/WWA/LppN0f+uDoHKR9/SZJOxUHSVCGYbGTJvNRoDjjQvZuTcq4oKSlg==",
|
||||
"version": "1.438.21",
|
||||
"resolved": "https://registry.npmjs.org/posthog-js/-/posthog-js-1.438.21.tgz",
|
||||
"integrity": "sha512-KFrb9SOhyWg65OYOJ6dIxog26AqyD3ETj5pin/dWBcGll3pqa3FnqoJxq5IkHC6dtms/YjRCj6cT06u9j+EkoA==",
|
||||
"license": "(Apache-2.0 AND MIT)",
|
||||
"dependencies": {
|
||||
"@posthog/browser-common": "^0.9.5",
|
||||
"@posthog/core": "^1.59.1",
|
||||
"@posthog/browser-common": "^0.9.11",
|
||||
"@posthog/core": "^1.60.1",
|
||||
"@posthog/types": "^1.416.0",
|
||||
"core-js": "^3.49.0",
|
||||
"dompurify": "^3.4.13",
|
||||
@@ -1423,13 +1508,13 @@
|
||||
}
|
||||
},
|
||||
"node_modules/rolldown": {
|
||||
"version": "1.2.13",
|
||||
"resolved": "https://registry.npmjs.org/rolldown/-/rolldown-1.2.13.tgz",
|
||||
"integrity": "sha512-/5apOkwWxtACcQtZ5WlrAsKS4JwXVThQPJZ3RqIruRY9UG9M8e0VlXN068xum/JRKA4aIUoJ13ghe/kGCvidiQ==",
|
||||
"version": "1.2.15",
|
||||
"resolved": "https://registry.npmjs.org/rolldown/-/rolldown-1.2.15.tgz",
|
||||
"integrity": "sha512-6odND+fel5zVw3I4Yc2e69gvguDnX0CAAGiNDZSq4ik5WUcaLrkD2GLuog0XcODbor31hZ5ayEMgVDno+KPV5g==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@oxc-project/types": "=0.153.0",
|
||||
"@oxc-project/types": "=0.155.0",
|
||||
"@rolldown/pluginutils": "^1.0.0"
|
||||
},
|
||||
"bin": {
|
||||
@@ -1439,21 +1524,21 @@
|
||||
"node": "^20.19.0 || >=22.12.0"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"@rolldown/binding-android-arm-eabi": "1.2.13",
|
||||
"@rolldown/binding-android-arm64": "1.2.13",
|
||||
"@rolldown/binding-darwin-arm64": "1.2.13",
|
||||
"@rolldown/binding-darwin-x64": "1.2.13",
|
||||
"@rolldown/binding-freebsd-x64": "1.2.13",
|
||||
"@rolldown/binding-linux-arm-gnueabihf": "1.2.13",
|
||||
"@rolldown/binding-linux-arm64-gnu": "1.2.13",
|
||||
"@rolldown/binding-linux-arm64-musl": "1.2.13",
|
||||
"@rolldown/binding-linux-ppc64-gnu": "1.2.13",
|
||||
"@rolldown/binding-linux-s390x-gnu": "1.2.13",
|
||||
"@rolldown/binding-linux-x64-gnu": "1.2.13",
|
||||
"@rolldown/binding-linux-x64-musl": "1.2.13",
|
||||
"@rolldown/binding-openharmony-arm64": "1.2.13",
|
||||
"@rolldown/binding-win32-arm64-msvc": "1.2.13",
|
||||
"@rolldown/binding-win32-x64-msvc": "1.2.13"
|
||||
"@rolldown/binding-android-arm-eabi": "1.2.15",
|
||||
"@rolldown/binding-android-arm64": "1.2.15",
|
||||
"@rolldown/binding-darwin-arm64": "1.2.15",
|
||||
"@rolldown/binding-darwin-x64": "1.2.15",
|
||||
"@rolldown/binding-freebsd-x64": "1.2.15",
|
||||
"@rolldown/binding-linux-arm-gnueabihf": "1.2.15",
|
||||
"@rolldown/binding-linux-arm64-gnu": "1.2.15",
|
||||
"@rolldown/binding-linux-arm64-musl": "1.2.15",
|
||||
"@rolldown/binding-linux-ppc64-gnu": "1.2.15",
|
||||
"@rolldown/binding-linux-s390x-gnu": "1.2.15",
|
||||
"@rolldown/binding-linux-x64-gnu": "1.2.15",
|
||||
"@rolldown/binding-linux-x64-musl": "1.2.15",
|
||||
"@rolldown/binding-openharmony-arm64": "1.2.15",
|
||||
"@rolldown/binding-win32-arm64-msvc": "1.2.15",
|
||||
"@rolldown/binding-win32-x64-msvc": "1.2.15"
|
||||
}
|
||||
},
|
||||
"node_modules/scheduler": {
|
||||
@@ -1542,16 +1627,16 @@
|
||||
}
|
||||
},
|
||||
"node_modules/vite": {
|
||||
"version": "8.3.4",
|
||||
"resolved": "https://registry.npmjs.org/vite/-/vite-8.3.4.tgz",
|
||||
"integrity": "sha512-IftLE8phJhdNRIGNEV4JCCvfNScoZQVfcXaN8TQropWGJtOHcu+iAB9pHcuGvmEb/kddw0LBe/jS8ztdC6xdiQ==",
|
||||
"version": "8.3.5",
|
||||
"resolved": "https://registry.npmjs.org/vite/-/vite-8.3.5.tgz",
|
||||
"integrity": "sha512-z1YpjieJ9g0ebTmQpLBv/oq9E3F9EIlOe+7LahW8SrE3LTiG3udBRUXQOlYXP9b+IC2q2phHeVxj9xGlw34OEQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"lightningcss": "^1.33.0",
|
||||
"picomatch": "^4.0.7",
|
||||
"postcss": "^8.5.29",
|
||||
"rolldown": "~1.2.12",
|
||||
"postcss": "^8.5.30",
|
||||
"rolldown": "~1.2.14",
|
||||
"tinyglobby": "^0.2.17"
|
||||
},
|
||||
"bin": {
|
||||
@@ -1568,7 +1653,7 @@
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@types/node": "^20.19.0 || >=22.12.0",
|
||||
"@vitejs/devtools": "^0.7.1",
|
||||
"@vitejs/devtools": "^0.7.1 || ^0.8.0",
|
||||
"esbuild": "^0.27.0 || ^0.28.0",
|
||||
"jiti": ">=1.21.0",
|
||||
"less": "^4.0.0",
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
"test": "node --test"
|
||||
},
|
||||
"dependencies": {
|
||||
"posthog-js": "^1.438.12",
|
||||
"posthog-js": "^1.438.21",
|
||||
"react": "^19.3.1",
|
||||
"react-dom": "^19.3.1"
|
||||
},
|
||||
@@ -18,6 +18,6 @@
|
||||
"@tailwindcss/vite": "^4.3.3",
|
||||
"@vitejs/plugin-react": "^6.1.2",
|
||||
"tailwindcss": "^4.3.3",
|
||||
"vite": "^8.3.4"
|
||||
"vite": "^8.3.5"
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user