Compare commits

...
Author SHA1 Message Date
maulanasdqnandClaude Opus 4.5 8728d0abd7 feat(landing): add Powered By Ancikri badge to hero section
Add clickable "Powered By Ancikri" badge beside the community badge
with matching pill design, linking to ancikri.com

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-21 21:58:35 +07:00
maulanasdqnandClaude Opus 4.5 1f4f4ddaa1 feat(landing): add Powered by Ancikri to footer
Add clickable "Powered by Ancikri" link in the footer
pointing to ancikri.com

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-21 21:38:19 +07:00
maulanasdqnandClaude Opus 4.5 4fcc249ff4 ci: add Nix build workflow with Cachix
- Build all packages (landing, backoffice, gacha, dimentorin, hackathon, infra)
- Push to msdqn Cachix cache
- Server can pull pre-built packages from Cachix

Requires CACHIX_AUTH_TOKEN secret in GitHub repository settings.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-21 21:23:45 +07:00
maulanasdqnandClaude Opus 4.5 c2bed98b06 security: patch Next.js RCE vulnerability (CVE-2025-55182)
Upgrade Next.js from 16.0.8 to 16.0.10 to fix critical RCE
vulnerability (CVSS 10.0) in React Server Components.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-21 21:09:51 +07:00
maulanasdqn ae1864c134 chore: remove Supabase dependency completely 2026-01-21 20:52:03 +07:00
maulanasdqn 3f30fbe89c fix: make Supabase client lazy to avoid errors when credentials missing 2026-01-21 20:41:28 +07:00
maulanasdqn 951db0f28a feat: add infra app for infrastructure documentation 2026-01-21 20:22:27 +07:00
maulanasdqn ad59d39f55 fix: add react-is dependency for recharts
This is a peer dependency required for recharts to work properly
in production builds.
2026-01-21 18:54:39 +07:00
maulanasdqn 1283689d84 fix(nix): use script command to create pseudo-terminal for Nx
This provides a pty that satisfies Nx's terminal requirements,
preventing the raw terminal mode crash in sandboxed builds.
2026-01-21 18:45:45 +07:00
maulanasdqn 7d1370d7f2 fix(nix): run nx build in background to handle SIGABRT
Background process signal handling allows wait to catch SIGABRT
and || true to suppress the non-zero exit status.
2026-01-21 18:39:05 +07:00
maulanasdqn ab0b56780f fix(nix): use set +e to handle SIGABRT from Nx crash
Signal handling in bash requires set +e to prevent errexit
from terminating the script when a process is killed by SIGABRT.
2026-01-21 18:33:03 +07:00
maulanasdqn 1a39ac37db fix(nix): improve Nx crash recovery for Vite builds
Use '|| true' to always continue past Nx terminal crash,
then verify build output directory exists separately.
2026-01-21 18:25:53 +07:00
maulanasdqnandClaude Opus 4.5 e5dc784301 fix(nix): handle Nx terminal crash for Vite apps
Add fallback check to continue if build output exists even when
Nx crashes after successful build completion.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-21 18:14:52 +07:00
maulanasdqnandClaude Opus 4.5 b2de22b0ef fix(nix): add --jitless flag to workaround V8 memory issue
Add --jitless Node.js flag to work around V8 JIT compilation
memory allocation issues on the server.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-21 17:16:51 +07:00
maulanasdqnandClaude Opus 4.5 ad20eda182 fix(nix): use proper bash path in wrapper script
Fix wrapper script to use explicit Nix bash path instead of
/usr/bin/env bash which doesn't work on NixOS.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-21 17:11:39 +07:00
maulanasdqnandClaude Opus 4.5 da65aa4109 chore(nix): update npmDepsHash for local fonts
Update hash after adding font files to the repository.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-21 17:02:14 +07:00
maulanasdqnandClaude Opus 4.5 1f0798752c feat(landing): use local fonts instead of Google Fonts
- Download Poppins and Bai Jamjuree font files locally
- Convert from next/font/google to next/font/local
- Enables builds in sandboxed environments without network access

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-21 16:55:26 +07:00
maulanasdqnandClaude Opus 4.5 5f28b9b406 fix(nix): allow network access for Google Fonts during build
Add __noChroot=true to enable network access for next/font/google
to fetch Poppins and Bai_Jamjuree fonts during the Next.js build.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-21 16:44:07 +07:00
maulanasdqnandClaude Opus 4.5 9e8fc7c07f fix(nix): use --output-style=static to bypass Nx terminal crash
Call Nx directly with --output-style=static flag instead of through
npm scripts to completely bypass the pseudo terminal initialization
that crashes in non-TTY environments.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-21 16:34:39 +07:00
maulanasdqnandClaude Opus 4.5 ca51f8aca2 fix(nix): disable Nx native terminal to prevent build crash
Add NX_TASKS_RUNNER_DYNAMIC_OUTPUT=false and NX_NATIVE=false
to completely disable Nx's Rust-based terminal handling that
crashes in non-TTY build environments.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-21 16:25:27 +07:00
maulanasdqnandClaude Opus 4.5 c086b1371c fix(nix): add CI environment flags to prevent terminal rendering crash
Added CI=true, NO_COLOR=1, TERM=dumb, and NX_SKIP_NX_CACHE=true
to both mkViteApp.nix and landing.nix to prevent the vt100-rust
panic during Nix builds.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-21 14:57:17 +07:00
maulanasdqn 398350795d fix: add legacy-peer-deps and makeCacheWritable for npm builds 2026-01-21 14:26:13 +07:00
maulanasdqnandClaude Opus 4.5 5be9ec1edf feat: add Nix flake for reproducible builds and deployment
- Add flake.nix with packages for all 5 apps (landing, gacha, backoffice, dimentorin, hackathon)
- Add NixOS modules for deployment (systemd service for Next.js, nginx for Vite apps)
- Add mkHackathonWithEnv function for build-time environment variables
- Add development shell with Node.js 22, npm, bun

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-21 10:02:46 +07:00
Hafid Nur f77967a092 feat(hackathon): update certificate to include project submission name (#74)
* update hackathon landing page

* feat(hackathon): draft winner certificate

* feat(hackathon): refine winner certificate

* feat(hackathon): update certificate

- add submission project name to the certificate
2025-12-16 13:58:43 +07:00
41 changed files with 1184 additions and 475 deletions
+19
View File
@@ -0,0 +1,19 @@
#!/usr/bin/env bash
set -e
if [[ ! -d "/Users/ms/Development/personal/imphnen-frontend-service" ]]; then
echo "Cannot find source directory; Did you move it?"
echo "(Looking for "/Users/ms/Development/personal/imphnen-frontend-service")"
echo 'Cannot force reload with this script - use "direnv reload" manually and then try again'
exit 1
fi
# rebuild the cache forcefully
_nix_direnv_force_reload=1 direnv exec "/Users/ms/Development/personal/imphnen-frontend-service" true
# Update the mtime for .envrc.
# This will cause direnv to reload again - but without re-building.
touch "/Users/ms/Development/personal/imphnen-frontend-service/.envrc"
# Also update the timestamp of whatever profile_rc we have.
# This makes sure that we know we are up to date.
touch -r "/Users/ms/Development/personal/imphnen-frontend-service/.envrc" "/Users/ms/Development/personal/imphnen-frontend-service/.direnv"/*.rc
-3
View File
@@ -1,3 +0,0 @@
VITE_SUPABASE_URL=https://your-project-id.supabase.co
VITE_SUPABASE_ANON_KEY=your-anon-key-here
+1
View File
@@ -0,0 +1 @@
use flake
+40
View File
@@ -0,0 +1,40 @@
name: Nix Build & Cache
on:
push:
branches: ['develop']
pull_request:
branches: ['develop']
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Install Nix
uses: DeterminateSystems/nix-installer-action@main
- name: Setup Cachix
uses: cachix/cachix-action@v15
with:
name: msdqn
authToken: '${{ secrets.CACHIX_AUTH_TOKEN }}'
- name: Build all packages
run: |
nix build .#landing -o result-landing
nix build .#backoffice -o result-backoffice
nix build .#gacha -o result-gacha
nix build .#dimentorin -o result-dimentorin
nix build .#hackathon -o result-hackathon
nix build .#infra -o result-infra
- name: Show build outputs
run: |
echo "Landing: $(readlink result-landing)"
echo "Backoffice: $(readlink result-backoffice)"
echo "Gacha: $(readlink result-gacha)"
echo "Dimentorin: $(readlink result-dimentorin)"
echo "Hackathon: $(readlink result-hackathon)"
echo "Infra: $(readlink result-infra)"
@@ -1,236 +0,0 @@
{
"message": "Success",
"data": [
{
"id": "afbead4b-2ffa-435e-ae7b-91f26e111fc6",
"team_id": "ab436f6e-027f-4831-873b-474345273491",
"team": {
"id": "ab436f6e-027f-4831-873b-474345273491",
"name": "nama timnya apa ya @All",
"description": "pikri carry",
"city": "Kota Depok",
"visibility": "public",
"logo": null,
"banner": "https://voymsjeqmvwrryetfldy.supabase.co/storage/v1/object/public/hackathon-uploads/teams/9a6dc902-c91b-4276-89cf-31e821531158-1764517227821.png",
"leader_id": "9a6dc902-c91b-4276-89cf-31e821531158",
"created_at": "2025-11-30T15:40:29.865564Z",
"updated_at": "2025-11-30T15:48:52.520850Z"
},
"rank": 1,
"prize": "Rp6.000.000",
"announced_at": "2025-12-15T16:41:01.931757Z",
"created_at": "2025-12-15T16:41:01.931757Z",
"updated_at": "2025-12-15T16:41:01.931757Z"
},
{
"id": "8e591dc6-3cff-4019-bdfc-5e42ea081208",
"team_id": "06cbf0f4-cdad-40d0-b0d0-1fa8a3d50968",
"team": {
"id": "06cbf0f4-cdad-40d0-b0d0-1fa8a3d50968",
"name": "TheLastOfUs",
"description": "We truly believe in Meaning First — designing innovation, powered by technology.",
"city": "Bandung",
"visibility": "private",
"logo": "https://voymsjeqmvwrryetfldy.supabase.co/storage/v1/object/public/hackathon-uploads/teams/a32c0e81-1fbd-4bec-8e91-4cd6d10f553b-1764074851150.png",
"banner": "https://voymsjeqmvwrryetfldy.supabase.co/storage/v1/object/public/hackathon-uploads/teams/a32c0e81-1fbd-4bec-8e91-4cd6d10f553b-1764074852181.png",
"leader_id": "a32c0e81-1fbd-4bec-8e91-4cd6d10f553b",
"created_at": "2025-11-25T12:47:33.040330Z",
"updated_at": "2025-11-25T12:47:33.040330Z"
},
"rank": 2,
"prize": "Rp4.000.000",
"announced_at": "2025-12-15T16:41:32.534295Z",
"created_at": "2025-12-15T16:41:32.534295Z",
"updated_at": "2025-12-15T16:41:32.534295Z"
},
{
"id": "5ca29971-5726-40dd-872c-853a6bfa03d9",
"team_id": "9d9ed9db-3523-47ae-a387-66c36dbec983",
"team": {
"id": "9d9ed9db-3523-47ae-a387-66c36dbec983",
"name": "Pecinta Capybara",
"description": "Ingin ikut meramaikan suasana.",
"city": "Tangerang",
"visibility": "public",
"logo": "https://voymsjeqmvwrryetfldy.supabase.co/storage/v1/object/public/hackathon-uploads/teams/648f6d3d-a92e-49cc-805e-2f600de87074-1764205746897.jpg",
"banner": "https://voymsjeqmvwrryetfldy.supabase.co/storage/v1/object/public/hackathon-uploads/teams/648f6d3d-a92e-49cc-805e-2f600de87074-1764205747479.png",
"leader_id": "648f6d3d-a92e-49cc-805e-2f600de87074",
"created_at": "2025-11-27T01:09:32.787150Z",
"updated_at": "2025-11-29T15:30:43.334609Z"
},
"rank": 3,
"prize": "Rp2.500.000",
"announced_at": "2025-12-15T16:41:59.091294Z",
"created_at": "2025-12-15T16:41:59.091294Z",
"updated_at": "2025-12-15T16:41:59.091294Z"
},
{
"id": "e9f82de6-f5d0-43c1-a0bd-4687f2e4ed5e",
"team_id": "95f782f4-433f-489d-a06d-eed89ca83beb",
"team": {
"id": "95f782f4-433f-489d-a06d-eed89ca83beb",
"name": "Savora",
"description": "a complete food ordering application for Indonesian SMEs (UMKM)",
"city": "Bandung",
"visibility": "private",
"logo": "https://voymsjeqmvwrryetfldy.supabase.co/storage/v1/object/public/hackathon-uploads/teams/748de15d-374a-4756-89e2-75754e90542f-1764071952995.png",
"banner": "https://voymsjeqmvwrryetfldy.supabase.co/storage/v1/object/public/hackathon-uploads/teams/748de15d-374a-4756-89e2-75754e90542f-1764071953753.png",
"leader_id": "748de15d-374a-4756-89e2-75754e90542f",
"created_at": "2025-11-25T11:57:52.098043Z",
"updated_at": "2025-11-25T11:59:14.508877Z"
},
"rank": 4,
"prize": "Rp500.000",
"announced_at": "2025-12-15T16:42:39.361469Z",
"created_at": "2025-12-15T16:42:39.361469Z",
"updated_at": "2025-12-15T16:42:39.361469Z"
},
{
"id": "ed93e080-0913-4c70-b69d-fce9bc0cdda7",
"team_id": "f9747574-8c01-4c3e-b20a-7ac1a70b947a",
"team": {
"id": "f9747574-8c01-4c3e-b20a-7ac1a70b947a",
"name": "AMBANET Corporation 🙀😸🤓",
"description": "Bersiaplah ambanet bakal mengguncang seluruh team hackathon ygy",
"city": "Kota Padang",
"visibility": "public",
"logo": "https://voymsjeqmvwrryetfldy.supabase.co/storage/v1/object/public/hackathon-uploads/teams/a5ea628a-24d9-4754-b461-3eda53da53bf-1764351234491.png",
"banner": "https://voymsjeqmvwrryetfldy.supabase.co/storage/v1/object/public/hackathon-uploads/teams/a5ea628a-24d9-4754-b461-3eda53da53bf-1764219109981.gif",
"leader_id": "a5ea628a-24d9-4754-b461-3eda53da53bf",
"created_at": "2025-11-27T04:48:53.080955Z",
"updated_at": "2025-11-29T13:31:51.276246Z"
},
"rank": 5,
"prize": "Rp500.000",
"announced_at": "2025-12-15T16:42:57.065225Z",
"created_at": "2025-12-15T16:42:57.065225Z",
"updated_at": "2025-12-15T16:42:57.065225Z"
},
{
"id": "7ed55b12-d585-419d-bae2-1a362a57798e",
"team_id": "4f3e2e85-3f3f-4880-9104-b3f66bb1c9d9",
"team": {
"id": "4f3e2e85-3f3f-4880-9104-b3f66bb1c9d9",
"name": "Pemuja Deadline Anti Refund",
"description": "Diusahakan banyak deadline tapi kg refund ~ \"Angga Kentod\"",
"city": "Kota Bandung",
"visibility": "public",
"logo": "https://voymsjeqmvwrryetfldy.supabase.co/storage/v1/object/public/hackathon-uploads/teams/6cf045e2-d853-4480-91b8-244fb0b76b7f-1764332887921.jpg",
"banner": null,
"leader_id": "6cf045e2-d853-4480-91b8-244fb0b76b7f",
"created_at": "2025-11-27T05:02:35.128625Z",
"updated_at": "2025-11-28T12:28:09.697222Z"
},
"rank": 6,
"prize": "Rp200.000",
"announced_at": "2025-12-15T16:43:09.471633Z",
"created_at": "2025-12-15T16:43:09.471633Z",
"updated_at": "2025-12-15T16:43:09.471633Z"
},
{
"id": "0b3a0b5c-2038-4d09-85a7-ae4709702951",
"team_id": "9d8cd404-8e69-4efd-a125-fc0863d7afc7",
"team": {
"id": "9d8cd404-8e69-4efd-a125-fc0863d7afc7",
"name": "Aku nak meletup",
"description": "masih pemula bg",
"city": "Boyolali",
"visibility": "public",
"logo": "https://voymsjeqmvwrryetfldy.supabase.co/storage/v1/object/public/hackathon-uploads/teams/c79d4b2b-e63f-4187-a8cd-520fde333ab3-1764211224866.jpg",
"banner": null,
"leader_id": "c79d4b2b-e63f-4187-a8cd-520fde333ab3",
"created_at": "2025-11-27T02:40:25.376372Z",
"updated_at": "2025-11-27T02:40:25.376372Z"
},
"rank": 7,
"prize": "Rp200.000",
"announced_at": "2025-12-15T16:43:22.467439Z",
"created_at": "2025-12-15T16:43:22.467439Z",
"updated_at": "2025-12-15T16:43:22.467439Z"
},
{
"id": "bb0706b9-b723-4a49-b0b0-3be9af70225b",
"team_id": "dd6c62dd-2632-4156-9da5-8ff9a3560f06",
"team": {
"id": "dd6c62dd-2632-4156-9da5-8ff9a3560f06",
"name": "Iseng Hackathon",
"description": "HME ITB Oke Champ",
"city": "Kota Bandung",
"visibility": "public",
"logo": null,
"banner": null,
"leader_id": "d1e4e3bf-098f-453e-bf00-612685d311d9",
"created_at": "2025-11-30T03:58:52.429673Z",
"updated_at": "2025-11-30T03:58:52.429673Z"
},
"rank": 8,
"prize": "Rp200.000",
"announced_at": "2025-12-15T16:43:34.191207Z",
"created_at": "2025-12-15T16:43:34.191207Z",
"updated_at": "2025-12-15T16:43:34.191207Z"
},
{
"id": "4a3e807c-2cf2-4557-a6af-99fcc726cebb",
"team_id": "52316c25-5697-4436-bfc2-02baef8ca956",
"team": {
"id": "52316c25-5697-4436-bfc2-02baef8ca956",
"name": "Gorengan 3 Ronde",
"description": "Jam 10 izin turun",
"city": "Kota Medan",
"visibility": "public",
"logo": "https://voymsjeqmvwrryetfldy.supabase.co/storage/v1/object/public/hackathon-uploads/teams/e7bec056-7f63-4642-a763-afa39c3c340e-1764509780084.png",
"banner": "https://voymsjeqmvwrryetfldy.supabase.co/storage/v1/object/public/hackathon-uploads/teams/e7bec056-7f63-4642-a763-afa39c3c340e-1764509810717.png",
"leader_id": "e7bec056-7f63-4642-a763-afa39c3c340e",
"created_at": "2025-11-30T13:36:52.344019Z",
"updated_at": "2025-11-30T13:36:52.344019Z"
},
"rank": 9,
"prize": "Rp200.000",
"announced_at": "2025-12-15T16:43:51.988908Z",
"created_at": "2025-12-15T16:43:51.988908Z",
"updated_at": "2025-12-15T16:43:51.988908Z"
},
{
"id": "e18827dd-839d-4e54-9126-c1faebce2c2c",
"team_id": "d2b2fb99-e934-405c-836e-711352e0f8a0",
"team": {
"id": "d2b2fb99-e934-405c-836e-711352e0f8a0",
"name": "Spark Developer",
"description": "Yang penting yakin untuk menang.",
"city": "Kota Batam",
"visibility": "public",
"logo": "https://voymsjeqmvwrryetfldy.supabase.co/storage/v1/object/public/hackathon-uploads/teams/087921fb-2d17-423b-9628-73de2176360f-1764486044138.png",
"banner": "https://voymsjeqmvwrryetfldy.supabase.co/storage/v1/object/public/hackathon-uploads/teams/087921fb-2d17-423b-9628-73de2176360f-1764486059581.jpg",
"leader_id": "087921fb-2d17-423b-9628-73de2176360f",
"created_at": "2025-11-29T04:49:54.266394Z",
"updated_at": "2025-11-30T07:01:02.316185Z"
},
"rank": 10,
"prize": "Rp200.000",
"announced_at": "2025-12-15T16:44:02.680036Z",
"created_at": "2025-12-15T16:44:02.680036Z",
"updated_at": "2025-12-15T16:44:02.680036Z"
},
{
"id": "a0ed8e58-f8e3-491c-8c03-20e82090d6f8",
"team_id": "d30d7d03-dce7-4220-9e7f-a537a45c54e0",
"team": {
"id": "d30d7d03-dce7-4220-9e7f-a537a45c54e0",
"name": "Eye of Horus",
"description": "Eye of horus",
"city": "Garut",
"visibility": "public",
"logo": "https://voymsjeqmvwrryetfldy.supabase.co/storage/v1/object/public/hackathon-uploads/teams/96dc1c2b-a1ef-441a-93d5-da2ccad37d81-1764145807852.png",
"banner": "https://voymsjeqmvwrryetfldy.supabase.co/storage/v1/object/public/hackathon-uploads/teams/96dc1c2b-a1ef-441a-93d5-da2ccad37d81-1764145810329.jpeg",
"leader_id": "96dc1c2b-a1ef-441a-93d5-da2ccad37d81",
"created_at": "2025-11-26T08:30:10.385714Z",
"updated_at": "2025-11-26T09:35:12.386986Z"
},
"rank": 11,
"prize": "hadiah",
"announced_at": "2025-12-16T04:19:09.502015Z",
"created_at": "2025-12-16T04:19:09.502015Z",
"updated_at": "2025-12-16T04:19:09.502015Z"
}
]
}
@@ -7,6 +7,7 @@ import {
useAuthStore,
useMyTeams,
useTeamById,
useTeamSubmission,
useWinners,
} from '@imphnen-frontend-service/service';
import QRCode from 'qrcode';
@@ -37,8 +38,20 @@ const formatOrdinalRank = (rank: number): string => {
}
};
const CERT_WIDTH = 1000;
const CERT_HEIGHT = (CERT_WIDTH * 595) / 842; // matches blank_winner_cert.svg aspect ratio
// Keep the template size aligned with the SVG native size (842x595) using an integer multiplier.
// This reduces sub-pixel scaling artifacts (blur) on thin lines when rasterizing with html2canvas.
const CERT_WIDTH = 842 * 2;
const CERT_HEIGHT = 595 * 2;
// Balance between output sharpness and file size.
// Output resolution will be (CERT_WIDTH * EXPORT_SCALE) x (CERT_HEIGHT * EXPORT_SCALE).
const EXPORT_SCALE = 2;
// The original layout was tuned around a ~1000px-wide template.
// We keep the same visual proportions by scaling fixed pixel values.
const LAYOUT_BASE_WIDTH = 1000;
const LAYOUT_SCALE = CERT_WIDTH / LAYOUT_BASE_WIDTH;
const s = (px: number) => Math.round(px * LAYOUT_SCALE);
const CertificateWinnerPage: FC = (): ReactElement => {
const { certId } = useParams<{ certId: string }>();
@@ -87,7 +100,12 @@ const CertificateWinnerPage: FC = (): ReactElement => {
!!decodedTeamId
);
const { data: submissionData, isLoading: isLoadingSubmission } =
useTeamSubmission(decodedTeamId, !!decodedTeamId);
const team = teamData?.data;
const submission = submissionData?.data;
const submissionName = submission?.project_name || '(Submission unavailable)';
const memberNames = useMemo(() => {
const members = team?.members || [];
@@ -112,7 +130,7 @@ const CertificateWinnerPage: FC = (): ReactElement => {
const certificateUrl = `${window.location.origin}/certificate/winner/${encodedCertId}`;
QRCode.toDataURL(certificateUrl, {
width: 200,
width: s(200),
margin: 1,
color: {
dark: '#000000',
@@ -130,13 +148,15 @@ const CertificateWinnerPage: FC = (): ReactElement => {
if (!team?.name) return;
if (!qrCodeUrl) return;
if (!winnerEntry?.rank) return;
if (isLoadingSubmission) return;
setIsGenerating(true);
try {
setShowTemplate(true);
await new Promise((resolve) => setTimeout(resolve, 1500));
const canvas = await html2canvas(certificateRef.current, {
scale: 4,
scale: EXPORT_SCALE,
useCORS: true,
backgroundColor: '#ffffff',
logging: false,
@@ -158,7 +178,14 @@ const CertificateWinnerPage: FC = (): ReactElement => {
};
generateCertificate();
}, [team?.name, memberNames, qrCodeUrl, winnerEntry?.rank]);
}, [
team?.name,
memberNames,
qrCodeUrl,
winnerEntry?.rank,
isLoadingSubmission,
submissionName,
]);
const handleDownloadCertificate = () => {
if (!certificateImage) return;
@@ -323,7 +350,8 @@ const CertificateWinnerPage: FC = (): ReactElement => {
style={{
position: 'relative',
backgroundImage: 'url(/images/blank_winner_cert.svg)',
backgroundSize: 'cover',
backgroundSize: '100% 100%',
backgroundRepeat: 'no-repeat',
backgroundPosition: 'center',
width: `${CERT_WIDTH}px`,
height: `${CERT_HEIGHT}px`,
@@ -339,7 +367,7 @@ const CertificateWinnerPage: FC = (): ReactElement => {
<div
style={{
position: 'absolute',
top: '37%',
top: '35%',
left: '3.5%',
width: '55%',
}}
@@ -350,7 +378,7 @@ const CertificateWinnerPage: FC = (): ReactElement => {
fontWeight: 'bold',
color: '#59bef5',
textAlign: 'left',
fontSize: '28px',
fontSize: `${s(28)}px`,
lineHeight: '1.2',
wordBreak: 'break-word',
margin: 0,
@@ -364,7 +392,7 @@ const CertificateWinnerPage: FC = (): ReactElement => {
<div
style={{
position: 'absolute',
top: '42.5%',
top: '40.5%',
left: '3.5%',
width: '55%',
}}
@@ -374,7 +402,7 @@ const CertificateWinnerPage: FC = (): ReactElement => {
style={{
margin: 0,
fontFamily: 'Poppins, sans-serif',
fontSize: '18px',
fontSize: `${s(18)}px`,
lineHeight: '1.35',
color: '#59bef5',
}}
@@ -392,7 +420,7 @@ const CertificateWinnerPage: FC = (): ReactElement => {
<div
style={{
position: 'absolute',
top: '62%',
top: '60%',
left: '3.5%',
width: '60%',
}}
@@ -401,7 +429,7 @@ const CertificateWinnerPage: FC = (): ReactElement => {
style={{
margin: 0,
fontFamily: 'Poppins, sans-serif',
fontSize: '18px',
fontSize: `${s(18)}px`,
lineHeight: '1.35',
color: '#6B6B6B',
}}
@@ -410,6 +438,10 @@ const CertificateWinnerPage: FC = (): ReactElement => {
<br />
<b>JUARA {winnerEntry.rank}</b> pada Hackathon IMPHNEN x
Kolosal.ai
<br />
<span>
dengan nama project: <b>{submissionName}</b>
</span>
</p>
</div>
@@ -420,7 +452,7 @@ const CertificateWinnerPage: FC = (): ReactElement => {
position: 'absolute',
top: '8%',
right: '8.5%',
width: '190px',
width: `${s(190)}px`,
display: 'flex',
justifyContent: 'center',
}}
@@ -430,12 +462,12 @@ const CertificateWinnerPage: FC = (): ReactElement => {
display: 'inline-flex',
alignItems: 'center',
justifyContent: 'center',
padding: '6px 16px',
padding: `${s(6)}px ${s(16)}px`,
textAlign: 'center',
fontFamily: 'Poppins, sans-serif',
fontWeight: 700,
color: '#78350F',
fontSize: '24px',
fontSize: `${s(24)}px`,
lineHeight: '1',
}}
>
@@ -450,8 +482,8 @@ const CertificateWinnerPage: FC = (): ReactElement => {
position: 'absolute',
top: '33%',
right: '9.3%',
width: '190px',
height: '190px',
width: `${s(190)}px`,
height: `${s(190)}px`,
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
@@ -461,7 +493,11 @@ const CertificateWinnerPage: FC = (): ReactElement => {
<img
src={qrCodeUrl}
alt="Certificate QR Code"
style={{ width: '190px', height: '190px', display: 'block' }}
style={{
width: `${s(190)}px`,
height: `${s(190)}px`,
display: 'block',
}}
/>
)}
</div>
+3
View File
@@ -0,0 +1,3 @@
import baseConfig from '../../eslint.config.mjs';
export default [...baseConfig];
+15
View File
@@ -0,0 +1,15 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>IMPHNEN Infrastructure</title>
<base href="/" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<link rel="icon" type="image/x-icon" href="/logos/simple.svg" />
<link rel="stylesheet" href="/src/index.css" />
</head>
<body>
<div id="root"></div>
<script type="module" src="/src/main.tsx"></script>
</body>
</html>
+9
View File
@@ -0,0 +1,9 @@
import { join } from 'path';
export default {
plugins: {
'@tailwindcss/postcss': {
base: join(import.meta.dirname, '../../'),
},
},
};
+8
View File
@@ -0,0 +1,8 @@
{
"name": "infra",
"$schema": "../../node_modules/nx/schemas/project-schema.json",
"sourceRoot": "apps/infra/src",
"projectType": "application",
"tags": [],
"targets": {}
}
File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 351 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 511 KiB

+235
View File
@@ -0,0 +1,235 @@
const apps = [
{ name: 'Landing', domain: 'imphnen.dev', type: 'Next.js', color: 'blue' },
{ name: 'Gacha', domain: 'gacha.imphnen.dev', type: 'Vite', color: 'green' },
{ name: 'Backoffice', domain: 'backoffice.imphnen.dev', type: 'Vite', color: 'green' },
{ name: 'Dimentorin', domain: 'dimentorin.imphnen.dev', type: 'Vite', color: 'green' },
{ name: 'Hackathon', domain: 'hackathon.imphnen.dev', type: 'Vite', color: 'green' },
{ name: 'Infra', domain: 'infra.imphnen.dev', type: 'Vite', color: 'green' },
];
const techStack = [
{ category: 'OS', items: ['NixOS 24.11'] },
{ category: 'Web Server', items: ['Nginx'] },
{ category: 'SSL', items: ['Let\'s Encrypt (ACME)'] },
{ category: 'Build', items: ['Nix Flakes', 'Nx Monorepo'] },
{ category: 'Frontend', items: ['React', 'Next.js', 'Vite', 'TailwindCSS'] },
{ category: 'Secrets', items: ['sops-nix'] },
];
export default function App() {
return (
<div className="min-h-screen bg-[#0a0a0a]">
{/* Header */}
<header className="border-b border-zinc-800 bg-[#0a0a0a]/80 backdrop-blur-sm sticky top-0 z-50">
<div className="container mx-auto px-6 py-4">
<div className="flex items-center justify-between">
<div className="flex items-center gap-3">
<div className="w-8 h-8 bg-blue-500 rounded-lg flex items-center justify-center font-bold">
I
</div>
<span className="text-xl font-semibold">IMPHNEN Infrastructure</span>
</div>
<a
href="https://github.com/IMPHNEN"
target="_blank"
rel="noopener noreferrer"
className="text-zinc-400 hover:text-white transition-colors"
>
GitHub
</a>
</div>
</div>
</header>
<main className="container mx-auto px-6 py-12">
{/* Hero */}
<section className="text-center mb-16">
<h1 className="text-4xl md:text-5xl font-bold mb-4">
Infrastructure Overview
</h1>
<p className="text-zinc-400 text-lg max-w-2xl mx-auto">
Declarative NixOS infrastructure powering IMPHNEN's frontend applications
on Hetzner Cloud.
</p>
</section>
{/* Architecture Diagram */}
<section className="mb-16">
<h2 className="text-2xl font-semibold mb-6">Architecture</h2>
<div className="card bg-[#141414] border-zinc-800 p-8">
<div className="flex flex-col items-center gap-6">
{/* Internet */}
<div className="flex items-center gap-2 text-zinc-400">
<span className="text-2xl">🌐</span>
<span>Internet</span>
</div>
<div className="w-px h-8 bg-zinc-700" />
{/* Cloudflare */}
<div className="card bg-orange-500/10 border-orange-500/30 px-6 py-3">
<span className="badge badge-orange">Cloudflare</span>
<p className="text-sm text-zinc-400 mt-1">DNS + CDN + DDoS Protection</p>
</div>
<div className="w-px h-8 bg-zinc-700" />
{/* Hetzner VPS */}
<div className="card bg-[#1a1a1a] border-zinc-700 w-full max-w-3xl">
<div className="text-center mb-4">
<span className="badge badge-purple">Hetzner Cloud VPS</span>
<p className="text-sm text-zinc-400 mt-1">NixOS | 167.235.70.37</p>
</div>
{/* Nginx */}
<div className="card bg-green-500/10 border-green-500/30 mb-4">
<div className="text-center">
<span className="badge badge-green">Nginx</span>
<p className="text-sm text-zinc-400 mt-1">Reverse Proxy + Static Files + SSL Termination</p>
</div>
</div>
{/* Apps Grid */}
<div className="grid grid-cols-2 md:grid-cols-3 gap-3">
{apps.map((app) => (
<div
key={app.name}
className="card bg-[#0a0a0a] border-zinc-800 text-center p-3"
>
<p className="font-medium text-sm">{app.name}</p>
<p className="text-xs text-zinc-500">{app.domain}</p>
<span className={`badge badge-${app.color} mt-2 text-xs`}>
{app.type}
</span>
</div>
))}
</div>
</div>
</div>
</div>
</section>
{/* Deployed Apps */}
<section className="mb-16">
<h2 className="text-2xl font-semibold mb-6">Deployed Applications</h2>
<div className="grid md:grid-cols-2 lg:grid-cols-3 gap-4">
{apps.map((app) => (
<a
key={app.name}
href={`https://${app.domain}`}
target="_blank"
rel="noopener noreferrer"
className="card bg-[#141414] border-zinc-800 hover:border-zinc-600 transition-colors group"
>
<div className="flex items-start justify-between">
<div>
<h3 className="font-semibold group-hover:text-blue-400 transition-colors">
{app.name}
</h3>
<p className="text-sm text-zinc-500">{app.domain}</p>
</div>
<span className={`badge badge-${app.color}`}>{app.type}</span>
</div>
</a>
))}
</div>
</section>
{/* Tech Stack */}
<section className="mb-16">
<h2 className="text-2xl font-semibold mb-6">Technology Stack</h2>
<div className="grid md:grid-cols-2 lg:grid-cols-3 gap-4">
{techStack.map((tech) => (
<div key={tech.category} className="card bg-[#141414] border-zinc-800">
<h3 className="text-sm text-zinc-500 uppercase tracking-wider mb-2">
{tech.category}
</h3>
<div className="flex flex-wrap gap-2">
{tech.items.map((item) => (
<span key={item} className="badge badge-blue">
{item}
</span>
))}
</div>
</div>
))}
</div>
</section>
{/* Deployment Flow */}
<section className="mb-16">
<h2 className="text-2xl font-semibold mb-6">Deployment Flow</h2>
<div className="card bg-[#141414] border-zinc-800">
<div className="flex flex-col md:flex-row items-center justify-between gap-4">
<div className="text-center">
<div className="w-12 h-12 bg-zinc-800 rounded-full flex items-center justify-center mx-auto mb-2">
<span>1</span>
</div>
<p className="text-sm font-medium">Push to GitHub</p>
<p className="text-xs text-zinc-500">develop branch</p>
</div>
<div className="hidden md:block text-zinc-600"></div>
<div className="text-center">
<div className="w-12 h-12 bg-zinc-800 rounded-full flex items-center justify-center mx-auto mb-2">
<span>2</span>
</div>
<p className="text-sm font-medium">Update Flake</p>
<p className="text-xs text-zinc-500">nix flake update</p>
</div>
<div className="hidden md:block text-zinc-600"></div>
<div className="text-center">
<div className="w-12 h-12 bg-zinc-800 rounded-full flex items-center justify-center mx-auto mb-2">
<span>3</span>
</div>
<p className="text-sm font-medium">Remote Build</p>
<p className="text-xs text-zinc-500">nixos-rebuild</p>
</div>
<div className="hidden md:block text-zinc-600"></div>
<div className="text-center">
<div className="w-12 h-12 bg-blue-500 rounded-full flex items-center justify-center mx-auto mb-2">
<span></span>
</div>
<p className="text-sm font-medium">Live</p>
<p className="text-xs text-zinc-500">Zero downtime</p>
</div>
</div>
</div>
</section>
{/* Repositories */}
<section>
<h2 className="text-2xl font-semibold mb-6">Repositories</h2>
<div className="grid md:grid-cols-2 gap-4">
<a
href="https://github.com/IMPHNEN/imphnen-frontend-service"
target="_blank"
rel="noopener noreferrer"
className="card bg-[#141414] border-zinc-800 hover:border-zinc-600 transition-colors"
>
<h3 className="font-semibold mb-1">imphnen-frontend-service</h3>
<p className="text-sm text-zinc-400">
Nx monorepo containing all frontend applications
</p>
</a>
<a
href="https://github.com/IMPHNEN/imphnen-infrastructure"
target="_blank"
rel="noopener noreferrer"
className="card bg-[#141414] border-zinc-800 hover:border-zinc-600 transition-colors"
>
<h3 className="font-semibold mb-1">imphnen-infrastructure</h3>
<p className="text-sm text-zinc-400">
NixOS flake configuration for server deployment
</p>
</a>
</div>
</section>
</main>
{/* Footer */}
<footer className="border-t border-zinc-800 mt-16">
<div className="container mx-auto px-6 py-8 text-center text-zinc-500 text-sm">
<p>IMPHNEN Infrastructure &copy; {new Date().getFullYear()}</p>
</div>
</footer>
</div>
);
}
+58
View File
@@ -0,0 +1,58 @@
@import 'tailwindcss';
@theme {
--color-primary: #3b82f6;
--color-primary-hover: #2563eb;
}
@layer base {
* {
box-sizing: border-box;
margin: 0;
padding: 0;
}
body {
font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
background-color: #0a0a0a;
color: #ffffff;
line-height: 1.6;
}
}
@layer components {
.card {
background: #141414;
border: 1px solid #27272a;
border-radius: 12px;
padding: 1.5rem;
}
.badge {
display: inline-block;
padding: 0.25rem 0.75rem;
border-radius: 9999px;
font-size: 0.75rem;
font-weight: 500;
}
.badge-blue {
background: rgba(59, 130, 246, 0.2);
color: #60a5fa;
}
.badge-green {
background: rgba(34, 197, 94, 0.2);
color: #4ade80;
}
.badge-purple {
background: rgba(168, 85, 247, 0.2);
color: #c084fc;
}
.badge-orange {
background: rgba(249, 115, 22, 0.2);
color: #fb923c;
}
}
+14
View File
@@ -0,0 +1,14 @@
import { createRoot } from 'react-dom/client';
import { StrictMode } from 'react';
import App from './app/App';
import './index.css';
const rootElement = document.getElementById('root');
if (!rootElement) throw new Error('Failed to find the root element');
createRoot(rootElement).render(
<StrictMode>
<App />
</StrictMode>
);
+9
View File
@@ -0,0 +1,9 @@
{
"extends": "./tsconfig.json",
"compilerOptions": {
"outDir": "../../dist/out-tsc",
"types": ["node", "vite/client"]
},
"exclude": ["src/**/*.spec.ts", "src/**/*.test.ts", "src/**/*.spec.tsx", "src/**/*.test.tsx"],
"include": ["src/**/*.js", "src/**/*.jsx", "src/**/*.ts", "src/**/*.tsx"]
}
+18
View File
@@ -0,0 +1,18 @@
{
"compilerOptions": {
"jsx": "react-jsx",
"allowJs": false,
"esModuleInterop": false,
"allowSyntheticDefaultImports": true,
"strict": true,
"types": ["vite/client"]
},
"files": [],
"include": [],
"references": [
{
"path": "./tsconfig.app.json"
}
],
"extends": "../../tsconfig.base.json"
}
+27
View File
@@ -0,0 +1,27 @@
/// <reference types='vitest' />
import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';
import { nxViteTsPaths } from '@nx/vite/plugins/nx-tsconfig-paths.plugin';
import { nxCopyAssetsPlugin } from '@nx/vite/plugins/nx-copy-assets.plugin';
export default defineConfig(() => ({
root: __dirname,
cacheDir: '../../node_modules/.vite/apps/infra',
server: {
port: 3006,
host: 'localhost',
},
preview: {
port: 3007,
host: 'localhost',
},
plugins: [react(), nxViteTsPaths(), nxCopyAssetsPlugin(['*.md'])],
build: {
outDir: '../../dist/apps/infra',
emptyOutDir: true,
reportCompressedSize: true,
commonjsOptions: {
transformMixedEsModules: true,
},
},
}));
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -54,9 +54,19 @@ export function HeroSection() {
animate={{ opacity: 1, y: 0 }}
transition={{ duration: 0.5 }}
>
<span className="inline-flex items-center rounded-full border px-3 py-1 text-sm w-fit">
{communityLabel}
</span>
<div className="flex flex-wrap items-center gap-2">
<span className="inline-flex items-center rounded-full border px-3 py-1 text-sm">
{communityLabel}
</span>
<a
href="https://ancikri.com"
target="_blank"
rel="noopener noreferrer"
className="inline-flex items-center rounded-full border px-3 py-1 text-sm hover:bg-muted transition-colors"
>
Powered By Ancikri
</a>
</div>
<div className="space-y-4">
<h1 className="text-4xl md:text-5xl lg:text-6xl xl:text-7xl font-bold tracking-tighter bg-clip-text text-transparent bg-gradient-to-r from-foreground via-foreground to-foreground/70">
@@ -104,11 +104,21 @@ export default function Footer() {
<ul className="space-y-2"></ul>
</div>
</div>
<div className="mt-8 border-t pt-8 text-center">
<div className="mt-8 border-t pt-8 text-center space-y-2">
<p className="text-xs text-muted-foreground">
© {new Date().getFullYear()} IMPHNEN - Ingin Menjadi Programmer
Handal, Namun Enggan Ngoding. All rights reserved.
</p>
<p className="text-xs text-muted-foreground">
Powered by{' '}
<Link
href="https://ancikri.com"
target="_blank"
className="font-medium text-foreground hover:underline"
>
Ancikri
</Link>
</p>
</div>
</div>
</footer>
+17 -7
View File
@@ -1,13 +1,23 @@
import { Bai_Jamjuree, Poppins } from 'next/font/google';
import localFont from 'next/font/local';
export const baiJamjureeFont = Bai_Jamjuree({
subsets: ['latin'],
weight: ['300', '400', '500', '600', '700'],
export const baiJamjureeFont = localFont({
src: [
{ path: '../../public/fonts/BaiJamjuree-Light.ttf', weight: '300', style: 'normal' },
{ path: '../../public/fonts/BaiJamjuree-Regular.ttf', weight: '400', style: 'normal' },
{ path: '../../public/fonts/BaiJamjuree-Medium.ttf', weight: '500', style: 'normal' },
{ path: '../../public/fonts/BaiJamjuree-SemiBold.ttf', weight: '600', style: 'normal' },
{ path: '../../public/fonts/BaiJamjuree-Bold.ttf', weight: '700', style: 'normal' },
],
display: 'swap',
});
export const poppinsFont = Poppins({
subsets: ['latin'],
weight: ['300', '400', '500', '600', '700'],
export const poppinsFont = localFont({
src: [
{ path: '../../public/fonts/Poppins-Light.ttf', weight: '300', style: 'normal' },
{ path: '../../public/fonts/Poppins-Regular.ttf', weight: '400', style: 'normal' },
{ path: '../../public/fonts/Poppins-Medium.ttf', weight: '500', style: 'normal' },
{ path: '../../public/fonts/Poppins-SemiBold.ttf', weight: '600', style: 'normal' },
{ path: '../../public/fonts/Poppins-Bold.ttf', weight: '700', style: 'normal' },
],
display: 'swap',
});
+119
View File
@@ -0,0 +1,119 @@
{
description = "Imphnen Frontend Service - Nx Monorepo";
inputs = {
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
flake-utils.url = "github:numtide/flake-utils";
};
outputs = { self, nixpkgs, flake-utils }:
flake-utils.lib.eachDefaultSystem (system:
let
pkgs = import nixpkgs { inherit system; };
# NPM dependencies hash (update with: nix run nixpkgs#prefetch-npm-deps -- package-lock.json)
npmDepsHash = "sha256-xmG0ej6GJk1HIFFmrB9CpovNA20sJ7RanFLMBCxKdy0=";
# Import helpers
mkViteApp = import ./nix/mkViteApp.nix {
inherit pkgs npmDepsHash;
src = ./.;
};
landingApp = import ./nix/landing.nix {
inherit pkgs npmDepsHash;
src = ./.;
};
in {
packages = {
# Static Vite apps
backoffice = mkViteApp { name = "backoffice"; buildScript = "backoffice:build"; };
gacha = mkViteApp { name = "gacha"; buildScript = "gacha:build"; };
dimentorin = mkViteApp { name = "dimentorin"; buildScript = "dimentorin:build"; };
hackathon = mkViteApp { name = "hackathon"; buildScript = "hackathon:build"; };
infra = mkViteApp { name = "infra"; buildScript = "infra:build"; };
# Next.js app
landing = landingApp;
# Default package
default = self.packages.${system}.landing;
};
# Development shell
devShells.default = pkgs.mkShell {
buildInputs = with pkgs; [
nodejs_22
nodePackages.npm
bun
# Useful dev tools
git
jq
];
shellHook = ''
echo "🚀 Imphnen Frontend Development Shell"
echo "Node.js: $(node --version)"
echo "npm: $(npm --version)"
echo ""
echo "Available commands:"
echo " npm install - Install dependencies"
echo " nx dev <app> - Start development server"
echo " nx build <app> - Build an app"
echo ""
echo "Apps: landing, backoffice, gacha, dimentorin, hackathon"
echo ""
echo "Build packages with:"
echo " nix build .#landing"
echo " nix build .#backoffice"
echo " nix build .#gacha"
echo " nix build .#dimentorin"
echo " nix build .#hackathon"
'';
};
}
) // {
# NixOS modules for deployment
nixosModules = {
landing = import ./nix/modules/landing.nix { inherit self; };
backoffice = import ./nix/modules/static-app.nix { inherit self; } { appName = "backoffice"; };
gacha = import ./nix/modules/static-app.nix { inherit self; } { appName = "gacha"; };
dimentorin = import ./nix/modules/static-app.nix { inherit self; } { appName = "dimentorin"; };
hackathon = import ./nix/modules/static-app.nix { inherit self; } { appName = "hackathon"; };
infra = import ./nix/modules/static-app.nix { inherit self; } { appName = "infra"; };
# All-in-one module that enables all apps
all = { config, lib, pkgs, ... }: {
imports = [
self.nixosModules.landing
self.nixosModules.backoffice
self.nixosModules.gacha
self.nixosModules.dimentorin
self.nixosModules.hackathon
self.nixosModules.infra
];
};
};
# Overlay for easy integration
overlays.default = final: prev: {
imphnen = {
landing = self.packages.${final.system}.landing;
backoffice = self.packages.${final.system}.backoffice;
gacha = self.packages.${final.system}.gacha;
dimentorin = self.packages.${final.system}.dimentorin;
hackathon = self.packages.${final.system}.hackathon;
infra = self.packages.${final.system}.infra;
# Function to build hackathon with custom environment variables (e.g., Supabase)
mkHackathonWithEnv = envVars: import ./nix/mkViteApp.nix {
pkgs = final;
src = self;
npmDepsHash = "sha256-xmG0ej6GJk1HIFFmrB9CpovNA20sJ7RanFLMBCxKdy0=";
} { name = "hackathon"; buildScript = "hackathon:build"; inherit envVars; };
};
};
};
}
-41
View File
@@ -1,41 +0,0 @@
import { createClient } from '@supabase/supabase-js';
const supabaseUrl = import.meta.env.VITE_SUPABASE_URL;
const supabaseAnonKey = import.meta.env.VITE_SUPABASE_ANON_KEY;
if (!supabaseUrl || !supabaseAnonKey) {
throw new Error('Missing Supabase environment variables');
}
// Create Supabase client with proper session management enabled
export const supabase = createClient(supabaseUrl, supabaseAnonKey, {
auth: {
autoRefreshToken: true, // ✅ Auto-refresh expired tokens
persistSession: true, // ✅ Persist session in storage
detectSessionInUrl: true, // ✅ Auto-detect OAuth callback
storage: typeof window !== 'undefined' ? window.localStorage : undefined,
},
global: {
headers: {
'X-Client-Info': 'supabase-js-web',
},
},
});
// Helper to create authenticated client (kept for backward compatibility)
// NOTE: With proper session management, this should no longer be needed
// Once session is set via supabase.auth.setSession(), the base client will have auth context
export const getAuthenticatedClient = (accessToken: string) => {
return createClient(supabaseUrl, supabaseAnonKey, {
auth: {
autoRefreshToken: false,
persistSession: false,
detectSessionInUrl: false,
},
global: {
headers: {
Authorization: `Bearer ${accessToken}`,
},
},
});
};
-1
View File
@@ -1 +0,0 @@
export * from './client';
+89
View File
@@ -0,0 +1,89 @@
# Example: How to use in imphnen-infrastructure
#
# In your imphnen-infrastructure flake.nix:
#
# {
# inputs = {
# nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
# imphnen-frontend = {
# url = "github:your-org/imphnen-frontend-service";
# # Or use local path during development:
# # url = "path:/path/to/imphnen-frontend-service";
# };
# };
#
# outputs = { self, nixpkgs, imphnen-frontend, ... }: {
# nixosConfigurations.your-server = nixpkgs.lib.nixosSystem {
# system = "x86_64-linux";
# modules = [
# # Import all modules at once
# imphnen-frontend.nixosModules.all
#
# # Or import individually:
# # imphnen-frontend.nixosModules.landing
# # imphnen-frontend.nixosModules.backoffice
#
# ./your-server-config.nix
# ];
# };
# };
# }
#
# Then in your-server-config.nix:
{ config, pkgs, ... }:
{
# Enable Landing (Next.js) - runs as systemd service
services.imphnen-landing = {
enable = true;
port = 3000;
hostname = "0.0.0.0";
openFirewall = true;
# environmentFile = /run/secrets/landing-env; # For secrets
};
# Enable Backoffice (Static) - served by nginx
services.imphnen-backoffice = {
enable = true;
domain = "backoffice.imphnen.dev";
enableSSL = true;
};
# Enable Gacha (Static)
services.imphnen-gacha = {
enable = true;
domain = "gacha.imphnen.dev";
enableSSL = true;
};
# Enable Dimentorin (Static)
services.imphnen-dimentorin = {
enable = true;
domain = "dimentorin.imphnen.dev";
enableSSL = true;
};
# Enable Hackathon (Static)
services.imphnen-hackathon = {
enable = true;
domain = "hackathon.imphnen.dev";
enableSSL = true;
};
# Nginx reverse proxy for landing (if needed)
services.nginx.virtualHosts."imphnen.dev" = {
forceSSL = true;
enableACME = true;
locations."/" = {
proxyPass = "http://127.0.0.1:3000";
proxyWebsockets = true;
};
};
# Enable ACME for SSL
security.acme = {
acceptTerms = true;
defaults.email = "admin@imphnen.dev";
};
}
+59
View File
@@ -0,0 +1,59 @@
# Next.js Landing App Package
{ pkgs, src, npmDepsHash }:
pkgs.buildNpmPackage {
pname = "imphnen-landing";
version = "0.0.1";
inherit src npmDepsHash;
npmFlags = [ "--legacy-peer-deps" ];
makeCacheWritable = true;
nativeBuildInputs = with pkgs; [
nodejs_22
nodePackages.npm
python3 # Required for node-gyp (sharp, etc.)
];
buildPhase = ''
runHook preBuild
export NX_DAEMON=false
export HOME=$TMPDIR
export CI=true
export NO_COLOR=1
export TERM=dumb
export NX_SKIP_NX_CACHE=true
export NX_TASKS_RUNNER_DYNAMIC_OUTPUT=false
export NX_NATIVE=false
./node_modules/.bin/nx build landing --output-style=static
runHook postBuild
'';
installPhase = ''
runHook preInstall
mkdir -p $out/bin $out/share/landing
# Copy standalone server
cp -r dist/apps/landing/.next/standalone/* $out/share/landing/
# Copy public assets
mkdir -p $out/share/landing/apps/landing/public
cp -r dist/apps/landing/public/* $out/share/landing/apps/landing/public/ || true
# Copy static files
mkdir -p $out/share/landing/dist/apps/landing/.next/static
cp -r dist/apps/landing/.next/static/* $out/share/landing/dist/apps/landing/.next/static/
# Create wrapper script
cat > $out/bin/imphnen-landing <<EOF
#!${pkgs.bash}/bin/bash
cd $out/share/landing
exec ${pkgs.nodejs_22}/bin/node --jitless apps/landing/server.js "\$@"
EOF
chmod +x $out/bin/imphnen-landing
runHook postInstall
'';
dontNpmBuild = true;
}
+47
View File
@@ -0,0 +1,47 @@
# Helper function to build Vite-based static apps
{ pkgs, src, npmDepsHash }:
{ name, buildScript, envVars ? {} }:
pkgs.buildNpmPackage {
pname = "imphnen-${name}";
version = "0.0.1";
inherit src npmDepsHash;
npmFlags = [ "--legacy-peer-deps" ];
makeCacheWritable = true;
nativeBuildInputs = with pkgs; [
nodejs_22
nodePackages.npm
util-linux # For script command to create pseudo-terminal
];
buildPhase = ''
runHook preBuild
export NX_DAEMON=false
export HOME=$TMPDIR
export CI=true
export NO_COLOR=1
export TERM=dumb
export NX_SKIP_NX_CACHE=true
export NX_TASKS_RUNNER_DYNAMIC_OUTPUT=false
export NX_NATIVE=false
${pkgs.lib.concatStringsSep "\n" (pkgs.lib.mapAttrsToList (k: v: "export ${k}=\"${v}\"") envVars)}
# Run nx build with pseudo-terminal to prevent terminal access errors
# Use script to create a pty, preventing Nx from crashing on raw terminal mode
script -q -c "./node_modules/.bin/nx build ${name} --output-style=static" /dev/null || true
# Verify the build output exists
test -d dist/apps/${name}
runHook postBuild
'';
installPhase = ''
runHook preInstall
mkdir -p $out
cp -r dist/apps/${name}/* $out/
runHook postInstall
'';
dontNpmBuild = true;
}
+83
View File
@@ -0,0 +1,83 @@
# NixOS Module for Imphnen Landing
{ self }:
{ config, lib, pkgs, ... }:
let
cfg = config.services.imphnen-landing;
in {
options.services.imphnen-landing = {
enable = lib.mkEnableOption "Imphnen Landing Page";
port = lib.mkOption {
type = lib.types.port;
default = 3000;
description = "Port to run the landing server on";
};
hostname = lib.mkOption {
type = lib.types.str;
default = "0.0.0.0";
description = "Hostname to bind to";
};
package = lib.mkOption {
type = lib.types.package;
default = self.packages.${pkgs.system}.landing;
description = "The landing package to use";
};
openFirewall = lib.mkOption {
type = lib.types.bool;
default = false;
description = "Open firewall for the landing port";
};
environmentFile = lib.mkOption {
type = lib.types.nullOr lib.types.path;
default = null;
description = "Environment file for secrets";
};
};
config = lib.mkIf cfg.enable {
systemd.services.imphnen-landing = {
description = "Imphnen Landing Page";
wantedBy = [ "multi-user.target" ];
after = [ "network.target" ];
environment = {
NODE_ENV = "production";
PORT = toString cfg.port;
HOSTNAME = cfg.hostname;
};
serviceConfig = {
Type = "simple";
ExecStart = "${cfg.package}/bin/imphnen-landing";
Restart = "on-failure";
RestartSec = "5s";
# Hardening
DynamicUser = true;
NoNewPrivileges = true;
ProtectSystem = "strict";
ProtectHome = true;
PrivateTmp = true;
ProtectKernelTunables = true;
ProtectKernelModules = true;
ProtectControlGroups = true;
RestrictAddressFamilies = [ "AF_INET" "AF_INET6" "AF_UNIX" ];
RestrictNamespaces = true;
LockPersonality = true;
MemoryDenyWriteExecute = true;
RestrictRealtime = true;
RestrictSUIDSGID = true;
} // lib.optionalAttrs (cfg.environmentFile != null) {
EnvironmentFile = cfg.environmentFile;
};
};
networking.firewall.allowedTCPPorts = lib.mkIf cfg.openFirewall [ cfg.port ];
};
}
+76
View File
@@ -0,0 +1,76 @@
# NixOS Module for Static Vite Apps (nginx-based)
{ self }:
{ appName }:
{ config, lib, pkgs, ... }:
let
cfg = config.services."imphnen-${appName}";
in {
options.services."imphnen-${appName}" = {
enable = lib.mkEnableOption "Imphnen ${appName}";
domain = lib.mkOption {
type = lib.types.str;
description = "Domain name for the app";
};
package = lib.mkOption {
type = lib.types.package;
default = self.packages.${pkgs.system}.${appName};
description = "The ${appName} package to use";
};
enableSSL = lib.mkOption {
type = lib.types.bool;
default = true;
description = "Enable ACME SSL";
};
extraLocations = lib.mkOption {
type = lib.types.attrsOf lib.types.anything;
default = {};
description = "Additional nginx locations";
};
extraConfig = lib.mkOption {
type = lib.types.lines;
default = "";
description = "Extra nginx configuration";
};
};
config = lib.mkIf cfg.enable {
services.nginx = {
enable = true;
recommendedGzipSettings = true;
recommendedOptimisation = true;
recommendedProxySettings = true;
recommendedTlsSettings = true;
virtualHosts.${cfg.domain} = {
forceSSL = cfg.enableSSL;
enableACME = cfg.enableSSL;
root = cfg.package;
locations = {
"/" = {
tryFiles = "$uri $uri/ /index.html";
};
# Cache static assets
"~* \\.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot)$" = {
tryFiles = "$uri =404";
extraConfig = ''
expires 1y;
add_header Cache-Control "public, immutable";
'';
};
} // cfg.extraLocations;
extraConfig = cfg.extraConfig;
};
};
};
}
+140 -163
View File
@@ -16,7 +16,6 @@
"@radix-ui/react-label": "^2.1.7",
"@radix-ui/react-slot": "^1.2.0",
"@redocly/ajv": "^8.11.2",
"@supabase/supabase-js": "^2.84.0",
"@tanstack/react-query": "^5.74.4",
"@tanstack/react-store": "^0.8.0",
"@tanstack/react-table": "^8.21.2",
@@ -28,7 +27,7 @@
"graphql": "^16.11.0",
"html2canvas": "^1.4.1",
"js-cookie": "^3.0.5",
"next": "^16.0.8",
"next": "^16.0.10",
"next-themes": "^0.4.6",
"openapi-fetch": "^0.15.0",
"openapi-react-query": "^0.5.0",
@@ -37,6 +36,7 @@
"react-dom": "^19.2.1",
"react-hook-form": "^7.56.4",
"react-icons": "^5.5.0",
"react-is": "^19.2.3",
"react-router-dom": "^7.3.0",
"recharts": "^3.1.2",
"sharp": "^0.34.1",
@@ -2587,6 +2587,7 @@
"version": "4.9.0",
"resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.9.0.tgz",
"integrity": "sha512-ayVFHdtZ+hsq1t2Dy24wCmGXGe4q9Gu3smhLYALJrr473ZH27MsnSL+LKUlimp4BWJqMDMLmPpx/Q9R3OAlL4g==",
"dev": true,
"license": "MIT",
"dependencies": {
"eslint-visitor-keys": "^3.4.3"
@@ -2605,6 +2606,7 @@
"version": "4.12.2",
"resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.2.tgz",
"integrity": "sha512-EriSTlt5OC9/7SXkRSCAhfSxxoSUgBm33OH+IkwbdpgoqsSsUg7y3uh+IICI/Qg4BBWr3U2i39RpmycbxMq4ew==",
"dev": true,
"license": "MIT",
"engines": {
"node": "^12.0.0 || ^14.0.0 || >=16.0.0"
@@ -2635,6 +2637,7 @@
"version": "0.21.1",
"resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.21.1.tgz",
"integrity": "sha512-aw1gNayWpdI/jSYVgzN5pL0cfzU02GT3NBpeT/DXbx1/1x7ZKxFPd9bwrzygx/qiwIQiJ1sw/zD8qY/kRvlGHA==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
"@eslint/object-schema": "^2.1.7",
@@ -2649,6 +2652,7 @@
"version": "0.4.2",
"resolved": "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.4.2.tgz",
"integrity": "sha512-gBrxN88gOIf3R7ja5K9slwNayVcZgK6SOUORm2uBzTeIEfeVaIhOpCtTox3P6R7o2jLFwLFTLnC7kU/RGcYEgw==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
"@eslint/core": "^0.17.0"
@@ -2661,6 +2665,7 @@
"version": "0.17.0",
"resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.17.0.tgz",
"integrity": "sha512-yL/sLrpmtDaFEiUj1osRP4TI2MDz1AddJL+jZ7KSqvBuliN4xqYY54IfdN8qD8Toa6g1iloph1fxQNkjOxrrpQ==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
"@types/json-schema": "^7.0.15"
@@ -2736,6 +2741,7 @@
"version": "3.3.1",
"resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.3.1.tgz",
"integrity": "sha512-gtF186CXhIl1p4pJNGZw8Yc6RlshoePRvE0X91oPGb3vZ8pM3qOS9W9NGPat9LziaBV7XrJWGylNQXkGcnM3IQ==",
"dev": true,
"license": "MIT",
"dependencies": {
"ajv": "^6.12.4",
@@ -2759,6 +2765,7 @@
"version": "9.39.1",
"resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.39.1.tgz",
"integrity": "sha512-S26Stp4zCy88tH94QbBv3XCuzRQiZ9yXofEILmglYTh/Ug/a9/umqvgFtYBAo3Lp0nsI/5/qH1CCrbdK3AP1Tw==",
"dev": true,
"license": "MIT",
"engines": {
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
@@ -2771,6 +2778,7 @@
"version": "2.1.7",
"resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-2.1.7.tgz",
"integrity": "sha512-VtAOaymWVfZcmZbp6E2mympDIHvyjXs/12LqWYjVw6qjrfF+VK+fyG33kChz3nnK+SU5/NeHOqrTEHS8sXO3OA==",
"dev": true,
"license": "Apache-2.0",
"engines": {
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
@@ -2780,6 +2788,7 @@
"version": "0.4.1",
"resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.4.1.tgz",
"integrity": "sha512-43/qtrDUokr7LJqoF2c3+RInu/t4zfrpYdoSDfYyhg52rwLV6TnOvdG4fXm7IkSB3wErkcmJS9iEhjVtOSEjjA==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
"@eslint/core": "^0.17.0",
@@ -2805,6 +2814,7 @@
"version": "0.19.1",
"resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.1.tgz",
"integrity": "sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==",
"dev": true,
"license": "Apache-2.0",
"engines": {
"node": ">=18.18.0"
@@ -2814,6 +2824,7 @@
"version": "0.16.7",
"resolved": "https://registry.npmjs.org/@humanfs/node/-/node-0.16.7.tgz",
"integrity": "sha512-/zUx+yOsIrG4Y43Eh2peDeKCxlRt/gET6aHfaKpuq267qXdYDFViVHfMaLyygZOnl0kGWxFIgsBy8QFuTLUXEQ==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
"@humanfs/core": "^0.19.1",
@@ -2827,6 +2838,7 @@
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz",
"integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==",
"dev": true,
"license": "Apache-2.0",
"engines": {
"node": ">=12.22"
@@ -2840,6 +2852,7 @@
"version": "0.4.3",
"resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.4.3.tgz",
"integrity": "sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==",
"dev": true,
"license": "Apache-2.0",
"engines": {
"node": ">=18.18"
@@ -4953,9 +4966,9 @@
}
},
"node_modules/@next/env": {
"version": "16.0.8",
"resolved": "https://registry.npmjs.org/@next/env/-/env-16.0.8.tgz",
"integrity": "sha512-xP4WrQZuj9MdmLJy3eWFHepo+R3vznsMSS8Dy3wdA7FKpjCiesQ6DxZvdGziQisj0tEtCgBKJzjcAc4yZOgLEQ==",
"version": "16.0.10",
"resolved": "https://registry.npmjs.org/@next/env/-/env-16.0.10.tgz",
"integrity": "sha512-8tuaQkyDVgeONQ1MeT9Mkk8pQmZapMKFh5B+OrFUlG3rVmYTXcXlBetBgTurKXGaIZvkoqRT9JL5K3phXcgang==",
"license": "MIT"
},
"node_modules/@next/eslint-plugin-next": {
@@ -4969,9 +4982,9 @@
}
},
"node_modules/@next/swc-darwin-arm64": {
"version": "16.0.8",
"resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-16.0.8.tgz",
"integrity": "sha512-yjVMvTQN21ZHOclQnhSFbjBTEizle+1uo4NV6L4rtS9WO3nfjaeJYw+H91G+nEf3Ef43TaEZvY5mPWfB/De7tA==",
"version": "16.0.10",
"resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-16.0.10.tgz",
"integrity": "sha512-4XgdKtdVsaflErz+B5XeG0T5PeXKDdruDf3CRpnhN+8UebNa5N2H58+3GDgpn/9GBurrQ1uWW768FfscwYkJRg==",
"cpu": [
"arm64"
],
@@ -4985,9 +4998,9 @@
}
},
"node_modules/@next/swc-darwin-x64": {
"version": "16.0.8",
"resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-16.0.8.tgz",
"integrity": "sha512-+zu2N3QQ0ZOb6RyqQKfcu/pn0UPGmg+mUDqpAAEviAcEVEYgDckemOpiMRsBP3IsEKpcoKuNzekDcPczEeEIzA==",
"version": "16.0.10",
"resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-16.0.10.tgz",
"integrity": "sha512-spbEObMvRKkQ3CkYVOME+ocPDFo5UqHb8EMTS78/0mQ+O1nqE8toHJVioZo4TvebATxgA8XMTHHrScPrn68OGw==",
"cpu": [
"x64"
],
@@ -5001,9 +5014,9 @@
}
},
"node_modules/@next/swc-linux-arm64-gnu": {
"version": "16.0.8",
"resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-16.0.8.tgz",
"integrity": "sha512-LConttk+BeD0e6RG0jGEP9GfvdaBVMYsLJ5aDDweKiJVVCu6sGvo+Ohz9nQhvj7EQDVVRJMCGhl19DmJwGr6bQ==",
"version": "16.0.10",
"resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-16.0.10.tgz",
"integrity": "sha512-uQtWE3X0iGB8apTIskOMi2w/MKONrPOUCi5yLO+v3O8Mb5c7K4Q5KD1jvTpTF5gJKa3VH/ijKjKUq9O9UhwOYw==",
"cpu": [
"arm64"
],
@@ -5017,9 +5030,9 @@
}
},
"node_modules/@next/swc-linux-arm64-musl": {
"version": "16.0.8",
"resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-16.0.8.tgz",
"integrity": "sha512-JaXFAlqn8fJV+GhhA9lpg6da/NCN/v9ub98n3HoayoUSPOVdoxEEt86iT58jXqQCs/R3dv5ZnxGkW8aF4obMrQ==",
"version": "16.0.10",
"resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-16.0.10.tgz",
"integrity": "sha512-llA+hiDTrYvyWI21Z0L1GiXwjQaanPVQQwru5peOgtooeJ8qx3tlqRV2P7uH2pKQaUfHxI/WVarvI5oYgGxaTw==",
"cpu": [
"arm64"
],
@@ -5033,9 +5046,9 @@
}
},
"node_modules/@next/swc-linux-x64-gnu": {
"version": "16.0.8",
"resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-16.0.8.tgz",
"integrity": "sha512-O7M9it6HyNhsJp3HNAsJoHk5BUsfj7hRshfptpGcVsPZ1u0KQ/oVy8oxF7tlwxA5tR43VUP0yRmAGm1us514ng==",
"version": "16.0.10",
"resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-16.0.10.tgz",
"integrity": "sha512-AK2q5H0+a9nsXbeZ3FZdMtbtu9jxW4R/NgzZ6+lrTm3d6Zb7jYrWcgjcpM1k8uuqlSy4xIyPR2YiuUr+wXsavA==",
"cpu": [
"x64"
],
@@ -5049,9 +5062,9 @@
}
},
"node_modules/@next/swc-linux-x64-musl": {
"version": "16.0.8",
"resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-16.0.8.tgz",
"integrity": "sha512-8+KClEC/GLI2dLYcrWwHu5JyC5cZYCFnccVIvmxpo6K+XQt4qzqM5L4coofNDZYkct/VCCyJWGbZZDsg6w6LFA==",
"version": "16.0.10",
"resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-16.0.10.tgz",
"integrity": "sha512-1TDG9PDKivNw5550S111gsO4RGennLVl9cipPhtkXIFVwo31YZ73nEbLjNC8qG3SgTz/QZyYyaFYMeY4BKZR/g==",
"cpu": [
"x64"
],
@@ -5065,9 +5078,9 @@
}
},
"node_modules/@next/swc-win32-arm64-msvc": {
"version": "16.0.8",
"resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-16.0.8.tgz",
"integrity": "sha512-rpQ/PgTEgH68SiXmhu/cJ2hk9aZ6YgFvspzQWe2I9HufY6g7V02DXRr/xrVqOaKm2lenBFPNQ+KAaeveywqV+A==",
"version": "16.0.10",
"resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-16.0.10.tgz",
"integrity": "sha512-aEZIS4Hh32xdJQbHz121pyuVZniSNoqDVx1yIr2hy+ZwJGipeqnMZBJHyMxv2tiuAXGx6/xpTcQJ6btIiBjgmg==",
"cpu": [
"arm64"
],
@@ -5081,9 +5094,9 @@
}
},
"node_modules/@next/swc-win32-x64-msvc": {
"version": "16.0.8",
"resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-16.0.8.tgz",
"integrity": "sha512-jWpWjWcMQu2iZz4pEK2IktcfR+OA9+cCG8zenyLpcW8rN4rzjfOzH4yj/b1FiEAZHKS+5Vq8+bZyHi+2yqHbFA==",
"version": "16.0.10",
"resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-16.0.10.tgz",
"integrity": "sha512-E+njfCoFLb01RAFEnGZn6ERoOqhK1Gl3Lfz1Kjnj0Ulfu7oJbuMyvBKNj/bw8XZnenHDASlygTjZICQW+rYW1Q==",
"cpu": [
"x64"
],
@@ -6262,7 +6275,7 @@
"version": "1.56.1",
"resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.56.1.tgz",
"integrity": "sha512-vSMYtL/zOcFpvJCW71Q/OEGQb7KYBPAdKh35WNSkaZA75JlAO8ED8UN6GUNTm3drWomcbcqRPFqQbLae8yBTdg==",
"devOptional": true,
"dev": true,
"license": "Apache-2.0",
"dependencies": {
"playwright": "1.56.1"
@@ -7945,106 +7958,6 @@
"integrity": "sha512-e7Mew686owMaPJVNNLs55PUvgz371nKgwsc4vxE49zsODpJEnxgxRo2y/OKrqueavXgZNMDVj3DdHFlaSAeU8g==",
"license": "MIT"
},
"node_modules/@supabase/auth-js": {
"version": "2.84.0",
"resolved": "https://registry.npmjs.org/@supabase/auth-js/-/auth-js-2.84.0.tgz",
"integrity": "sha512-J6XKbqqg1HQPMfYkAT9BrC8anPpAiifl7qoVLsYhQq5B/dnu/lxab1pabnxtJEsvYG5rwI5HEVEGXMjoQ6Wz2Q==",
"license": "MIT",
"dependencies": {
"tslib": "2.8.1"
},
"engines": {
"node": ">=20.0.0"
}
},
"node_modules/@supabase/functions-js": {
"version": "2.84.0",
"resolved": "https://registry.npmjs.org/@supabase/functions-js/-/functions-js-2.84.0.tgz",
"integrity": "sha512-2oY5QBV4py/s64zMlhPEz+4RTdlwxzmfhM1k2xftD2v1DruRZKfoe7Yn9DCz1VondxX8evcvpc2udEIGzHI+VA==",
"license": "MIT",
"dependencies": {
"tslib": "2.8.1"
},
"engines": {
"node": ">=20.0.0"
}
},
"node_modules/@supabase/postgrest-js": {
"version": "2.84.0",
"resolved": "https://registry.npmjs.org/@supabase/postgrest-js/-/postgrest-js-2.84.0.tgz",
"integrity": "sha512-oplc/3jfJeVW4F0J8wqywHkjIZvOVHtqzF0RESijepDAv5Dn/LThlGW1ftysoP4+PXVIrnghAbzPHo88fNomPQ==",
"license": "MIT",
"dependencies": {
"tslib": "2.8.1"
},
"engines": {
"node": ">=20.0.0"
}
},
"node_modules/@supabase/realtime-js": {
"version": "2.84.0",
"resolved": "https://registry.npmjs.org/@supabase/realtime-js/-/realtime-js-2.84.0.tgz",
"integrity": "sha512-ThqjxiCwWiZAroHnYPmnNl6tZk6jxGcG2a7Hp/3kcolPcMj89kWjUTA3cHmhdIWYsP84fHp8MAQjYWMLf7HEUg==",
"license": "MIT",
"dependencies": {
"@types/phoenix": "^1.6.6",
"@types/ws": "^8.18.1",
"tslib": "2.8.1",
"ws": "^8.18.2"
},
"engines": {
"node": ">=20.0.0"
}
},
"node_modules/@supabase/realtime-js/node_modules/ws": {
"version": "8.18.3",
"resolved": "https://registry.npmjs.org/ws/-/ws-8.18.3.tgz",
"integrity": "sha512-PEIGCY5tSlUt50cqyMXfCzX+oOPqN0vuGqWzbcJ2xvnkzkq46oOpz7dQaTDBdfICb4N14+GARUDw2XV2N4tvzg==",
"license": "MIT",
"engines": {
"node": ">=10.0.0"
},
"peerDependencies": {
"bufferutil": "^4.0.1",
"utf-8-validate": ">=5.0.2"
},
"peerDependenciesMeta": {
"bufferutil": {
"optional": true
},
"utf-8-validate": {
"optional": true
}
}
},
"node_modules/@supabase/storage-js": {
"version": "2.84.0",
"resolved": "https://registry.npmjs.org/@supabase/storage-js/-/storage-js-2.84.0.tgz",
"integrity": "sha512-vXvAJ1euCuhryOhC6j60dG8ky+lk0V06ubNo+CbhuoUv+sl39PyY0lc+k+qpQhTk/VcI6SiM0OECLN83+nyJ5A==",
"license": "MIT",
"dependencies": {
"tslib": "2.8.1"
},
"engines": {
"node": ">=20.0.0"
}
},
"node_modules/@supabase/supabase-js": {
"version": "2.84.0",
"resolved": "https://registry.npmjs.org/@supabase/supabase-js/-/supabase-js-2.84.0.tgz",
"integrity": "sha512-byMqYBvb91sx2jcZsdp0qLpmd4Dioe80e4OU/UexXftCkpTcgrkoENXHf5dO8FCSai8SgNeq16BKg10QiDI6xg==",
"license": "MIT",
"dependencies": {
"@supabase/auth-js": "2.84.0",
"@supabase/functions-js": "2.84.0",
"@supabase/postgrest-js": "2.84.0",
"@supabase/realtime-js": "2.84.0",
"@supabase/storage-js": "2.84.0"
},
"engines": {
"node": ">=20.0.0"
}
},
"node_modules/@svgr/babel-plugin-add-jsx-attribute": {
"version": "8.0.0",
"resolved": "https://registry.npmjs.org/@svgr/babel-plugin-add-jsx-attribute/-/babel-plugin-add-jsx-attribute-8.0.0.tgz",
@@ -9472,6 +9385,7 @@
"version": "1.0.8",
"resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz",
"integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==",
"dev": true,
"license": "MIT"
},
"node_modules/@types/express": {
@@ -9583,6 +9497,7 @@
"version": "7.0.15",
"resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz",
"integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==",
"dev": true,
"license": "MIT"
},
"node_modules/@types/json5": {
@@ -9610,6 +9525,7 @@
"version": "22.19.1",
"resolved": "https://registry.npmjs.org/@types/node/-/node-22.19.1.tgz",
"integrity": "sha512-LCCV0HdSZZZb34qifBsyWlUmok6W7ouER+oQIGBScS8EsZsQbrtFTUrDX4hOl+CS6p7cnNC4td+qrSVGSCTUfQ==",
"dev": true,
"license": "MIT",
"dependencies": {
"undici-types": "~6.21.0"
@@ -9632,12 +9548,6 @@
"dev": true,
"license": "MIT"
},
"node_modules/@types/phoenix": {
"version": "1.6.6",
"resolved": "https://registry.npmjs.org/@types/phoenix/-/phoenix-1.6.6.tgz",
"integrity": "sha512-PIzZZlEppgrpoT2QgbnDU+MMzuR6BbCjllj0bM70lWoejMeNJAxCchxnv7J3XFkI8MpygtRpzXrIlmWUBclP5A==",
"license": "MIT"
},
"node_modules/@types/qrcode": {
"version": "1.5.6",
"resolved": "https://registry.npmjs.org/@types/qrcode/-/qrcode-1.5.6.tgz",
@@ -9666,7 +9576,7 @@
"version": "19.2.7",
"resolved": "https://registry.npmjs.org/@types/react/-/react-19.2.7.tgz",
"integrity": "sha512-MWtvHrGZLFttgeEj28VXHxpmwYbor/ATPYbBfSFZEIRK0ecCFLl2Qo55z52Hss+UV9CRN7trSeq1zbgx7YDWWg==",
"devOptional": true,
"dev": true,
"license": "MIT",
"dependencies": {
"csstype": "^3.2.2"
@@ -9676,7 +9586,7 @@
"version": "19.2.3",
"resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-19.2.3.tgz",
"integrity": "sha512-jp2L/eY6fn+KgVVQAOqYItbF0VY/YApe5Mz2F0aykSO8gx31bYCZyvSeYxCHKvzHG5eZjc+zyaS5BrBWya2+kQ==",
"devOptional": true,
"dev": true,
"license": "MIT",
"peerDependencies": {
"@types/react": "^19.2.0"
@@ -9776,6 +9686,7 @@
"version": "8.18.1",
"resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.18.1.tgz",
"integrity": "sha512-ThVF6DCVhA8kUGy+aazFQ4kXQ7E1Ty7A3ypFOe0IcJV8O/M511G99AW24irKrW56Wt44yG9+ij8FaqoBGkuBXg==",
"dev": true,
"license": "MIT",
"dependencies": {
"@types/node": "*"
@@ -11664,6 +11575,7 @@
"version": "8.15.0",
"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz",
"integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==",
"dev": true,
"license": "MIT",
"bin": {
"acorn": "bin/acorn"
@@ -11689,6 +11601,7 @@
"version": "5.3.2",
"resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz",
"integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==",
"dev": true,
"license": "MIT",
"peerDependencies": {
"acorn": "^6.0.0 || ^7.0.0 || ^8.0.0"
@@ -11744,6 +11657,7 @@
"version": "6.12.6",
"resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
"integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
"dev": true,
"license": "MIT",
"dependencies": {
"fast-deep-equal": "^3.1.1",
@@ -11805,6 +11719,7 @@
"version": "0.4.1",
"resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
"integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==",
"dev": true,
"license": "MIT"
},
"node_modules/alien-signals": {
@@ -11940,6 +11855,7 @@
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
"integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==",
"dev": true,
"license": "Python-2.0"
},
"node_modules/aria-hidden": {
@@ -12502,6 +12418,7 @@
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
"integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
"dev": true,
"license": "MIT"
},
"node_modules/bare-events": {
@@ -12890,6 +12807,7 @@
"version": "1.1.12",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz",
"integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==",
"dev": true,
"license": "MIT",
"dependencies": {
"balanced-match": "^1.0.0",
@@ -13140,6 +13058,7 @@
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz",
"integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=6"
@@ -13219,6 +13138,7 @@
"version": "4.1.2",
"resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
"integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
"dev": true,
"license": "MIT",
"dependencies": {
"ansi-styles": "^4.1.0",
@@ -13275,7 +13195,7 @@
"version": "4.0.3",
"resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz",
"integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==",
"devOptional": true,
"dev": true,
"license": "MIT",
"dependencies": {
"readdirp": "^4.0.1"
@@ -13679,6 +13599,7 @@
"version": "0.0.1",
"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
"integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==",
"dev": true,
"license": "MIT"
},
"node_modules/concat-with-sourcemaps": {
@@ -13927,6 +13848,7 @@
"version": "7.0.6",
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz",
"integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==",
"dev": true,
"license": "MIT",
"dependencies": {
"path-key": "^3.1.0",
@@ -14259,7 +14181,7 @@
"version": "3.2.3",
"resolved": "https://registry.npmjs.org/csstype/-/csstype-3.2.3.tgz",
"integrity": "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==",
"devOptional": true,
"dev": true,
"license": "MIT"
},
"node_modules/d3-array": {
@@ -14499,6 +14421,7 @@
"version": "4.4.3",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz",
"integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==",
"dev": true,
"license": "MIT",
"dependencies": {
"ms": "^2.1.3"
@@ -14594,6 +14517,7 @@
"version": "0.1.4",
"resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz",
"integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==",
"dev": true,
"license": "MIT"
},
"node_modules/deepmerge": {
@@ -15483,6 +15407,7 @@
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz",
"integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=10"
@@ -15495,6 +15420,7 @@
"version": "9.39.1",
"resolved": "https://registry.npmjs.org/eslint/-/eslint-9.39.1.tgz",
"integrity": "sha512-BhHmn2yNOFA9H9JmmIVKJmd288g9hrVRDkdoIgRCRuSySRUHH7r/DI6aAXW9T1WwUuY3DFgrcaqB+deURBLR5g==",
"dev": true,
"license": "MIT",
"dependencies": {
"@eslint-community/eslint-utils": "^4.8.0",
@@ -16144,6 +16070,7 @@
"version": "8.4.0",
"resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.4.0.tgz",
"integrity": "sha512-sNXOfKCn74rt8RICKMvJS7XKV/Xk9kA7DyJr8mJik3S7Cwgy3qlkkmyS2uQB3jiJg6VNdZd/pDBJu0nvG2NlTg==",
"dev": true,
"license": "BSD-2-Clause",
"dependencies": {
"esrecurse": "^4.3.0",
@@ -16160,6 +16087,7 @@
"version": "3.4.3",
"resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz",
"integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==",
"dev": true,
"license": "Apache-2.0",
"engines": {
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
@@ -16172,6 +16100,7 @@
"version": "4.2.1",
"resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.1.tgz",
"integrity": "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==",
"dev": true,
"license": "Apache-2.0",
"engines": {
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
@@ -16184,6 +16113,7 @@
"version": "10.4.0",
"resolved": "https://registry.npmjs.org/espree/-/espree-10.4.0.tgz",
"integrity": "sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ==",
"dev": true,
"license": "BSD-2-Clause",
"dependencies": {
"acorn": "^8.15.0",
@@ -16201,6 +16131,7 @@
"version": "4.2.1",
"resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.1.tgz",
"integrity": "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==",
"dev": true,
"license": "Apache-2.0",
"engines": {
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
@@ -16227,6 +16158,7 @@
"version": "1.6.0",
"resolved": "https://registry.npmjs.org/esquery/-/esquery-1.6.0.tgz",
"integrity": "sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==",
"dev": true,
"license": "BSD-3-Clause",
"dependencies": {
"estraverse": "^5.1.0"
@@ -16239,6 +16171,7 @@
"version": "4.3.0",
"resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz",
"integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==",
"dev": true,
"license": "BSD-2-Clause",
"dependencies": {
"estraverse": "^5.2.0"
@@ -16251,6 +16184,7 @@
"version": "5.3.0",
"resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz",
"integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==",
"dev": true,
"license": "BSD-2-Clause",
"engines": {
"node": ">=4.0"
@@ -16267,6 +16201,7 @@
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz",
"integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==",
"dev": true,
"license": "BSD-2-Clause",
"engines": {
"node": ">=0.10.0"
@@ -16542,12 +16477,14 @@
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz",
"integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==",
"dev": true,
"license": "MIT"
},
"node_modules/fast-levenshtein": {
"version": "2.0.6",
"resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz",
"integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==",
"dev": true,
"license": "MIT"
},
"node_modules/fast-uri": {
@@ -16644,6 +16581,7 @@
"version": "8.0.0",
"resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz",
"integrity": "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==",
"dev": true,
"license": "MIT",
"dependencies": {
"flat-cache": "^4.0.0"
@@ -16869,6 +16807,7 @@
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz",
"integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==",
"dev": true,
"license": "MIT",
"dependencies": {
"locate-path": "^6.0.0",
@@ -16911,6 +16850,7 @@
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-4.0.1.tgz",
"integrity": "sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==",
"dev": true,
"license": "MIT",
"dependencies": {
"flatted": "^3.2.9",
@@ -16924,6 +16864,7 @@
"version": "3.3.3",
"resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.3.tgz",
"integrity": "sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==",
"dev": true,
"license": "ISC"
},
"node_modules/follow-redirects": {
@@ -17562,6 +17503,7 @@
"version": "6.0.2",
"resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz",
"integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==",
"dev": true,
"license": "ISC",
"dependencies": {
"is-glob": "^4.0.3"
@@ -17666,6 +17608,7 @@
"version": "14.0.0",
"resolved": "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz",
"integrity": "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=18"
@@ -18040,6 +17983,7 @@
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
"integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=8"
@@ -18515,6 +18459,7 @@
"version": "5.3.2",
"resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz",
"integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">= 4"
@@ -18548,7 +18493,7 @@
"version": "5.1.4",
"resolved": "https://registry.npmjs.org/immutable/-/immutable-5.1.4.tgz",
"integrity": "sha512-p6u1bG3YSnINT5RQmx/yRZBpenIl30kVxkTLDyHLIMk0gict704Q9n+thfDI7lTRm9vXdDYutVzXhzcThxTnXA==",
"devOptional": true,
"dev": true,
"license": "MIT"
},
"node_modules/import-cwd": {
@@ -18568,6 +18513,7 @@
"version": "3.3.1",
"resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.1.tgz",
"integrity": "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==",
"dev": true,
"license": "MIT",
"dependencies": {
"parent-module": "^1.0.0",
@@ -18617,6 +18563,7 @@
"version": "0.1.4",
"resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz",
"integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=0.8.19"
@@ -18957,6 +18904,7 @@
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
"integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=0.10.0"
@@ -19011,6 +18959,7 @@
"version": "4.0.3",
"resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz",
"integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==",
"dev": true,
"license": "MIT",
"dependencies": {
"is-extglob": "^2.1.1"
@@ -19429,6 +19378,7 @@
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
"integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==",
"dev": true,
"license": "ISC"
},
"node_modules/isobject": {
@@ -19702,7 +19652,7 @@
"version": "2.4.2",
"resolved": "https://registry.npmjs.org/jiti/-/jiti-2.4.2.tgz",
"integrity": "sha512-rg9zJN+G4n2nfJl5MW3BMygZX56zKPNVEYYqq7adpmMh4Jn2QNEwhvQlFy6jPVdcod7txZtKHWnyZiA3a0zP7A==",
"devOptional": true,
"dev": true,
"license": "MIT",
"bin": {
"jiti": "lib/jiti-cli.mjs"
@@ -19745,6 +19695,7 @@
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.1.tgz",
"integrity": "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==",
"dev": true,
"license": "MIT",
"dependencies": {
"argparse": "^2.0.1"
@@ -19846,6 +19797,7 @@
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz",
"integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==",
"dev": true,
"license": "MIT"
},
"node_modules/json-parse-even-better-errors": {
@@ -19872,6 +19824,7 @@
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz",
"integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==",
"dev": true,
"license": "MIT"
},
"node_modules/json-stringify-safe": {
@@ -20100,6 +20053,7 @@
"version": "4.5.4",
"resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz",
"integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==",
"dev": true,
"license": "MIT",
"dependencies": {
"json-buffer": "3.0.1"
@@ -20339,6 +20293,7 @@
"version": "0.4.1",
"resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz",
"integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==",
"dev": true,
"license": "MIT",
"dependencies": {
"prelude-ls": "^1.2.1",
@@ -20701,6 +20656,7 @@
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz",
"integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==",
"dev": true,
"license": "MIT",
"dependencies": {
"p-locate": "^5.0.0"
@@ -20803,6 +20759,7 @@
"version": "4.6.2",
"resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz",
"integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==",
"dev": true,
"license": "MIT"
},
"node_modules/lodash.once": {
@@ -21239,6 +21196,7 @@
"version": "3.1.2",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
"integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
"dev": true,
"license": "ISC",
"dependencies": {
"brace-expansion": "^1.1.7"
@@ -21341,6 +21299,7 @@
"version": "2.1.3",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
"integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
"dev": true,
"license": "MIT"
},
"node_modules/muggle-string": {
@@ -21412,6 +21371,7 @@
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz",
"integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==",
"dev": true,
"license": "MIT"
},
"node_modules/needle": {
@@ -21450,12 +21410,12 @@
"license": "MIT"
},
"node_modules/next": {
"version": "16.0.8",
"resolved": "https://registry.npmjs.org/next/-/next-16.0.8.tgz",
"integrity": "sha512-LmcZzG04JuzNXi48s5P+TnJBsTGPJunViNKV/iE4uM6kstjTQsQhvsAv+xF6MJxU2Pr26tl15eVbp0jQnsv6/g==",
"version": "16.0.10",
"resolved": "https://registry.npmjs.org/next/-/next-16.0.10.tgz",
"integrity": "sha512-RtWh5PUgI+vxlV3HdR+IfWA1UUHu0+Ram/JBO4vWB54cVPentCD0e+lxyAYEsDTqGGMg7qpjhKh6dc6aW7W/sA==",
"license": "MIT",
"dependencies": {
"@next/env": "16.0.8",
"@next/env": "16.0.10",
"@swc/helpers": "0.5.15",
"caniuse-lite": "^1.0.30001579",
"postcss": "8.4.31",
@@ -21468,14 +21428,14 @@
"node": ">=20.9.0"
},
"optionalDependencies": {
"@next/swc-darwin-arm64": "16.0.8",
"@next/swc-darwin-x64": "16.0.8",
"@next/swc-linux-arm64-gnu": "16.0.8",
"@next/swc-linux-arm64-musl": "16.0.8",
"@next/swc-linux-x64-gnu": "16.0.8",
"@next/swc-linux-x64-musl": "16.0.8",
"@next/swc-win32-arm64-msvc": "16.0.8",
"@next/swc-win32-x64-msvc": "16.0.8",
"@next/swc-darwin-arm64": "16.0.10",
"@next/swc-darwin-x64": "16.0.10",
"@next/swc-linux-arm64-gnu": "16.0.10",
"@next/swc-linux-arm64-musl": "16.0.10",
"@next/swc-linux-x64-gnu": "16.0.10",
"@next/swc-linux-x64-musl": "16.0.10",
"@next/swc-win32-arm64-msvc": "16.0.10",
"@next/swc-win32-x64-msvc": "16.0.10",
"sharp": "^0.34.4"
},
"peerDependencies": {
@@ -22207,6 +22167,7 @@
"version": "0.9.4",
"resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz",
"integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==",
"dev": true,
"license": "MIT",
"dependencies": {
"deep-is": "^0.1.3",
@@ -22285,6 +22246,7 @@
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz",
"integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==",
"dev": true,
"license": "MIT",
"dependencies": {
"yocto-queue": "^0.1.0"
@@ -22300,6 +22262,7 @@
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz",
"integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==",
"dev": true,
"license": "MIT",
"dependencies": {
"p-limit": "^3.0.2"
@@ -22386,6 +22349,7 @@
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz",
"integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==",
"dev": true,
"license": "MIT",
"dependencies": {
"callsites": "^3.0.0"
@@ -22494,6 +22458,7 @@
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
"integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=8"
@@ -22879,7 +22844,7 @@
"version": "1.56.1",
"resolved": "https://registry.npmjs.org/playwright/-/playwright-1.56.1.tgz",
"integrity": "sha512-aFi5B0WovBHTEvpM3DzXTUaeN6eN0qWnTkKx4NQaH4Wvcmc153PdaY2UBdSYKaGYw+UyWXSVyxDUg5DoPEttjw==",
"devOptional": true,
"dev": true,
"license": "Apache-2.0",
"dependencies": {
"playwright-core": "1.56.1"
@@ -22898,7 +22863,7 @@
"version": "1.56.1",
"resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.56.1.tgz",
"integrity": "sha512-hutraynyn31F+Bifme+Ps9Vq59hKuUCz7H1kDOcBs+2oGguKkWTU50bBWrtz34OUWmIwpBTWDxaRPXrIXkgvmQ==",
"devOptional": true,
"dev": true,
"license": "Apache-2.0",
"bin": {
"playwright-core": "cli.js"
@@ -23695,6 +23660,7 @@
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz",
"integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">= 0.8.0"
@@ -23885,6 +23851,7 @@
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz",
"integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=6"
@@ -24251,11 +24218,10 @@
}
},
"node_modules/react-is": {
"version": "19.2.0",
"resolved": "https://registry.npmjs.org/react-is/-/react-is-19.2.0.tgz",
"integrity": "sha512-x3Ax3kNSMIIkyVYhWPyO09bu0uttcAIoecO/um/rKGQ4EltYWVYtyiGkS/3xMynrbVQdS69Jhlv8FXUEZehlzA==",
"license": "MIT",
"peer": true
"version": "19.2.3",
"resolved": "https://registry.npmjs.org/react-is/-/react-is-19.2.3.tgz",
"integrity": "sha512-qJNJfu81ByyabuG7hPFEbXqNcWSU3+eVus+KJs+0ncpGfMyYdvSmxiJxbWR65lYi1I+/0HBcliO029gc4F+PnA==",
"license": "MIT"
},
"node_modules/react-redux": {
"version": "9.2.0",
@@ -24435,7 +24401,7 @@
"version": "4.1.2",
"resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.1.2.tgz",
"integrity": "sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==",
"devOptional": true,
"dev": true,
"license": "MIT",
"engines": {
"node": ">= 14.18.0"
@@ -24727,6 +24693,7 @@
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz",
"integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=4"
@@ -26108,7 +26075,7 @@
"version": "1.94.2",
"resolved": "https://registry.npmjs.org/sass/-/sass-1.94.2.tgz",
"integrity": "sha512-N+7WK20/wOr7CzA2snJcUSSNTCzeCGUTFY3OgeQP3mZ1aj9NMQ0mSTXwlrnd89j33zzQJGqIN52GIOmYrfq46A==",
"devOptional": true,
"dev": true,
"license": "MIT",
"dependencies": {
"chokidar": "^4.0.0",
@@ -27193,6 +27160,7 @@
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
"integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==",
"dev": true,
"license": "MIT",
"dependencies": {
"shebang-regex": "^3.0.0"
@@ -27205,6 +27173,7 @@
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz",
"integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=8"
@@ -27939,6 +27908,7 @@
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz",
"integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=8"
@@ -28052,6 +28022,7 @@
"version": "7.2.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
"integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
"dev": true,
"license": "MIT",
"dependencies": {
"has-flag": "^4.0.0"
@@ -28908,6 +28879,7 @@
"version": "0.4.0",
"resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz",
"integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==",
"dev": true,
"license": "MIT",
"dependencies": {
"prelude-ls": "^1.2.1"
@@ -29455,6 +29427,7 @@
"version": "6.21.0",
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz",
"integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==",
"dev": true,
"license": "MIT"
},
"node_modules/unicode-canonical-property-names-ecmascript": {
@@ -29632,6 +29605,7 @@
"version": "4.4.1",
"resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz",
"integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==",
"dev": true,
"license": "BSD-2-Clause",
"dependencies": {
"punycode": "^2.1.0"
@@ -30725,6 +30699,7 @@
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
"integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
"dev": true,
"license": "ISC",
"dependencies": {
"isexe": "^2.0.0"
@@ -30922,6 +30897,7 @@
"version": "1.2.5",
"resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz",
"integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=0.10.0"
@@ -31153,6 +31129,7 @@
"version": "0.1.0",
"resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz",
"integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=10"
+2 -2
View File
@@ -39,7 +39,6 @@
"@radix-ui/react-label": "^2.1.7",
"@radix-ui/react-slot": "^1.2.0",
"@redocly/ajv": "^8.11.2",
"@supabase/supabase-js": "^2.84.0",
"@tanstack/react-query": "^5.74.4",
"@tanstack/react-store": "^0.8.0",
"@tanstack/react-table": "^8.21.2",
@@ -51,7 +50,7 @@
"graphql": "^16.11.0",
"html2canvas": "^1.4.1",
"js-cookie": "^3.0.5",
"next": "^16.0.8",
"next": "^16.0.10",
"next-themes": "^0.4.6",
"openapi-fetch": "^0.15.0",
"openapi-react-query": "^0.5.0",
@@ -60,6 +59,7 @@
"react-dom": "^19.2.1",
"react-hook-form": "^7.56.4",
"react-icons": "^5.5.0",
"react-is": "^19.2.3",
"react-router-dom": "^7.3.0",
"recharts": "^3.1.2",
"sharp": "^0.34.1",