commit 39f5b8d5cce39e719c026a48965d77d9484c3d78 Author: Hein Date: Tue Aug 11 23:31:35 2026 +0200 feat(ui): add wedding theme styles and layout components * Introduced wedding-themed CSS variables for styling. * Created layout component for the wedding site with navigation and countdown. * Added RSVP and photo upload pages with form handling. * Implemented QR code page for wedding site access. * Configured TypeScript and Vite for the project. * Added robots.txt for search engine crawling. diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..14a5a56 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,7 @@ +data/ +config.yaml +ui/node_modules +ui/build +ui/.svelte-kit +server/wedding-server +.git diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..c678264 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,4 @@ +*.jpg filter=lfs diff=lfs merge=lfs -text +*.png filter=lfs diff=lfs merge=lfs -text +*.mp3 filter=lfs diff=lfs merge=lfs -text +*.ogg filter=lfs diff=lfs merge=lfs -text diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..d32251c --- /dev/null +++ b/.gitignore @@ -0,0 +1,8 @@ +data/ +config.yaml +ui/node_modules/ +ui/build/ +ui/.svelte-kit/ +server/wedding-server +server/web/dist/* +!server/web/dist/index.html diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..9a14ceb --- /dev/null +++ b/Dockerfile @@ -0,0 +1,23 @@ +# syntax=docker/dockerfile:1 + +FROM node:20-alpine AS frontend-builder +WORKDIR /app/ui +COPY ui/package*.json ./ +RUN npm ci +COPY ui/ ./ +RUN npm run build + +FROM golang:1.26-alpine AS backend-builder +WORKDIR /app +COPY server/go.mod server/go.sum ./ +RUN go mod download +COPY server/ ./ +COPY --from=frontend-builder /app/ui/build ./web/dist +RUN CGO_ENABLED=0 go build -o /wedding-server . + +FROM alpine:3.20 +RUN apk add --no-cache ca-certificates +COPY --from=backend-builder /wedding-server /usr/local/bin/wedding-server +WORKDIR /app +EXPOSE 8080 +ENTRYPOINT ["wedding-server"] diff --git a/PLAN.md b/PLAN.md new file mode 100644 index 0000000..28d663c --- /dev/null +++ b/PLAN.md @@ -0,0 +1,176 @@ +# Plan: Zoé & Shaldon Wedding Site + +## Goal +QR-code-accessible site for save-the-date, RSVP, and guest photo uploads. Wedding date: **7 November 2026**. + +## Stack +- **Frontend**: SvelteKit, `adapter-static`, prerendered. No SSR needed. +- **UI/theming**: Tailwind CSS + [Skeleton](https://skeleton.dev) (Svelte), custom theme for the blue/yellow palette — Skeleton handles light/dark switching itself, no hand-rolled CSS variables needed. +- **Backend**: Go, single binary, `embed.FS` serves the built static site + JSON API on one port. +- **Storage**: SQLite via `modernc.org/sqlite` (pure Go, no cgo — keeps the Docker build static/`CGO_ENABLED=0`) for RSVP/upload metadata. Photos on disk. +- **Email**: Go `net/smtp` (STARTTLS) to notify the couple on new RSVP / photo upload. + +## Repo layout +``` +zoe-shaldon/ +├── ui/ SvelteKit frontend +│ ├── tailwind.config.ts +│ ├── assets/photos/ curated couple photos (checked in), source for the background slideshow +│ └── src/ +│ ├── app.css Tailwind + Skeleton custom theme (wedding-theme) +│ ├── lib/components/PhotoBackground.svelte ambient slide-in/out photo background +│ └── routes/ +│ ├── +page.svelte landing: hero, countdown, photo background, nav +│ ├── rsvp/+page.svelte RSVP form +│ └── photos/+page.svelte upload form (gated) + status message before open date +├── server/ Go backend +│ ├── main.go +│ ├── internal/api/ HTTP handlers +│ ├── internal/store/ SQLite access +│ ├── internal/mail/ SMTP sending +│ └── web/ embedded static build (go:embed) +├── data/ runtime data, gitignored +│ ├── rsvp.db +│ └── photos// +├── concept/ source assets (save-the-date image) +├── config.example.yaml template, checked in +├── config.yaml real config, gitignored +├── Dockerfile +└── docker-compose.yml +``` + +## Data model (SQLite) +``` +rsvps(id, message, created_at) +rsvp_guests(id, rsvp_id FK, name) +photo_uploads(id, name, email, phone, message, created_at) +photo_files(id, upload_id FK, filename, path, url, created_at) +``` +RSVP is a party: one or more guest names attached to a single RSVP + optional shared message — no email/phone captured for RSVP (contact for RSVP questions is the phone number on the invite instead). Photo upload keeps its own name/email/phone/message, unchanged. + +## API +| Method | Path | Body | Notes | +|---|---|---|---| +| POST | `/api/rsvp` | `{names: string[], message?}` | at least one non-blank name required; insert party + guests, email couple | +| GET | `/api/config` | — | `{weddingDate, ceremonyTime, rsvpByDate, venueName, venueAddress, rsvpPhone}` (all RFC3339 where dates) — single source of truth for countdowns, gate, and displayed details | +| POST | `/api/photos/upload` | multipart: `name, message?, email?, phone?, files[]` | rejected with 403 if `now < weddingDate`, **enforced server-side** regardless of client clock | +| GET | `/healthz` | — | liveness | + +## Countdowns +- Global: a compact countdown to `weddingDate` sits below the nav bar on every page (`+layout.svelte`). Once passed, it reads "Already married! 🎉" instead of digits. +- Landing page: hero shows the day/date (e.g. "Saturday, 7 November 2026"), `ceremonyTime` ("16:00 for 16:30"), and venue name/address — all from `GET /api/config`. RSVP button is hidden once the guest has RSVP'd (tracked client-side via `localStorage`, see below); replaced with a thank-you note. +- RSVP page: its own live countdown to `rsvpByDate` ("RSVP by "). Once `rsvpByDate` passes, the countdown and form are replaced by an "RSVP missed" notice pointing to `rsvpPhone`. +- Photos page: reuses `weddingDate` — before that time shows "uploads open on the wedding day" instead of the upload form (no separate countdown here, the global one covers it). +- One date per purpose, no duplicated "opens at" settings to keep in sync. + +## RSVP-submitted tracking +No accounts/auth — `localStorage` flag (`zoe-shaldon-rsvp-submitted`) set after a successful `POST /api/rsvp`, read by the landing page to decide whether to show the RSVP button or a confirmation. Per-browser only; a guest RSVPing from a different device won't see the flag, which is an acceptable prototype limitation. + +## Photo background (landing page) +Curated couple photos already checked in at `ui/assets/photos` (33 images) — separate from `data/photos/` (runtime, guest-uploaded, gitignored). These are the source for an ambient background behind the hero content. + +- `PhotoBackground.svelte`: full-bleed layer behind the hero text, cycling through a shuffled list of the photos on an interval (~6s). Each photo slides in from one edge and slides out the opposite edge (CSS `transform: translateX` + `opacity` transition, one photo at a time, next one queued behind). +- Photo list built at compile time via Vite's `import.meta.glob('/assets/photos/*.{jpg,jpeg,png}', { eager: true })` — drop a file in the folder, it's picked up on next build, no code change. +- A semi-transparent overlay in the theme's `primary` blue sits between the photos and the text so the hero copy (white/yellow) stays legible over any photo. +- Respect `prefers-reduced-motion: reduce` — fall back to a plain crossfade (opacity only, no slide) or a static single image. +- **`IMG_E8488.HEIC` in `ui/assets/photos` needs converting to JPG before build** — browsers don't render HEIC natively and Vite won't transform it; either convert now or add a build-step check that fails loudly if a `.heic` file is present. + +## Photo upload gating +- Gate value is `wedding.date` from the config file (see Config below) — no separate open-date field. +- Client: countdown shown before that time; upload form hidden until then. +- Server: hard check on every upload request — client-side gating is UX only, not security. + +## Upload validation +- Allowed types: jpg/png/webp/heic, sniffed via `http.DetectContentType` (not trusted from filename/extension). +- Max file size and max files per submission — values TBD, suggest 15MB/file, 10 files/submission. +- Stored at `data/photos//_`. + +## Email +SMTP settings come from the config file (see below). +- On RSVP: send guest names + message. +- On photo upload: send name/message/contact + direct links to each stored photo. + +## Config +Single YAML file, path resolved from `CONFIG_PATH` env var (default `./config.yaml`) — this is the *only* env var; everything else lives in the file so it can be edited/mounted without touching Docker env blocks. + +```yaml +server: + port: 8080 + +wedding: + date: "2026-11-07T16:00:00+02:00" # RFC3339, guest arrival time; drives countdown + upload gate + ceremony_time: "16:00 for 16:30" # display text + rsvp_by: "2026-09-01T00:00:00+02:00" # RFC3339, RSVP deadline; drives the RSVP countdown + venue_name: "Rivier Plaas" + venue_address: "Langenhoven Rd, Sherman Park AH, Meyerton, 1961" + rsvp_phone: "076 925 1718" + +storage: + data_dir: "./data" # SQLite db + uploaded photos + +email: + smtp_host: "" + smtp_port: 587 + smtp_user: "" + smtp_pass: "" + from: "" + to: "" # couple's inbox + +upload: + max_size_mb: 15 + max_files: 10 +``` +`config.example.yaml` is checked in as a template; `config.yaml` is gitignored (holds real SMTP credentials). Venue/RSVP details sourced from `concept/IMG-20260811-WA0020.jpg` (the formal invitation). + +## Deployment +Host: **`zoeshaldon.warky.info`**, Docker Compose, behind an **existing Apache reverse proxy on the host** (Apache owns TLS/certs — no Caddy/in-container TLS needed). The container publishes only to `127.0.0.1:8080`, and Apache proxies to it. + +### Docker +- `Dockerfile`: multi-stage — (1) `node:alpine` builds the SvelteKit static output, (2) `golang:alpine` compiles the Go binary with the built frontend copied in for `go:embed`, (3) minimal `alpine` runtime stage with just the binary. +- `docker-compose.yml`: one service, `wedding`, builds from the Dockerfile, mounts `./config.yaml:/app/config.yaml:ro` and `./data:/app/data`, published as `127.0.0.1:8080:8080` (loopback only — Apache is the only thing that should reach it). + +### Apache config (host side, not part of this repo) +``` + + ServerName zoeshaldon.warky.info + + ProxyPreserveHost On + ProxyPass / http://127.0.0.1:8080/ + ProxyPassReverse / http://127.0.0.1:8080/ + + # existing SSL cert config for warky.info + +``` +Needs `mod_proxy` and `mod_proxy_http` enabled. Multipart photo uploads: raise `LimitRequestBody` (or leave unset/0) on this vhost so Apache doesn't reject large uploads ahead of the app's own `upload.max_size_mb` check. + +## QR code +Generate pointing at `https://zoeshaldon.warky.info` once the container is deployed behind Apache. + +## Colour palette +Skeleton custom theme (`wedding-theme`), generated with the [Skeleton theme generator](https://skeleton.dev/docs/design/themes) from two seed colours and applied via `data-theme="wedding-theme"` in `app.html`. Light/dark mode is Skeleton's built-in mode switch (`data-mode`) — it derives both from the same theme, so there's no separate light/dark table to hand-maintain. + +| Slot | Seed colour | Source | +|---|---|---| +| `primary` (blue) | `#1E4E79` | groom's shirt / dusk sky in `concept/IMG-20260811-WA0019.jpg` | +| `secondary` (yellow) | `#D9A441` | warm gold title text in the same image | + +Skeleton generates the full 50–900 scale and light/dark contrast pairs from these two seeds. Tailwind utility classes (`bg-primary-500`, `text-secondary-600`, etc.) and Skeleton components consume the theme directly — no custom CSS variables needed on top. + +## Design — invitation framing +Landing and RSVP pages borrow the framed-card look from the formal invitation (`concept/IMG-20260811-WA0020.jpg`): a thin border around the core content block, small-caps tracked micro-copy above the couple's names ("Save the date" / "Please join us to celebrate the union of"), day+date formatted as "Saturday, 7 November 2026" (`Intl.DateTimeFormat('en-GB', {weekday:'long', day:'numeric', month:'long', year:'numeric'})`), and the venue name/address displayed beneath. + +## Open decisions (need input before/at implementation) +1. ~~Domain / hosting target~~ — resolved: `zoeshaldon.warky.info`, Docker Compose (see Deployment). +2. SMTP provider/credentials to send from (e.g. existing Gmail/SES/other). +3. Timezone for the 7 Nov 2026 cutoff — assumed SAST (+02:00). +4. Max photo size / count per submission — defaults proposed above, confirm. +5. ~~Colour palette~~ — resolved, see above. Fonts still open (image uses a script face for names/heading + serif for the date — confirm if we should source similar web fonts). + +## Prototype status +Working end-to-end: `ui/` (landing with countdown + sliding photo background, invitation-framed RSVP form with party-of-guests entry + its own countdown, gated photo upload form) builds and is served by `server/` (Go, SQLite via `modernc.org/sqlite`, SMTP notifications, server-side upload gate). Verified locally: page rendering, multi-guest RSVP submit (add/remove guest rows, blank-name filtering), photo upload with content-type sniffing (rejects non-images, detects HEIC), and both the wedding-date and RSVP-deadline gates/countdowns. + +Known gaps before this is real: +- SMTP not configured (open decision #2) — emails currently log "skipped" instead of sending. +- Photos in `ui/assets/photos` are unoptimized (several multi-MB originals) — fine for the background slideshow (one loads at a time), but worth compressing before going live given the site is reached over mobile data via QR code. +- No automated tests yet. +- `Dockerfile`/`docker-compose.yml` not yet run end-to-end (only `go build`/`npm run build` and the local binary were verified). diff --git a/README.md b/README.md new file mode 100644 index 0000000..5626f4e --- /dev/null +++ b/README.md @@ -0,0 +1,52 @@ +# Zoé & Shaldon — Wedding Site + +Save-the-date / RSVP / guest photo-upload site. Wedding: **7 November 2026**. Accessed via QR code from the printed save-the-date. Hosted at `https://zoeshaldon.warky.info`. + +See [PLAN.md](PLAN.md) for full design. + +## Stack +- `ui/` — SvelteKit (static adapter), Tailwind + Skeleton theming +- `server/` — Go, single binary, embeds the built frontend +- `data/` — runtime SQLite DB + guest-uploaded photos (gitignored, not yet created) + +## Status +Working prototype. `ui/` builds and `server/` serves it + the API, verified locally (RSVP, gated photo upload, countdown). Not yet run via Docker end-to-end; SMTP not yet configured. See PLAN.md "Prototype status" for the current gap list. + +## Develop locally +``` +cd ui && npm install && npm run build # outputs ui/build +rm -rf server/web/dist && cp -r ui/build server/web/dist +cd ../server && go build -o wedding-server . +cp ../config.example.yaml ../config.yaml # edit the wedding date/SMTP/etc. +CONFIG_PATH=../config.yaml ./wedding-server # serves on :8080 +``` + +## Requirements +- Countdown to the wedding date, with day/date/time and venue, on the landing page. +- Landing page background: photos from `ui/assets/photos` slide in/out continuously behind the hero content. +- RSVP form: one or more guest names (add/remove rows, at least one required), message (optional) — no email/phone captured → saved + emailed to couple. Shows the RSVP deadline and its own countdown. +- Photo upload: name (required), message (optional), email/phone (optional) + photo files → saved to `data/photos/`, links emailed to couple. +- Photo upload only opens **7 November 2026** (same date drives the countdown) — enforced server-side, not just hidden in the UI. +- Venue, RSVP deadline, and RSVP phone number sourced from the formal invitation (`concept/IMG-20260811-WA0020.jpg`). + +## Repo layout +``` +ui/ SvelteKit frontend (assets/photos/ = curated background photos, checked in) +server/ Go backend (API + static file serving) +data/ runtime data (gitignored) +concept/ source assets (save-the-date image) +config.example.yaml config template (checked in) +config.yaml real config: date, SMTP, storage path (gitignored) +Dockerfile multi-stage: build ui -> build server -> runtime image +docker-compose.yml wedding app, published to 127.0.0.1:8080 only +``` + +## Config +Copy `config.example.yaml` to `config.yaml` and fill in the wedding date, SMTP settings, and storage path. Path is resolved from `CONFIG_PATH` (default `./config.yaml`) — that's the only env var; everything else lives in the file. + +## Run with Docker +Runs behind an existing Apache reverse proxy on the host (Apache owns TLS for `zoeshaldon.warky.info`) — see `PLAN.md` for the Apache vhost config. Not yet verified end-to-end. +``` +cp config.example.yaml config.yaml # edit it first +docker compose up --build +``` diff --git a/concept/IMG-20260811-WA0019.jpg b/concept/IMG-20260811-WA0019.jpg new file mode 100644 index 0000000..a6ff6e1 --- /dev/null +++ b/concept/IMG-20260811-WA0019.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6ac3d80992fd04149bd286170689f80c746fb859c89a0eb96893056112b13e06 +size 91707 diff --git a/concept/IMG-20260811-WA0020.jpg b/concept/IMG-20260811-WA0020.jpg new file mode 100644 index 0000000..4418335 --- /dev/null +++ b/concept/IMG-20260811-WA0020.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2138156184524ca1f7b15c107cb849adaf470c3d992a8ba36e1cf1808e575a51 +size 31925 diff --git a/config.example.yaml b/config.example.yaml new file mode 100644 index 0000000..a34350a --- /dev/null +++ b/config.example.yaml @@ -0,0 +1,28 @@ +server: + port: 8080 + +site: + url: "https://zoeshaldon.warky.info" # canonical URL, used for the /qr page + +wedding: + date: "2026-11-07T16:00:00+02:00" # RFC3339, guest arrival time; drives countdown + photo upload gate + ceremony_time: "16:00 for 16:30" # display text + rsvp_by: "2026-09-01T00:00:00+02:00" # RFC3339, RSVP deadline; drives the RSVP countdown + venue_name: "Rivier Plaas" + venue_address: "Langenhoven Rd, Sherman Park AH, Meyerton, 1961" + rsvp_phone: "076 925 1718" + +storage: + data_dir: "./data" # SQLite db + uploaded photos + +email: + smtp_host: "" + smtp_port: 587 + smtp_user: "" + smtp_pass: "" + from: "" + to: "" # couple's inbox, receives RSVP + photo notifications + +upload: + max_size_mb: 15 + max_files: 10 diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..60beb53 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,11 @@ +services: + wedding: + build: . + ports: + - "127.0.0.1:8080:8080" + environment: + - CONFIG_PATH=/app/config.yaml + volumes: + - ./config.yaml:/app/config.yaml:ro + - ./data:/app/data + restart: unless-stopped diff --git a/server/go.mod b/server/go.mod new file mode 100644 index 0000000..5ff3e46 --- /dev/null +++ b/server/go.mod @@ -0,0 +1,17 @@ +module wedding-server + +go 1.26.5 + +require ( + github.com/dustin/go-humanize v1.0.1 // indirect + github.com/google/uuid v1.6.0 // indirect + github.com/mattn/go-isatty v0.0.24 // indirect + github.com/ncruces/go-strftime v1.0.0 // indirect + github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect + golang.org/x/sys v0.47.0 // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect + modernc.org/libc v1.74.4 // indirect + modernc.org/mathutil v1.7.1 // indirect + modernc.org/memory v1.11.0 // indirect + modernc.org/sqlite v1.56.0 // indirect +) diff --git a/server/go.sum b/server/go.sum new file mode 100644 index 0000000..001de2a --- /dev/null +++ b/server/go.sum @@ -0,0 +1,23 @@ +github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY= +github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto= +github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= +github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/mattn/go-isatty v0.0.24 h1:tGZZoVgT/KiqK1c8ocVLeDS8BSWMRd47J3Lbz7vsReI= +github.com/mattn/go-isatty v0.0.24/go.mod h1:nMCL3Zebbrt45jsMDgnfIwz6ydEQApk5oEI3HqDio6A= +github.com/ncruces/go-strftime v1.0.0 h1:HMFp8mLCTPp341M/ZnA4qaf7ZlsbTc+miZjCLOFAw7w= +github.com/ncruces/go-strftime v1.0.0/go.mod h1:Fwc5htZGVVkseilnfgOVb9mKy6w1naJmn9CehxcKcls= +github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec h1:W09IVJc94icq4NjY3clb7Lk8O1qJ8BdBEF8z0ibU0rE= +github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo= +golang.org/x/sys v0.47.0 h1:o7XGOvZQCADBQQ4Y7VNq2dRWQR7JmOUW8Kxx4ZsNgWs= +golang.org/x/sys v0.47.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +modernc.org/libc v1.74.4 h1:fX1Omw4o2/1C2iRkkIsrQTasJQldLhRmuPreXLoWs9k= +modernc.org/libc v1.74.4/go.mod h1:eeQAS9W3sZeKYMFubydxJpII9ybHWshk+7or7bLG9co= +modernc.org/mathutil v1.7.1 h1:GCZVGXdaN8gTqB1Mf/usp1Y/hSqgI2vAGGP4jZMCxOU= +modernc.org/mathutil v1.7.1/go.mod h1:4p5IwJITfppl0G4sUEDtCr4DthTaT47/N3aT6MhfgJg= +modernc.org/memory v1.11.0 h1:o4QC8aMQzmcwCK3t3Ux/ZHmwFPzE6hf2Y5LbkRs+hbI= +modernc.org/memory v1.11.0/go.mod h1:/JP4VbVC+K5sU2wZi9bHoq2MAkCnrt2r98UGeSK7Mjw= +modernc.org/sqlite v1.56.0 h1:/D8e2RfFqoy/Zc6PuC76U28zFwmI/sYx1Kjm4yEn9e0= +modernc.org/sqlite v1.56.0/go.mod h1:yCJ2cmAaIkHQ25oXWrF8H4O1lIfPYPR26yCEDj2P3pQ= diff --git a/server/internal/api/handlers.go b/server/internal/api/handlers.go new file mode 100644 index 0000000..87ccf25 --- /dev/null +++ b/server/internal/api/handlers.go @@ -0,0 +1,267 @@ +package api + +import ( + "crypto/rand" + "encoding/hex" + "encoding/json" + "fmt" + "io" + "log" + "net/http" + "os" + "path/filepath" + "strconv" + "strings" + "time" + + "wedding-server/internal/config" + "wedding-server/internal/mail" + "wedding-server/internal/store" +) + +type Server struct { + cfg *config.Config + store *store.Store + mailer *mail.Mailer +} + +func New(cfg *config.Config, st *store.Store, mailer *mail.Mailer) *Server { + return &Server{cfg: cfg, store: st, mailer: mailer} +} + +func (s *Server) Routes(mux *http.ServeMux) { + mux.HandleFunc("GET /healthz", s.handleHealthz) + mux.HandleFunc("GET /api/config", s.handleConfig) + mux.HandleFunc("POST /api/rsvp", s.handleRSVP) + mux.HandleFunc("POST /api/photos/upload", s.handlePhotoUpload) +} + +func writeJSON(w http.ResponseWriter, status int, v any) { + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(status) + _ = json.NewEncoder(w).Encode(v) +} + +func writeError(w http.ResponseWriter, status int, message string) { + writeJSON(w, status, map[string]string{"error": message}) +} + +func (s *Server) handleHealthz(w http.ResponseWriter, r *http.Request) { + w.WriteHeader(http.StatusOK) +} + +func (s *Server) handleConfig(w http.ResponseWriter, r *http.Request) { + writeJSON(w, http.StatusOK, map[string]string{ + "siteUrl": s.cfg.Site.URL, + "weddingDate": s.cfg.Wedding.Date.Format(time.RFC3339), + "ceremonyTime": s.cfg.Wedding.CeremonyTime, + "rsvpByDate": s.cfg.Wedding.RSVPBy.Format(time.RFC3339), + "venueName": s.cfg.Wedding.VenueName, + "venueAddress": s.cfg.Wedding.VenueAddress, + "rsvpPhone": s.cfg.Wedding.RSVPPhone, + }) +} + +type guestRequest struct { + Name string `json:"name"` + Type string `json:"type"` +} + +type rsvpRequest struct { + Guests []guestRequest `json:"guests"` + Message string `json:"message"` +} + +func (s *Server) handleRSVP(w http.ResponseWriter, r *http.Request) { + var req rsvpRequest + if err := json.NewDecoder(io.LimitReader(r.Body, 1<<20)).Decode(&req); err != nil { + writeError(w, http.StatusBadRequest, "invalid request body") + return + } + + var guests []store.Guest + for _, g := range req.Guests { + name := strings.TrimSpace(g.Name) + if name != "" { + guests = append(guests, store.Guest{Name: name, IsChild: g.Type == "child"}) + } + } + if len(guests) == 0 { + writeError(w, http.StatusBadRequest, "at least one name is required") + return + } + + rsvp := store.RSVP{ + Guests: guests, + Message: strings.TrimSpace(req.Message), + } + if err := s.store.InsertRSVP(rsvp); err != nil { + log.Printf("rsvp: insert failed: %v", err) + writeError(w, http.StatusInternalServerError, "could not save RSVP") + return + } + + if err := s.mailer.SendRSVP(rsvp); err != nil { + log.Printf("rsvp: email failed: %v", err) + } + + writeJSON(w, http.StatusCreated, map[string]bool{"ok": true}) +} + +var allowedImageTypes = map[string]bool{ + "image/jpeg": true, + "image/png": true, + "image/webp": true, + "image/heic": true, + "image/heif": true, +} + +func (s *Server) handlePhotoUpload(w http.ResponseWriter, r *http.Request) { + if time.Now().Before(s.cfg.Wedding.Date) { + writeError(w, http.StatusForbidden, "photo uploads open on the wedding day") + return + } + + maxTotalBytes := int64(s.cfg.Upload.MaxSizeMB) * int64(s.cfg.Upload.MaxFiles) * 1024 * 1024 + r.Body = http.MaxBytesReader(w, r.Body, maxTotalBytes+1<<20) + + if err := r.ParseMultipartForm(10 << 20); err != nil { + writeError(w, http.StatusBadRequest, "invalid upload (too large or malformed)") + return + } + defer r.MultipartForm.RemoveAll() + + name := strings.TrimSpace(r.FormValue("name")) + if name == "" { + writeError(w, http.StatusBadRequest, "name is required") + return + } + message := strings.TrimSpace(r.FormValue("message")) + email := strings.TrimSpace(r.FormValue("email")) + phone := strings.TrimSpace(r.FormValue("phone")) + + headers := r.MultipartForm.File["files"] + if len(headers) == 0 { + writeError(w, http.StatusBadRequest, "at least one photo is required") + return + } + if len(headers) > s.cfg.Upload.MaxFiles { + writeError(w, http.StatusBadRequest, fmt.Sprintf("at most %d photos per submission", s.cfg.Upload.MaxFiles)) + return + } + + maxFileBytes := int64(s.cfg.Upload.MaxSizeMB) * 1024 * 1024 + for _, fh := range headers { + if fh.Size > maxFileBytes { + writeError(w, http.StatusBadRequest, fmt.Sprintf("%q is larger than %dMB", fh.Filename, s.cfg.Upload.MaxSizeMB)) + return + } + } + + // Sniff and validate every file's actual content before creating any + // database row or directory, so a rejected upload leaves no trace. + for _, fh := range headers { + file, err := fh.Open() + if err != nil { + writeError(w, http.StatusBadRequest, "could not read uploaded file") + return + } + sniff := make([]byte, 512) + n, _ := io.ReadFull(file, sniff) + file.Close() + sniff = sniff[:n] + + contentType := http.DetectContentType(sniff) + if contentType == "application/octet-stream" && isHEIC(sniff) { + // net/http's sniffer table has no ISOBMFF/HEIC signature. + contentType = "image/heic" + } + if !allowedImageTypes[contentType] { + writeError(w, http.StatusBadRequest, fmt.Sprintf("%q is not a supported image type", fh.Filename)) + return + } + } + + uploadID, err := s.store.CreatePhotoUpload(store.PhotoUpload{ + Name: name, Message: message, Email: email, Phone: phone, + }) + if err != nil { + log.Printf("photos: create upload failed: %v", err) + writeError(w, http.StatusInternalServerError, "could not save upload") + return + } + + uploadDir := filepath.Join(s.cfg.Storage.DataDir, "photos", strconv.FormatInt(uploadID, 10)) + if err := os.MkdirAll(uploadDir, 0o755); err != nil { + log.Printf("photos: mkdir failed: %v", err) + writeError(w, http.StatusInternalServerError, "could not save upload") + return + } + + var saved []store.PhotoFile + for _, fh := range headers { + file, err := fh.Open() + if err != nil { + writeError(w, http.StatusBadRequest, "could not read uploaded file") + return + } + + storedName := randomHex(8) + "_" + filepath.Base(fh.Filename) + destPath := filepath.Join(uploadDir, storedName) + dest, err := os.OpenFile(destPath, os.O_CREATE|os.O_WRONLY|os.O_TRUNC, 0o644) + if err != nil { + file.Close() + log.Printf("photos: create file failed: %v", err) + writeError(w, http.StatusInternalServerError, "could not save upload") + return + } + + _, err = io.Copy(dest, file) + dest.Close() + file.Close() + if err != nil { + log.Printf("photos: write file failed: %v", err) + writeError(w, http.StatusInternalServerError, "could not save upload") + return + } + + saved = append(saved, store.PhotoFile{ + Filename: fh.Filename, + Path: destPath, + URL: fmt.Sprintf("/uploads/%d/%s", uploadID, storedName), + }) + } + + if err := s.store.AddPhotoFiles(uploadID, saved); err != nil { + log.Printf("photos: add files failed: %v", err) + writeError(w, http.StatusInternalServerError, "could not save upload") + return + } + + upload := store.PhotoUpload{Name: name, Message: message, Email: email, Phone: phone} + if err := s.mailer.SendPhotoUpload(upload, saved); err != nil { + log.Printf("photos: email failed: %v", err) + } + + writeJSON(w, http.StatusCreated, map[string]bool{"ok": true}) +} + +// isHEIC checks for the ISOBMFF "ftyp" box and a HEIC/HEIF brand, since +// net/http.DetectContentType does not recognize this container format. +func isHEIC(b []byte) bool { + if len(b) < 12 || string(b[4:8]) != "ftyp" { + return false + } + switch string(b[8:12]) { + case "heic", "heix", "hevc", "hevx", "heim", "heis", "hevm", "hevs", "mif1", "msf1": + return true + default: + return false + } +} + +func randomHex(n int) string { + b := make([]byte, n) + _, _ = rand.Read(b) + return hex.EncodeToString(b) +} diff --git a/server/internal/config/config.go b/server/internal/config/config.go new file mode 100644 index 0000000..149f347 --- /dev/null +++ b/server/internal/config/config.go @@ -0,0 +1,94 @@ +package config + +import ( + "fmt" + "os" + "time" + + "gopkg.in/yaml.v3" +) + +type Config struct { + Server ServerConfig `yaml:"server"` + Site SiteConfig `yaml:"site"` + Wedding WeddingConfig `yaml:"wedding"` + Storage StorageConfig `yaml:"storage"` + Email EmailConfig `yaml:"email"` + Upload UploadConfig `yaml:"upload"` +} + +type ServerConfig struct { + Port int `yaml:"port"` +} + +type SiteConfig struct { + URL string `yaml:"url"` +} + +type WeddingConfig struct { + Date time.Time `yaml:"date"` + CeremonyTime string `yaml:"ceremony_time"` + RSVPBy time.Time `yaml:"rsvp_by"` + VenueName string `yaml:"venue_name"` + VenueAddress string `yaml:"venue_address"` + RSVPPhone string `yaml:"rsvp_phone"` +} + +type StorageConfig struct { + DataDir string `yaml:"data_dir"` +} + +type EmailConfig struct { + SMTPHost string `yaml:"smtp_host"` + SMTPPort int `yaml:"smtp_port"` + SMTPUser string `yaml:"smtp_user"` + SMTPPass string `yaml:"smtp_pass"` + From string `yaml:"from"` + To string `yaml:"to"` +} + +type UploadConfig struct { + MaxSizeMB int `yaml:"max_size_mb"` + MaxFiles int `yaml:"max_files"` +} + +// Path resolves the config file location: $CONFIG_PATH, or ./config.yaml. +func Path() string { + if p := os.Getenv("CONFIG_PATH"); p != "" { + return p + } + return "config.yaml" +} + +func Load(path string) (*Config, error) { + data, err := os.ReadFile(path) + if err != nil { + return nil, fmt.Errorf("reading config %s: %w", path, err) + } + + var cfg Config + if err := yaml.Unmarshal(data, &cfg); err != nil { + return nil, fmt.Errorf("parsing config %s: %w", path, err) + } + + if cfg.Server.Port == 0 { + cfg.Server.Port = 8080 + } + if cfg.Storage.DataDir == "" { + cfg.Storage.DataDir = "./data" + } + if cfg.Upload.MaxSizeMB == 0 { + cfg.Upload.MaxSizeMB = 15 + } + if cfg.Upload.MaxFiles == 0 { + cfg.Upload.MaxFiles = 10 + } + if cfg.Wedding.Date.IsZero() { + return nil, fmt.Errorf("wedding.date is required in %s", path) + } + if cfg.Wedding.RSVPBy.IsZero() { + return nil, fmt.Errorf("wedding.rsvp_by is required in %s", path) + } + + return &cfg, nil +} diff --git a/server/internal/mail/mail.go b/server/internal/mail/mail.go new file mode 100644 index 0000000..7a2d1e7 --- /dev/null +++ b/server/internal/mail/mail.go @@ -0,0 +1,77 @@ +package mail + +import ( + "fmt" + "log" + "net/smtp" + "strings" + + "wedding-server/internal/config" + "wedding-server/internal/store" +) + +type Mailer struct { + cfg config.EmailConfig +} + +func New(cfg config.EmailConfig) *Mailer { + return &Mailer{cfg: cfg} +} + +func (m *Mailer) send(subject, body string) error { + if m.cfg.SMTPHost == "" { + log.Printf("mail: SMTP not configured, skipping email %q", subject) + return nil + } + + addr := fmt.Sprintf("%s:%d", m.cfg.SMTPHost, m.cfg.SMTPPort) + auth := smtp.PlainAuth("", m.cfg.SMTPUser, m.cfg.SMTPPass, m.cfg.SMTPHost) + + msg := fmt.Sprintf( + "From: %s\r\nTo: %s\r\nSubject: %s\r\nContent-Type: text/plain; charset=UTF-8\r\n\r\n%s", + m.cfg.From, m.cfg.To, subject, body, + ) + + return smtp.SendMail(addr, auth, m.cfg.From, []string{m.cfg.To}, []byte(msg)) +} + +func (m *Mailer) SendRSVP(r store.RSVP) error { + names := make([]string, len(r.Guests)) + adults, children := 0, 0 + for i, g := range r.Guests { + if g.IsChild { + names[i] = g.Name + " (child)" + children++ + } else { + names[i] = g.Name + adults++ + } + } + joined := strings.Join(names, ", ") + + var b strings.Builder + fmt.Fprintf(&b, "New RSVP for %d guest(s) — %d adult(s), %d child(ren): %s\n", len(r.Guests), adults, children, joined) + if r.Message != "" { + fmt.Fprintf(&b, "\nMessage:\n%s\n", r.Message) + } + return m.send(fmt.Sprintf("RSVP from %s", joined), b.String()) +} + +func (m *Mailer) SendPhotoUpload(u store.PhotoUpload, files []store.PhotoFile) error { + var b strings.Builder + fmt.Fprintf(&b, "%s uploaded %d photo(s)\n\n", u.Name, len(files)) + if u.Email != "" { + fmt.Fprintf(&b, "Email: %s\n", u.Email) + } + if u.Phone != "" { + fmt.Fprintf(&b, "Phone: %s\n", u.Phone) + } + if u.Message != "" { + fmt.Fprintf(&b, "\nMessage:\n%s\n", u.Message) + } + b.WriteString("\nPhotos:\n") + for _, f := range files { + fmt.Fprintf(&b, "- %s\n", f.URL) + } + return m.send(fmt.Sprintf("%s uploaded photos", u.Name), b.String()) +} diff --git a/server/internal/store/store.go b/server/internal/store/store.go new file mode 100644 index 0000000..80900fd --- /dev/null +++ b/server/internal/store/store.go @@ -0,0 +1,155 @@ +package store + +import ( + "database/sql" + "fmt" + "path/filepath" + "time" + + _ "modernc.org/sqlite" +) + +type Store struct { + db *sql.DB +} + +const schema = ` +CREATE TABLE IF NOT EXISTS rsvps ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + message TEXT, + created_at DATETIME NOT NULL +); + +CREATE TABLE IF NOT EXISTS rsvp_guests ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + rsvp_id INTEGER NOT NULL REFERENCES rsvps(id), + name TEXT NOT NULL, + is_child INTEGER NOT NULL DEFAULT 0 +); + +CREATE TABLE IF NOT EXISTS photo_uploads ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + name TEXT NOT NULL, + message TEXT, + email TEXT, + phone TEXT, + created_at DATETIME NOT NULL +); + +CREATE TABLE IF NOT EXISTS photo_files ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + upload_id INTEGER NOT NULL REFERENCES photo_uploads(id), + filename TEXT NOT NULL, + path TEXT NOT NULL, + url TEXT NOT NULL, + created_at DATETIME NOT NULL +); +` + +func Open(dataDir string) (*Store, error) { + dbPath := filepath.Join(dataDir, "rsvp.db") + db, err := sql.Open("sqlite", dbPath) + if err != nil { + return nil, fmt.Errorf("opening database: %w", err) + } + // SQLite only supports one writer at a time; a single connection avoids + // SQLITE_BUSY errors under concurrent requests instead of retry logic. + db.SetMaxOpenConns(1) + + if _, err := db.Exec(schema); err != nil { + db.Close() + return nil, fmt.Errorf("migrating schema: %w", err) + } + + return &Store{db: db}, nil +} + +func (s *Store) Close() error { + return s.db.Close() +} + +type Guest struct { + Name string + IsChild bool +} + +type RSVP struct { + Guests []Guest + Message string +} + +func (s *Store) InsertRSVP(r RSVP) error { + tx, err := s.db.Begin() + if err != nil { + return err + } + defer tx.Rollback() + + res, err := tx.Exec( + `INSERT INTO rsvps (message, created_at) VALUES (?, ?)`, + r.Message, time.Now().UTC(), + ) + if err != nil { + return err + } + rsvpID, err := res.LastInsertId() + if err != nil { + return err + } + + for _, guest := range r.Guests { + if _, err := tx.Exec( + `INSERT INTO rsvp_guests (rsvp_id, name, is_child) VALUES (?, ?, ?)`, + rsvpID, guest.Name, guest.IsChild, + ); err != nil { + return err + } + } + + return tx.Commit() +} + +type PhotoFile struct { + Filename string + Path string + URL string +} + +type PhotoUpload struct { + Name string + Message string + Email string + Phone string +} + +// CreatePhotoUpload inserts the upload record and returns its id, which the +// caller uses as the on-disk directory name before attaching files. +func (s *Store) CreatePhotoUpload(u PhotoUpload) (int64, error) { + res, err := s.db.Exec( + `INSERT INTO photo_uploads (name, message, email, phone, created_at) VALUES (?, ?, ?, ?, ?)`, + u.Name, u.Message, u.Email, u.Phone, time.Now().UTC(), + ) + if err != nil { + return 0, err + } + return res.LastInsertId() +} + +func (s *Store) AddPhotoFiles(uploadID int64, files []PhotoFile) error { + tx, err := s.db.Begin() + if err != nil { + return err + } + defer tx.Rollback() + + now := time.Now().UTC() + for _, f := range files { + if _, err := tx.Exec( + `INSERT INTO photo_files (upload_id, filename, path, url, created_at) VALUES (?, ?, ?, ?, ?)`, + uploadID, f.Filename, f.Path, f.URL, now, + ); err != nil { + return err + } + } + return tx.Commit() +} diff --git a/server/main.go b/server/main.go new file mode 100644 index 0000000..ba8a072 --- /dev/null +++ b/server/main.go @@ -0,0 +1,79 @@ +package main + +import ( + "embed" + "fmt" + "io/fs" + "log" + "net/http" + "os" + "path/filepath" + "strings" + + "wedding-server/internal/api" + "wedding-server/internal/config" + "wedding-server/internal/mail" + "wedding-server/internal/store" +) + +//go:embed web/dist +var embeddedWeb embed.FS + +func main() { + cfgPath := config.Path() + cfg, err := config.Load(cfgPath) + if err != nil { + log.Fatalf("config: %v", err) + } + + if err := os.MkdirAll(cfg.Storage.DataDir, 0o755); err != nil { + log.Fatalf("data dir: %v", err) + } + + st, err := store.Open(cfg.Storage.DataDir) + if err != nil { + log.Fatalf("store: %v", err) + } + defer st.Close() + + mailer := mail.New(cfg.Email) + + mux := http.NewServeMux() + api.New(cfg, st, mailer).Routes(mux) + + uploadsDir := filepath.Join(cfg.Storage.DataDir, "photos") + mux.Handle("/uploads/", http.StripPrefix("/uploads/", http.FileServer(http.Dir(uploadsDir)))) + + webFS, err := fs.Sub(embeddedWeb, "web/dist") + if err != nil { + log.Fatalf("embedded web assets: %v", err) + } + mux.Handle("/", staticHandler(webFS)) + + addr := fmt.Sprintf(":%d", cfg.Server.Port) + log.Printf("listening on %s", addr) + if err := http.ListenAndServe(addr, mux); err != nil { + log.Fatal(err) + } +} + +// staticHandler serves the prerendered SvelteKit build, where routes are +// written as flat files (e.g. "rsvp.html") rather than "rsvp/index.html". +func staticHandler(fsys fs.FS) http.Handler { + fileServer := http.FileServer(http.FS(fsys)) + return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + p := strings.TrimPrefix(r.URL.Path, "/") + if p == "" { + p = "index.html" + } + if _, err := fs.Stat(fsys, p); err != nil { + if _, err := fs.Stat(fsys, p+".html"); err == nil { + r2 := *r + r2.URL.Path = "/" + p + ".html" + fileServer.ServeHTTP(w, &r2) + return + } + } + fileServer.ServeHTTP(w, r) + }) +} diff --git a/server/web/dist/index.html b/server/web/dist/index.html new file mode 100644 index 0000000..14b1a81 --- /dev/null +++ b/server/web/dist/index.html @@ -0,0 +1 @@ + diff --git a/ui/.gitignore b/ui/.gitignore new file mode 100644 index 0000000..3b462cb --- /dev/null +++ b/ui/.gitignore @@ -0,0 +1,23 @@ +node_modules + +# Output +.output +.vercel +.netlify +.wrangler +/.svelte-kit +/build + +# OS +.DS_Store +Thumbs.db + +# Env +.env +.env.* +!.env.example +!.env.test + +# Vite +vite.config.js.timestamp-* +vite.config.ts.timestamp-* diff --git a/ui/.npmrc b/ui/.npmrc new file mode 100644 index 0000000..b6f27f1 --- /dev/null +++ b/ui/.npmrc @@ -0,0 +1 @@ +engine-strict=true diff --git a/ui/.vscode/extensions.json b/ui/.vscode/extensions.json new file mode 100644 index 0000000..5449017 --- /dev/null +++ b/ui/.vscode/extensions.json @@ -0,0 +1,6 @@ +{ + "recommendations": [ + "svelte.svelte-vscode", + "bradlc.vscode-tailwindcss" + ] +} diff --git a/ui/.vscode/settings.json b/ui/.vscode/settings.json new file mode 100644 index 0000000..bc31e15 --- /dev/null +++ b/ui/.vscode/settings.json @@ -0,0 +1,5 @@ +{ + "files.associations": { + "*.css": "tailwindcss" + } +} diff --git a/ui/README.md b/ui/README.md new file mode 100644 index 0000000..bab165a --- /dev/null +++ b/ui/README.md @@ -0,0 +1,42 @@ +# sv + +Everything you need to build a Svelte project, powered by [`sv`](https://github.com/sveltejs/cli). + +## Creating a project + +If you're seeing this, you've probably already done this step. Congrats! + +```sh +# create a new project +npx sv create my-app +``` + +To recreate this project with the same configuration: + +```sh +# recreate this project +npx sv@0.17.0 create --template minimal --types ts --add tailwindcss="plugins:none" sveltekit-adapter="adapter:static" --no-download-check --install npm ui +``` + +## Developing + +Once you've created a project and installed dependencies with `npm install` (or `pnpm install` or `yarn`), start a development server: + +```sh +npm run dev + +# or start the server and open the app in a new browser tab +npm run dev -- --open +``` + +## Building + +To create a production version of your app: + +```sh +npm run build +``` + +You can preview the production build with `npm run preview`. + +> To deploy your app, you may need to install an [adapter](https://svelte.dev/docs/kit/adapters) for your target environment. diff --git a/ui/assets/fonts/Bilbo-Regular.ttf b/ui/assets/fonts/Bilbo-Regular.ttf new file mode 100644 index 0000000..e08cb41 Binary files /dev/null and b/ui/assets/fonts/Bilbo-Regular.ttf differ diff --git a/ui/assets/fonts/Dairy Whitener.otf b/ui/assets/fonts/Dairy Whitener.otf new file mode 100644 index 0000000..b8888d4 Binary files /dev/null and b/ui/assets/fonts/Dairy Whitener.otf differ diff --git a/ui/assets/fonts/Dairy Whitener.ttf b/ui/assets/fonts/Dairy Whitener.ttf new file mode 100644 index 0000000..4243cd8 Binary files /dev/null and b/ui/assets/fonts/Dairy Whitener.ttf differ diff --git a/ui/assets/fonts/Darling.ttf b/ui/assets/fonts/Darling.ttf new file mode 100644 index 0000000..ff0aa30 Binary files /dev/null and b/ui/assets/fonts/Darling.ttf differ diff --git a/ui/assets/fonts/Malibu.otf b/ui/assets/fonts/Malibu.otf new file mode 100644 index 0000000..a05141f Binary files /dev/null and b/ui/assets/fonts/Malibu.otf differ diff --git a/ui/assets/fonts/Malibu.ttf b/ui/assets/fonts/Malibu.ttf new file mode 100644 index 0000000..0333b7b Binary files /dev/null and b/ui/assets/fonts/Malibu.ttf differ diff --git a/ui/assets/fonts/Malibu.woff b/ui/assets/fonts/Malibu.woff new file mode 100644 index 0000000..86946aa Binary files /dev/null and b/ui/assets/fonts/Malibu.woff differ diff --git a/ui/assets/fonts/White Lotus Regular.otf b/ui/assets/fonts/White Lotus Regular.otf new file mode 100644 index 0000000..3d2ae66 Binary files /dev/null and b/ui/assets/fonts/White Lotus Regular.otf differ diff --git a/ui/assets/photos/13.jpg b/ui/assets/photos/13.jpg new file mode 100644 index 0000000..9fcf77d --- /dev/null +++ b/ui/assets/photos/13.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e12042756e1f2aa7557df0fc576dff601010ce58bf040c1bd3e15a4695a91a28 +size 1053025 diff --git a/ui/assets/photos/15.jpg b/ui/assets/photos/15.jpg new file mode 100644 index 0000000..f589339 --- /dev/null +++ b/ui/assets/photos/15.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f816303bf16b53936133eaecab27876a85e37708ab231e2a527d36cb62cc9d80 +size 1723784 diff --git a/ui/assets/photos/4.jpg b/ui/assets/photos/4.jpg new file mode 100644 index 0000000..413f5a5 --- /dev/null +++ b/ui/assets/photos/4.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f6ab018d9d9274004e412178f87bd7d1033ff613999f4b78763ee691407e0751 +size 1600091 diff --git a/ui/assets/photos/Elite_Models_250.jpg b/ui/assets/photos/Elite_Models_250.jpg new file mode 100644 index 0000000..29faba5 --- /dev/null +++ b/ui/assets/photos/Elite_Models_250.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1d92cb570cb2f6d9fe8f20fb153d60bf0820bbac43e9e4cc02d68805b3ac36c1 +size 6458114 diff --git a/ui/assets/photos/Engagement 2023.jpg b/ui/assets/photos/Engagement 2023.jpg new file mode 100644 index 0000000..3b5cc14 --- /dev/null +++ b/ui/assets/photos/Engagement 2023.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0e2e5bdc2ed2e117fac9b3521b0bcca0e351743483cbc9328feb6623ab524ea6 +size 237931 diff --git a/ui/assets/photos/FB_IMG_1703527669142.jpg b/ui/assets/photos/FB_IMG_1703527669142.jpg new file mode 100644 index 0000000..deaf213 --- /dev/null +++ b/ui/assets/photos/FB_IMG_1703527669142.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f7d06e383c58dc68968e3d3986f42fe092fce0ee01bd135b69d7bb3373120d55 +size 83785 diff --git a/ui/assets/photos/FB_IMG_1743444484838.jpg b/ui/assets/photos/FB_IMG_1743444484838.jpg new file mode 100644 index 0000000..14d3d29 --- /dev/null +++ b/ui/assets/photos/FB_IMG_1743444484838.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:10a4f2d3fd82c745ce4020a50abb2ed0625b9f834dd8fadf8e9e98831fdb2416 +size 126050 diff --git a/ui/assets/photos/IFKB8122.JPG b/ui/assets/photos/IFKB8122.JPG new file mode 100644 index 0000000..bb0289a Binary files /dev/null and b/ui/assets/photos/IFKB8122.JPG differ diff --git a/ui/assets/photos/IMG-20201003-WA0004.jpg b/ui/assets/photos/IMG-20201003-WA0004.jpg new file mode 100644 index 0000000..2adcef2 --- /dev/null +++ b/ui/assets/photos/IMG-20201003-WA0004.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ddef6190a60b66e11c3ad92d2218f677a3ceec907275f914fa9827047eb1e1e0 +size 379240 diff --git a/ui/assets/photos/IMG-20211024-WA0017.jpg b/ui/assets/photos/IMG-20211024-WA0017.jpg new file mode 100644 index 0000000..af49bbd --- /dev/null +++ b/ui/assets/photos/IMG-20211024-WA0017.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:fb7c32ae215a6f52e62524f3bd129de5ed5781e251fc1e797d24f0da148920c5 +size 77973 diff --git a/ui/assets/photos/IMG-20220131-WA0069.jpg b/ui/assets/photos/IMG-20220131-WA0069.jpg new file mode 100644 index 0000000..a360299 --- /dev/null +++ b/ui/assets/photos/IMG-20220131-WA0069.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:fb4923bd091c6748d7a6be0a59bb4844b04329034324396e5e951c88a8ee6297 +size 266690 diff --git a/ui/assets/photos/IMG-20220316-WA0022.jpg b/ui/assets/photos/IMG-20220316-WA0022.jpg new file mode 100644 index 0000000..2887738 --- /dev/null +++ b/ui/assets/photos/IMG-20220316-WA0022.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f893b673590369400cc0d13ef92230bed2e1ba1c4ab118dafc526ed47a9b97fc +size 32082 diff --git a/ui/assets/photos/IMG-20231002-WA0001.jpg b/ui/assets/photos/IMG-20231002-WA0001.jpg new file mode 100644 index 0000000..6516038 --- /dev/null +++ b/ui/assets/photos/IMG-20231002-WA0001.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0b0555a562e4f4c0ab8ca3c3dbd92f31bc98b41b05814b8b72c297a20c738089 +size 277062 diff --git a/ui/assets/photos/IMG-20240418-WA0011.jpg b/ui/assets/photos/IMG-20240418-WA0011.jpg new file mode 100644 index 0000000..b1b3ba0 --- /dev/null +++ b/ui/assets/photos/IMG-20240418-WA0011.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d802b299e9d2781ecbe661956b9ed5be4ef4b61e5499f8a9f0a906a984c041c9 +size 401073 diff --git a/ui/assets/photos/IMG-20240418-WA0029.jpg b/ui/assets/photos/IMG-20240418-WA0029.jpg new file mode 100644 index 0000000..80caa99 --- /dev/null +++ b/ui/assets/photos/IMG-20240418-WA0029.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:afd07f54733f9184a525c7057b51ecdef4f17fcb78473d4e6dcaceab56cb0f24 +size 114151 diff --git a/ui/assets/photos/IMG-20240418-WA0035.jpg b/ui/assets/photos/IMG-20240418-WA0035.jpg new file mode 100644 index 0000000..1247ad4 --- /dev/null +++ b/ui/assets/photos/IMG-20240418-WA0035.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:52c5d6d0b2d8ee31199f889e5eefa20e87544b97e565836e2ceb58498c923574 +size 233075 diff --git a/ui/assets/photos/IMG-20240418-WA0050.jpg b/ui/assets/photos/IMG-20240418-WA0050.jpg new file mode 100644 index 0000000..b6d7f96 --- /dev/null +++ b/ui/assets/photos/IMG-20240418-WA0050.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5e814f543ca330605fad9c2588d513cf6d857c4296d134c63a267bbbda45eee6 +size 163322 diff --git a/ui/assets/photos/IMG-20240418-WA0059.jpg b/ui/assets/photos/IMG-20240418-WA0059.jpg new file mode 100644 index 0000000..c9f58bf --- /dev/null +++ b/ui/assets/photos/IMG-20240418-WA0059.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0ebe9eadb2f9601b18f24f6389e5d3f730be96769d1e993b3462b93e7c176418 +size 83669 diff --git a/ui/assets/photos/IMG-20240418-WA0062.jpg b/ui/assets/photos/IMG-20240418-WA0062.jpg new file mode 100644 index 0000000..f2f335b --- /dev/null +++ b/ui/assets/photos/IMG-20240418-WA0062.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:79940839932742ca50e1df21d53520bddf34f6984435c52bd35e2b20842cd85c +size 85408 diff --git a/ui/assets/photos/IMG-20240418-WA0066.jpg b/ui/assets/photos/IMG-20240418-WA0066.jpg new file mode 100644 index 0000000..edc4a91 --- /dev/null +++ b/ui/assets/photos/IMG-20240418-WA0066.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d188fc751fadf2ecc9615de2e39845d2881eff7c89f71612bdda906e762669f1 +size 83743 diff --git a/ui/assets/photos/IMG-20240418-WA0072.jpg b/ui/assets/photos/IMG-20240418-WA0072.jpg new file mode 100644 index 0000000..de9652c --- /dev/null +++ b/ui/assets/photos/IMG-20240418-WA0072.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a331ae3c4826109db4b662e983a68b815f47aaec5ed9598a7c7be8d3c69f035b +size 81896 diff --git a/ui/assets/photos/IMG-20240418-WA0080.jpg b/ui/assets/photos/IMG-20240418-WA0080.jpg new file mode 100644 index 0000000..10423dd --- /dev/null +++ b/ui/assets/photos/IMG-20240418-WA0080.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f75a587177b907366cf158f6a59e6dc62176c99e48f500093ba8b7c482f46f23 +size 92661 diff --git a/ui/assets/photos/IMG-20240418-WA0090.jpg b/ui/assets/photos/IMG-20240418-WA0090.jpg new file mode 100644 index 0000000..70f0825 --- /dev/null +++ b/ui/assets/photos/IMG-20240418-WA0090.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:66b877dc3beac2324e2daf6b038f5db2b04b2e85390f55082c725699c84a7e8a +size 98535 diff --git a/ui/assets/photos/IMG-20240418-WA0113.jpg b/ui/assets/photos/IMG-20240418-WA0113.jpg new file mode 100644 index 0000000..c79a72a --- /dev/null +++ b/ui/assets/photos/IMG-20240418-WA0113.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:037ada2e25d248f6bc808ca73fdd0ac14d70b62438b5308babb7d5fbd261137c +size 242389 diff --git a/ui/assets/photos/IMG-20240418-WA0116.jpg b/ui/assets/photos/IMG-20240418-WA0116.jpg new file mode 100644 index 0000000..3963b80 --- /dev/null +++ b/ui/assets/photos/IMG-20240418-WA0116.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4376bd6155dacaf39501b11506bfd47f34112fa845c77108b6204cd9b32275f4 +size 148449 diff --git a/ui/assets/photos/IMG-20240418-WA0120.jpg b/ui/assets/photos/IMG-20240418-WA0120.jpg new file mode 100644 index 0000000..ec7a3b3 --- /dev/null +++ b/ui/assets/photos/IMG-20240418-WA0120.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ef3c204d0075f168ff01fcfe419d735494b56b320cedbff0fce5192c008cefbd +size 199371 diff --git a/ui/assets/photos/IMG-20240418-WA0141.jpg b/ui/assets/photos/IMG-20240418-WA0141.jpg new file mode 100644 index 0000000..cdf597a --- /dev/null +++ b/ui/assets/photos/IMG-20240418-WA0141.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8807a89995c068a498182de6cde07cb211ae548b6f490feb78936a616e7a8319 +size 86393 diff --git a/ui/assets/photos/IMG-20240418-WA0144.jpg b/ui/assets/photos/IMG-20240418-WA0144.jpg new file mode 100644 index 0000000..c68c748 --- /dev/null +++ b/ui/assets/photos/IMG-20240418-WA0144.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:eaca107c2ff5193500529c751f87b0ee80bee9c7e435e67ed93eecdf78a228d3 +size 69894 diff --git a/ui/assets/photos/IMG-20240418-WA0165.jpg b/ui/assets/photos/IMG-20240418-WA0165.jpg new file mode 100644 index 0000000..c4cd2fb --- /dev/null +++ b/ui/assets/photos/IMG-20240418-WA0165.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e74411558585073e4505715b2d40429d6c6ad2e11b2bac2203d1484c77dcb900 +size 239618 diff --git a/ui/assets/photos/IMG20210903192403.jpg b/ui/assets/photos/IMG20210903192403.jpg new file mode 100644 index 0000000..e09e636 --- /dev/null +++ b/ui/assets/photos/IMG20210903192403.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ffbc2996dbbead05c316254fbcf1a99ef74a3c67828cf2aa10e1c437f065c1f8 +size 2291973 diff --git a/ui/assets/photos/IMG20220121181023.jpg b/ui/assets/photos/IMG20220121181023.jpg new file mode 100644 index 0000000..1f29b20 --- /dev/null +++ b/ui/assets/photos/IMG20220121181023.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:497512a07c4008f7091285057af2d019485720b659eebda055c1d41354ce43b4 +size 3454160 diff --git a/ui/assets/photos/IMG_0528.JPG b/ui/assets/photos/IMG_0528.JPG new file mode 100644 index 0000000..9bf5844 Binary files /dev/null and b/ui/assets/photos/IMG_0528.JPG differ diff --git a/ui/assets/photos/IMG_0563.JPG b/ui/assets/photos/IMG_0563.JPG new file mode 100644 index 0000000..2e380f9 Binary files /dev/null and b/ui/assets/photos/IMG_0563.JPG differ diff --git a/ui/assets/photos/imgfix.jpg b/ui/assets/photos/imgfix.jpg new file mode 100644 index 0000000..9655303 --- /dev/null +++ b/ui/assets/photos/imgfix.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a5e466fa3d47392f12e17197538c517d6a931ac1cc76f295d531c37fcc7c10de +size 5996532 diff --git a/ui/package-lock.json b/ui/package-lock.json new file mode 100644 index 0000000..a15fae8 --- /dev/null +++ b/ui/package-lock.json @@ -0,0 +1,2739 @@ +{ + "name": "ui", + "version": "0.0.1", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "ui", + "version": "0.0.1", + "devDependencies": { + "@skeletonlabs/skeleton": "^5.0.0", + "@skeletonlabs/skeleton-svelte": "^5.0.0", + "@sveltejs/adapter-static": "^3.0.10", + "@sveltejs/kit": "^2.63.0", + "@sveltejs/vite-plugin-svelte": "^7.1.2", + "@tailwindcss/vite": "^4.3.0", + "svelte": "^5.56.1", + "svelte-check": "^4.6.0", + "tailwindcss": "^4.3.0", + "typescript": "^6.0.3", + "vite": "^8.0.16" + } + }, + "node_modules/@floating-ui/core": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.8.0.tgz", + "integrity": "sha512-0CIZ5itps/8x7BG8dEIhs53BvCUH2PCoogtakwRTut+Arm58sJooJ0AuZhLw2HJYIR5cMLNPBSS728sPho2khQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@floating-ui/utils": "^0.2.12" + } + }, + "node_modules/@floating-ui/dom": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.8.0.tgz", + "integrity": "sha512-yXSrzeHZBTZadLOlfyhCkJHNeLJnHRnRInwdZ40L7ZiaAtrBwoYlsDrX3v5zB1Utk7CLfzcOVnVVWoXEky7Ceg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@floating-ui/core": "^1.8.0", + "@floating-ui/utils": "^0.2.12" + } + }, + "node_modules/@floating-ui/utils": { + "version": "0.2.12", + "resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.2.12.tgz", + "integrity": "sha512-HpCo8tmWzLVad5s2d19EhAz5zqrrQ6s69qd6moPMQvkOuSwDT1YgRfWSVuc4ennqrgv3OHppiOGMQ7oC13yIww==", + "dev": true, + "license": "MIT" + }, + "node_modules/@internationalized/date": { + "version": "3.12.2", + "resolved": "https://registry.npmjs.org/@internationalized/date/-/date-3.12.2.tgz", + "integrity": "sha512-FY1Y+H64NDs+HAF6omlnWxm3mEpfgaCSWtL5l551ZZfImA+kGjPFgrnJrGjH6lfmLL0g8Z/mBu1R3kufeCp6Jw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@swc/helpers": "^0.5.0" + } + }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.13", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz", + "integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.0", + "@jridgewell/trace-mapping": "^0.3.24" + } + }, + "node_modules/@jridgewell/remapping": { + "version": "2.3.5", + "resolved": "https://registry.npmjs.org/@jridgewell/remapping/-/remapping-2.3.5.tgz", + "integrity": "sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.24" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz", + "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==", + "dev": true, + "license": "MIT" + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.31", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz", + "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "node_modules/@oxc-project/types": { + "version": "0.143.0", + "resolved": "https://registry.npmjs.org/@oxc-project/types/-/types-0.143.0.tgz", + "integrity": "sha512-u6JZdLBTLotrNC9Vd6vPssINdzcCzleKAH6EJKImQb7GtYvX5keN2dxkoK44stCc4tffE6QQRtZTXVSzsLUlWA==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/Boshen" + } + }, + "node_modules/@polka/url": { + "version": "1.0.0-next.29", + "resolved": "https://registry.npmjs.org/@polka/url/-/url-1.0.0-next.29.tgz", + "integrity": "sha512-wwQAWhWSuHaag8c4q/KN/vCoeOJYshAIvMQwD4GpSb3OiZklFfvAgmj0VCBBImRpuF/aFgIRzllXlVX93Jevww==", + "dev": true, + "license": "MIT" + }, + "node_modules/@rolldown/binding-android-arm64": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/@rolldown/binding-android-arm64/-/binding-android-arm64-1.2.3.tgz", + "integrity": "sha512-zrJtHDcaZJ1Fp7xf4hNl+7seH9Cn/N5TwLYkhgXREtBwAd/jaqW3uqeHxpDugJLVICWg4eW44kOQEGJ1r6jCGw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-darwin-arm64": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-arm64/-/binding-darwin-arm64-1.2.3.tgz", + "integrity": "sha512-ieIiibVCp0tX7TLu2cafoNPv8wJyYi01ekXpbf8q2j7F4rGAhhXb/eQh7ge9DRBY78GwmRQtvjZDux7EDbA8kA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-darwin-x64": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-x64/-/binding-darwin-x64-1.2.3.tgz", + "integrity": "sha512-Zh9tCon19eDXJoihx0rqKhMUlMYqzwj3aPsSuHmI4RWZh62dWUL+DJN4C5YQya5TcQBJU/Fe8+rY0jhXTQITqA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-freebsd-x64": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/@rolldown/binding-freebsd-x64/-/binding-freebsd-x64-1.2.3.tgz", + "integrity": "sha512-nGbJWewA1wrXXZiQhjAT5rhibGfns5ZNkDVqxsO6zJ3f3YvpoDNNmGMSbbhLuXKjNScaBJVOAboztAWVespQMg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-arm-gnueabihf": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-1.2.3.tgz", + "integrity": "sha512-QNniJr5Kml0kDEB98jiDOJjXNroxIIi0IXIbdYzY26Xt1pVbeP62+KnoIZLwirOymX/0jDk/2gI/bNUv7A7OIw==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-arm64-gnu": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-1.2.3.tgz", + "integrity": "sha512-TkqEAcmmvH3I/q4114NB4RVt6241Dao48pF45uLcFGrwAaIn0iITgTAKP/dLjbN0R4buJjGb91+UHSoFmpgIWw==", + "cpu": [ + "arm64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-arm64-musl": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-musl/-/binding-linux-arm64-musl-1.2.3.tgz", + "integrity": "sha512-NHqjnxpsndf4MPymxteFAWHHfkTL8HjWh1KB7z23ofZ6QO2euONuxDXjat69dKZRALnGypg8k8SsK8vZJoXv1Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-ppc64-gnu": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-ppc64-gnu/-/binding-linux-ppc64-gnu-1.2.3.tgz", + "integrity": "sha512-6tbrbwfz5GB9DQ4Jwo6hy9v+vR31xZlvzZ6n5Xut6Hhx5PvrA9q/HsK8KMaYQp063iqZGXwNvZtYNLD7EM/x0w==", + "cpu": [ + "ppc64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-s390x-gnu": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-s390x-gnu/-/binding-linux-s390x-gnu-1.2.3.tgz", + "integrity": "sha512-oyuXxXmoZHjXC917IAPFAAv4wWAa0cM9afk8nx1+9/jNNOX1uPf8yDA6p7G0RypOfw/X0PQt5IfoquY1um+zSg==", + "cpu": [ + "s390x" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-x64-gnu": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-gnu/-/binding-linux-x64-gnu-1.2.3.tgz", + "integrity": "sha512-TytMwF2KVGqP2tgd0I1OY0PAv78dZRAYcF5ssDzjM34SUXCED3uXvSd5+lHoC0bTD6eEdFz7LdQNCO1y0oVk9w==", + "cpu": [ + "x64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-x64-musl": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-musl/-/binding-linux-x64-musl-1.2.3.tgz", + "integrity": "sha512-/E9m3qstrJFVPoULV25mVQblSNExY2+kBsYe4sy0Tn0yOOgJ8wZbZt3KnRbF/XeU2Gl1STKUQnDNTqhIE5MD4A==", + "cpu": [ + "x64" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-openharmony-arm64": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/@rolldown/binding-openharmony-arm64/-/binding-openharmony-arm64-1.2.3.tgz", + "integrity": "sha512-Kr0OcsoQI816i6HOl3vFHpd1K0eZyh76zgfj4c1nTyaTsd5r2Mj1lwM4R90y/qaCfmTn9eHy0SKwi98eitRxug==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-win32-arm64-msvc": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-1.2.3.tgz", + "integrity": "sha512-hOtMwTqnME+/gJcH/PCZ0wn0zPUjiWOgkHpxbSJpfGKMezHltx1S7/k1SitzVa7Ww2cqrDDaFbZEhcJZO8o+Jw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-win32-x64-msvc": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-x64-msvc/-/binding-win32-x64-msvc-1.2.3.tgz", + "integrity": "sha512-ekcqMMkI2PlhYnfzQnB/cEdYUVVJViWvoUyLrbzgDoi3Snfc1mVBwdnc306ufA5ejy8JSPjT2RlW1nQSjW7efg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/pluginutils": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.1.tgz", + "integrity": "sha512-2j9bGt5Jh8hj+vPtgzPtl72j0yRxHAyumoo6TNfAjsLB04UtpSvPbPcDcBMxz7n+9CYB0c1GxQFxYRg2jimqGw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@skeletonlabs/skeleton": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/@skeletonlabs/skeleton/-/skeleton-5.0.0.tgz", + "integrity": "sha512-kcUU77eZTNdbz59FgCxIjimH1d9DkZtMU3+IT2yBxoFQczZGPkJ0xw97ecHeJfzBp8Ah16NqPOcxHjXxO77O9w==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "tailwindcss": "^4.0.0" + } + }, + "node_modules/@skeletonlabs/skeleton-common": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/@skeletonlabs/skeleton-common/-/skeleton-common-5.0.0.tgz", + "integrity": "sha512-OzBf8nUsYMXPSo6FO2MSZ+pKzAN66Dro9Jis3Xf7sJRpbpzLU9sr4PSW9K9uDy4Z6/EiQPk7R9JMr0J633ft6w==", + "dev": true, + "license": "MIT" + }, + "node_modules/@skeletonlabs/skeleton-svelte": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/@skeletonlabs/skeleton-svelte/-/skeleton-svelte-5.0.0.tgz", + "integrity": "sha512-SuUX19bCFku8GF2kmLPFUTC1c7k8GeSSYJz4oJfa7Nb3LTIY+WDMWeGbwvMzfqyhV6s2XV3xefyf1joVHgzPAg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@internationalized/date": "3.12.2", + "@skeletonlabs/skeleton-common": "5.0.0", + "@zag-js/accordion": "1.42.0", + "@zag-js/avatar": "1.42.0", + "@zag-js/carousel": "1.42.0", + "@zag-js/collapsible": "1.42.0", + "@zag-js/collection": "1.42.0", + "@zag-js/combobox": "1.42.0", + "@zag-js/date-picker": "1.42.0", + "@zag-js/dialog": "1.42.0", + "@zag-js/file-upload": "1.42.0", + "@zag-js/floating-panel": "1.42.0", + "@zag-js/i18n-utils": "1.42.0", + "@zag-js/listbox": "1.42.0", + "@zag-js/marquee": "1.42.0", + "@zag-js/menu": "1.42.0", + "@zag-js/pagination": "1.42.0", + "@zag-js/popover": "1.42.0", + "@zag-js/progress": "1.42.0", + "@zag-js/qr-code": "1.42.0", + "@zag-js/radio-group": "1.42.0", + "@zag-js/rating-group": "1.42.0", + "@zag-js/slider": "1.42.0", + "@zag-js/steps": "1.42.0", + "@zag-js/svelte": "1.42.0", + "@zag-js/switch": "1.42.0", + "@zag-js/tabs": "1.42.0", + "@zag-js/tags-input": "1.42.0", + "@zag-js/toast": "1.42.0", + "@zag-js/toggle-group": "1.42.0", + "@zag-js/tooltip": "1.42.0", + "@zag-js/tree-view": "1.42.0" + }, + "peerDependencies": { + "svelte": "^5.40.0" + } + }, + "node_modules/@standard-schema/spec": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@standard-schema/spec/-/spec-1.1.0.tgz", + "integrity": "sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w==", + "dev": true, + "license": "MIT" + }, + "node_modules/@sveltejs/acorn-typescript": { + "version": "1.0.12", + "resolved": "https://registry.npmjs.org/@sveltejs/acorn-typescript/-/acorn-typescript-1.0.12.tgz", + "integrity": "sha512-J1jNYG23QWd67UfrQSFHtjhV37r9mVi0gdc12A3MWPldOjRK35Xk+um+qACPVjgw3AleiqoyEAhok8Wm3q46NA==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "acorn": "^8.9.0" + } + }, + "node_modules/@sveltejs/adapter-static": { + "version": "3.0.10", + "resolved": "https://registry.npmjs.org/@sveltejs/adapter-static/-/adapter-static-3.0.10.tgz", + "integrity": "sha512-7D9lYFWJmB7zxZyTE/qxjksvMqzMuYrrsyh1f4AlZqeZeACPRySjbC3aFiY55wb1tWUaKOQG9PVbm74JcN2Iew==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "@sveltejs/kit": "^2.0.0" + } + }, + "node_modules/@sveltejs/kit": { + "version": "2.70.2", + "resolved": "https://registry.npmjs.org/@sveltejs/kit/-/kit-2.70.2.tgz", + "integrity": "sha512-RzRoRpuR2KXqc5yMO0akQHDZeT4AslOlznGITURsqHaVbtyYP4Wn3eE3gxj9JcDyNYO0crkxhdwFHc+2vkVm6w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@standard-schema/spec": "^1.0.0", + "@sveltejs/acorn-typescript": "^1.0.9", + "@types/cookie": "^0.6.0", + "acorn": "^8.16.0", + "cookie": "^0.6.0", + "devalue": "^5.8.1", + "esm-env": "^1.2.2", + "kleur": "^4.1.5", + "magic-string": "^0.30.5", + "mrmime": "^2.0.0", + "set-cookie-parser": "^3.0.0", + "sirv": "^3.0.0" + }, + "bin": { + "svelte-kit": "svelte-kit.js" + }, + "engines": { + "node": ">=18.13" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.0.0", + "@sveltejs/vite-plugin-svelte": "^3.0.0 || ^4.0.0-next.1 || ^5.0.0 || ^6.0.0-next.0 || ^7.0.0", + "svelte": "^4.0.0 || ^5.0.0-next.0", + "typescript": "^5.3.3 || ^6.0.0", + "vite": "^5.0.3 || ^6.0.0 || ^7.0.0-beta.0 || ^8.0.0" + }, + "peerDependenciesMeta": { + "@opentelemetry/api": { + "optional": true + }, + "typescript": { + "optional": true + } + } + }, + "node_modules/@sveltejs/load-config": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/@sveltejs/load-config/-/load-config-0.2.2.tgz", + "integrity": "sha512-K7dsJDQxBOF+f+epuhMactcjK2VP4MRkLKtwSykNtEI+cKVEyzrmmhQ1pmoxI800m4JKcyJ05L2M4yPwAGiBNw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 18.0.0" + } + }, + "node_modules/@sveltejs/vite-plugin-svelte": { + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/@sveltejs/vite-plugin-svelte/-/vite-plugin-svelte-7.3.0.tgz", + "integrity": "sha512-QbRoJyD92e9R0ufeQIWRHrCC0ObcqSv/aBDdrQMoU+sypav3cDx5wytdQ6GLdXjEMO6xjrXGzfkUygng8JMv0A==", + "dev": true, + "license": "MIT", + "dependencies": { + "deepmerge": "^4.3.1", + "magic-string": "^1.0.0", + "obug": "^2.1.0", + "vitefu": "^1.1.2" + }, + "engines": { + "node": "^20.19 || ^22.12 || >=24" + }, + "peerDependencies": { + "svelte": "^5.46.4", + "vite": "^8.0.0-beta.7 || ^8.0.0" + } + }, + "node_modules/@sveltejs/vite-plugin-svelte/node_modules/magic-string": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-1.1.0.tgz", + "integrity": "sha512-kS3VHe0nEPST2saQV4Rbkchcd3UBRkVTQHo1D3h/ZTwFDhai/mfKkmtPAtD129EOI7K3HlHIsFOt0WrI2/oU9g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.5" + } + }, + "node_modules/@swc/helpers": { + "version": "0.5.23", + "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.23.tgz", + "integrity": "sha512-5lSsMOTXURePglDfvuAQUqkGek9Hg2kksOYay2m0+XR++b2NWYL/4sWyuvVBIs8oKnJaxkdi9whaL/sqN13afw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.8.0" + } + }, + "node_modules/@tailwindcss/node": { + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/@tailwindcss/node/-/node-4.3.3.tgz", + "integrity": "sha512-/T8IKEsf9VTU6tLjgC7+sv2mOPtQxzE2jMw7u4Tt40Tx+QSZxpzh95/H6cMKoja9XuW7iMdLJYBB0o9G1CaAgg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/remapping": "^2.3.5", + "enhanced-resolve": "^5.24.1", + "jiti": "^2.7.0", + "lightningcss": "1.32.0", + "magic-string": "^0.30.21", + "source-map-js": "^1.2.1", + "tailwindcss": "4.3.3" + } + }, + "node_modules/@tailwindcss/oxide": { + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide/-/oxide-4.3.3.tgz", + "integrity": "sha512-krXjAikiaFSPaK/FkAQT5UTx3VormQaiZ5hBFlJZ9UFQGB/rwg1MZIhHAG9smMQRTdyJxP6Qt5MwMtdyU5FWrA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 20" + }, + "optionalDependencies": { + "@tailwindcss/oxide-android-arm64": "4.3.3", + "@tailwindcss/oxide-darwin-arm64": "4.3.3", + "@tailwindcss/oxide-darwin-x64": "4.3.3", + "@tailwindcss/oxide-freebsd-x64": "4.3.3", + "@tailwindcss/oxide-linux-arm-gnueabihf": "4.3.3", + "@tailwindcss/oxide-linux-arm64-gnu": "4.3.3", + "@tailwindcss/oxide-linux-arm64-musl": "4.3.3", + "@tailwindcss/oxide-linux-x64-gnu": "4.3.3", + "@tailwindcss/oxide-linux-x64-musl": "4.3.3", + "@tailwindcss/oxide-wasm32-wasi": "4.3.3", + "@tailwindcss/oxide-win32-arm64-msvc": "4.3.3", + "@tailwindcss/oxide-win32-x64-msvc": "4.3.3" + } + }, + "node_modules/@tailwindcss/oxide-android-arm64": { + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-android-arm64/-/oxide-android-arm64-4.3.3.tgz", + "integrity": "sha512-Y85A2gmPSkl5Ve5qR86GL4HT509cFqQh1aes9p3sSkyTPwt0Pppf3GkwGe4JPACcRYjgJIEhQgM6dBClnr0NYw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">= 20" + } + }, + "node_modules/@tailwindcss/oxide-darwin-arm64": { + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-arm64/-/oxide-darwin-arm64-4.3.3.tgz", + "integrity": "sha512-BiaWatpBcERQFDlOjRDpIVXuFK5PJez5SA4JMg6VYZdBYU+qKfV/vqjcIs+IYmtitf1xYQZTwXvU/8y4lfZUGw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 20" + } + }, + "node_modules/@tailwindcss/oxide-darwin-x64": { + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-x64/-/oxide-darwin-x64-4.3.3.tgz", + "integrity": "sha512-fAeUqfV5ndhxRwai8cXGzdLvul9utWOmeTkv69unv4ZXixjn61Z+p9lCWdwOwA3TYboG3BwdVuN/RDjhBRl0mw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 20" + } + }, + "node_modules/@tailwindcss/oxide-freebsd-x64": { + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-freebsd-x64/-/oxide-freebsd-x64-4.3.3.tgz", + "integrity": "sha512-iyf5bV6+wnAlflVeEy7R25dupxTNECZN5QMI0qNT6eT+EgaGdZcKhGkr5SdoaWiLJ3spLqIY9VCeSGrwmtg4kw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">= 20" + } + }, + "node_modules/@tailwindcss/oxide-linux-arm-gnueabihf": { + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm-gnueabihf/-/oxide-linux-arm-gnueabihf-4.3.3.tgz", + "integrity": "sha512-aAYUprJAJQWWbRrPvtjdroZ56Md+JM8pMiopS6xGEwDfLhqj+2ver2p4nU4Mb3CRqcMmNBjo8KkUgcxhkzVQGQ==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 20" + } + }, + "node_modules/@tailwindcss/oxide-linux-arm64-gnu": { + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-gnu/-/oxide-linux-arm64-gnu-4.3.3.tgz", + "integrity": "sha512-nDxldcEENOxZRzC2uu9jrutZdAAQtb+8WWDCSnWL1zvBk1+FN+x6MtDViPB5AJMfttVCUhehGWus3XBPgatM/w==", + "cpu": [ + "arm64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 20" + } + }, + "node_modules/@tailwindcss/oxide-linux-arm64-musl": { + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-musl/-/oxide-linux-arm64-musl-4.3.3.tgz", + "integrity": "sha512-Md44bD6veX/PC5iyF8cDVnw4HBIANZepRZZ7a8DQOvkfo5WUBwcp6iAuCUz23u+4SUkhJlD3eL7hNdW8ezd/kA==", + "cpu": [ + "arm64" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 20" + } + }, + "node_modules/@tailwindcss/oxide-linux-x64-gnu": { + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-gnu/-/oxide-linux-x64-gnu-4.3.3.tgz", + "integrity": "sha512-tx7us1muwOKAKWao2v/GaafFeQboE6aj88vC6ziN2NCGcRm8gWUhwjzg+YdVB1e4boAtdtma4L43onunI6NS4w==", + "cpu": [ + "x64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 20" + } + }, + "node_modules/@tailwindcss/oxide-linux-x64-musl": { + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-musl/-/oxide-linux-x64-musl-4.3.3.tgz", + "integrity": "sha512-SJxX60smvHgasZoBy11dX6YRjXJFovwWBoedhbQPOBzgFWBHGB+TVPWB9BxzR7TTxU8FQZAI2AyiNCMzFm8Img==", + "cpu": [ + "x64" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 20" + } + }, + "node_modules/@tailwindcss/oxide-wasm32-wasi": { + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-wasm32-wasi/-/oxide-wasm32-wasi-4.3.3.tgz", + "integrity": "sha512-jx1+rPhY/5Ympkktd656HBWEBLxP7dH06losBLjjf5vgCODXvi9KhtftWcMIwTFIDqBr7cRnQkdLnAG+IOlGvQ==", + "bundleDependencies": [ + "@napi-rs/wasm-runtime", + "@emnapi/core", + "@emnapi/runtime", + "@tybys/wasm-util", + "@emnapi/wasi-threads", + "tslib" + ], + "cpu": [ + "wasm32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "@emnapi/core": "^1.11.1", + "@emnapi/runtime": "^1.11.1", + "@emnapi/wasi-threads": "^1.2.2", + "@napi-rs/wasm-runtime": "^1.1.4", + "@tybys/wasm-util": "^0.10.2", + "tslib": "^2.8.1" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "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", + "integrity": "sha512-3rc292Ca2ceK6Ulcc/bAVnTs/3nDtoPhyEKlgPv+yQJQi/JS/AMJlqzxvlDacL1nekbrcf6bTqp/jV4qgnPxNQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 20" + } + }, + "node_modules/@tailwindcss/oxide-win32-x64-msvc": { + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-x64-msvc/-/oxide-win32-x64-msvc-4.3.3.tgz", + "integrity": "sha512-yJ0pwIVc/nYeGoV02WtsN8KYyLQv7kyI2wDnkezyJlGGjkd4QLwDGAwl47YpPJeuI0M0ObaXGSPjvWDPeTPggw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 20" + } + }, + "node_modules/@tailwindcss/vite": { + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/@tailwindcss/vite/-/vite-4.3.3.tgz", + "integrity": "sha512-yYU8cogLeSh/ms2jh8Fj7jaba/EWa7Ja6GoUqYZaraEuCI5YS6ms6ObZgjjedm+jm6XZjdNRWBpPP6Z86oOxcw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@tailwindcss/node": "4.3.3", + "@tailwindcss/oxide": "4.3.3", + "tailwindcss": "4.3.3" + }, + "peerDependencies": { + "vite": "^5.2.0 || ^6 || ^7 || ^8" + } + }, + "node_modules/@types/cookie": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/@types/cookie/-/cookie-0.6.0.tgz", + "integrity": "sha512-4Kh9a6B2bQciAhf7FSuMRRkUWecJgJu9nPnx3yzpsfXX/c50REIqpHY4C82bXP90qrLtXtkDxTZosYO3UpOwlA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/estree": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.9.tgz", + "integrity": "sha512-GhdPgy1el4/ImP05X05Uw4cw2/M93BCUmnEvWZNStlCzEKME4Fkk+YpoA5OiHNQmoS7Cafb8Xa3Pya8m1Qrzeg==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/trusted-types": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/@types/trusted-types/-/trusted-types-2.0.7.tgz", + "integrity": "sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@zag-js/accordion": { + "version": "1.42.0", + "resolved": "https://registry.npmjs.org/@zag-js/accordion/-/accordion-1.42.0.tgz", + "integrity": "sha512-eTVh6Uz3CqdcJDr5mHWTT+oICSrZFfYCCxIpOKF00nADmb96nCDqOAYFMf8gM3J/4UDS/V27QzEH5GPmFWiHIw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@zag-js/anatomy": "1.42.0", + "@zag-js/core": "1.42.0", + "@zag-js/dom-query": "1.42.0", + "@zag-js/types": "1.42.0", + "@zag-js/utils": "1.42.0" + } + }, + "node_modules/@zag-js/anatomy": { + "version": "1.42.0", + "resolved": "https://registry.npmjs.org/@zag-js/anatomy/-/anatomy-1.42.0.tgz", + "integrity": "sha512-F6kRAPxgBZRZmuV5SLywcrGNSclKcAcPAAgSrEdr2Z2dzFgQngbvS4dmdQyGau/vtQ42OlCI48Ri4t0hZxXkMw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@zag-js/aria-hidden": { + "version": "1.42.0", + "resolved": "https://registry.npmjs.org/@zag-js/aria-hidden/-/aria-hidden-1.42.0.tgz", + "integrity": "sha512-ao1RyEbHbglJtLLR4sJLPiD3hWF1CacuN5eqvODh/7HcntWULrkUHo8DIdzYgFL9GUHDyDmpaechMX5wL3kdPg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@zag-js/dom-query": "1.42.0" + } + }, + "node_modules/@zag-js/auto-resize": { + "version": "1.42.0", + "resolved": "https://registry.npmjs.org/@zag-js/auto-resize/-/auto-resize-1.42.0.tgz", + "integrity": "sha512-iL7EI30VknEkVb8PhTcLkvR8aiZda0IwJGT4K0cb7J/fMxsDAGjnjdLRu+dGUPZsXji1n58wlaKjTtCQCaXfOA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@zag-js/dom-query": "1.42.0" + } + }, + "node_modules/@zag-js/avatar": { + "version": "1.42.0", + "resolved": "https://registry.npmjs.org/@zag-js/avatar/-/avatar-1.42.0.tgz", + "integrity": "sha512-rY2OxTTlvX1EMXENruejUUOZeiHusEpWLHNhrlqXMWMPWmcCe3aZ7iGMvjPFMb2mTMn0fzWmuY0nZDdVYk3V/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@zag-js/anatomy": "1.42.0", + "@zag-js/core": "1.42.0", + "@zag-js/dom-query": "1.42.0", + "@zag-js/types": "1.42.0", + "@zag-js/utils": "1.42.0" + } + }, + "node_modules/@zag-js/carousel": { + "version": "1.42.0", + "resolved": "https://registry.npmjs.org/@zag-js/carousel/-/carousel-1.42.0.tgz", + "integrity": "sha512-8VMPlg5DP8vye4ujyEqzM/EQ0osOVtoG3bUJ6CGWdRIdSkbgjIt1tY8DlS1WzOvSUMnTcTAi/RPxoxYZwTIhsw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@zag-js/anatomy": "1.42.0", + "@zag-js/core": "1.42.0", + "@zag-js/dom-query": "1.42.0", + "@zag-js/scroll-snap": "1.42.0", + "@zag-js/types": "1.42.0", + "@zag-js/utils": "1.42.0" + } + }, + "node_modules/@zag-js/collapsible": { + "version": "1.42.0", + "resolved": "https://registry.npmjs.org/@zag-js/collapsible/-/collapsible-1.42.0.tgz", + "integrity": "sha512-MSQo9qRwp2r6aj3G/lKd3gSXAAjuCaq1LtLT3BxHEQ5skn2NQWTKVgReUSuDJNl0Lz+Z5WYq5+5TCDHr4YKHRA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@zag-js/anatomy": "1.42.0", + "@zag-js/core": "1.42.0", + "@zag-js/dom-query": "1.42.0", + "@zag-js/types": "1.42.0", + "@zag-js/utils": "1.42.0" + } + }, + "node_modules/@zag-js/collection": { + "version": "1.42.0", + "resolved": "https://registry.npmjs.org/@zag-js/collection/-/collection-1.42.0.tgz", + "integrity": "sha512-+Bhj/2zqVVzmS788lsg/xK1ezksMc2pfVg2oO6MnipLCo8KrgzuuvhUahUzK+uIOc9ljBW4zl9Wcm3G248gh0A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@zag-js/utils": "1.42.0" + } + }, + "node_modules/@zag-js/combobox": { + "version": "1.42.0", + "resolved": "https://registry.npmjs.org/@zag-js/combobox/-/combobox-1.42.0.tgz", + "integrity": "sha512-fe+Sco278h8PPFM0g3eR5366/oVIfSI3B7qDXl/xmYKMQXhIp+bKxew3U0q1COSVof0x3wrIoIpY51BXj1McGw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@zag-js/anatomy": "1.42.0", + "@zag-js/collection": "1.42.0", + "@zag-js/core": "1.42.0", + "@zag-js/dismissable": "1.42.0", + "@zag-js/dom-query": "1.42.0", + "@zag-js/focus-visible": "1.42.0", + "@zag-js/live-region": "1.42.0", + "@zag-js/popper": "1.42.0", + "@zag-js/types": "1.42.0", + "@zag-js/utils": "1.42.0" + } + }, + "node_modules/@zag-js/core": { + "version": "1.42.0", + "resolved": "https://registry.npmjs.org/@zag-js/core/-/core-1.42.0.tgz", + "integrity": "sha512-jE/sbpZvbD+/etbawzhL/L2lP1pPefed5d919je+K5h9b6GAK3lUThleaDUCww3bT53B1L7O5gtqBapW37N1ug==", + "dev": true, + "license": "MIT", + "dependencies": { + "@zag-js/dom-query": "1.42.0", + "@zag-js/utils": "1.42.0" + } + }, + "node_modules/@zag-js/date-picker": { + "version": "1.42.0", + "resolved": "https://registry.npmjs.org/@zag-js/date-picker/-/date-picker-1.42.0.tgz", + "integrity": "sha512-M8zt5kdOld7YKYmCZCQ8xPJ8+xwBpxIumzWgzFGoadSxYQPaK8gPqPFKxADJZWX7p/oHdpw2BVcVFWNC0urcyg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@zag-js/anatomy": "1.42.0", + "@zag-js/core": "1.42.0", + "@zag-js/date-utils": "1.42.0", + "@zag-js/dismissable": "1.42.0", + "@zag-js/dom-query": "1.42.0", + "@zag-js/live-region": "1.42.0", + "@zag-js/popper": "1.42.0", + "@zag-js/types": "1.42.0", + "@zag-js/utils": "1.42.0" + }, + "peerDependencies": { + "@internationalized/date": ">=3.0.0" + } + }, + "node_modules/@zag-js/date-utils": { + "version": "1.42.0", + "resolved": "https://registry.npmjs.org/@zag-js/date-utils/-/date-utils-1.42.0.tgz", + "integrity": "sha512-pjFahzgNGlIIbNQWaPY4RcFhMo+9d9nHj7FctmexXdQ6x4aByfD8bPCUKomO2MsMs0/2lRkACjqZeJwP4oivAw==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "@internationalized/date": ">=3.0.0" + } + }, + "node_modules/@zag-js/dialog": { + "version": "1.42.0", + "resolved": "https://registry.npmjs.org/@zag-js/dialog/-/dialog-1.42.0.tgz", + "integrity": "sha512-2KpLQASTjr2JUR0XvqsMueVo+AAPeanD9ShFCY/YKv2qp6WRHo1Ig/tRj6pInsSBiHFo7QXyAD4SDax6C0zDcw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@zag-js/anatomy": "1.42.0", + "@zag-js/aria-hidden": "1.42.0", + "@zag-js/core": "1.42.0", + "@zag-js/dismissable": "1.42.0", + "@zag-js/dom-query": "1.42.0", + "@zag-js/focus-trap": "1.42.0", + "@zag-js/remove-scroll": "1.42.0", + "@zag-js/types": "1.42.0", + "@zag-js/utils": "1.42.0" + } + }, + "node_modules/@zag-js/dismissable": { + "version": "1.42.0", + "resolved": "https://registry.npmjs.org/@zag-js/dismissable/-/dismissable-1.42.0.tgz", + "integrity": "sha512-Cx/FAQ2MuQy3kecdmswrFk94Zie1ieBa1Pnt/2ECI5FR914EJd3DwY9Krsmlrq4Z15Wm+pVtfLXgakDewVgsiQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@zag-js/dom-query": "1.42.0", + "@zag-js/interact-outside": "1.42.0", + "@zag-js/utils": "1.42.0" + } + }, + "node_modules/@zag-js/dom-query": { + "version": "1.42.0", + "resolved": "https://registry.npmjs.org/@zag-js/dom-query/-/dom-query-1.42.0.tgz", + "integrity": "sha512-JgCNfp7F+YNFNb7Xmt6rXQr3N3V9Mp+pFRvZ8j5BTC3/G8ZYj/enrgOcuVwPlXPBGtA7ysvjig2x1c0Uou/6kg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@zag-js/types": "1.42.0" + } + }, + "node_modules/@zag-js/file-upload": { + "version": "1.42.0", + "resolved": "https://registry.npmjs.org/@zag-js/file-upload/-/file-upload-1.42.0.tgz", + "integrity": "sha512-1I8mCSh6fykHmTStuD9qS425vySOhBjFZfkqLG1J10IfGjz8KCoHcOEbZDHqbJa4/Yq0d+mrwHpOYPS6jYBimA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@zag-js/anatomy": "1.42.0", + "@zag-js/core": "1.42.0", + "@zag-js/dom-query": "1.42.0", + "@zag-js/file-utils": "1.42.0", + "@zag-js/i18n-utils": "1.42.0", + "@zag-js/types": "1.42.0", + "@zag-js/utils": "1.42.0" + } + }, + "node_modules/@zag-js/file-utils": { + "version": "1.42.0", + "resolved": "https://registry.npmjs.org/@zag-js/file-utils/-/file-utils-1.42.0.tgz", + "integrity": "sha512-goU5T/8SVpeoR33PS4kRWZkcfSERI7FVqqSn521PmxZ/wZMVDrXaivygbttGV8nCWfbwmsMqeyp2iy5MnbNovQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@zag-js/i18n-utils": "1.42.0" + } + }, + "node_modules/@zag-js/floating-panel": { + "version": "1.42.0", + "resolved": "https://registry.npmjs.org/@zag-js/floating-panel/-/floating-panel-1.42.0.tgz", + "integrity": "sha512-C1nUUgpkAex6QG7/5IkTu38ZBj4RMLbK3sNrssMoZ6kR60jB7D1Lz7D4NbD2b0dYabM6XH10TEaCzEPY8LpC3A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@zag-js/anatomy": "1.42.0", + "@zag-js/core": "1.42.0", + "@zag-js/dom-query": "1.42.0", + "@zag-js/popper": "1.42.0", + "@zag-js/rect-utils": "1.42.0", + "@zag-js/store": "1.42.0", + "@zag-js/types": "1.42.0", + "@zag-js/utils": "1.42.0" + } + }, + "node_modules/@zag-js/focus-trap": { + "version": "1.42.0", + "resolved": "https://registry.npmjs.org/@zag-js/focus-trap/-/focus-trap-1.42.0.tgz", + "integrity": "sha512-47O/OpLUm9o8CZd3ez0ntAOUKZEQ1zFj7e86fpYuQ+fNtBlpYMFHQxMRftPkiU5Ysjrz5x8RYV8A8uJ9cboNig==", + "dev": true, + "license": "MIT", + "dependencies": { + "@zag-js/dom-query": "1.42.0" + } + }, + "node_modules/@zag-js/focus-visible": { + "version": "1.42.0", + "resolved": "https://registry.npmjs.org/@zag-js/focus-visible/-/focus-visible-1.42.0.tgz", + "integrity": "sha512-zT1Fk+8m6x6hzoD5fOIEV4JQIX33pwkBzANqwruQwaSqkOYtI2FmsG71YHnzKvrBppG2okPrRHEMyZEgfshIcQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@zag-js/dom-query": "1.42.0" + } + }, + "node_modules/@zag-js/i18n-utils": { + "version": "1.42.0", + "resolved": "https://registry.npmjs.org/@zag-js/i18n-utils/-/i18n-utils-1.42.0.tgz", + "integrity": "sha512-uVw+Ua3apxaBCRcsfHOlXcRPDNygSGoJ6ivmK0UJaw5QikZLEBYr7grzXDwRvZrdk0j0sA9Hk/gg3GdSXkhI3Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@zag-js/dom-query": "1.42.0" + } + }, + "node_modules/@zag-js/interact-outside": { + "version": "1.42.0", + "resolved": "https://registry.npmjs.org/@zag-js/interact-outside/-/interact-outside-1.42.0.tgz", + "integrity": "sha512-CNNT1OtASacXEst8NMWDGmDwkOQgVQ0Ahc2SpPjSBZoVpxQIfhZ9FoeqcggDX7Nvze7kl6/OwA7pPi5TGQTVZQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@zag-js/dom-query": "1.42.0", + "@zag-js/utils": "1.42.0" + } + }, + "node_modules/@zag-js/listbox": { + "version": "1.42.0", + "resolved": "https://registry.npmjs.org/@zag-js/listbox/-/listbox-1.42.0.tgz", + "integrity": "sha512-nt842jgTaBYTgkqu3y+4l88wpmoyesXkS+Bc3Uvuc7ze9IB04vicSiRi+vstYyA20s/EjOr2tR9Kq7dNoROLaQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@zag-js/anatomy": "1.42.0", + "@zag-js/collection": "1.42.0", + "@zag-js/core": "1.42.0", + "@zag-js/dom-query": "1.42.0", + "@zag-js/focus-visible": "1.42.0", + "@zag-js/types": "1.42.0", + "@zag-js/utils": "1.42.0" + } + }, + "node_modules/@zag-js/live-region": { + "version": "1.42.0", + "resolved": "https://registry.npmjs.org/@zag-js/live-region/-/live-region-1.42.0.tgz", + "integrity": "sha512-YFkytNxBJDQIndh7W+bWMN9P74qsnQkzqqLv6LtX/TiOYr1PnL0p54DMvWhE7hqYiCyyLscBM9nbA1foSoPIPg==", + "dev": true, + "license": "MIT" + }, + "node_modules/@zag-js/marquee": { + "version": "1.42.0", + "resolved": "https://registry.npmjs.org/@zag-js/marquee/-/marquee-1.42.0.tgz", + "integrity": "sha512-bTYbNFuDdKV7SyHchyCLhE+JtReO8VUaGfv9Prh3LfFq7yNEqiFngqhY7TZBw6Vok4q8msu0r9aAqOspZqHEHA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@zag-js/anatomy": "1.42.0", + "@zag-js/core": "1.42.0", + "@zag-js/dom-query": "1.42.0", + "@zag-js/types": "1.42.0", + "@zag-js/utils": "1.42.0" + } + }, + "node_modules/@zag-js/menu": { + "version": "1.42.0", + "resolved": "https://registry.npmjs.org/@zag-js/menu/-/menu-1.42.0.tgz", + "integrity": "sha512-Jg2q+FrHeZ2ZTxrz/TAnNelapN6IGtyCnBmoNbcHGcnf3gqnEjJpug3Fn6BmPQrmTNw0+q7hBmrESyncjrfbUg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@zag-js/anatomy": "1.42.0", + "@zag-js/core": "1.42.0", + "@zag-js/dismissable": "1.42.0", + "@zag-js/dom-query": "1.42.0", + "@zag-js/focus-visible": "1.42.0", + "@zag-js/popper": "1.42.0", + "@zag-js/rect-utils": "1.42.0", + "@zag-js/types": "1.42.0", + "@zag-js/utils": "1.42.0" + } + }, + "node_modules/@zag-js/pagination": { + "version": "1.42.0", + "resolved": "https://registry.npmjs.org/@zag-js/pagination/-/pagination-1.42.0.tgz", + "integrity": "sha512-QEcnc8z0U4RREOa1MVGFNbKJONLzbo5egdUppURkbAwhv+paR9ufG4uli7QlMvA3KgdfCHPM92+MhnYwutp5nw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@zag-js/anatomy": "1.42.0", + "@zag-js/core": "1.42.0", + "@zag-js/dom-query": "1.42.0", + "@zag-js/types": "1.42.0", + "@zag-js/utils": "1.42.0" + } + }, + "node_modules/@zag-js/popover": { + "version": "1.42.0", + "resolved": "https://registry.npmjs.org/@zag-js/popover/-/popover-1.42.0.tgz", + "integrity": "sha512-4knrgFDeYlKqjyRfYPEUfpIRjsTvg4zY/C0i3sbdxNEWiOW30DzW+/8Igabb00bOabrtRuIHBejm0Jorgn5JIQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@zag-js/anatomy": "1.42.0", + "@zag-js/aria-hidden": "1.42.0", + "@zag-js/core": "1.42.0", + "@zag-js/dismissable": "1.42.0", + "@zag-js/dom-query": "1.42.0", + "@zag-js/focus-trap": "1.42.0", + "@zag-js/popper": "1.42.0", + "@zag-js/remove-scroll": "1.42.0", + "@zag-js/types": "1.42.0", + "@zag-js/utils": "1.42.0" + } + }, + "node_modules/@zag-js/popper": { + "version": "1.42.0", + "resolved": "https://registry.npmjs.org/@zag-js/popper/-/popper-1.42.0.tgz", + "integrity": "sha512-hQvXzLen/hXCItww5tJT6+VLxnee8CpsX0FabIiHub/fKIB6OeHmS/lk+RnIII57bljdjLSus/KnT8Xlmj6tRw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@floating-ui/dom": "^1.7.6", + "@zag-js/dom-query": "1.42.0", + "@zag-js/utils": "1.42.0" + } + }, + "node_modules/@zag-js/progress": { + "version": "1.42.0", + "resolved": "https://registry.npmjs.org/@zag-js/progress/-/progress-1.42.0.tgz", + "integrity": "sha512-ZGex63fTJHy4or5N8fBUxiwqxBGd1Vr+OE0Bnm8+FAQNjJ5BtCLhIlmsIUS8aX2SrBR0j/tp8E0ss35/PNq29Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@zag-js/anatomy": "1.42.0", + "@zag-js/core": "1.42.0", + "@zag-js/dom-query": "1.42.0", + "@zag-js/types": "1.42.0", + "@zag-js/utils": "1.42.0" + } + }, + "node_modules/@zag-js/qr-code": { + "version": "1.42.0", + "resolved": "https://registry.npmjs.org/@zag-js/qr-code/-/qr-code-1.42.0.tgz", + "integrity": "sha512-X9cUPzJKI7aWrf8ie2jgaXlFFetJf1fdwhnWnP5rG8v3jrFe4tDA1n3z6HE4bXkluZv/2EL9cROglbz5WGB6/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@zag-js/anatomy": "1.42.0", + "@zag-js/core": "1.42.0", + "@zag-js/dom-query": "1.42.0", + "@zag-js/types": "1.42.0", + "@zag-js/utils": "1.42.0", + "proxy-memoize": "3.0.1", + "uqr": "0.1.3" + } + }, + "node_modules/@zag-js/radio-group": { + "version": "1.42.0", + "resolved": "https://registry.npmjs.org/@zag-js/radio-group/-/radio-group-1.42.0.tgz", + "integrity": "sha512-VtoN9/d3HCe/oumjdwKzv/KilF2aLzbt1IYpejXF7Cwat8xmqnCoxiA2PLjE9NfD97ZM7grng1YGcjqrWOWvuQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@zag-js/anatomy": "1.42.0", + "@zag-js/core": "1.42.0", + "@zag-js/dom-query": "1.42.0", + "@zag-js/focus-visible": "1.42.0", + "@zag-js/types": "1.42.0", + "@zag-js/utils": "1.42.0" + } + }, + "node_modules/@zag-js/rating-group": { + "version": "1.42.0", + "resolved": "https://registry.npmjs.org/@zag-js/rating-group/-/rating-group-1.42.0.tgz", + "integrity": "sha512-0+OQ+iy0djWJBzWdH8pMn+ze88B0T4TdO3kJuHyG2fgJnVgmuGWkoKp8RtXSAv2CVqXfx+diivqF9ZmhNmzLQA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@zag-js/anatomy": "1.42.0", + "@zag-js/core": "1.42.0", + "@zag-js/dom-query": "1.42.0", + "@zag-js/types": "1.42.0", + "@zag-js/utils": "1.42.0" + } + }, + "node_modules/@zag-js/rect-utils": { + "version": "1.42.0", + "resolved": "https://registry.npmjs.org/@zag-js/rect-utils/-/rect-utils-1.42.0.tgz", + "integrity": "sha512-4hIvDZEPxYAqhiSNVkZtQLzd7dV7IAn7c5GdWnVVAYtJDD1Tn+v0TYkoPuGQMqLsdpNDwncw3baT3xq1+PQi+w==", + "dev": true, + "license": "MIT" + }, + "node_modules/@zag-js/remove-scroll": { + "version": "1.42.0", + "resolved": "https://registry.npmjs.org/@zag-js/remove-scroll/-/remove-scroll-1.42.0.tgz", + "integrity": "sha512-RP1SzQuVDk+np5knkEz/mRasLHZUbO6f3xgq4M2u4SQhpOe34uJybd+14f4ElBntAJQWVeMhohpW4n0pNUW6WQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@zag-js/dom-query": "1.42.0" + } + }, + "node_modules/@zag-js/scroll-snap": { + "version": "1.42.0", + "resolved": "https://registry.npmjs.org/@zag-js/scroll-snap/-/scroll-snap-1.42.0.tgz", + "integrity": "sha512-gFc5LZvHa4lyCmlt5n6nODc77dGeOc+3sWQMK+20cm/VjYNCsUDjoHP2KO5tgqLJNjPrON+i0BN/QfJUfoNA7Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@zag-js/dom-query": "1.42.0" + } + }, + "node_modules/@zag-js/slider": { + "version": "1.42.0", + "resolved": "https://registry.npmjs.org/@zag-js/slider/-/slider-1.42.0.tgz", + "integrity": "sha512-bHTNGxM2H2oag5IbsfsV/OJegz4ic1Zs89Mvm+ryVzqOc0upJl0xMC/D/K8wnRJ8OPubNnldA+R4W8o+/4IU8w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@zag-js/anatomy": "1.42.0", + "@zag-js/core": "1.42.0", + "@zag-js/dom-query": "1.42.0", + "@zag-js/types": "1.42.0", + "@zag-js/utils": "1.42.0" + } + }, + "node_modules/@zag-js/steps": { + "version": "1.42.0", + "resolved": "https://registry.npmjs.org/@zag-js/steps/-/steps-1.42.0.tgz", + "integrity": "sha512-IDJKk4zPhQjJv5fxAvOy+LRcdnim5rJjpUdEsWq0/aDiVZiddg3sXLgJ8dTGfv6e58AIjTlaz85xv21dldWKYw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@zag-js/anatomy": "1.42.0", + "@zag-js/core": "1.42.0", + "@zag-js/dom-query": "1.42.0", + "@zag-js/types": "1.42.0", + "@zag-js/utils": "1.42.0" + } + }, + "node_modules/@zag-js/store": { + "version": "1.42.0", + "resolved": "https://registry.npmjs.org/@zag-js/store/-/store-1.42.0.tgz", + "integrity": "sha512-qQ5LB+l2dR1rZFCsErn9PeSrOADjnsvDl1NreEN/AaKXw9RK0YiQDqaCh7ndqjjA72UAcrnzgXsS0AAqxCC+MQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "proxy-compare": "3.0.1" + } + }, + "node_modules/@zag-js/svelte": { + "version": "1.42.0", + "resolved": "https://registry.npmjs.org/@zag-js/svelte/-/svelte-1.42.0.tgz", + "integrity": "sha512-24UesuYzeRA5blEQcAiWt5tWLG05NhiJ1WNHhwafmn5HFBRvlaU7J7VymIHE06cKMCThwy2YjSgq3b56e+f3VQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@zag-js/core": "1.42.0", + "@zag-js/types": "1.42.0", + "@zag-js/utils": "1.42.0" + }, + "peerDependencies": { + "svelte": ">=5" + } + }, + "node_modules/@zag-js/switch": { + "version": "1.42.0", + "resolved": "https://registry.npmjs.org/@zag-js/switch/-/switch-1.42.0.tgz", + "integrity": "sha512-227GNBAz8mYSKVsHV6r4YA/1/0rtbrP2foygPligDOkWMsNP9cjnW1HwM/z3x54UPWLqKuZjsjD7LSuDhbxtBA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@zag-js/anatomy": "1.42.0", + "@zag-js/core": "1.42.0", + "@zag-js/dom-query": "1.42.0", + "@zag-js/focus-visible": "1.42.0", + "@zag-js/types": "1.42.0", + "@zag-js/utils": "1.42.0" + } + }, + "node_modules/@zag-js/tabs": { + "version": "1.42.0", + "resolved": "https://registry.npmjs.org/@zag-js/tabs/-/tabs-1.42.0.tgz", + "integrity": "sha512-O0qFmeneJHr85AUL/44mHQy8Cr/jCZzh55rTKz5sBoZxmk7PIGopsasNLnpyaZ34tOpcKnNEg96FdlZ4O1bjlQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@zag-js/anatomy": "1.42.0", + "@zag-js/core": "1.42.0", + "@zag-js/dom-query": "1.42.0", + "@zag-js/types": "1.42.0", + "@zag-js/utils": "1.42.0" + } + }, + "node_modules/@zag-js/tags-input": { + "version": "1.42.0", + "resolved": "https://registry.npmjs.org/@zag-js/tags-input/-/tags-input-1.42.0.tgz", + "integrity": "sha512-+zGHcW1EeYCfxfngR4DXJEUWn6iKBoWkN2OnP4HrrWIAwk+0yTOQpwEd4UcCoUOo7CPtqwBmZp2Y92AMuAFA+Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@zag-js/anatomy": "1.42.0", + "@zag-js/auto-resize": "1.42.0", + "@zag-js/core": "1.42.0", + "@zag-js/dom-query": "1.42.0", + "@zag-js/interact-outside": "1.42.0", + "@zag-js/live-region": "1.42.0", + "@zag-js/types": "1.42.0", + "@zag-js/utils": "1.42.0" + } + }, + "node_modules/@zag-js/toast": { + "version": "1.42.0", + "resolved": "https://registry.npmjs.org/@zag-js/toast/-/toast-1.42.0.tgz", + "integrity": "sha512-8WLogVjJiCrvQ4hv9vQrcjaFJLFGtOCb/pnir7SjqR1RzbYHoPLj5ASbM9bbjpcgQQYr0GaLovP6beQW8kjBjg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@zag-js/anatomy": "1.42.0", + "@zag-js/core": "1.42.0", + "@zag-js/dismissable": "1.42.0", + "@zag-js/dom-query": "1.42.0", + "@zag-js/types": "1.42.0", + "@zag-js/utils": "1.42.0" + } + }, + "node_modules/@zag-js/toggle-group": { + "version": "1.42.0", + "resolved": "https://registry.npmjs.org/@zag-js/toggle-group/-/toggle-group-1.42.0.tgz", + "integrity": "sha512-lhsPcj115a646wxHgzSkhSW4IZFKw4pqRTHSL0e8vR4jgCRhGLBzE70S+EgYIj+000A05eB+or0PhX5zeMK5qQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@zag-js/anatomy": "1.42.0", + "@zag-js/core": "1.42.0", + "@zag-js/dom-query": "1.42.0", + "@zag-js/types": "1.42.0", + "@zag-js/utils": "1.42.0" + } + }, + "node_modules/@zag-js/tooltip": { + "version": "1.42.0", + "resolved": "https://registry.npmjs.org/@zag-js/tooltip/-/tooltip-1.42.0.tgz", + "integrity": "sha512-viRGjX2yxF317M2G2tYvPS7+ZS3osmE+iGm40ZPg0sciezSZW1l4ZFSQ56qyCJ8rTUKv3T1m0NPWYhqVoT3eoA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@zag-js/anatomy": "1.42.0", + "@zag-js/core": "1.42.0", + "@zag-js/dom-query": "1.42.0", + "@zag-js/focus-visible": "1.42.0", + "@zag-js/popper": "1.42.0", + "@zag-js/types": "1.42.0", + "@zag-js/utils": "1.42.0" + } + }, + "node_modules/@zag-js/tree-view": { + "version": "1.42.0", + "resolved": "https://registry.npmjs.org/@zag-js/tree-view/-/tree-view-1.42.0.tgz", + "integrity": "sha512-QXIfFgE7BbtB7cHXwi8Gu/9ezkOaeZ4XFAixoJttiOgnw3EIRZPqATRijh446SDPuqsFh9RSjC2zEe3vcFssZA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@zag-js/anatomy": "1.42.0", + "@zag-js/collection": "1.42.0", + "@zag-js/core": "1.42.0", + "@zag-js/dom-query": "1.42.0", + "@zag-js/types": "1.42.0", + "@zag-js/utils": "1.42.0" + } + }, + "node_modules/@zag-js/types": { + "version": "1.42.0", + "resolved": "https://registry.npmjs.org/@zag-js/types/-/types-1.42.0.tgz", + "integrity": "sha512-4ghao1wuLouepdYMheEYtyOlKpVsvL0Eg9tf//5VyAf7S9zC7cgGxD6ttGTlIMxqKqnAuxIMsYHG76qkb8tv1w==", + "dev": true, + "license": "MIT", + "dependencies": { + "csstype": "3.2.3" + } + }, + "node_modules/@zag-js/utils": { + "version": "1.42.0", + "resolved": "https://registry.npmjs.org/@zag-js/utils/-/utils-1.42.0.tgz", + "integrity": "sha512-Km0r9hY+f6/oCJXrO4nqCIuo+4gTqbloD0V0q7B8Jq8qeWte7HN+YJSagVlk8tfADqFMRgEW4Rug0bYHzrGbVA==", + "dev": true, + "license": "MIT" + }, + "node_modules/acorn": { + "version": "8.18.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.18.0.tgz", + "integrity": "sha512-lGq+9yr1/GuAWaVYIHRjvvySG5/4VfKIvC8EWxStPdcDh/Ka7FG3twP6v4d5BkravUilhIAsG4Qj83t02LWUPQ==", + "dev": true, + "license": "MIT", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/aria-query": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.3.1.tgz", + "integrity": "sha512-Z/ZeOgVl7bcSYZ/u/rh0fOpvEpq//LZmdbkXyc7syVzjPAhfOa9ebsdTSjEBDU4vs5nC98Kfduj1uFo0qyET3g==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/axobject-query": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-4.1.0.tgz", + "integrity": "sha512-qIj0G9wZbMGNLjLmg1PT6v2mE9AH2zlnADJD/2tC6E00hgmhUOfEB6greHPAfLRSufHqROIUTkw6E+M3lH0PTQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/chokidar": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz", + "integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==", + "dev": true, + "license": "MIT", + "dependencies": { + "readdirp": "^4.0.1" + }, + "engines": { + "node": ">= 14.16.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/clsx": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.1.tgz", + "integrity": "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/cookie": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.6.0.tgz", + "integrity": "sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/csstype": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.2.3.tgz", + "integrity": "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/deepmerge": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz", + "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/detect-libc": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz", + "integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=8" + } + }, + "node_modules/devalue": { + "version": "5.9.0", + "resolved": "https://registry.npmjs.org/devalue/-/devalue-5.9.0.tgz", + "integrity": "sha512-RWrqdArjvPbsATEhOPUo6Wndc/iWnkWKlhIrdlF3zMMYo/c3CVtoaVAyLtWxz5h8nSlkHzxnzV2uLydPXmtF+A==", + "dev": true, + "license": "MIT" + }, + "node_modules/enhanced-resolve": { + "version": "5.24.5", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.24.5.tgz", + "integrity": "sha512-L1l8TNvomm6UVW5B253AGxQagSQr+vGwhMlrrfRS2qmhx46AMpMVJKQYLvWYbysTMY8VoicOvzHzoHMbyzB+4A==", + "dev": true, + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.4", + "tapable": "^2.3.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/esm-env": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/esm-env/-/esm-env-1.2.2.tgz", + "integrity": "sha512-Epxrv+Nr/CaL4ZcFGPJIYLWFom+YeV1DqMLHJoEd9SYRxNbaFruBwfEX/kkHUJf55j2+TUbmDcmuilbP1TmXHA==", + "dev": true, + "license": "MIT" + }, + "node_modules/esrap": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/esrap/-/esrap-2.3.2.tgz", + "integrity": "sha512-40GyiEJevYKXzYTHtZkFqAgTjLOuFcaXMao8TPyOlnWTlkHDlvZ6mPMJaJyOqVwrVCgomEG1WhJd81w0X+IcCw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.4.15" + }, + "peerDependencies": { + "@typescript-eslint/types": "^8.2.0" + }, + "peerDependenciesMeta": { + "@typescript-eslint/types": { + "optional": true + } + } + }, + "node_modules/fdir": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", + "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } + } + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/is-reference": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/is-reference/-/is-reference-3.0.3.tgz", + "integrity": "sha512-ixkJoqQvAP88E6wLydLGGqCJsrFUnqoH6HnaczB8XmDH1oaWU+xxdptvikTgaEhtZ53Ky6YXiBuUI2WXLMCwjw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.6" + } + }, + "node_modules/jiti": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/jiti/-/jiti-2.7.0.tgz", + "integrity": "sha512-AC/7JofJvZGrrneWNaEnJeOLUx+JlGt7tNa0wZiRPT4MY1wmfKjt2+6O2p2uz2+skll8OZZmJMNqeke7kKbNgQ==", + "dev": true, + "license": "MIT", + "bin": { + "jiti": "lib/jiti-cli.mjs" + } + }, + "node_modules/kleur": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/kleur/-/kleur-4.1.5.tgz", + "integrity": "sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/lightningcss": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.32.0.tgz", + "integrity": "sha512-NXYBzinNrblfraPGyrbPoD19C1h9lfI/1mzgWYvXUTe414Gz/X1FD2XBZSZM7rRTrMA8JL3OtAaGifrIKhQ5yQ==", + "dev": true, + "license": "MPL-2.0", + "dependencies": { + "detect-libc": "^2.0.3" + }, + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + }, + "optionalDependencies": { + "lightningcss-android-arm64": "1.32.0", + "lightningcss-darwin-arm64": "1.32.0", + "lightningcss-darwin-x64": "1.32.0", + "lightningcss-freebsd-x64": "1.32.0", + "lightningcss-linux-arm-gnueabihf": "1.32.0", + "lightningcss-linux-arm64-gnu": "1.32.0", + "lightningcss-linux-arm64-musl": "1.32.0", + "lightningcss-linux-x64-gnu": "1.32.0", + "lightningcss-linux-x64-musl": "1.32.0", + "lightningcss-win32-arm64-msvc": "1.32.0", + "lightningcss-win32-x64-msvc": "1.32.0" + } + }, + "node_modules/lightningcss-android-arm64": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-android-arm64/-/lightningcss-android-arm64-1.32.0.tgz", + "integrity": "sha512-YK7/ClTt4kAK0vo6w3X+Pnm0D2cf2vPHbhOXdoNti1Ga0al1P4TBZhwjATvjNwLEBCnKvjJc2jQgHXH0NEwlAg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-darwin-arm64": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.32.0.tgz", + "integrity": "sha512-RzeG9Ju5bag2Bv1/lwlVJvBE3q6TtXskdZLLCyfg5pt+HLz9BqlICO7LZM7VHNTTn/5PRhHFBSjk5lc4cmscPQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-darwin-x64": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.32.0.tgz", + "integrity": "sha512-U+QsBp2m/s2wqpUYT/6wnlagdZbtZdndSmut/NJqlCcMLTWp5muCrID+K5UJ6jqD2BFshejCYXniPDbNh73V8w==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-freebsd-x64": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-freebsd-x64/-/lightningcss-freebsd-x64-1.32.0.tgz", + "integrity": "sha512-JCTigedEksZk3tHTTthnMdVfGf61Fky8Ji2E4YjUTEQX14xiy/lTzXnu1vwiZe3bYe0q+SpsSH/CTeDXK6WHig==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-arm-gnueabihf": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.32.0.tgz", + "integrity": "sha512-x6rnnpRa2GL0zQOkt6rts3YDPzduLpWvwAF6EMhXFVZXD4tPrBkEFqzGowzCsIWsPjqSK+tyNEODUBXeeVHSkw==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-arm64-gnu": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.32.0.tgz", + "integrity": "sha512-0nnMyoyOLRJXfbMOilaSRcLH3Jw5z9HDNGfT/gwCPgaDjnx0i8w7vBzFLFR1f6CMLKF8gVbebmkUN3fa/kQJpQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-arm64-musl": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.32.0.tgz", + "integrity": "sha512-UpQkoenr4UJEzgVIYpI80lDFvRmPVg6oqboNHfoH4CQIfNA+HOrZ7Mo7KZP02dC6LjghPQJeBsvXhJod/wnIBg==", + "cpu": [ + "arm64" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-x64-gnu": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.32.0.tgz", + "integrity": "sha512-V7Qr52IhZmdKPVr+Vtw8o+WLsQJYCTd8loIfpDaMRWGUZfBOYEJeyJIkqGIDMZPwPx24pUMfwSxxI8phr/MbOA==", + "cpu": [ + "x64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-x64-musl": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.32.0.tgz", + "integrity": "sha512-bYcLp+Vb0awsiXg/80uCRezCYHNg1/l3mt0gzHnWV9XP1W5sKa5/TCdGWaR/zBM2PeF/HbsQv/j2URNOiVuxWg==", + "cpu": [ + "x64" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-win32-arm64-msvc": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-win32-arm64-msvc/-/lightningcss-win32-arm64-msvc-1.32.0.tgz", + "integrity": "sha512-8SbC8BR40pS6baCM8sbtYDSwEVQd4JlFTOlaD3gWGHfThTcABnNDBda6eTZeqbofalIJhFx0qKzgHJmcPTnGdw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-win32-x64-msvc": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.32.0.tgz", + "integrity": "sha512-Amq9B/SoZYdDi1kFrojnoqPLxYhQ4Wo5XiL8EVJrVsB8ARoC1PWW6VGtT0WKCemjy8aC+louJnjS7U18x3b06Q==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/locate-character": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/locate-character/-/locate-character-3.0.0.tgz", + "integrity": "sha512-SW13ws7BjaeJ6p7Q6CO2nchbYEc3X3J6WrmTTDto7yMPqVSZTUyY5Tjbid+Ab8gLnATtygYtiDIJGQRRn2ZOiA==", + "dev": true, + "license": "MIT" + }, + "node_modules/magic-string": { + "version": "0.30.21", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.21.tgz", + "integrity": "sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.5" + } + }, + "node_modules/mri": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/mri/-/mri-1.2.0.tgz", + "integrity": "sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/mrmime": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/mrmime/-/mrmime-2.0.1.tgz", + "integrity": "sha512-Y3wQdFg2Va6etvQ5I82yUhGdsKrcYox6p7FfL1LbK2J4V01F9TGlepTIhnK24t7koZibmg82KGglhA1XK5IsLQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + } + }, + "node_modules/nanoid": { + "version": "3.3.18", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.18.tgz", + "integrity": "sha512-DTg4MJbGMWkfi6VZFdNt2/caMbQy4Ou+Op/hJQvGEWcnVfoA1QA+xzRKAzw9jD6+GVOOeYr/mIcuDSdug6F6+w==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/obug": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/obug/-/obug-2.1.4.tgz", + "integrity": "sha512-4a+OsYv9UktOJKE+l1A4OufDgdRF9PifWj+tJnHURo/P+WOxpG4GzUFL9qCalmWauao6ogiG+QvnCovwPoyAWA==", + "dev": true, + "funding": [ + "https://github.com/sponsors/sxzz", + "https://opencollective.com/debug" + ], + "license": "MIT", + "engines": { + "node": ">=12.20.0" + } + }, + "node_modules/picocolors": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "dev": true, + "license": "ISC" + }, + "node_modules/picomatch": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.5.tgz", + "integrity": "sha512-RvwwcruNjI1ncT5xRakeyS9Lf8lcItv34KD+aif+VH9kduAyfYBipGh12274xtenIPZ119/R9BdTBa8gAwSh0A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/postcss": { + "version": "8.5.26", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.26.tgz", + "integrity": "sha512-u82N74LFzG8ca+dD8puPnplTXoGH4fTPpVGuIbt36G3qvNlkvfD0lEAZSxaly3KX8TS/L1A1gsCEmvKmBcVbkQ==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "nanoid": "^3.3.17", + "picocolors": "^1.1.1", + "source-map-js": "^1.2.1" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/proxy-compare": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/proxy-compare/-/proxy-compare-3.0.1.tgz", + "integrity": "sha512-V9plBAt3qjMlS1+nC8771KNf6oJ12gExvaxnNzN/9yVRLdTv/lc+oJlnSzrdYDAvBfTStPCoiaCOTmTs0adv7Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/proxy-memoize": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/proxy-memoize/-/proxy-memoize-3.0.1.tgz", + "integrity": "sha512-VDdG/VYtOgdGkWJx7y0o7p+zArSf2383Isci8C+BP3YXgMYDoPd3cCBjw0JdWb6YBb9sFiOPbAADDVTPJnh+9g==", + "dev": true, + "license": "MIT", + "dependencies": { + "proxy-compare": "^3.0.0" + } + }, + "node_modules/readdirp": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.1.2.tgz", + "integrity": "sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 14.18.0" + }, + "funding": { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/rolldown": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/rolldown/-/rolldown-1.2.3.tgz", + "integrity": "sha512-rn9wpmxplLf7NLNyCk9FyWh3FM43DbY8jOzCdEPzH7uflhTftRbCEpqi6Ly2osgoU8OwObtmavMbWLaWy4LX7A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@oxc-project/types": "=0.143.0", + "@rolldown/pluginutils": "^1.0.0" + }, + "bin": { + "rolldown": "bin/cli.mjs" + }, + "engines": { + "node": "^20.19.0 || >=22.12.0" + }, + "optionalDependencies": { + "@rolldown/binding-android-arm64": "1.2.3", + "@rolldown/binding-darwin-arm64": "1.2.3", + "@rolldown/binding-darwin-x64": "1.2.3", + "@rolldown/binding-freebsd-x64": "1.2.3", + "@rolldown/binding-linux-arm-gnueabihf": "1.2.3", + "@rolldown/binding-linux-arm64-gnu": "1.2.3", + "@rolldown/binding-linux-arm64-musl": "1.2.3", + "@rolldown/binding-linux-ppc64-gnu": "1.2.3", + "@rolldown/binding-linux-s390x-gnu": "1.2.3", + "@rolldown/binding-linux-x64-gnu": "1.2.3", + "@rolldown/binding-linux-x64-musl": "1.2.3", + "@rolldown/binding-openharmony-arm64": "1.2.3", + "@rolldown/binding-win32-arm64-msvc": "1.2.3", + "@rolldown/binding-win32-x64-msvc": "1.2.3" + } + }, + "node_modules/sade": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/sade/-/sade-1.8.1.tgz", + "integrity": "sha512-xal3CZX1Xlo/k4ApwCFrHVACi9fBqJ7V+mwhBsuf/1IOKbBy098Fex+Wa/5QMubw09pSZ/u8EY8PWgevJsXp1A==", + "dev": true, + "license": "MIT", + "dependencies": { + "mri": "^1.1.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/set-cookie-parser": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/set-cookie-parser/-/set-cookie-parser-3.1.2.tgz", + "integrity": "sha512-5/r/lTwbJ3zQ+qwdUFZYeRNqda7P5HD8zQKqlSjdGt1/S0cjLAphHusj4Y58ahDtWn/g32xrIS58/ikOvwl0Lw==", + "dev": true, + "license": "MIT" + }, + "node_modules/sirv": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/sirv/-/sirv-3.0.2.tgz", + "integrity": "sha512-2wcC/oGxHis/BoHkkPwldgiPSYcpZK3JU28WoMVv55yHJgcZ8rlXvuG9iZggz+sU1d4bRgIGASwyWqjxu3FM0g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@polka/url": "^1.0.0-next.24", + "mrmime": "^2.0.0", + "totalist": "^3.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/source-map-js": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", + "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/svelte": { + "version": "5.56.8", + "resolved": "https://registry.npmjs.org/svelte/-/svelte-5.56.8.tgz", + "integrity": "sha512-PY8LOw7xP6c8IOiVqdo0sbbZVYhXRSfklOQLAUyGBKqjTX0wx/z4l/9J+PmBpmlLnxzEb1NqltxQ5/wZme/Cmg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/remapping": "^2.3.4", + "@jridgewell/sourcemap-codec": "^1.5.0", + "@sveltejs/acorn-typescript": "^1.0.10", + "@types/estree": "^1.0.5", + "@types/trusted-types": "^2.0.7", + "acorn": "^8.12.1", + "aria-query": "5.3.1", + "axobject-query": "^4.1.0", + "clsx": "^2.1.1", + "devalue": "^5.8.1", + "esm-env": "^1.2.1", + "esrap": "^2.2.12", + "is-reference": "^3.0.3", + "locate-character": "^3.0.0", + "magic-string": "^0.30.11", + "zimmerframe": "^1.1.2" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/svelte-check": { + "version": "4.7.5", + "resolved": "https://registry.npmjs.org/svelte-check/-/svelte-check-4.7.5.tgz", + "integrity": "sha512-NnkHGCTPH6k4ka1E9IpTuNv40uLArHnX52kLEuaHSGqRlPYTnkbFs529jSWG+y+wDy+v+jA2PQ0soN1umVK+OA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/trace-mapping": "^0.3.25", + "@sveltejs/load-config": "^0.2.2", + "chokidar": "^4.0.1", + "fdir": "^6.2.0", + "picocolors": "^1.0.0", + "sade": "^1.7.4" + }, + "bin": { + "svelte-check": "bin/svelte-check" + }, + "engines": { + "node": ">= 18.0.0" + }, + "peerDependencies": { + "svelte": "^4.0.0 || ^5.0.0-next.0", + "typescript": "^5.0.0 || ^6.0.0" + } + }, + "node_modules/tailwindcss": { + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-4.3.3.tgz", + "integrity": "sha512-gOhV3P7ufE62QDGg1zVaTgCR+EtPv92k2nIhVcVKcLmxT1sUBsQGhnZj175j+MqRt4zLF7ic+sCYjfhxMxj7YQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/tapable": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.3.3.tgz", + "integrity": "sha512-uxc/zpqFg6x7C8vOE7lh6Lbda8eEL9zmVm/PLeTPBRhh1xCgdWaQ+J1CUieGpIfm2HdtsUpRv+HshiasBMcc6A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/tinyglobby": { + "version": "0.2.17", + "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.17.tgz", + "integrity": "sha512-wXR/dYpcqKmfWpEdZjiKJOwCNFndD0DMnrW/cYjVGttEkBfVgcLFHoNrlj47mjOVic9yyNu65alsgF4NQyTa2g==", + "dev": true, + "license": "MIT", + "dependencies": { + "fdir": "^6.5.0", + "picomatch": "^4.0.4" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/SuperchupuDev" + } + }, + "node_modules/totalist": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/totalist/-/totalist-3.0.1.tgz", + "integrity": "sha512-sf4i37nQ2LBx4m3wB74y+ubopq6W/dIzXg0FDGjsYnZHVa1Da8FH853wlL2gtUhg+xJXjfk3kUZS3BRoQeoQBQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "dev": true, + "license": "0BSD" + }, + "node_modules/typescript": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-6.0.3.tgz", + "integrity": "sha512-y2TvuxSZPDyQakkFRPZHKFm+KKVqIisdg9/CZwm9ftvKXLP8NRWj38/ODjNbr43SsoXqNuAisEf1GdCxqWcdBw==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/uqr": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/uqr/-/uqr-0.1.3.tgz", + "integrity": "sha512-0rjE8iEJe4YmT9TOhwsZtqCMRLc5DXZUI2UEYUUg63ikBkqqE5EYWaI0etFe/5KUcmcYwLih2RND1kq+hrUJXA==", + "dev": true, + "license": "MIT" + }, + "node_modules/vite": { + "version": "8.2.1", + "resolved": "https://registry.npmjs.org/vite/-/vite-8.2.1.tgz", + "integrity": "sha512-EU/eS7BH3XROHh2YnBefjM6DBKA6ZeMZEYQbj7NLWg5wHYlhB8B/Mayd5XsgWq+NFYccDOTemRpdETWR6Ka/lw==", + "dev": true, + "license": "MIT", + "dependencies": { + "lightningcss": "^1.33.0", + "picomatch": "^4.0.5", + "postcss": "^8.5.25", + "rolldown": "~1.2.1", + "tinyglobby": "^0.2.17" + }, + "bin": { + "vite": "bin/vite.js" + }, + "engines": { + "node": "^20.19.0 || >=22.12.0" + }, + "funding": { + "url": "https://github.com/vitejs/vite?sponsor=1" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" + }, + "peerDependencies": { + "@types/node": "^20.19.0 || >=22.12.0", + "@vitejs/devtools": "^0.4.0", + "esbuild": "^0.27.0 || ^0.28.0", + "jiti": ">=1.21.0", + "less": "^4.0.0", + "sass": "^1.70.0", + "sass-embedded": "^1.70.0", + "stylus": ">=0.54.8", + "sugarss": "^5.0.0", + "terser": "^5.16.0", + "tsx": "^4.8.1", + "yaml": "^2.4.2" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "@vitejs/devtools": { + "optional": true + }, + "esbuild": { + "optional": true + }, + "jiti": { + "optional": true + }, + "less": { + "optional": true + }, + "sass": { + "optional": true + }, + "sass-embedded": { + "optional": true + }, + "stylus": { + "optional": true + }, + "sugarss": { + "optional": true + }, + "terser": { + "optional": true + }, + "tsx": { + "optional": true + }, + "yaml": { + "optional": true + } + } + }, + "node_modules/vite/node_modules/lightningcss": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.33.0.tgz", + "integrity": "sha512-WkUDrojuJs0xkgGf2udWxa3yGBRxPtxUkB79i6aCZLRgc7PM8fZe9TosfPDcvEpQZbuFASnHYmRLBLUbmLOIIA==", + "dev": true, + "license": "MPL-2.0", + "dependencies": { + "detect-libc": "^2.0.3" + }, + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + }, + "optionalDependencies": { + "lightningcss-android-arm64": "1.33.0", + "lightningcss-darwin-arm64": "1.33.0", + "lightningcss-darwin-x64": "1.33.0", + "lightningcss-freebsd-x64": "1.33.0", + "lightningcss-linux-arm-gnueabihf": "1.33.0", + "lightningcss-linux-arm64-gnu": "1.33.0", + "lightningcss-linux-arm64-musl": "1.33.0", + "lightningcss-linux-x64-gnu": "1.33.0", + "lightningcss-linux-x64-musl": "1.33.0", + "lightningcss-win32-arm64-msvc": "1.33.0", + "lightningcss-win32-x64-msvc": "1.33.0" + } + }, + "node_modules/vite/node_modules/lightningcss-android-arm64": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-android-arm64/-/lightningcss-android-arm64-1.33.0.tgz", + "integrity": "sha512-gEpRTalKdosp4Bb8qWtc2iOgE5SeIHlpS1up9bFq2wAyYhl1UdTObYiHe98zEM9SQvSoqQZ1IQD0JNpg3Ml5pg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/vite/node_modules/lightningcss-darwin-arm64": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.33.0.tgz", + "integrity": "sha512-Sciaz8eenNTKn9b3t7+xr0ipTp9YxKQY4npwQ3mrRuL0BAVHBLyZxofhaKBAVtzmtRZ/zTyo0/to4B1uWG/Djg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/vite/node_modules/lightningcss-darwin-x64": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.33.0.tgz", + "integrity": "sha512-Z5UPAxzrjlWNNyGy6i65cJzzvgJ5D3T6wMvs+gWpY9d7qRhANrxqAp6LhxIgZhWEw18RfJTGcRxjuLIBr+m8XQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/vite/node_modules/lightningcss-freebsd-x64": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-freebsd-x64/-/lightningcss-freebsd-x64-1.33.0.tgz", + "integrity": "sha512-QQM/Ti/hQajJwCY+RiWuCZ9sdtI/XQk7nDK5vC8kkdwixezOlDgvDx7+RT+QjK6FcFT4MpsuoBnHIo/O3StRRg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/vite/node_modules/lightningcss-linux-arm-gnueabihf": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.33.0.tgz", + "integrity": "sha512-N7FVBe6iS24MlM6R/4RBTxGhQheZGs7tiQ9U32UtF75NzP5Q7xWPRqLBCKxlRQRk3rY1jCIPLzx7WzOhuUIRLQ==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/vite/node_modules/lightningcss-linux-arm64-gnu": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.33.0.tgz", + "integrity": "sha512-j2v/itmy4HlNxlc6voKXYgBqNi0Ng2LShg4z7GufpEgs05P+2suBVyi9I6YHq5uoVFx9ETin3eCEhLVyXGQnKg==", + "cpu": [ + "arm64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/vite/node_modules/lightningcss-linux-arm64-musl": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.33.0.tgz", + "integrity": "sha512-yiO5ROMuYQgXbC60yjZU5CYSFZGKXL0HFATXt9mHJn1+zW55oCtMI9NfcVhYLMFDL7gV7oBPon/EmMMGg2OvtQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/vite/node_modules/lightningcss-linux-x64-gnu": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.33.0.tgz", + "integrity": "sha512-ar+Ju7LmcN0Jo4FpL4hpFybwNG9/3A/Br5KW2n2jyODg3MEZXaDYADdemoNS+BDNfMgKvylJLj4S5tyRActuAg==", + "cpu": [ + "x64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/vite/node_modules/lightningcss-linux-x64-musl": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.33.0.tgz", + "integrity": "sha512-RYiYbkokw0trfKqqzfF55lginwEPrD3OJDfTuJzFs1MK6iFnDenaz1fqLLtX4ITG3OktJQXOeTaw1awrBAlZPw==", + "cpu": [ + "x64" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/vite/node_modules/lightningcss-win32-arm64-msvc": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-win32-arm64-msvc/-/lightningcss-win32-arm64-msvc-1.33.0.tgz", + "integrity": "sha512-1K+MPfLSFVpphzpdbfkhlWk6wBrTObBzS2T6db10PNOZgR9GoVsAWzwNyuhUYYbTp23j+4RrncfujZ4uAzXvwA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/vite/node_modules/lightningcss-win32-x64-msvc": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.33.0.tgz", + "integrity": "sha512-OlEICDx/Xl0FqSp4bry8zFnCvGpig3Gl4gCquvYwHuqJKEC1+n9NgDniFvqHGmMv1ZkqDJrDqKKSykTDX+ehuA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/vitefu": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/vitefu/-/vitefu-1.1.3.tgz", + "integrity": "sha512-ub4okH7Z5KLjb6hDyjqrGXqWtWvoYdU3IGm/NorpgHncKoLTCfRIbvlhBm7r0YstIaQRYlp4yEbFqDcKSzXSSg==", + "dev": true, + "license": "MIT", + "workspaces": [ + "tests/deps/*", + "tests/projects/*", + "tests/projects/workspace/packages/*" + ], + "peerDependencies": { + "vite": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0" + }, + "peerDependenciesMeta": { + "vite": { + "optional": true + } + } + }, + "node_modules/zimmerframe": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/zimmerframe/-/zimmerframe-1.1.4.tgz", + "integrity": "sha512-B58NGBEoc8Y9MWWCQGl/gq9xBCe4IiKM0a2x7GZdQKOW5Exr8S1W24J6OgM1njK8xCRGvAJIL/MxXHf6SkmQKQ==", + "dev": true, + "license": "MIT" + } + } +} diff --git a/ui/package.json b/ui/package.json new file mode 100644 index 0000000..53e07b4 --- /dev/null +++ b/ui/package.json @@ -0,0 +1,27 @@ +{ + "name": "ui", + "private": true, + "version": "0.0.1", + "type": "module", + "scripts": { + "dev": "vite dev", + "build": "vite build", + "preview": "vite preview", + "prepare": "svelte-kit sync || echo ''", + "check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json", + "check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch" + }, + "devDependencies": { + "@skeletonlabs/skeleton": "^5.0.0", + "@skeletonlabs/skeleton-svelte": "^5.0.0", + "@sveltejs/adapter-static": "^3.0.10", + "@sveltejs/kit": "^2.63.0", + "@sveltejs/vite-plugin-svelte": "^7.1.2", + "@tailwindcss/vite": "^4.3.0", + "svelte": "^5.56.1", + "svelte-check": "^4.6.0", + "tailwindcss": "^4.3.0", + "typescript": "^6.0.3", + "vite": "^8.0.16" + } +} diff --git a/ui/pnpm-lock.yaml b/ui/pnpm-lock.yaml new file mode 100644 index 0000000..efbec13 --- /dev/null +++ b/ui/pnpm-lock.yaml @@ -0,0 +1,1751 @@ +lockfileVersion: '9.0' + +settings: + autoInstallPeers: true + excludeLinksFromLockfile: false + +importers: + + .: + devDependencies: + '@skeletonlabs/skeleton': + specifier: ^5.0.0 + version: 5.0.0(tailwindcss@4.3.3) + '@skeletonlabs/skeleton-svelte': + specifier: ^5.0.0 + version: 5.0.0(svelte@5.56.8) + '@sveltejs/adapter-static': + specifier: ^3.0.10 + version: 3.0.10(@sveltejs/kit@2.70.2(@sveltejs/vite-plugin-svelte@7.3.0(svelte@5.56.8)(vite@8.2.1(jiti@2.7.0)))(svelte@5.56.8)(typescript@6.0.3)(vite@8.2.1(jiti@2.7.0))) + '@sveltejs/kit': + specifier: ^2.63.0 + version: 2.70.2(@sveltejs/vite-plugin-svelte@7.3.0(svelte@5.56.8)(vite@8.2.1(jiti@2.7.0)))(svelte@5.56.8)(typescript@6.0.3)(vite@8.2.1(jiti@2.7.0)) + '@sveltejs/vite-plugin-svelte': + specifier: ^7.1.2 + version: 7.3.0(svelte@5.56.8)(vite@8.2.1(jiti@2.7.0)) + '@tailwindcss/vite': + specifier: ^4.3.0 + version: 4.3.3(vite@8.2.1(jiti@2.7.0)) + svelte: + specifier: ^5.56.1 + version: 5.56.8 + svelte-check: + specifier: ^4.6.0 + version: 4.7.5(picomatch@4.0.5)(svelte@5.56.8)(typescript@6.0.3) + tailwindcss: + specifier: ^4.3.0 + version: 4.3.3 + typescript: + specifier: ^6.0.3 + version: 6.0.3 + vite: + specifier: ^8.0.16 + version: 8.2.1(jiti@2.7.0) + +packages: + + '@floating-ui/core@1.8.0': + resolution: {integrity: sha512-0CIZ5itps/8x7BG8dEIhs53BvCUH2PCoogtakwRTut+Arm58sJooJ0AuZhLw2HJYIR5cMLNPBSS728sPho2khQ==} + + '@floating-ui/dom@1.8.0': + resolution: {integrity: sha512-yXSrzeHZBTZadLOlfyhCkJHNeLJnHRnRInwdZ40L7ZiaAtrBwoYlsDrX3v5zB1Utk7CLfzcOVnVVWoXEky7Ceg==} + + '@floating-ui/utils@0.2.12': + resolution: {integrity: sha512-HpCo8tmWzLVad5s2d19EhAz5zqrrQ6s69qd6moPMQvkOuSwDT1YgRfWSVuc4ennqrgv3OHppiOGMQ7oC13yIww==} + + '@internationalized/date@3.12.2': + resolution: {integrity: sha512-FY1Y+H64NDs+HAF6omlnWxm3mEpfgaCSWtL5l551ZZfImA+kGjPFgrnJrGjH6lfmLL0g8Z/mBu1R3kufeCp6Jw==} + + '@jridgewell/gen-mapping@0.3.13': + resolution: {integrity: sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==} + + '@jridgewell/remapping@2.3.5': + resolution: {integrity: sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==} + + '@jridgewell/resolve-uri@3.1.2': + resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==} + engines: {node: '>=6.0.0'} + + '@jridgewell/sourcemap-codec@1.5.5': + resolution: {integrity: sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==} + + '@jridgewell/trace-mapping@0.3.31': + resolution: {integrity: sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==} + + '@oxc-project/types@0.143.0': + resolution: {integrity: sha512-u6JZdLBTLotrNC9Vd6vPssINdzcCzleKAH6EJKImQb7GtYvX5keN2dxkoK44stCc4tffE6QQRtZTXVSzsLUlWA==} + + '@polka/url@1.0.0-next.29': + resolution: {integrity: sha512-wwQAWhWSuHaag8c4q/KN/vCoeOJYshAIvMQwD4GpSb3OiZklFfvAgmj0VCBBImRpuF/aFgIRzllXlVX93Jevww==} + + '@rolldown/binding-android-arm64@1.2.3': + resolution: {integrity: sha512-zrJtHDcaZJ1Fp7xf4hNl+7seH9Cn/N5TwLYkhgXREtBwAd/jaqW3uqeHxpDugJLVICWg4eW44kOQEGJ1r6jCGw==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [android] + + '@rolldown/binding-darwin-arm64@1.2.3': + resolution: {integrity: sha512-ieIiibVCp0tX7TLu2cafoNPv8wJyYi01ekXpbf8q2j7F4rGAhhXb/eQh7ge9DRBY78GwmRQtvjZDux7EDbA8kA==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [darwin] + + '@rolldown/binding-darwin-x64@1.2.3': + resolution: {integrity: sha512-Zh9tCon19eDXJoihx0rqKhMUlMYqzwj3aPsSuHmI4RWZh62dWUL+DJN4C5YQya5TcQBJU/Fe8+rY0jhXTQITqA==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [darwin] + + '@rolldown/binding-freebsd-x64@1.2.3': + resolution: {integrity: sha512-nGbJWewA1wrXXZiQhjAT5rhibGfns5ZNkDVqxsO6zJ3f3YvpoDNNmGMSbbhLuXKjNScaBJVOAboztAWVespQMg==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [freebsd] + + '@rolldown/binding-linux-arm-gnueabihf@1.2.3': + resolution: {integrity: sha512-QNniJr5Kml0kDEB98jiDOJjXNroxIIi0IXIbdYzY26Xt1pVbeP62+KnoIZLwirOymX/0jDk/2gI/bNUv7A7OIw==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm] + os: [linux] + + '@rolldown/binding-linux-arm64-gnu@1.2.3': + resolution: {integrity: sha512-TkqEAcmmvH3I/q4114NB4RVt6241Dao48pF45uLcFGrwAaIn0iITgTAKP/dLjbN0R4buJjGb91+UHSoFmpgIWw==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [linux] + libc: [glibc] + + '@rolldown/binding-linux-arm64-musl@1.2.3': + resolution: {integrity: sha512-NHqjnxpsndf4MPymxteFAWHHfkTL8HjWh1KB7z23ofZ6QO2euONuxDXjat69dKZRALnGypg8k8SsK8vZJoXv1Q==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [linux] + libc: [musl] + + '@rolldown/binding-linux-ppc64-gnu@1.2.3': + resolution: {integrity: sha512-6tbrbwfz5GB9DQ4Jwo6hy9v+vR31xZlvzZ6n5Xut6Hhx5PvrA9q/HsK8KMaYQp063iqZGXwNvZtYNLD7EM/x0w==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [ppc64] + os: [linux] + libc: [glibc] + + '@rolldown/binding-linux-s390x-gnu@1.2.3': + resolution: {integrity: sha512-oyuXxXmoZHjXC917IAPFAAv4wWAa0cM9afk8nx1+9/jNNOX1uPf8yDA6p7G0RypOfw/X0PQt5IfoquY1um+zSg==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [s390x] + os: [linux] + libc: [glibc] + + '@rolldown/binding-linux-x64-gnu@1.2.3': + resolution: {integrity: sha512-TytMwF2KVGqP2tgd0I1OY0PAv78dZRAYcF5ssDzjM34SUXCED3uXvSd5+lHoC0bTD6eEdFz7LdQNCO1y0oVk9w==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [linux] + libc: [glibc] + + '@rolldown/binding-linux-x64-musl@1.2.3': + resolution: {integrity: sha512-/E9m3qstrJFVPoULV25mVQblSNExY2+kBsYe4sy0Tn0yOOgJ8wZbZt3KnRbF/XeU2Gl1STKUQnDNTqhIE5MD4A==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [linux] + libc: [musl] + + '@rolldown/binding-openharmony-arm64@1.2.3': + resolution: {integrity: sha512-Kr0OcsoQI816i6HOl3vFHpd1K0eZyh76zgfj4c1nTyaTsd5r2Mj1lwM4R90y/qaCfmTn9eHy0SKwi98eitRxug==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [openharmony] + + '@rolldown/binding-win32-arm64-msvc@1.2.3': + resolution: {integrity: sha512-hOtMwTqnME+/gJcH/PCZ0wn0zPUjiWOgkHpxbSJpfGKMezHltx1S7/k1SitzVa7Ww2cqrDDaFbZEhcJZO8o+Jw==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [win32] + + '@rolldown/binding-win32-x64-msvc@1.2.3': + resolution: {integrity: sha512-ekcqMMkI2PlhYnfzQnB/cEdYUVVJViWvoUyLrbzgDoi3Snfc1mVBwdnc306ufA5ejy8JSPjT2RlW1nQSjW7efg==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [win32] + + '@rolldown/pluginutils@1.0.1': + resolution: {integrity: sha512-2j9bGt5Jh8hj+vPtgzPtl72j0yRxHAyumoo6TNfAjsLB04UtpSvPbPcDcBMxz7n+9CYB0c1GxQFxYRg2jimqGw==} + + '@skeletonlabs/skeleton-common@5.0.0': + resolution: {integrity: sha512-OzBf8nUsYMXPSo6FO2MSZ+pKzAN66Dro9Jis3Xf7sJRpbpzLU9sr4PSW9K9uDy4Z6/EiQPk7R9JMr0J633ft6w==} + + '@skeletonlabs/skeleton-svelte@5.0.0': + resolution: {integrity: sha512-SuUX19bCFku8GF2kmLPFUTC1c7k8GeSSYJz4oJfa7Nb3LTIY+WDMWeGbwvMzfqyhV6s2XV3xefyf1joVHgzPAg==} + peerDependencies: + svelte: ^5.40.0 + + '@skeletonlabs/skeleton@5.0.0': + resolution: {integrity: sha512-kcUU77eZTNdbz59FgCxIjimH1d9DkZtMU3+IT2yBxoFQczZGPkJ0xw97ecHeJfzBp8Ah16NqPOcxHjXxO77O9w==} + peerDependencies: + tailwindcss: ^4.0.0 + + '@standard-schema/spec@1.1.0': + resolution: {integrity: sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w==} + + '@sveltejs/acorn-typescript@1.0.12': + resolution: {integrity: sha512-J1jNYG23QWd67UfrQSFHtjhV37r9mVi0gdc12A3MWPldOjRK35Xk+um+qACPVjgw3AleiqoyEAhok8Wm3q46NA==} + peerDependencies: + acorn: ^8.9.0 + + '@sveltejs/adapter-static@3.0.10': + resolution: {integrity: sha512-7D9lYFWJmB7zxZyTE/qxjksvMqzMuYrrsyh1f4AlZqeZeACPRySjbC3aFiY55wb1tWUaKOQG9PVbm74JcN2Iew==} + peerDependencies: + '@sveltejs/kit': ^2.0.0 + + '@sveltejs/kit@2.70.2': + resolution: {integrity: sha512-RzRoRpuR2KXqc5yMO0akQHDZeT4AslOlznGITURsqHaVbtyYP4Wn3eE3gxj9JcDyNYO0crkxhdwFHc+2vkVm6w==} + engines: {node: '>=18.13'} + hasBin: true + peerDependencies: + '@opentelemetry/api': ^1.0.0 + '@sveltejs/vite-plugin-svelte': ^3.0.0 || ^4.0.0-next.1 || ^5.0.0 || ^6.0.0-next.0 || ^7.0.0 + svelte: ^4.0.0 || ^5.0.0-next.0 + typescript: ^5.3.3 || ^6.0.0 + vite: ^5.0.3 || ^6.0.0 || ^7.0.0-beta.0 || ^8.0.0 + peerDependenciesMeta: + '@opentelemetry/api': + optional: true + typescript: + optional: true + + '@sveltejs/load-config@0.2.2': + resolution: {integrity: sha512-K7dsJDQxBOF+f+epuhMactcjK2VP4MRkLKtwSykNtEI+cKVEyzrmmhQ1pmoxI800m4JKcyJ05L2M4yPwAGiBNw==} + engines: {node: '>= 18.0.0'} + + '@sveltejs/vite-plugin-svelte@7.3.0': + resolution: {integrity: sha512-QbRoJyD92e9R0ufeQIWRHrCC0ObcqSv/aBDdrQMoU+sypav3cDx5wytdQ6GLdXjEMO6xjrXGzfkUygng8JMv0A==} + engines: {node: ^20.19 || ^22.12 || >=24} + peerDependencies: + svelte: ^5.46.4 + vite: ^8.0.0-beta.7 || ^8.0.0 + + '@swc/helpers@0.5.23': + resolution: {integrity: sha512-5lSsMOTXURePglDfvuAQUqkGek9Hg2kksOYay2m0+XR++b2NWYL/4sWyuvVBIs8oKnJaxkdi9whaL/sqN13afw==} + + '@tailwindcss/node@4.3.3': + resolution: {integrity: sha512-/T8IKEsf9VTU6tLjgC7+sv2mOPtQxzE2jMw7u4Tt40Tx+QSZxpzh95/H6cMKoja9XuW7iMdLJYBB0o9G1CaAgg==} + + '@tailwindcss/oxide-android-arm64@4.3.3': + resolution: {integrity: sha512-Y85A2gmPSkl5Ve5qR86GL4HT509cFqQh1aes9p3sSkyTPwt0Pppf3GkwGe4JPACcRYjgJIEhQgM6dBClnr0NYw==} + engines: {node: '>= 20'} + cpu: [arm64] + os: [android] + + '@tailwindcss/oxide-darwin-arm64@4.3.3': + resolution: {integrity: sha512-BiaWatpBcERQFDlOjRDpIVXuFK5PJez5SA4JMg6VYZdBYU+qKfV/vqjcIs+IYmtitf1xYQZTwXvU/8y4lfZUGw==} + engines: {node: '>= 20'} + cpu: [arm64] + os: [darwin] + + '@tailwindcss/oxide-darwin-x64@4.3.3': + resolution: {integrity: sha512-fAeUqfV5ndhxRwai8cXGzdLvul9utWOmeTkv69unv4ZXixjn61Z+p9lCWdwOwA3TYboG3BwdVuN/RDjhBRl0mw==} + engines: {node: '>= 20'} + cpu: [x64] + os: [darwin] + + '@tailwindcss/oxide-freebsd-x64@4.3.3': + resolution: {integrity: sha512-iyf5bV6+wnAlflVeEy7R25dupxTNECZN5QMI0qNT6eT+EgaGdZcKhGkr5SdoaWiLJ3spLqIY9VCeSGrwmtg4kw==} + engines: {node: '>= 20'} + cpu: [x64] + os: [freebsd] + + '@tailwindcss/oxide-linux-arm-gnueabihf@4.3.3': + resolution: {integrity: sha512-aAYUprJAJQWWbRrPvtjdroZ56Md+JM8pMiopS6xGEwDfLhqj+2ver2p4nU4Mb3CRqcMmNBjo8KkUgcxhkzVQGQ==} + engines: {node: '>= 20'} + cpu: [arm] + os: [linux] + + '@tailwindcss/oxide-linux-arm64-gnu@4.3.3': + resolution: {integrity: sha512-nDxldcEENOxZRzC2uu9jrutZdAAQtb+8WWDCSnWL1zvBk1+FN+x6MtDViPB5AJMfttVCUhehGWus3XBPgatM/w==} + engines: {node: '>= 20'} + cpu: [arm64] + os: [linux] + libc: [glibc] + + '@tailwindcss/oxide-linux-arm64-musl@4.3.3': + resolution: {integrity: sha512-Md44bD6veX/PC5iyF8cDVnw4HBIANZepRZZ7a8DQOvkfo5WUBwcp6iAuCUz23u+4SUkhJlD3eL7hNdW8ezd/kA==} + engines: {node: '>= 20'} + cpu: [arm64] + os: [linux] + libc: [musl] + + '@tailwindcss/oxide-linux-x64-gnu@4.3.3': + resolution: {integrity: sha512-tx7us1muwOKAKWao2v/GaafFeQboE6aj88vC6ziN2NCGcRm8gWUhwjzg+YdVB1e4boAtdtma4L43onunI6NS4w==} + engines: {node: '>= 20'} + cpu: [x64] + os: [linux] + libc: [glibc] + + '@tailwindcss/oxide-linux-x64-musl@4.3.3': + resolution: {integrity: sha512-SJxX60smvHgasZoBy11dX6YRjXJFovwWBoedhbQPOBzgFWBHGB+TVPWB9BxzR7TTxU8FQZAI2AyiNCMzFm8Img==} + engines: {node: '>= 20'} + cpu: [x64] + os: [linux] + libc: [musl] + + '@tailwindcss/oxide-wasm32-wasi@4.3.3': + resolution: {integrity: sha512-jx1+rPhY/5Ympkktd656HBWEBLxP7dH06losBLjjf5vgCODXvi9KhtftWcMIwTFIDqBr7cRnQkdLnAG+IOlGvQ==} + engines: {node: '>=14.0.0'} + cpu: [wasm32] + bundledDependencies: + - '@napi-rs/wasm-runtime' + - '@emnapi/core' + - '@emnapi/runtime' + - '@tybys/wasm-util' + - '@emnapi/wasi-threads' + - tslib + + '@tailwindcss/oxide-win32-arm64-msvc@4.3.3': + resolution: {integrity: sha512-3rc292Ca2ceK6Ulcc/bAVnTs/3nDtoPhyEKlgPv+yQJQi/JS/AMJlqzxvlDacL1nekbrcf6bTqp/jV4qgnPxNQ==} + engines: {node: '>= 20'} + cpu: [arm64] + os: [win32] + + '@tailwindcss/oxide-win32-x64-msvc@4.3.3': + resolution: {integrity: sha512-yJ0pwIVc/nYeGoV02WtsN8KYyLQv7kyI2wDnkezyJlGGjkd4QLwDGAwl47YpPJeuI0M0ObaXGSPjvWDPeTPggw==} + engines: {node: '>= 20'} + cpu: [x64] + os: [win32] + + '@tailwindcss/oxide@4.3.3': + resolution: {integrity: sha512-krXjAikiaFSPaK/FkAQT5UTx3VormQaiZ5hBFlJZ9UFQGB/rwg1MZIhHAG9smMQRTdyJxP6Qt5MwMtdyU5FWrA==} + engines: {node: '>= 20'} + + '@tailwindcss/vite@4.3.3': + resolution: {integrity: sha512-yYU8cogLeSh/ms2jh8Fj7jaba/EWa7Ja6GoUqYZaraEuCI5YS6ms6ObZgjjedm+jm6XZjdNRWBpPP6Z86oOxcw==} + peerDependencies: + vite: ^5.2.0 || ^6 || ^7 || ^8 + + '@types/cookie@0.6.0': + resolution: {integrity: sha512-4Kh9a6B2bQciAhf7FSuMRRkUWecJgJu9nPnx3yzpsfXX/c50REIqpHY4C82bXP90qrLtXtkDxTZosYO3UpOwlA==} + + '@types/estree@1.0.9': + resolution: {integrity: sha512-GhdPgy1el4/ImP05X05Uw4cw2/M93BCUmnEvWZNStlCzEKME4Fkk+YpoA5OiHNQmoS7Cafb8Xa3Pya8m1Qrzeg==} + + '@types/trusted-types@2.0.7': + resolution: {integrity: sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==} + + '@zag-js/accordion@1.42.0': + resolution: {integrity: sha512-eTVh6Uz3CqdcJDr5mHWTT+oICSrZFfYCCxIpOKF00nADmb96nCDqOAYFMf8gM3J/4UDS/V27QzEH5GPmFWiHIw==} + + '@zag-js/anatomy@1.42.0': + resolution: {integrity: sha512-F6kRAPxgBZRZmuV5SLywcrGNSclKcAcPAAgSrEdr2Z2dzFgQngbvS4dmdQyGau/vtQ42OlCI48Ri4t0hZxXkMw==} + + '@zag-js/aria-hidden@1.42.0': + resolution: {integrity: sha512-ao1RyEbHbglJtLLR4sJLPiD3hWF1CacuN5eqvODh/7HcntWULrkUHo8DIdzYgFL9GUHDyDmpaechMX5wL3kdPg==} + + '@zag-js/auto-resize@1.42.0': + resolution: {integrity: sha512-iL7EI30VknEkVb8PhTcLkvR8aiZda0IwJGT4K0cb7J/fMxsDAGjnjdLRu+dGUPZsXji1n58wlaKjTtCQCaXfOA==} + + '@zag-js/avatar@1.42.0': + resolution: {integrity: sha512-rY2OxTTlvX1EMXENruejUUOZeiHusEpWLHNhrlqXMWMPWmcCe3aZ7iGMvjPFMb2mTMn0fzWmuY0nZDdVYk3V/g==} + + '@zag-js/carousel@1.42.0': + resolution: {integrity: sha512-8VMPlg5DP8vye4ujyEqzM/EQ0osOVtoG3bUJ6CGWdRIdSkbgjIt1tY8DlS1WzOvSUMnTcTAi/RPxoxYZwTIhsw==} + + '@zag-js/collapsible@1.42.0': + resolution: {integrity: sha512-MSQo9qRwp2r6aj3G/lKd3gSXAAjuCaq1LtLT3BxHEQ5skn2NQWTKVgReUSuDJNl0Lz+Z5WYq5+5TCDHr4YKHRA==} + + '@zag-js/collection@1.42.0': + resolution: {integrity: sha512-+Bhj/2zqVVzmS788lsg/xK1ezksMc2pfVg2oO6MnipLCo8KrgzuuvhUahUzK+uIOc9ljBW4zl9Wcm3G248gh0A==} + + '@zag-js/combobox@1.42.0': + resolution: {integrity: sha512-fe+Sco278h8PPFM0g3eR5366/oVIfSI3B7qDXl/xmYKMQXhIp+bKxew3U0q1COSVof0x3wrIoIpY51BXj1McGw==} + + '@zag-js/core@1.42.0': + resolution: {integrity: sha512-jE/sbpZvbD+/etbawzhL/L2lP1pPefed5d919je+K5h9b6GAK3lUThleaDUCww3bT53B1L7O5gtqBapW37N1ug==} + + '@zag-js/date-picker@1.42.0': + resolution: {integrity: sha512-M8zt5kdOld7YKYmCZCQ8xPJ8+xwBpxIumzWgzFGoadSxYQPaK8gPqPFKxADJZWX7p/oHdpw2BVcVFWNC0urcyg==} + peerDependencies: + '@internationalized/date': '>=3.0.0' + + '@zag-js/date-utils@1.42.0': + resolution: {integrity: sha512-pjFahzgNGlIIbNQWaPY4RcFhMo+9d9nHj7FctmexXdQ6x4aByfD8bPCUKomO2MsMs0/2lRkACjqZeJwP4oivAw==} + peerDependencies: + '@internationalized/date': '>=3.0.0' + + '@zag-js/dialog@1.42.0': + resolution: {integrity: sha512-2KpLQASTjr2JUR0XvqsMueVo+AAPeanD9ShFCY/YKv2qp6WRHo1Ig/tRj6pInsSBiHFo7QXyAD4SDax6C0zDcw==} + + '@zag-js/dismissable@1.42.0': + resolution: {integrity: sha512-Cx/FAQ2MuQy3kecdmswrFk94Zie1ieBa1Pnt/2ECI5FR914EJd3DwY9Krsmlrq4Z15Wm+pVtfLXgakDewVgsiQ==} + + '@zag-js/dom-query@1.42.0': + resolution: {integrity: sha512-JgCNfp7F+YNFNb7Xmt6rXQr3N3V9Mp+pFRvZ8j5BTC3/G8ZYj/enrgOcuVwPlXPBGtA7ysvjig2x1c0Uou/6kg==} + + '@zag-js/file-upload@1.42.0': + resolution: {integrity: sha512-1I8mCSh6fykHmTStuD9qS425vySOhBjFZfkqLG1J10IfGjz8KCoHcOEbZDHqbJa4/Yq0d+mrwHpOYPS6jYBimA==} + + '@zag-js/file-utils@1.42.0': + resolution: {integrity: sha512-goU5T/8SVpeoR33PS4kRWZkcfSERI7FVqqSn521PmxZ/wZMVDrXaivygbttGV8nCWfbwmsMqeyp2iy5MnbNovQ==} + + '@zag-js/floating-panel@1.42.0': + resolution: {integrity: sha512-C1nUUgpkAex6QG7/5IkTu38ZBj4RMLbK3sNrssMoZ6kR60jB7D1Lz7D4NbD2b0dYabM6XH10TEaCzEPY8LpC3A==} + + '@zag-js/focus-trap@1.42.0': + resolution: {integrity: sha512-47O/OpLUm9o8CZd3ez0ntAOUKZEQ1zFj7e86fpYuQ+fNtBlpYMFHQxMRftPkiU5Ysjrz5x8RYV8A8uJ9cboNig==} + + '@zag-js/focus-visible@1.42.0': + resolution: {integrity: sha512-zT1Fk+8m6x6hzoD5fOIEV4JQIX33pwkBzANqwruQwaSqkOYtI2FmsG71YHnzKvrBppG2okPrRHEMyZEgfshIcQ==} + + '@zag-js/i18n-utils@1.42.0': + resolution: {integrity: sha512-uVw+Ua3apxaBCRcsfHOlXcRPDNygSGoJ6ivmK0UJaw5QikZLEBYr7grzXDwRvZrdk0j0sA9Hk/gg3GdSXkhI3Q==} + + '@zag-js/interact-outside@1.42.0': + resolution: {integrity: sha512-CNNT1OtASacXEst8NMWDGmDwkOQgVQ0Ahc2SpPjSBZoVpxQIfhZ9FoeqcggDX7Nvze7kl6/OwA7pPi5TGQTVZQ==} + + '@zag-js/listbox@1.42.0': + resolution: {integrity: sha512-nt842jgTaBYTgkqu3y+4l88wpmoyesXkS+Bc3Uvuc7ze9IB04vicSiRi+vstYyA20s/EjOr2tR9Kq7dNoROLaQ==} + + '@zag-js/live-region@1.42.0': + resolution: {integrity: sha512-YFkytNxBJDQIndh7W+bWMN9P74qsnQkzqqLv6LtX/TiOYr1PnL0p54DMvWhE7hqYiCyyLscBM9nbA1foSoPIPg==} + + '@zag-js/marquee@1.42.0': + resolution: {integrity: sha512-bTYbNFuDdKV7SyHchyCLhE+JtReO8VUaGfv9Prh3LfFq7yNEqiFngqhY7TZBw6Vok4q8msu0r9aAqOspZqHEHA==} + + '@zag-js/menu@1.42.0': + resolution: {integrity: sha512-Jg2q+FrHeZ2ZTxrz/TAnNelapN6IGtyCnBmoNbcHGcnf3gqnEjJpug3Fn6BmPQrmTNw0+q7hBmrESyncjrfbUg==} + + '@zag-js/pagination@1.42.0': + resolution: {integrity: sha512-QEcnc8z0U4RREOa1MVGFNbKJONLzbo5egdUppURkbAwhv+paR9ufG4uli7QlMvA3KgdfCHPM92+MhnYwutp5nw==} + + '@zag-js/popover@1.42.0': + resolution: {integrity: sha512-4knrgFDeYlKqjyRfYPEUfpIRjsTvg4zY/C0i3sbdxNEWiOW30DzW+/8Igabb00bOabrtRuIHBejm0Jorgn5JIQ==} + + '@zag-js/popper@1.42.0': + resolution: {integrity: sha512-hQvXzLen/hXCItww5tJT6+VLxnee8CpsX0FabIiHub/fKIB6OeHmS/lk+RnIII57bljdjLSus/KnT8Xlmj6tRw==} + + '@zag-js/progress@1.42.0': + resolution: {integrity: sha512-ZGex63fTJHy4or5N8fBUxiwqxBGd1Vr+OE0Bnm8+FAQNjJ5BtCLhIlmsIUS8aX2SrBR0j/tp8E0ss35/PNq29Q==} + + '@zag-js/qr-code@1.42.0': + resolution: {integrity: sha512-X9cUPzJKI7aWrf8ie2jgaXlFFetJf1fdwhnWnP5rG8v3jrFe4tDA1n3z6HE4bXkluZv/2EL9cROglbz5WGB6/g==} + + '@zag-js/radio-group@1.42.0': + resolution: {integrity: sha512-VtoN9/d3HCe/oumjdwKzv/KilF2aLzbt1IYpejXF7Cwat8xmqnCoxiA2PLjE9NfD97ZM7grng1YGcjqrWOWvuQ==} + + '@zag-js/rating-group@1.42.0': + resolution: {integrity: sha512-0+OQ+iy0djWJBzWdH8pMn+ze88B0T4TdO3kJuHyG2fgJnVgmuGWkoKp8RtXSAv2CVqXfx+diivqF9ZmhNmzLQA==} + + '@zag-js/rect-utils@1.42.0': + resolution: {integrity: sha512-4hIvDZEPxYAqhiSNVkZtQLzd7dV7IAn7c5GdWnVVAYtJDD1Tn+v0TYkoPuGQMqLsdpNDwncw3baT3xq1+PQi+w==} + + '@zag-js/remove-scroll@1.42.0': + resolution: {integrity: sha512-RP1SzQuVDk+np5knkEz/mRasLHZUbO6f3xgq4M2u4SQhpOe34uJybd+14f4ElBntAJQWVeMhohpW4n0pNUW6WQ==} + + '@zag-js/scroll-snap@1.42.0': + resolution: {integrity: sha512-gFc5LZvHa4lyCmlt5n6nODc77dGeOc+3sWQMK+20cm/VjYNCsUDjoHP2KO5tgqLJNjPrON+i0BN/QfJUfoNA7Q==} + + '@zag-js/slider@1.42.0': + resolution: {integrity: sha512-bHTNGxM2H2oag5IbsfsV/OJegz4ic1Zs89Mvm+ryVzqOc0upJl0xMC/D/K8wnRJ8OPubNnldA+R4W8o+/4IU8w==} + + '@zag-js/steps@1.42.0': + resolution: {integrity: sha512-IDJKk4zPhQjJv5fxAvOy+LRcdnim5rJjpUdEsWq0/aDiVZiddg3sXLgJ8dTGfv6e58AIjTlaz85xv21dldWKYw==} + + '@zag-js/store@1.42.0': + resolution: {integrity: sha512-qQ5LB+l2dR1rZFCsErn9PeSrOADjnsvDl1NreEN/AaKXw9RK0YiQDqaCh7ndqjjA72UAcrnzgXsS0AAqxCC+MQ==} + + '@zag-js/svelte@1.42.0': + resolution: {integrity: sha512-24UesuYzeRA5blEQcAiWt5tWLG05NhiJ1WNHhwafmn5HFBRvlaU7J7VymIHE06cKMCThwy2YjSgq3b56e+f3VQ==} + peerDependencies: + svelte: '>=5' + + '@zag-js/switch@1.42.0': + resolution: {integrity: sha512-227GNBAz8mYSKVsHV6r4YA/1/0rtbrP2foygPligDOkWMsNP9cjnW1HwM/z3x54UPWLqKuZjsjD7LSuDhbxtBA==} + + '@zag-js/tabs@1.42.0': + resolution: {integrity: sha512-O0qFmeneJHr85AUL/44mHQy8Cr/jCZzh55rTKz5sBoZxmk7PIGopsasNLnpyaZ34tOpcKnNEg96FdlZ4O1bjlQ==} + + '@zag-js/tags-input@1.42.0': + resolution: {integrity: sha512-+zGHcW1EeYCfxfngR4DXJEUWn6iKBoWkN2OnP4HrrWIAwk+0yTOQpwEd4UcCoUOo7CPtqwBmZp2Y92AMuAFA+Q==} + + '@zag-js/toast@1.42.0': + resolution: {integrity: sha512-8WLogVjJiCrvQ4hv9vQrcjaFJLFGtOCb/pnir7SjqR1RzbYHoPLj5ASbM9bbjpcgQQYr0GaLovP6beQW8kjBjg==} + + '@zag-js/toggle-group@1.42.0': + resolution: {integrity: sha512-lhsPcj115a646wxHgzSkhSW4IZFKw4pqRTHSL0e8vR4jgCRhGLBzE70S+EgYIj+000A05eB+or0PhX5zeMK5qQ==} + + '@zag-js/tooltip@1.42.0': + resolution: {integrity: sha512-viRGjX2yxF317M2G2tYvPS7+ZS3osmE+iGm40ZPg0sciezSZW1l4ZFSQ56qyCJ8rTUKv3T1m0NPWYhqVoT3eoA==} + + '@zag-js/tree-view@1.42.0': + resolution: {integrity: sha512-QXIfFgE7BbtB7cHXwi8Gu/9ezkOaeZ4XFAixoJttiOgnw3EIRZPqATRijh446SDPuqsFh9RSjC2zEe3vcFssZA==} + + '@zag-js/types@1.42.0': + resolution: {integrity: sha512-4ghao1wuLouepdYMheEYtyOlKpVsvL0Eg9tf//5VyAf7S9zC7cgGxD6ttGTlIMxqKqnAuxIMsYHG76qkb8tv1w==} + + '@zag-js/utils@1.42.0': + resolution: {integrity: sha512-Km0r9hY+f6/oCJXrO4nqCIuo+4gTqbloD0V0q7B8Jq8qeWte7HN+YJSagVlk8tfADqFMRgEW4Rug0bYHzrGbVA==} + + acorn@8.18.0: + resolution: {integrity: sha512-lGq+9yr1/GuAWaVYIHRjvvySG5/4VfKIvC8EWxStPdcDh/Ka7FG3twP6v4d5BkravUilhIAsG4Qj83t02LWUPQ==} + engines: {node: '>=0.4.0'} + hasBin: true + + aria-query@5.3.1: + resolution: {integrity: sha512-Z/ZeOgVl7bcSYZ/u/rh0fOpvEpq//LZmdbkXyc7syVzjPAhfOa9ebsdTSjEBDU4vs5nC98Kfduj1uFo0qyET3g==} + engines: {node: '>= 0.4'} + + axobject-query@4.1.0: + resolution: {integrity: sha512-qIj0G9wZbMGNLjLmg1PT6v2mE9AH2zlnADJD/2tC6E00hgmhUOfEB6greHPAfLRSufHqROIUTkw6E+M3lH0PTQ==} + engines: {node: '>= 0.4'} + + chokidar@4.0.3: + resolution: {integrity: sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==} + engines: {node: '>= 14.16.0'} + + clsx@2.1.1: + resolution: {integrity: sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==} + engines: {node: '>=6'} + + cookie@0.6.0: + resolution: {integrity: sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==} + engines: {node: '>= 0.6'} + + csstype@3.2.3: + resolution: {integrity: sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==} + + deepmerge@4.3.1: + resolution: {integrity: sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==} + engines: {node: '>=0.10.0'} + + detect-libc@2.1.2: + resolution: {integrity: sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==} + engines: {node: '>=8'} + + devalue@5.9.0: + resolution: {integrity: sha512-RWrqdArjvPbsATEhOPUo6Wndc/iWnkWKlhIrdlF3zMMYo/c3CVtoaVAyLtWxz5h8nSlkHzxnzV2uLydPXmtF+A==} + + enhanced-resolve@5.24.5: + resolution: {integrity: sha512-L1l8TNvomm6UVW5B253AGxQagSQr+vGwhMlrrfRS2qmhx46AMpMVJKQYLvWYbysTMY8VoicOvzHzoHMbyzB+4A==} + engines: {node: '>=10.13.0'} + + esm-env@1.2.2: + resolution: {integrity: sha512-Epxrv+Nr/CaL4ZcFGPJIYLWFom+YeV1DqMLHJoEd9SYRxNbaFruBwfEX/kkHUJf55j2+TUbmDcmuilbP1TmXHA==} + + esrap@2.3.2: + resolution: {integrity: sha512-40GyiEJevYKXzYTHtZkFqAgTjLOuFcaXMao8TPyOlnWTlkHDlvZ6mPMJaJyOqVwrVCgomEG1WhJd81w0X+IcCw==} + peerDependencies: + '@typescript-eslint/types': ^8.2.0 + peerDependenciesMeta: + '@typescript-eslint/types': + optional: true + + fdir@6.5.0: + resolution: {integrity: sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==} + engines: {node: '>=12.0.0'} + peerDependencies: + picomatch: ^3 || ^4 + peerDependenciesMeta: + picomatch: + optional: true + + fsevents@2.3.3: + resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} + engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} + os: [darwin] + + graceful-fs@4.2.11: + resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==} + + is-reference@3.0.3: + resolution: {integrity: sha512-ixkJoqQvAP88E6wLydLGGqCJsrFUnqoH6HnaczB8XmDH1oaWU+xxdptvikTgaEhtZ53Ky6YXiBuUI2WXLMCwjw==} + + jiti@2.7.0: + resolution: {integrity: sha512-AC/7JofJvZGrrneWNaEnJeOLUx+JlGt7tNa0wZiRPT4MY1wmfKjt2+6O2p2uz2+skll8OZZmJMNqeke7kKbNgQ==} + hasBin: true + + kleur@4.1.5: + resolution: {integrity: sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ==} + engines: {node: '>=6'} + + lightningcss-android-arm64@1.32.0: + resolution: {integrity: sha512-YK7/ClTt4kAK0vo6w3X+Pnm0D2cf2vPHbhOXdoNti1Ga0al1P4TBZhwjATvjNwLEBCnKvjJc2jQgHXH0NEwlAg==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [android] + + lightningcss-android-arm64@1.33.0: + resolution: {integrity: sha512-gEpRTalKdosp4Bb8qWtc2iOgE5SeIHlpS1up9bFq2wAyYhl1UdTObYiHe98zEM9SQvSoqQZ1IQD0JNpg3Ml5pg==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [android] + + lightningcss-darwin-arm64@1.32.0: + resolution: {integrity: sha512-RzeG9Ju5bag2Bv1/lwlVJvBE3q6TtXskdZLLCyfg5pt+HLz9BqlICO7LZM7VHNTTn/5PRhHFBSjk5lc4cmscPQ==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [darwin] + + lightningcss-darwin-arm64@1.33.0: + resolution: {integrity: sha512-Sciaz8eenNTKn9b3t7+xr0ipTp9YxKQY4npwQ3mrRuL0BAVHBLyZxofhaKBAVtzmtRZ/zTyo0/to4B1uWG/Djg==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [darwin] + + lightningcss-darwin-x64@1.32.0: + resolution: {integrity: sha512-U+QsBp2m/s2wqpUYT/6wnlagdZbtZdndSmut/NJqlCcMLTWp5muCrID+K5UJ6jqD2BFshejCYXniPDbNh73V8w==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [darwin] + + lightningcss-darwin-x64@1.33.0: + resolution: {integrity: sha512-Z5UPAxzrjlWNNyGy6i65cJzzvgJ5D3T6wMvs+gWpY9d7qRhANrxqAp6LhxIgZhWEw18RfJTGcRxjuLIBr+m8XQ==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [darwin] + + lightningcss-freebsd-x64@1.32.0: + resolution: {integrity: sha512-JCTigedEksZk3tHTTthnMdVfGf61Fky8Ji2E4YjUTEQX14xiy/lTzXnu1vwiZe3bYe0q+SpsSH/CTeDXK6WHig==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [freebsd] + + lightningcss-freebsd-x64@1.33.0: + resolution: {integrity: sha512-QQM/Ti/hQajJwCY+RiWuCZ9sdtI/XQk7nDK5vC8kkdwixezOlDgvDx7+RT+QjK6FcFT4MpsuoBnHIo/O3StRRg==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [freebsd] + + lightningcss-linux-arm-gnueabihf@1.32.0: + resolution: {integrity: sha512-x6rnnpRa2GL0zQOkt6rts3YDPzduLpWvwAF6EMhXFVZXD4tPrBkEFqzGowzCsIWsPjqSK+tyNEODUBXeeVHSkw==} + engines: {node: '>= 12.0.0'} + cpu: [arm] + os: [linux] + + lightningcss-linux-arm-gnueabihf@1.33.0: + resolution: {integrity: sha512-N7FVBe6iS24MlM6R/4RBTxGhQheZGs7tiQ9U32UtF75NzP5Q7xWPRqLBCKxlRQRk3rY1jCIPLzx7WzOhuUIRLQ==} + engines: {node: '>= 12.0.0'} + cpu: [arm] + os: [linux] + + lightningcss-linux-arm64-gnu@1.32.0: + resolution: {integrity: sha512-0nnMyoyOLRJXfbMOilaSRcLH3Jw5z9HDNGfT/gwCPgaDjnx0i8w7vBzFLFR1f6CMLKF8gVbebmkUN3fa/kQJpQ==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [linux] + libc: [glibc] + + lightningcss-linux-arm64-gnu@1.33.0: + resolution: {integrity: sha512-j2v/itmy4HlNxlc6voKXYgBqNi0Ng2LShg4z7GufpEgs05P+2suBVyi9I6YHq5uoVFx9ETin3eCEhLVyXGQnKg==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [linux] + libc: [glibc] + + lightningcss-linux-arm64-musl@1.32.0: + resolution: {integrity: sha512-UpQkoenr4UJEzgVIYpI80lDFvRmPVg6oqboNHfoH4CQIfNA+HOrZ7Mo7KZP02dC6LjghPQJeBsvXhJod/wnIBg==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [linux] + libc: [musl] + + lightningcss-linux-arm64-musl@1.33.0: + resolution: {integrity: sha512-yiO5ROMuYQgXbC60yjZU5CYSFZGKXL0HFATXt9mHJn1+zW55oCtMI9NfcVhYLMFDL7gV7oBPon/EmMMGg2OvtQ==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [linux] + libc: [musl] + + lightningcss-linux-x64-gnu@1.32.0: + resolution: {integrity: sha512-V7Qr52IhZmdKPVr+Vtw8o+WLsQJYCTd8loIfpDaMRWGUZfBOYEJeyJIkqGIDMZPwPx24pUMfwSxxI8phr/MbOA==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [linux] + libc: [glibc] + + lightningcss-linux-x64-gnu@1.33.0: + resolution: {integrity: sha512-ar+Ju7LmcN0Jo4FpL4hpFybwNG9/3A/Br5KW2n2jyODg3MEZXaDYADdemoNS+BDNfMgKvylJLj4S5tyRActuAg==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [linux] + libc: [glibc] + + lightningcss-linux-x64-musl@1.32.0: + resolution: {integrity: sha512-bYcLp+Vb0awsiXg/80uCRezCYHNg1/l3mt0gzHnWV9XP1W5sKa5/TCdGWaR/zBM2PeF/HbsQv/j2URNOiVuxWg==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [linux] + libc: [musl] + + lightningcss-linux-x64-musl@1.33.0: + resolution: {integrity: sha512-RYiYbkokw0trfKqqzfF55lginwEPrD3OJDfTuJzFs1MK6iFnDenaz1fqLLtX4ITG3OktJQXOeTaw1awrBAlZPw==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [linux] + libc: [musl] + + lightningcss-win32-arm64-msvc@1.32.0: + resolution: {integrity: sha512-8SbC8BR40pS6baCM8sbtYDSwEVQd4JlFTOlaD3gWGHfThTcABnNDBda6eTZeqbofalIJhFx0qKzgHJmcPTnGdw==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [win32] + + lightningcss-win32-arm64-msvc@1.33.0: + resolution: {integrity: sha512-1K+MPfLSFVpphzpdbfkhlWk6wBrTObBzS2T6db10PNOZgR9GoVsAWzwNyuhUYYbTp23j+4RrncfujZ4uAzXvwA==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [win32] + + lightningcss-win32-x64-msvc@1.32.0: + resolution: {integrity: sha512-Amq9B/SoZYdDi1kFrojnoqPLxYhQ4Wo5XiL8EVJrVsB8ARoC1PWW6VGtT0WKCemjy8aC+louJnjS7U18x3b06Q==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [win32] + + lightningcss-win32-x64-msvc@1.33.0: + resolution: {integrity: sha512-OlEICDx/Xl0FqSp4bry8zFnCvGpig3Gl4gCquvYwHuqJKEC1+n9NgDniFvqHGmMv1ZkqDJrDqKKSykTDX+ehuA==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [win32] + + lightningcss@1.32.0: + resolution: {integrity: sha512-NXYBzinNrblfraPGyrbPoD19C1h9lfI/1mzgWYvXUTe414Gz/X1FD2XBZSZM7rRTrMA8JL3OtAaGifrIKhQ5yQ==} + engines: {node: '>= 12.0.0'} + + lightningcss@1.33.0: + resolution: {integrity: sha512-WkUDrojuJs0xkgGf2udWxa3yGBRxPtxUkB79i6aCZLRgc7PM8fZe9TosfPDcvEpQZbuFASnHYmRLBLUbmLOIIA==} + engines: {node: '>= 12.0.0'} + + locate-character@3.0.0: + resolution: {integrity: sha512-SW13ws7BjaeJ6p7Q6CO2nchbYEc3X3J6WrmTTDto7yMPqVSZTUyY5Tjbid+Ab8gLnATtygYtiDIJGQRRn2ZOiA==} + + magic-string@0.30.21: + resolution: {integrity: sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==} + + magic-string@1.1.0: + resolution: {integrity: sha512-kS3VHe0nEPST2saQV4Rbkchcd3UBRkVTQHo1D3h/ZTwFDhai/mfKkmtPAtD129EOI7K3HlHIsFOt0WrI2/oU9g==} + + mri@1.2.0: + resolution: {integrity: sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==} + engines: {node: '>=4'} + + mrmime@2.0.1: + resolution: {integrity: sha512-Y3wQdFg2Va6etvQ5I82yUhGdsKrcYox6p7FfL1LbK2J4V01F9TGlepTIhnK24t7koZibmg82KGglhA1XK5IsLQ==} + engines: {node: '>=10'} + + nanoid@3.3.18: + resolution: {integrity: sha512-DTg4MJbGMWkfi6VZFdNt2/caMbQy4Ou+Op/hJQvGEWcnVfoA1QA+xzRKAzw9jD6+GVOOeYr/mIcuDSdug6F6+w==} + engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} + hasBin: true + + obug@2.1.4: + resolution: {integrity: sha512-4a+OsYv9UktOJKE+l1A4OufDgdRF9PifWj+tJnHURo/P+WOxpG4GzUFL9qCalmWauao6ogiG+QvnCovwPoyAWA==} + engines: {node: '>=12.20.0'} + + picocolors@1.1.1: + resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} + + picomatch@4.0.5: + resolution: {integrity: sha512-RvwwcruNjI1ncT5xRakeyS9Lf8lcItv34KD+aif+VH9kduAyfYBipGh12274xtenIPZ119/R9BdTBa8gAwSh0A==} + engines: {node: '>=12'} + + postcss@8.5.26: + resolution: {integrity: sha512-u82N74LFzG8ca+dD8puPnplTXoGH4fTPpVGuIbt36G3qvNlkvfD0lEAZSxaly3KX8TS/L1A1gsCEmvKmBcVbkQ==} + engines: {node: ^10 || ^12 || >=14} + + proxy-compare@3.0.1: + resolution: {integrity: sha512-V9plBAt3qjMlS1+nC8771KNf6oJ12gExvaxnNzN/9yVRLdTv/lc+oJlnSzrdYDAvBfTStPCoiaCOTmTs0adv7Q==} + + proxy-memoize@3.0.1: + resolution: {integrity: sha512-VDdG/VYtOgdGkWJx7y0o7p+zArSf2383Isci8C+BP3YXgMYDoPd3cCBjw0JdWb6YBb9sFiOPbAADDVTPJnh+9g==} + + readdirp@4.1.2: + resolution: {integrity: sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==} + engines: {node: '>= 14.18.0'} + + rolldown@1.2.3: + resolution: {integrity: sha512-rn9wpmxplLf7NLNyCk9FyWh3FM43DbY8jOzCdEPzH7uflhTftRbCEpqi6Ly2osgoU8OwObtmavMbWLaWy4LX7A==} + engines: {node: ^20.19.0 || >=22.12.0} + hasBin: true + + sade@1.8.1: + resolution: {integrity: sha512-xal3CZX1Xlo/k4ApwCFrHVACi9fBqJ7V+mwhBsuf/1IOKbBy098Fex+Wa/5QMubw09pSZ/u8EY8PWgevJsXp1A==} + engines: {node: '>=6'} + + set-cookie-parser@3.1.2: + resolution: {integrity: sha512-5/r/lTwbJ3zQ+qwdUFZYeRNqda7P5HD8zQKqlSjdGt1/S0cjLAphHusj4Y58ahDtWn/g32xrIS58/ikOvwl0Lw==} + + sirv@3.0.2: + resolution: {integrity: sha512-2wcC/oGxHis/BoHkkPwldgiPSYcpZK3JU28WoMVv55yHJgcZ8rlXvuG9iZggz+sU1d4bRgIGASwyWqjxu3FM0g==} + engines: {node: '>=18'} + + source-map-js@1.2.1: + resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==} + engines: {node: '>=0.10.0'} + + svelte-check@4.7.5: + resolution: {integrity: sha512-NnkHGCTPH6k4ka1E9IpTuNv40uLArHnX52kLEuaHSGqRlPYTnkbFs529jSWG+y+wDy+v+jA2PQ0soN1umVK+OA==} + engines: {node: '>= 18.0.0'} + hasBin: true + peerDependencies: + svelte: ^4.0.0 || ^5.0.0-next.0 + typescript: ^5.0.0 || ^6.0.0 + + svelte@5.56.8: + resolution: {integrity: sha512-PY8LOw7xP6c8IOiVqdo0sbbZVYhXRSfklOQLAUyGBKqjTX0wx/z4l/9J+PmBpmlLnxzEb1NqltxQ5/wZme/Cmg==} + engines: {node: '>=18'} + + tailwindcss@4.3.3: + resolution: {integrity: sha512-gOhV3P7ufE62QDGg1zVaTgCR+EtPv92k2nIhVcVKcLmxT1sUBsQGhnZj175j+MqRt4zLF7ic+sCYjfhxMxj7YQ==} + + tapable@2.3.3: + resolution: {integrity: sha512-uxc/zpqFg6x7C8vOE7lh6Lbda8eEL9zmVm/PLeTPBRhh1xCgdWaQ+J1CUieGpIfm2HdtsUpRv+HshiasBMcc6A==} + engines: {node: '>=6'} + + tinyglobby@0.2.17: + resolution: {integrity: sha512-wXR/dYpcqKmfWpEdZjiKJOwCNFndD0DMnrW/cYjVGttEkBfVgcLFHoNrlj47mjOVic9yyNu65alsgF4NQyTa2g==} + engines: {node: '>=12.0.0'} + + totalist@3.0.1: + resolution: {integrity: sha512-sf4i37nQ2LBx4m3wB74y+ubopq6W/dIzXg0FDGjsYnZHVa1Da8FH853wlL2gtUhg+xJXjfk3kUZS3BRoQeoQBQ==} + engines: {node: '>=6'} + + tslib@2.8.1: + resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==} + + typescript@6.0.3: + resolution: {integrity: sha512-y2TvuxSZPDyQakkFRPZHKFm+KKVqIisdg9/CZwm9ftvKXLP8NRWj38/ODjNbr43SsoXqNuAisEf1GdCxqWcdBw==} + engines: {node: '>=14.17'} + hasBin: true + + uqr@0.1.3: + resolution: {integrity: sha512-0rjE8iEJe4YmT9TOhwsZtqCMRLc5DXZUI2UEYUUg63ikBkqqE5EYWaI0etFe/5KUcmcYwLih2RND1kq+hrUJXA==} + + vite@8.2.1: + resolution: {integrity: sha512-EU/eS7BH3XROHh2YnBefjM6DBKA6ZeMZEYQbj7NLWg5wHYlhB8B/Mayd5XsgWq+NFYccDOTemRpdETWR6Ka/lw==} + engines: {node: ^20.19.0 || >=22.12.0} + hasBin: true + peerDependencies: + '@types/node': ^20.19.0 || >=22.12.0 + '@vitejs/devtools': ^0.4.0 + esbuild: ^0.27.0 || ^0.28.0 + jiti: '>=1.21.0' + less: ^4.0.0 + sass: ^1.70.0 + sass-embedded: ^1.70.0 + stylus: '>=0.54.8' + sugarss: ^5.0.0 + terser: ^5.16.0 + tsx: ^4.8.1 + yaml: ^2.4.2 + peerDependenciesMeta: + '@types/node': + optional: true + '@vitejs/devtools': + optional: true + esbuild: + optional: true + jiti: + optional: true + less: + optional: true + sass: + optional: true + sass-embedded: + optional: true + stylus: + optional: true + sugarss: + optional: true + terser: + optional: true + tsx: + optional: true + yaml: + optional: true + + vitefu@1.1.3: + resolution: {integrity: sha512-ub4okH7Z5KLjb6hDyjqrGXqWtWvoYdU3IGm/NorpgHncKoLTCfRIbvlhBm7r0YstIaQRYlp4yEbFqDcKSzXSSg==} + peerDependencies: + vite: ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0 + peerDependenciesMeta: + vite: + optional: true + + zimmerframe@1.1.4: + resolution: {integrity: sha512-B58NGBEoc8Y9MWWCQGl/gq9xBCe4IiKM0a2x7GZdQKOW5Exr8S1W24J6OgM1njK8xCRGvAJIL/MxXHf6SkmQKQ==} + +snapshots: + + '@floating-ui/core@1.8.0': + dependencies: + '@floating-ui/utils': 0.2.12 + + '@floating-ui/dom@1.8.0': + dependencies: + '@floating-ui/core': 1.8.0 + '@floating-ui/utils': 0.2.12 + + '@floating-ui/utils@0.2.12': {} + + '@internationalized/date@3.12.2': + dependencies: + '@swc/helpers': 0.5.23 + + '@jridgewell/gen-mapping@0.3.13': + dependencies: + '@jridgewell/sourcemap-codec': 1.5.5 + '@jridgewell/trace-mapping': 0.3.31 + + '@jridgewell/remapping@2.3.5': + dependencies: + '@jridgewell/gen-mapping': 0.3.13 + '@jridgewell/trace-mapping': 0.3.31 + + '@jridgewell/resolve-uri@3.1.2': {} + + '@jridgewell/sourcemap-codec@1.5.5': {} + + '@jridgewell/trace-mapping@0.3.31': + dependencies: + '@jridgewell/resolve-uri': 3.1.2 + '@jridgewell/sourcemap-codec': 1.5.5 + + '@oxc-project/types@0.143.0': {} + + '@polka/url@1.0.0-next.29': {} + + '@rolldown/binding-android-arm64@1.2.3': + optional: true + + '@rolldown/binding-darwin-arm64@1.2.3': + optional: true + + '@rolldown/binding-darwin-x64@1.2.3': + optional: true + + '@rolldown/binding-freebsd-x64@1.2.3': + optional: true + + '@rolldown/binding-linux-arm-gnueabihf@1.2.3': + optional: true + + '@rolldown/binding-linux-arm64-gnu@1.2.3': + optional: true + + '@rolldown/binding-linux-arm64-musl@1.2.3': + optional: true + + '@rolldown/binding-linux-ppc64-gnu@1.2.3': + optional: true + + '@rolldown/binding-linux-s390x-gnu@1.2.3': + optional: true + + '@rolldown/binding-linux-x64-gnu@1.2.3': + optional: true + + '@rolldown/binding-linux-x64-musl@1.2.3': + optional: true + + '@rolldown/binding-openharmony-arm64@1.2.3': + optional: true + + '@rolldown/binding-win32-arm64-msvc@1.2.3': + optional: true + + '@rolldown/binding-win32-x64-msvc@1.2.3': + optional: true + + '@rolldown/pluginutils@1.0.1': {} + + '@skeletonlabs/skeleton-common@5.0.0': {} + + '@skeletonlabs/skeleton-svelte@5.0.0(svelte@5.56.8)': + dependencies: + '@internationalized/date': 3.12.2 + '@skeletonlabs/skeleton-common': 5.0.0 + '@zag-js/accordion': 1.42.0 + '@zag-js/avatar': 1.42.0 + '@zag-js/carousel': 1.42.0 + '@zag-js/collapsible': 1.42.0 + '@zag-js/collection': 1.42.0 + '@zag-js/combobox': 1.42.0 + '@zag-js/date-picker': 1.42.0(@internationalized/date@3.12.2) + '@zag-js/dialog': 1.42.0 + '@zag-js/file-upload': 1.42.0 + '@zag-js/floating-panel': 1.42.0 + '@zag-js/i18n-utils': 1.42.0 + '@zag-js/listbox': 1.42.0 + '@zag-js/marquee': 1.42.0 + '@zag-js/menu': 1.42.0 + '@zag-js/pagination': 1.42.0 + '@zag-js/popover': 1.42.0 + '@zag-js/progress': 1.42.0 + '@zag-js/qr-code': 1.42.0 + '@zag-js/radio-group': 1.42.0 + '@zag-js/rating-group': 1.42.0 + '@zag-js/slider': 1.42.0 + '@zag-js/steps': 1.42.0 + '@zag-js/svelte': 1.42.0(svelte@5.56.8) + '@zag-js/switch': 1.42.0 + '@zag-js/tabs': 1.42.0 + '@zag-js/tags-input': 1.42.0 + '@zag-js/toast': 1.42.0 + '@zag-js/toggle-group': 1.42.0 + '@zag-js/tooltip': 1.42.0 + '@zag-js/tree-view': 1.42.0 + svelte: 5.56.8 + + '@skeletonlabs/skeleton@5.0.0(tailwindcss@4.3.3)': + dependencies: + tailwindcss: 4.3.3 + + '@standard-schema/spec@1.1.0': {} + + '@sveltejs/acorn-typescript@1.0.12(acorn@8.18.0)': + dependencies: + acorn: 8.18.0 + + '@sveltejs/adapter-static@3.0.10(@sveltejs/kit@2.70.2(@sveltejs/vite-plugin-svelte@7.3.0(svelte@5.56.8)(vite@8.2.1(jiti@2.7.0)))(svelte@5.56.8)(typescript@6.0.3)(vite@8.2.1(jiti@2.7.0)))': + dependencies: + '@sveltejs/kit': 2.70.2(@sveltejs/vite-plugin-svelte@7.3.0(svelte@5.56.8)(vite@8.2.1(jiti@2.7.0)))(svelte@5.56.8)(typescript@6.0.3)(vite@8.2.1(jiti@2.7.0)) + + '@sveltejs/kit@2.70.2(@sveltejs/vite-plugin-svelte@7.3.0(svelte@5.56.8)(vite@8.2.1(jiti@2.7.0)))(svelte@5.56.8)(typescript@6.0.3)(vite@8.2.1(jiti@2.7.0))': + dependencies: + '@standard-schema/spec': 1.1.0 + '@sveltejs/acorn-typescript': 1.0.12(acorn@8.18.0) + '@sveltejs/vite-plugin-svelte': 7.3.0(svelte@5.56.8)(vite@8.2.1(jiti@2.7.0)) + '@types/cookie': 0.6.0 + acorn: 8.18.0 + cookie: 0.6.0 + devalue: 5.9.0 + esm-env: 1.2.2 + kleur: 4.1.5 + magic-string: 0.30.21 + mrmime: 2.0.1 + set-cookie-parser: 3.1.2 + sirv: 3.0.2 + svelte: 5.56.8 + vite: 8.2.1(jiti@2.7.0) + optionalDependencies: + typescript: 6.0.3 + + '@sveltejs/load-config@0.2.2': {} + + '@sveltejs/vite-plugin-svelte@7.3.0(svelte@5.56.8)(vite@8.2.1(jiti@2.7.0))': + dependencies: + deepmerge: 4.3.1 + magic-string: 1.1.0 + obug: 2.1.4 + svelte: 5.56.8 + vite: 8.2.1(jiti@2.7.0) + vitefu: 1.1.3(vite@8.2.1(jiti@2.7.0)) + + '@swc/helpers@0.5.23': + dependencies: + tslib: 2.8.1 + + '@tailwindcss/node@4.3.3': + dependencies: + '@jridgewell/remapping': 2.3.5 + enhanced-resolve: 5.24.5 + jiti: 2.7.0 + lightningcss: 1.32.0 + magic-string: 0.30.21 + source-map-js: 1.2.1 + tailwindcss: 4.3.3 + + '@tailwindcss/oxide-android-arm64@4.3.3': + optional: true + + '@tailwindcss/oxide-darwin-arm64@4.3.3': + optional: true + + '@tailwindcss/oxide-darwin-x64@4.3.3': + optional: true + + '@tailwindcss/oxide-freebsd-x64@4.3.3': + optional: true + + '@tailwindcss/oxide-linux-arm-gnueabihf@4.3.3': + optional: true + + '@tailwindcss/oxide-linux-arm64-gnu@4.3.3': + optional: true + + '@tailwindcss/oxide-linux-arm64-musl@4.3.3': + optional: true + + '@tailwindcss/oxide-linux-x64-gnu@4.3.3': + optional: true + + '@tailwindcss/oxide-linux-x64-musl@4.3.3': + optional: true + + '@tailwindcss/oxide-wasm32-wasi@4.3.3': + optional: true + + '@tailwindcss/oxide-win32-arm64-msvc@4.3.3': + optional: true + + '@tailwindcss/oxide-win32-x64-msvc@4.3.3': + optional: true + + '@tailwindcss/oxide@4.3.3': + optionalDependencies: + '@tailwindcss/oxide-android-arm64': 4.3.3 + '@tailwindcss/oxide-darwin-arm64': 4.3.3 + '@tailwindcss/oxide-darwin-x64': 4.3.3 + '@tailwindcss/oxide-freebsd-x64': 4.3.3 + '@tailwindcss/oxide-linux-arm-gnueabihf': 4.3.3 + '@tailwindcss/oxide-linux-arm64-gnu': 4.3.3 + '@tailwindcss/oxide-linux-arm64-musl': 4.3.3 + '@tailwindcss/oxide-linux-x64-gnu': 4.3.3 + '@tailwindcss/oxide-linux-x64-musl': 4.3.3 + '@tailwindcss/oxide-wasm32-wasi': 4.3.3 + '@tailwindcss/oxide-win32-arm64-msvc': 4.3.3 + '@tailwindcss/oxide-win32-x64-msvc': 4.3.3 + + '@tailwindcss/vite@4.3.3(vite@8.2.1(jiti@2.7.0))': + dependencies: + '@tailwindcss/node': 4.3.3 + '@tailwindcss/oxide': 4.3.3 + tailwindcss: 4.3.3 + vite: 8.2.1(jiti@2.7.0) + + '@types/cookie@0.6.0': {} + + '@types/estree@1.0.9': {} + + '@types/trusted-types@2.0.7': {} + + '@zag-js/accordion@1.42.0': + dependencies: + '@zag-js/anatomy': 1.42.0 + '@zag-js/core': 1.42.0 + '@zag-js/dom-query': 1.42.0 + '@zag-js/types': 1.42.0 + '@zag-js/utils': 1.42.0 + + '@zag-js/anatomy@1.42.0': {} + + '@zag-js/aria-hidden@1.42.0': + dependencies: + '@zag-js/dom-query': 1.42.0 + + '@zag-js/auto-resize@1.42.0': + dependencies: + '@zag-js/dom-query': 1.42.0 + + '@zag-js/avatar@1.42.0': + dependencies: + '@zag-js/anatomy': 1.42.0 + '@zag-js/core': 1.42.0 + '@zag-js/dom-query': 1.42.0 + '@zag-js/types': 1.42.0 + '@zag-js/utils': 1.42.0 + + '@zag-js/carousel@1.42.0': + dependencies: + '@zag-js/anatomy': 1.42.0 + '@zag-js/core': 1.42.0 + '@zag-js/dom-query': 1.42.0 + '@zag-js/scroll-snap': 1.42.0 + '@zag-js/types': 1.42.0 + '@zag-js/utils': 1.42.0 + + '@zag-js/collapsible@1.42.0': + dependencies: + '@zag-js/anatomy': 1.42.0 + '@zag-js/core': 1.42.0 + '@zag-js/dom-query': 1.42.0 + '@zag-js/types': 1.42.0 + '@zag-js/utils': 1.42.0 + + '@zag-js/collection@1.42.0': + dependencies: + '@zag-js/utils': 1.42.0 + + '@zag-js/combobox@1.42.0': + dependencies: + '@zag-js/anatomy': 1.42.0 + '@zag-js/collection': 1.42.0 + '@zag-js/core': 1.42.0 + '@zag-js/dismissable': 1.42.0 + '@zag-js/dom-query': 1.42.0 + '@zag-js/focus-visible': 1.42.0 + '@zag-js/live-region': 1.42.0 + '@zag-js/popper': 1.42.0 + '@zag-js/types': 1.42.0 + '@zag-js/utils': 1.42.0 + + '@zag-js/core@1.42.0': + dependencies: + '@zag-js/dom-query': 1.42.0 + '@zag-js/utils': 1.42.0 + + '@zag-js/date-picker@1.42.0(@internationalized/date@3.12.2)': + dependencies: + '@internationalized/date': 3.12.2 + '@zag-js/anatomy': 1.42.0 + '@zag-js/core': 1.42.0 + '@zag-js/date-utils': 1.42.0(@internationalized/date@3.12.2) + '@zag-js/dismissable': 1.42.0 + '@zag-js/dom-query': 1.42.0 + '@zag-js/live-region': 1.42.0 + '@zag-js/popper': 1.42.0 + '@zag-js/types': 1.42.0 + '@zag-js/utils': 1.42.0 + + '@zag-js/date-utils@1.42.0(@internationalized/date@3.12.2)': + dependencies: + '@internationalized/date': 3.12.2 + + '@zag-js/dialog@1.42.0': + dependencies: + '@zag-js/anatomy': 1.42.0 + '@zag-js/aria-hidden': 1.42.0 + '@zag-js/core': 1.42.0 + '@zag-js/dismissable': 1.42.0 + '@zag-js/dom-query': 1.42.0 + '@zag-js/focus-trap': 1.42.0 + '@zag-js/remove-scroll': 1.42.0 + '@zag-js/types': 1.42.0 + '@zag-js/utils': 1.42.0 + + '@zag-js/dismissable@1.42.0': + dependencies: + '@zag-js/dom-query': 1.42.0 + '@zag-js/interact-outside': 1.42.0 + '@zag-js/utils': 1.42.0 + + '@zag-js/dom-query@1.42.0': + dependencies: + '@zag-js/types': 1.42.0 + + '@zag-js/file-upload@1.42.0': + dependencies: + '@zag-js/anatomy': 1.42.0 + '@zag-js/core': 1.42.0 + '@zag-js/dom-query': 1.42.0 + '@zag-js/file-utils': 1.42.0 + '@zag-js/i18n-utils': 1.42.0 + '@zag-js/types': 1.42.0 + '@zag-js/utils': 1.42.0 + + '@zag-js/file-utils@1.42.0': + dependencies: + '@zag-js/i18n-utils': 1.42.0 + + '@zag-js/floating-panel@1.42.0': + dependencies: + '@zag-js/anatomy': 1.42.0 + '@zag-js/core': 1.42.0 + '@zag-js/dom-query': 1.42.0 + '@zag-js/popper': 1.42.0 + '@zag-js/rect-utils': 1.42.0 + '@zag-js/store': 1.42.0 + '@zag-js/types': 1.42.0 + '@zag-js/utils': 1.42.0 + + '@zag-js/focus-trap@1.42.0': + dependencies: + '@zag-js/dom-query': 1.42.0 + + '@zag-js/focus-visible@1.42.0': + dependencies: + '@zag-js/dom-query': 1.42.0 + + '@zag-js/i18n-utils@1.42.0': + dependencies: + '@zag-js/dom-query': 1.42.0 + + '@zag-js/interact-outside@1.42.0': + dependencies: + '@zag-js/dom-query': 1.42.0 + '@zag-js/utils': 1.42.0 + + '@zag-js/listbox@1.42.0': + dependencies: + '@zag-js/anatomy': 1.42.0 + '@zag-js/collection': 1.42.0 + '@zag-js/core': 1.42.0 + '@zag-js/dom-query': 1.42.0 + '@zag-js/focus-visible': 1.42.0 + '@zag-js/types': 1.42.0 + '@zag-js/utils': 1.42.0 + + '@zag-js/live-region@1.42.0': {} + + '@zag-js/marquee@1.42.0': + dependencies: + '@zag-js/anatomy': 1.42.0 + '@zag-js/core': 1.42.0 + '@zag-js/dom-query': 1.42.0 + '@zag-js/types': 1.42.0 + '@zag-js/utils': 1.42.0 + + '@zag-js/menu@1.42.0': + dependencies: + '@zag-js/anatomy': 1.42.0 + '@zag-js/core': 1.42.0 + '@zag-js/dismissable': 1.42.0 + '@zag-js/dom-query': 1.42.0 + '@zag-js/focus-visible': 1.42.0 + '@zag-js/popper': 1.42.0 + '@zag-js/rect-utils': 1.42.0 + '@zag-js/types': 1.42.0 + '@zag-js/utils': 1.42.0 + + '@zag-js/pagination@1.42.0': + dependencies: + '@zag-js/anatomy': 1.42.0 + '@zag-js/core': 1.42.0 + '@zag-js/dom-query': 1.42.0 + '@zag-js/types': 1.42.0 + '@zag-js/utils': 1.42.0 + + '@zag-js/popover@1.42.0': + dependencies: + '@zag-js/anatomy': 1.42.0 + '@zag-js/aria-hidden': 1.42.0 + '@zag-js/core': 1.42.0 + '@zag-js/dismissable': 1.42.0 + '@zag-js/dom-query': 1.42.0 + '@zag-js/focus-trap': 1.42.0 + '@zag-js/popper': 1.42.0 + '@zag-js/remove-scroll': 1.42.0 + '@zag-js/types': 1.42.0 + '@zag-js/utils': 1.42.0 + + '@zag-js/popper@1.42.0': + dependencies: + '@floating-ui/dom': 1.8.0 + '@zag-js/dom-query': 1.42.0 + '@zag-js/utils': 1.42.0 + + '@zag-js/progress@1.42.0': + dependencies: + '@zag-js/anatomy': 1.42.0 + '@zag-js/core': 1.42.0 + '@zag-js/dom-query': 1.42.0 + '@zag-js/types': 1.42.0 + '@zag-js/utils': 1.42.0 + + '@zag-js/qr-code@1.42.0': + dependencies: + '@zag-js/anatomy': 1.42.0 + '@zag-js/core': 1.42.0 + '@zag-js/dom-query': 1.42.0 + '@zag-js/types': 1.42.0 + '@zag-js/utils': 1.42.0 + proxy-memoize: 3.0.1 + uqr: 0.1.3 + + '@zag-js/radio-group@1.42.0': + dependencies: + '@zag-js/anatomy': 1.42.0 + '@zag-js/core': 1.42.0 + '@zag-js/dom-query': 1.42.0 + '@zag-js/focus-visible': 1.42.0 + '@zag-js/types': 1.42.0 + '@zag-js/utils': 1.42.0 + + '@zag-js/rating-group@1.42.0': + dependencies: + '@zag-js/anatomy': 1.42.0 + '@zag-js/core': 1.42.0 + '@zag-js/dom-query': 1.42.0 + '@zag-js/types': 1.42.0 + '@zag-js/utils': 1.42.0 + + '@zag-js/rect-utils@1.42.0': {} + + '@zag-js/remove-scroll@1.42.0': + dependencies: + '@zag-js/dom-query': 1.42.0 + + '@zag-js/scroll-snap@1.42.0': + dependencies: + '@zag-js/dom-query': 1.42.0 + + '@zag-js/slider@1.42.0': + dependencies: + '@zag-js/anatomy': 1.42.0 + '@zag-js/core': 1.42.0 + '@zag-js/dom-query': 1.42.0 + '@zag-js/types': 1.42.0 + '@zag-js/utils': 1.42.0 + + '@zag-js/steps@1.42.0': + dependencies: + '@zag-js/anatomy': 1.42.0 + '@zag-js/core': 1.42.0 + '@zag-js/dom-query': 1.42.0 + '@zag-js/types': 1.42.0 + '@zag-js/utils': 1.42.0 + + '@zag-js/store@1.42.0': + dependencies: + proxy-compare: 3.0.1 + + '@zag-js/svelte@1.42.0(svelte@5.56.8)': + dependencies: + '@zag-js/core': 1.42.0 + '@zag-js/types': 1.42.0 + '@zag-js/utils': 1.42.0 + svelte: 5.56.8 + + '@zag-js/switch@1.42.0': + dependencies: + '@zag-js/anatomy': 1.42.0 + '@zag-js/core': 1.42.0 + '@zag-js/dom-query': 1.42.0 + '@zag-js/focus-visible': 1.42.0 + '@zag-js/types': 1.42.0 + '@zag-js/utils': 1.42.0 + + '@zag-js/tabs@1.42.0': + dependencies: + '@zag-js/anatomy': 1.42.0 + '@zag-js/core': 1.42.0 + '@zag-js/dom-query': 1.42.0 + '@zag-js/types': 1.42.0 + '@zag-js/utils': 1.42.0 + + '@zag-js/tags-input@1.42.0': + dependencies: + '@zag-js/anatomy': 1.42.0 + '@zag-js/auto-resize': 1.42.0 + '@zag-js/core': 1.42.0 + '@zag-js/dom-query': 1.42.0 + '@zag-js/interact-outside': 1.42.0 + '@zag-js/live-region': 1.42.0 + '@zag-js/types': 1.42.0 + '@zag-js/utils': 1.42.0 + + '@zag-js/toast@1.42.0': + dependencies: + '@zag-js/anatomy': 1.42.0 + '@zag-js/core': 1.42.0 + '@zag-js/dismissable': 1.42.0 + '@zag-js/dom-query': 1.42.0 + '@zag-js/types': 1.42.0 + '@zag-js/utils': 1.42.0 + + '@zag-js/toggle-group@1.42.0': + dependencies: + '@zag-js/anatomy': 1.42.0 + '@zag-js/core': 1.42.0 + '@zag-js/dom-query': 1.42.0 + '@zag-js/types': 1.42.0 + '@zag-js/utils': 1.42.0 + + '@zag-js/tooltip@1.42.0': + dependencies: + '@zag-js/anatomy': 1.42.0 + '@zag-js/core': 1.42.0 + '@zag-js/dom-query': 1.42.0 + '@zag-js/focus-visible': 1.42.0 + '@zag-js/popper': 1.42.0 + '@zag-js/types': 1.42.0 + '@zag-js/utils': 1.42.0 + + '@zag-js/tree-view@1.42.0': + dependencies: + '@zag-js/anatomy': 1.42.0 + '@zag-js/collection': 1.42.0 + '@zag-js/core': 1.42.0 + '@zag-js/dom-query': 1.42.0 + '@zag-js/types': 1.42.0 + '@zag-js/utils': 1.42.0 + + '@zag-js/types@1.42.0': + dependencies: + csstype: 3.2.3 + + '@zag-js/utils@1.42.0': {} + + acorn@8.18.0: {} + + aria-query@5.3.1: {} + + axobject-query@4.1.0: {} + + chokidar@4.0.3: + dependencies: + readdirp: 4.1.2 + + clsx@2.1.1: {} + + cookie@0.6.0: {} + + csstype@3.2.3: {} + + deepmerge@4.3.1: {} + + detect-libc@2.1.2: {} + + devalue@5.9.0: {} + + enhanced-resolve@5.24.5: + dependencies: + graceful-fs: 4.2.11 + tapable: 2.3.3 + + esm-env@1.2.2: {} + + esrap@2.3.2: + dependencies: + '@jridgewell/sourcemap-codec': 1.5.5 + + fdir@6.5.0(picomatch@4.0.5): + optionalDependencies: + picomatch: 4.0.5 + + fsevents@2.3.3: + optional: true + + graceful-fs@4.2.11: {} + + is-reference@3.0.3: + dependencies: + '@types/estree': 1.0.9 + + jiti@2.7.0: {} + + kleur@4.1.5: {} + + lightningcss-android-arm64@1.32.0: + optional: true + + lightningcss-android-arm64@1.33.0: + optional: true + + lightningcss-darwin-arm64@1.32.0: + optional: true + + lightningcss-darwin-arm64@1.33.0: + optional: true + + lightningcss-darwin-x64@1.32.0: + optional: true + + lightningcss-darwin-x64@1.33.0: + optional: true + + lightningcss-freebsd-x64@1.32.0: + optional: true + + lightningcss-freebsd-x64@1.33.0: + optional: true + + lightningcss-linux-arm-gnueabihf@1.32.0: + optional: true + + lightningcss-linux-arm-gnueabihf@1.33.0: + optional: true + + lightningcss-linux-arm64-gnu@1.32.0: + optional: true + + lightningcss-linux-arm64-gnu@1.33.0: + optional: true + + lightningcss-linux-arm64-musl@1.32.0: + optional: true + + lightningcss-linux-arm64-musl@1.33.0: + optional: true + + lightningcss-linux-x64-gnu@1.32.0: + optional: true + + lightningcss-linux-x64-gnu@1.33.0: + optional: true + + lightningcss-linux-x64-musl@1.32.0: + optional: true + + lightningcss-linux-x64-musl@1.33.0: + optional: true + + lightningcss-win32-arm64-msvc@1.32.0: + optional: true + + lightningcss-win32-arm64-msvc@1.33.0: + optional: true + + lightningcss-win32-x64-msvc@1.32.0: + optional: true + + lightningcss-win32-x64-msvc@1.33.0: + optional: true + + lightningcss@1.32.0: + dependencies: + detect-libc: 2.1.2 + optionalDependencies: + lightningcss-android-arm64: 1.32.0 + lightningcss-darwin-arm64: 1.32.0 + lightningcss-darwin-x64: 1.32.0 + lightningcss-freebsd-x64: 1.32.0 + lightningcss-linux-arm-gnueabihf: 1.32.0 + lightningcss-linux-arm64-gnu: 1.32.0 + lightningcss-linux-arm64-musl: 1.32.0 + lightningcss-linux-x64-gnu: 1.32.0 + lightningcss-linux-x64-musl: 1.32.0 + lightningcss-win32-arm64-msvc: 1.32.0 + lightningcss-win32-x64-msvc: 1.32.0 + + lightningcss@1.33.0: + dependencies: + detect-libc: 2.1.2 + optionalDependencies: + lightningcss-android-arm64: 1.33.0 + lightningcss-darwin-arm64: 1.33.0 + lightningcss-darwin-x64: 1.33.0 + lightningcss-freebsd-x64: 1.33.0 + lightningcss-linux-arm-gnueabihf: 1.33.0 + lightningcss-linux-arm64-gnu: 1.33.0 + lightningcss-linux-arm64-musl: 1.33.0 + lightningcss-linux-x64-gnu: 1.33.0 + lightningcss-linux-x64-musl: 1.33.0 + lightningcss-win32-arm64-msvc: 1.33.0 + lightningcss-win32-x64-msvc: 1.33.0 + + locate-character@3.0.0: {} + + magic-string@0.30.21: + dependencies: + '@jridgewell/sourcemap-codec': 1.5.5 + + magic-string@1.1.0: + dependencies: + '@jridgewell/sourcemap-codec': 1.5.5 + + mri@1.2.0: {} + + mrmime@2.0.1: {} + + nanoid@3.3.18: {} + + obug@2.1.4: {} + + picocolors@1.1.1: {} + + picomatch@4.0.5: {} + + postcss@8.5.26: + dependencies: + nanoid: 3.3.18 + picocolors: 1.1.1 + source-map-js: 1.2.1 + + proxy-compare@3.0.1: {} + + proxy-memoize@3.0.1: + dependencies: + proxy-compare: 3.0.1 + + readdirp@4.1.2: {} + + rolldown@1.2.3: + dependencies: + '@oxc-project/types': 0.143.0 + '@rolldown/pluginutils': 1.0.1 + optionalDependencies: + '@rolldown/binding-android-arm64': 1.2.3 + '@rolldown/binding-darwin-arm64': 1.2.3 + '@rolldown/binding-darwin-x64': 1.2.3 + '@rolldown/binding-freebsd-x64': 1.2.3 + '@rolldown/binding-linux-arm-gnueabihf': 1.2.3 + '@rolldown/binding-linux-arm64-gnu': 1.2.3 + '@rolldown/binding-linux-arm64-musl': 1.2.3 + '@rolldown/binding-linux-ppc64-gnu': 1.2.3 + '@rolldown/binding-linux-s390x-gnu': 1.2.3 + '@rolldown/binding-linux-x64-gnu': 1.2.3 + '@rolldown/binding-linux-x64-musl': 1.2.3 + '@rolldown/binding-openharmony-arm64': 1.2.3 + '@rolldown/binding-win32-arm64-msvc': 1.2.3 + '@rolldown/binding-win32-x64-msvc': 1.2.3 + + sade@1.8.1: + dependencies: + mri: 1.2.0 + + set-cookie-parser@3.1.2: {} + + sirv@3.0.2: + dependencies: + '@polka/url': 1.0.0-next.29 + mrmime: 2.0.1 + totalist: 3.0.1 + + source-map-js@1.2.1: {} + + svelte-check@4.7.5(picomatch@4.0.5)(svelte@5.56.8)(typescript@6.0.3): + dependencies: + '@jridgewell/trace-mapping': 0.3.31 + '@sveltejs/load-config': 0.2.2 + chokidar: 4.0.3 + fdir: 6.5.0(picomatch@4.0.5) + picocolors: 1.1.1 + sade: 1.8.1 + svelte: 5.56.8 + typescript: 6.0.3 + transitivePeerDependencies: + - picomatch + + svelte@5.56.8: + dependencies: + '@jridgewell/remapping': 2.3.5 + '@jridgewell/sourcemap-codec': 1.5.5 + '@sveltejs/acorn-typescript': 1.0.12(acorn@8.18.0) + '@types/estree': 1.0.9 + '@types/trusted-types': 2.0.7 + acorn: 8.18.0 + aria-query: 5.3.1 + axobject-query: 4.1.0 + clsx: 2.1.1 + devalue: 5.9.0 + esm-env: 1.2.2 + esrap: 2.3.2 + is-reference: 3.0.3 + locate-character: 3.0.0 + magic-string: 0.30.21 + zimmerframe: 1.1.4 + transitivePeerDependencies: + - '@typescript-eslint/types' + + tailwindcss@4.3.3: {} + + tapable@2.3.3: {} + + tinyglobby@0.2.17: + dependencies: + fdir: 6.5.0(picomatch@4.0.5) + picomatch: 4.0.5 + + totalist@3.0.1: {} + + tslib@2.8.1: {} + + typescript@6.0.3: {} + + uqr@0.1.3: {} + + vite@8.2.1(jiti@2.7.0): + dependencies: + lightningcss: 1.33.0 + picomatch: 4.0.5 + postcss: 8.5.26 + rolldown: 1.2.3 + tinyglobby: 0.2.17 + optionalDependencies: + fsevents: 2.3.3 + jiti: 2.7.0 + + vitefu@1.1.3(vite@8.2.1(jiti@2.7.0)): + optionalDependencies: + vite: 8.2.1(jiti@2.7.0) + + zimmerframe@1.1.4: {} diff --git a/ui/src/app.css b/ui/src/app.css new file mode 100644 index 0000000..7717003 --- /dev/null +++ b/ui/src/app.css @@ -0,0 +1,28 @@ +@import 'tailwindcss'; +@import '@skeletonlabs/skeleton'; +@import './lib/wedding-theme.css'; + +@font-face { + font-family: 'Malibu'; + src: + url('../assets/fonts/Malibu.woff') format('woff'), + url('../assets/fonts/Malibu.ttf') format('truetype'); + font-weight: normal; + font-style: normal; + font-display: swap; +} + +@font-face { + font-family: 'Bilbo'; + src: url('../assets/fonts/Bilbo-Regular.ttf') format('truetype'); + font-weight: normal; + font-style: normal; + font-display: swap; +} + +@theme { + /* Script face reserved for "Zoé & Shaldon" — nav title, hero, RSVP, QR page. */ + --font-malibu: 'Malibu', cursive; + /* Formal face for everything else: headings, body, buttons, inputs. */ + --font-serif: 'Bilbo', Georgia, 'Iowan Old Style', 'Palatino Linotype', 'Book Antiqua', Palatino, serif; +} diff --git a/ui/src/app.d.ts b/ui/src/app.d.ts new file mode 100644 index 0000000..da08e6d --- /dev/null +++ b/ui/src/app.d.ts @@ -0,0 +1,13 @@ +// See https://svelte.dev/docs/kit/types#app.d.ts +// for information about these interfaces +declare global { + namespace App { + // interface Error {} + // interface Locals {} + // interface PageData {} + // interface PageState {} + // interface Platform {} + } +} + +export {}; diff --git a/ui/src/app.html b/ui/src/app.html new file mode 100644 index 0000000..55d276a --- /dev/null +++ b/ui/src/app.html @@ -0,0 +1,12 @@ + + + + + + + %sveltekit.head% + + +
%sveltekit.body%
+ + diff --git a/ui/src/lib/api.ts b/ui/src/lib/api.ts new file mode 100644 index 0000000..609c45b --- /dev/null +++ b/ui/src/lib/api.ts @@ -0,0 +1,75 @@ +export interface WeddingConfig { + siteUrl: string; + weddingDate: string; + ceremonyTime: string; + rsvpByDate: string; + venueName: string; + venueAddress: string; + rsvpPhone: string; +} + +export type GuestType = 'adult' | 'child'; + +export interface Guest { + name: string; + type: GuestType; +} + +export interface RsvpPayload { + guests: Guest[]; + message?: string; +} + +export interface PhotoUploadPayload { + name: string; + message?: string; + email?: string; + phone?: string; + files: FileList; +} + +export class ApiError extends Error { + constructor( + message: string, + public status: number + ) { + super(message); + } +} + +async function parseError(response: Response): Promise { + try { + const body = await response.json(); + if (typeof body?.error === 'string') return body.error; + } catch { + // fall through to status text + } + return response.statusText || `Request failed (${response.status})`; +} + +export async function fetchConfig(fetchImpl: typeof fetch = fetch): Promise { + const response = await fetchImpl('/api/config'); + if (!response.ok) throw new ApiError(await parseError(response), response.status); + return response.json(); +} + +export async function submitRsvp(payload: RsvpPayload): Promise { + const response = await fetch('/api/rsvp', { + method: 'POST', + headers: { 'content-type': 'application/json' }, + body: JSON.stringify(payload) + }); + if (!response.ok) throw new ApiError(await parseError(response), response.status); +} + +export async function uploadPhotos(payload: PhotoUploadPayload): Promise { + const form = new FormData(); + form.set('name', payload.name); + if (payload.message) form.set('message', payload.message); + if (payload.email) form.set('email', payload.email); + if (payload.phone) form.set('phone', payload.phone); + for (const file of payload.files) form.append('files', file); + + const response = await fetch('/api/photos/upload', { method: 'POST', body: form }); + if (!response.ok) throw new ApiError(await parseError(response), response.status); +} diff --git a/ui/src/lib/assets/favicon.svg b/ui/src/lib/assets/favicon.svg new file mode 100644 index 0000000..cc5dc66 --- /dev/null +++ b/ui/src/lib/assets/favicon.svg @@ -0,0 +1 @@ +svelte-logo \ No newline at end of file diff --git a/ui/src/lib/components/Countdown.svelte b/ui/src/lib/components/Countdown.svelte new file mode 100644 index 0000000..206d305 --- /dev/null +++ b/ui/src/lib/components/Countdown.svelte @@ -0,0 +1,54 @@ + + +{#if isPast} +

{pastMessage}

+{:else if compact} +
+ {#each units as unit, i (unit.label)} + {#if i > 0}·{/if} + {unit.value} + {unit.label} + {/each} +
+{:else} +
+ {#each units as unit (unit.label)} +
+ + {String(unit.value).padStart(2, '0')} + + {unit.label} +
+ {/each} +
+{/if} diff --git a/ui/src/lib/components/PhotoBackground.svelte b/ui/src/lib/components/PhotoBackground.svelte new file mode 100644 index 0000000..0303c95 --- /dev/null +++ b/ui/src/lib/components/PhotoBackground.svelte @@ -0,0 +1,87 @@ + + +{#if photos.length > 0} + +{/if} diff --git a/ui/src/lib/config.ts b/ui/src/lib/config.ts new file mode 100644 index 0000000..8ee2390 --- /dev/null +++ b/ui/src/lib/config.ts @@ -0,0 +1,10 @@ +// Matches wedding.* / site.* in config.example.yaml. Used as an immediate +// fallback while /api/config loads (and when developing the UI without the Go server). +export const FALLBACK_SITE_URL = "https://zoeshaldon.warky.info"; +export const FALLBACK_WEDDING_DATE = "2026-11-07T16:00:00+02:00"; +export const FALLBACK_CEREMONY_TIME = "16:00 for 16:30"; +export const FALLBACK_RSVP_BY_DATE = "2026-09-01T00:00:00+02:00"; +export const FALLBACK_VENUE_NAME = "Rivier Plaas"; +export const FALLBACK_VENUE_ADDRESS = + "Langenhoven Rd, Sherman Park AH, Meyerton, 1961"; +export const FALLBACK_RSVP_PHONE = "076 925 1718"; diff --git a/ui/src/lib/index.ts b/ui/src/lib/index.ts new file mode 100644 index 0000000..856f2b6 --- /dev/null +++ b/ui/src/lib/index.ts @@ -0,0 +1 @@ +// place files you want to import through the `$lib` alias in this folder. diff --git a/ui/src/lib/rsvp-status.svelte.ts b/ui/src/lib/rsvp-status.svelte.ts new file mode 100644 index 0000000..a432a66 --- /dev/null +++ b/ui/src/lib/rsvp-status.svelte.ts @@ -0,0 +1,24 @@ +import { browser } from '$app/environment'; + +const STORAGE_KEY = 'zoe-shaldon-rsvp-submitted'; + +export function createRsvpStatus() { + let submitted = $state(false); + + $effect(() => { + if (!browser) return; + submitted = localStorage.getItem(STORAGE_KEY) === 'true'; + }); + + function markSubmitted() { + submitted = true; + if (browser) localStorage.setItem(STORAGE_KEY, 'true'); + } + + return { + get submitted() { + return submitted; + }, + markSubmitted + }; +} diff --git a/ui/src/lib/wedding-info.svelte.ts b/ui/src/lib/wedding-info.svelte.ts new file mode 100644 index 0000000..a6d7da9 --- /dev/null +++ b/ui/src/lib/wedding-info.svelte.ts @@ -0,0 +1,73 @@ +import { browser } from '$app/environment'; +import { fetchConfig } from './api'; +import { + FALLBACK_SITE_URL, + FALLBACK_WEDDING_DATE, + FALLBACK_CEREMONY_TIME, + FALLBACK_RSVP_BY_DATE, + FALLBACK_VENUE_NAME, + FALLBACK_VENUE_ADDRESS, + FALLBACK_RSVP_PHONE +} from './config'; + +export function createWeddingInfo() { + let siteUrl = $state(FALLBACK_SITE_URL); + let date = $state(new Date(FALLBACK_WEDDING_DATE)); + let ceremonyTime = $state(FALLBACK_CEREMONY_TIME); + let rsvpByDate = $state(new Date(FALLBACK_RSVP_BY_DATE)); + let venueName = $state(FALLBACK_VENUE_NAME); + let venueAddress = $state(FALLBACK_VENUE_ADDRESS); + let rsvpPhone = $state(FALLBACK_RSVP_PHONE); + + $effect(() => { + if (!browser) return; + fetchConfig() + .then((config) => { + siteUrl = config.siteUrl; + date = new Date(config.weddingDate); + ceremonyTime = config.ceremonyTime; + rsvpByDate = new Date(config.rsvpByDate); + venueName = config.venueName; + venueAddress = config.venueAddress; + rsvpPhone = config.rsvpPhone; + }) + .catch(() => { + // keep the fallback values; the API may not be running yet in dev + }); + }); + + return { + get siteUrl() { + return siteUrl; + }, + get date() { + return date; + }, + get ceremonyTime() { + return ceremonyTime; + }, + get rsvpByDate() { + return rsvpByDate; + }, + get venueName() { + return venueName; + }, + get venueAddress() { + return venueAddress; + }, + get rsvpPhone() { + return rsvpPhone; + } + }; +} + +const dayDateFormatter = new Intl.DateTimeFormat('en-GB', { + weekday: 'long', + day: 'numeric', + month: 'long', + year: 'numeric' +}); + +export function formatFullDate(date: Date): string { + return dayDateFormatter.format(date); +} diff --git a/ui/src/lib/wedding-theme.css b/ui/src/lib/wedding-theme.css new file mode 100644 index 0000000..cd1f586 --- /dev/null +++ b/ui/src/lib/wedding-theme.css @@ -0,0 +1,256 @@ +[data-theme='wedding'] { + --spacing: 0.25rem; + --text-scaling: 1; + --typo-base--font-family: + 'Bilbo', Georgia, 'Iowan Old Style', 'Palatino Linotype', 'Book Antiqua', Palatino, serif; + --typo-base--font-size: inherit; + --typo-base--color-light: var(--color-surface-950); + --typo-base--color-dark: var(--color-surface-50); + --typo-base--line-height: inherit; + --typo-base--font-weight: bold; + --typo-base--font-style: normal; + --typo-base--letter-spacing: 0em; + --typo-base--font-stretch: inherit; + --typo-base--font-kerning: inherit; + --typo-base--text-shadow: inherit; + --typo-base--word-spacing: inherit; + --typo-base--hyphens: inherit; + --typo-base--text-transform: inherit; + --typo-heading--font-family: inherit; + --typo-heading--color-light: inherit; + --typo-heading--color-dark: inherit; + --typo-heading--font-weight: bold; + --typo-heading--font-style: normal; + --typo-heading--letter-spacing: inherit; + --typo-heading--font-stretch: inherit; + --typo-heading--font-kerning: inherit; + --typo-heading--text-shadow: inherit; + --typo-heading--word-spacing: inherit; + --typo-heading--hyphens: inherit; + --typo-heading--text-transform: inherit; + --typo-anchor--font-family: inherit; + --typo-anchor--font-size: inherit; + --typo-anchor--color-light: var(--color-primary-500); + --typo-anchor--color-dark: var(--color-primary-400); + --typo-anchor--line-height: inherit; + --typo-anchor--font-weight: inherit; + --typo-anchor--font-style: inherit; + --typo-anchor--letter-spacing: inherit; + --typo-anchor--font-stretch: inherit; + --typo-anchor--font-kerning: inherit; + --typo-anchor--text-shadow: inherit; + --typo-anchor--word-spacing: inherit; + --typo-anchor--hyphens: inherit; + --typo-anchor--text-transform: inherit; + --typo-anchor--text-decoration-line: none; + --typo-anchor--text-decoration-color: inherit; + --typo-anchor--text-decoration-style: inherit; + --typo-anchor--text-decoration-thickness: inherit; + --typo-anchor--text-underline-offset: inherit; + --typo-anchor--text-underline-position: inherit; + --typo-anchor--hover--text-decoration-line: underline; + --typo-anchor--hover--text-decoration-color: inherit; + --typo-anchor--hover--text-decoration-style: inherit; + --typo-anchor--hover--text-decoration-thickness: inherit; + --typo-anchor--hover--text-underline-offset: inherit; + --typo-anchor--hover--text-underline-position: inherit; + --typo-anchor--active--text-decoration-line: none; + --typo-anchor--active--text-decoration-color: inherit; + --typo-anchor--active--text-decoration-style: inherit; + --typo-anchor--active--text-decoration-thickness: inherit; + --typo-anchor--active--text-underline-offset: inherit; + --typo-anchor--active--text-underline-position: inherit; + --typo-anchor--focus--text-decoration-line: none; + --typo-anchor--focus--text-decoration-color: inherit; + --typo-anchor--focus--text-decoration-style: inherit; + --typo-anchor--focus--text-decoration-thickness: inherit; + --typo-anchor--focus--text-underline-offset: inherit; + --typo-anchor--focus--text-underline-position: inherit; + --radius-base: 0.5rem; + --radius-container: 0.5rem; + --default-border-width: 1px; + --default-outline-width: 1px; + --default-ring-width: 1px; + --corner-shape-base: squircle; + --corner-shape-container: squircle; + --color-root-bg-light: var(--color-surface-50); + --color-root-bg-dark: var(--color-surface-950); + --color-brand-light: var(--color-primary-500); + --color-brand-contrast-light: var(--color-primary-contrast-500); + --color-brand-dark: var(--color-primary-500); + --color-brand-contrast-dark: var(--color-primary-contrast-500); + + /* primary (blue) — seed #1E4E79, from the groom's shirt / dusk sky in the save-the-date photo */ + --color-primary-50: oklch(0.97 0.0133 248.73); + --color-primary-100: oklch(0.93 0.0266 248.73); + --color-primary-200: oklch(0.86 0.0488 248.73); + --color-primary-300: oklch(0.78 0.0666 248.73); + --color-primary-400: oklch(0.7 0.0799 248.73); + --color-primary-500: oklch(0.62 0.0888 248.73); + --color-primary-600: oklch(0.54 0.0817 248.73); + --color-primary-700: oklch(0.46 0.071 248.73); + --color-primary-800: oklch(0.38 0.0577 248.73); + --color-primary-900: oklch(0.3 0.0444 248.73); + --color-primary-950: oklch(0.22 0.0311 248.73); + --color-primary-contrast-dark: var(--color-primary-950); + --color-primary-contrast-light: var(--color-primary-50); + --color-primary-contrast-50: var(--color-primary-contrast-dark); + --color-primary-contrast-100: var(--color-primary-contrast-dark); + --color-primary-contrast-200: var(--color-primary-contrast-dark); + --color-primary-contrast-300: var(--color-primary-contrast-dark); + --color-primary-contrast-400: var(--color-primary-contrast-dark); + --color-primary-contrast-500: var(--color-primary-contrast-light); + --color-primary-contrast-600: var(--color-primary-contrast-light); + --color-primary-contrast-700: var(--color-primary-contrast-light); + --color-primary-contrast-800: var(--color-primary-contrast-light); + --color-primary-contrast-900: var(--color-primary-contrast-light); + --color-primary-contrast-950: var(--color-primary-contrast-light); + + /* secondary (yellow) — seed #D9A441, from the warm gold title text in the same photo */ + --color-secondary-50: oklch(0.97 0.0194 79.85); + --color-secondary-100: oklch(0.93 0.0389 79.85); + --color-secondary-200: oklch(0.86 0.0712 79.85); + --color-secondary-300: oklch(0.78 0.0971 79.85); + --color-secondary-400: oklch(0.7 0.1166 79.85); + --color-secondary-500: oklch(0.62 0.1295 79.85); + --color-secondary-600: oklch(0.54 0.1191 79.85); + --color-secondary-700: oklch(0.46 0.1036 79.85); + --color-secondary-800: oklch(0.38 0.0842 79.85); + --color-secondary-900: oklch(0.3 0.0648 79.85); + --color-secondary-950: oklch(0.22 0.0453 79.85); + --color-secondary-contrast-dark: var(--color-secondary-950); + --color-secondary-contrast-light: var(--color-secondary-50); + --color-secondary-contrast-50: var(--color-secondary-contrast-light); + --color-secondary-contrast-100: var(--color-secondary-contrast-light); + --color-secondary-contrast-200: var(--color-secondary-contrast-dark); + --color-secondary-contrast-300: var(--color-secondary-contrast-dark); + --color-secondary-contrast-400: var(--color-secondary-contrast-dark); + --color-secondary-contrast-500: var(--color-secondary-contrast-dark); + --color-secondary-contrast-600: var(--color-secondary-contrast-light); + --color-secondary-contrast-700: var(--color-secondary-contrast-light); + --color-secondary-contrast-800: var(--color-secondary-contrast-light); + --color-secondary-contrast-900: var(--color-secondary-contrast-light); + --color-secondary-contrast-950: var(--color-secondary-contrast-light); + + /* tertiary/success/warning/error/surface: unmodified neutrals, not part of the brand ask */ + --color-tertiary-50: oklch(0.91 0.08 328.89); + --color-tertiary-100: oklch(0.83 0.13 339.66); + --color-tertiary-200: oklch(0.76 0.18 345.54); + --color-tertiary-300: oklch(0.7 0.23 350.67); + --color-tertiary-400: oklch(0.66 0.25 355.84); + --color-tertiary-500: oklch(0.65 0.26 2.47); + --color-tertiary-600: oklch(0.59 0.24 1.69); + --color-tertiary-700: oklch(0.54 0.22 0.5); + --color-tertiary-800: oklch(0.48 0.2 359.65); + --color-tertiary-900: oklch(0.43 0.17 357.7); + --color-tertiary-950: oklch(0.37 0.15 355.33); + --color-tertiary-contrast-dark: var(--color-tertiary-950); + --color-tertiary-contrast-light: var(--color-tertiary-50); + --color-tertiary-contrast-50: var(--color-tertiary-contrast-dark); + --color-tertiary-contrast-100: var(--color-tertiary-contrast-dark); + --color-tertiary-contrast-200: var(--color-tertiary-contrast-dark); + --color-tertiary-contrast-300: var(--color-tertiary-contrast-dark); + --color-tertiary-contrast-400: var(--color-tertiary-contrast-light); + --color-tertiary-contrast-500: var(--color-tertiary-contrast-light); + --color-tertiary-contrast-600: var(--color-tertiary-contrast-light); + --color-tertiary-contrast-700: var(--color-tertiary-contrast-light); + --color-tertiary-contrast-800: var(--color-tertiary-contrast-light); + --color-tertiary-contrast-900: var(--color-tertiary-contrast-light); + --color-tertiary-contrast-950: var(--color-tertiary-contrast-light); + --color-success-50: oklch(0.94 0.09 178.68); + --color-success-100: oklch(0.92 0.1 178.62); + --color-success-200: oklch(0.89 0.11 177.17); + --color-success-300: oklch(0.87 0.12 176.91); + --color-success-400: oklch(0.85 0.13 175.46); + --color-success-500: oklch(0.83 0.13 174.96); + --color-success-600: oklch(0.73 0.12 175.71); + --color-success-700: oklch(0.62 0.1 176); + --color-success-800: oklch(0.51 0.08 178.29); + --color-success-900: oklch(0.4 0.06 179.75); + --color-success-950: oklch(0.27 0.04 185.3); + --color-success-contrast-dark: var(--color-success-950); + --color-success-contrast-light: var(--color-success-50); + --color-success-contrast-50: var(--color-success-contrast-dark); + --color-success-contrast-100: var(--color-success-contrast-dark); + --color-success-contrast-200: var(--color-success-contrast-dark); + --color-success-contrast-300: var(--color-success-contrast-dark); + --color-success-contrast-400: var(--color-success-contrast-dark); + --color-success-contrast-500: var(--color-success-contrast-dark); + --color-success-contrast-600: var(--color-success-contrast-dark); + --color-success-contrast-700: var(--color-success-contrast-light); + --color-success-contrast-800: var(--color-success-contrast-light); + --color-success-contrast-900: var(--color-success-contrast-light); + --color-success-contrast-950: var(--color-success-contrast-light); + --color-warning-50: oklch(0.96 0.05 84.57); + --color-warning-100: oklch(0.93 0.06 82.17); + --color-warning-200: oklch(0.9 0.08 80.34); + --color-warning-300: oklch(0.88 0.1 80.02); + --color-warning-400: oklch(0.85 0.12 78.36); + --color-warning-500: oklch(0.82 0.14 76.72); + --color-warning-600: oklch(0.76 0.13 72.26); + --color-warning-700: oklch(0.7 0.13 68.1); + --color-warning-800: oklch(0.64 0.13 63.18); + --color-warning-900: oklch(0.58 0.13 57.97); + --color-warning-950: oklch(0.52 0.13 51.44); + --color-warning-contrast-dark: var(--color-warning-950); + --color-warning-contrast-light: var(--color-warning-50); + --color-warning-contrast-50: var(--color-warning-contrast-dark); + --color-warning-contrast-100: var(--color-warning-contrast-dark); + --color-warning-contrast-200: var(--color-warning-contrast-dark); + --color-warning-contrast-300: var(--color-warning-contrast-dark); + --color-warning-contrast-400: var(--color-warning-contrast-dark); + --color-warning-contrast-500: var(--color-warning-contrast-dark); + --color-warning-contrast-600: var(--color-warning-contrast-light); + --color-warning-contrast-700: var(--color-warning-contrast-light); + --color-warning-contrast-800: var(--color-warning-contrast-light); + --color-warning-contrast-900: var(--color-warning-contrast-light); + --color-warning-contrast-950: var(--color-warning-contrast-light); + --color-error-50: oklch(0.9 0.04 14); + --color-error-100: oklch(0.83 0.07 19.8); + --color-error-200: oklch(0.77 0.11 21.97); + --color-error-300: oklch(0.72 0.15 24.89); + --color-error-400: oklch(0.67 0.19 26.71); + --color-error-500: oklch(0.64 0.22 28.71); + --color-error-600: oklch(0.59 0.21 28.53); + --color-error-700: oklch(0.55 0.2 28.58); + --color-error-800: oklch(0.51 0.19 28.72); + --color-error-900: oklch(0.46 0.18 28.88); + --color-error-950: oklch(0.42 0.17 29.23); + --color-error-contrast-dark: var(--color-error-950); + --color-error-contrast-light: var(--color-error-50); + --color-error-contrast-50: var(--color-error-contrast-dark); + --color-error-contrast-100: var(--color-error-contrast-dark); + --color-error-contrast-200: var(--color-error-contrast-dark); + --color-error-contrast-300: var(--color-error-contrast-dark); + --color-error-contrast-400: var(--color-error-contrast-light); + --color-error-contrast-500: var(--color-error-contrast-light); + --color-error-contrast-600: var(--color-error-contrast-light); + --color-error-contrast-700: var(--color-error-contrast-light); + --color-error-contrast-800: var(--color-error-contrast-light); + --color-error-contrast-900: var(--color-error-contrast-light); + --color-error-contrast-950: var(--color-error-contrast-light); + --color-surface-50: oklch(0.99 0 0); + --color-surface-100: oklch(0.91 0 0); + --color-surface-200: oklch(0.81 0 0); + --color-surface-300: oklch(0.72 0 0); + --color-surface-400: oklch(0.62 0 0); + --color-surface-500: oklch(0.51 0 0); + --color-surface-600: oklch(0.45 0 0); + --color-surface-700: oklch(0.39 0 0); + --color-surface-800: oklch(0.32 0 0); + --color-surface-900: oklch(0.25 0 0); + --color-surface-950: oklch(0.18 0 0); + --color-surface-contrast-dark: var(--color-surface-950); + --color-surface-contrast-light: var(--color-surface-50); + --color-surface-contrast-50: var(--color-surface-contrast-dark); + --color-surface-contrast-100: var(--color-surface-contrast-dark); + --color-surface-contrast-200: var(--color-surface-contrast-dark); + --color-surface-contrast-300: var(--color-surface-contrast-dark); + --color-surface-contrast-400: var(--color-surface-contrast-light); + --color-surface-contrast-500: var(--color-surface-contrast-light); + --color-surface-contrast-600: var(--color-surface-contrast-light); + --color-surface-contrast-700: var(--color-surface-contrast-light); + --color-surface-contrast-800: var(--color-surface-contrast-light); + --color-surface-contrast-900: var(--color-surface-contrast-light); + --color-surface-contrast-950: var(--color-surface-contrast-light); +} diff --git a/ui/src/routes/+layout.svelte b/ui/src/routes/+layout.svelte new file mode 100644 index 0000000..aa63bee --- /dev/null +++ b/ui/src/routes/+layout.svelte @@ -0,0 +1,45 @@ + + + + +
+
+ +
+ +
+
+
+ {@render children()} +
+
diff --git a/ui/src/routes/+layout.ts b/ui/src/routes/+layout.ts new file mode 100644 index 0000000..189f71e --- /dev/null +++ b/ui/src/routes/+layout.ts @@ -0,0 +1 @@ +export const prerender = true; diff --git a/ui/src/routes/+page.svelte b/ui/src/routes/+page.svelte new file mode 100644 index 0000000..4db0d42 --- /dev/null +++ b/ui/src/routes/+page.svelte @@ -0,0 +1,49 @@ + + +
+ + +
+

+ Zoé & Shaldon +

+

are getting married

+ +
+

+ {formatFullDate(wedding.date)} +

+

+ {wedding.ceremonyTime} +

+
+ +
+

{wedding.venueName}

+

{wedding.venueAddress}

+
+ +
+ {#if !rsvpStatus.submitted} + RSVP + {:else} +

✓ You've RSVP'd — thank you!

+ {/if} + Share photos +
+
+
diff --git a/ui/src/routes/photos/+page.svelte b/ui/src/routes/photos/+page.svelte new file mode 100644 index 0000000..1fa49a4 --- /dev/null +++ b/ui/src/routes/photos/+page.svelte @@ -0,0 +1,126 @@ + + +
+ {#if !isOpen} +
+

Photo uploads open on the wedding day

+

Come back on {formatFullDate(wedding.date)} to share your photos with Zoé & Shaldon.

+
+ {:else if status === 'done'} +
+ Thank you — your photos have been uploaded! +
+ {:else} +
+

Share your photos

+

+ Upload photos from the day — up to {MAX_FILES} at a time, {MAX_SIZE_MB}MB each. +

+ +
+ + + + + + + + + + + {#if status === 'error'} +

{errorMessage}

+ {/if} + + +
+
+ {/if} +
diff --git a/ui/src/routes/qr/+page.svelte b/ui/src/routes/qr/+page.svelte new file mode 100644 index 0000000..852ba53 --- /dev/null +++ b/ui/src/routes/qr/+page.svelte @@ -0,0 +1,25 @@ + + +
+
+

Scan to visit

+

Zoé & Shaldon

+ + + + + + +

{wedding.siteUrl}

+ + + Download PNG + +
+
+
diff --git a/ui/src/routes/rsvp/+page.svelte b/ui/src/routes/rsvp/+page.svelte new file mode 100644 index 0000000..7fd828c --- /dev/null +++ b/ui/src/routes/rsvp/+page.svelte @@ -0,0 +1,191 @@ + + +
+ + +
+
+

+ Please join us to celebrate the union of +

+

Zoé & Shaldon

+

+ {formatFullDate(wedding.date)} +

+

{wedding.ceremonyTime}

+

{wedding.venueName}

+

{wedding.venueAddress}

+
+ + {#if isRsvpOpen} +
+

+ RSVP by {formatFullDate(wedding.rsvpByDate)} +

+ +
+ {/if} + + {#if !isRsvpOpen} +
+

RSVP missed

+

+ The RSVP deadline has passed. Please contact us directly on {wedding.rsvpPhone}. +

+
+ {:else if status === "done"} +
+ Thank you — your RSVP has been received! +
+ {:else} +
+
+ Who's coming? * + {#each guests as guest, i (i)} +
+ + {guest.type === "child" ? "Child" : "Adult"} + + + {#if guests.length > 1} + + {/if} +
+ {/each} +
+ + +
+
+ + + + {#if status === "error"} +

{errorMessage}

+ {/if} + + + +

+ Or RSVP by phone: {wedding.rsvpPhone} +

+
+ {/if} +
+
diff --git a/ui/static/robots.txt b/ui/static/robots.txt new file mode 100644 index 0000000..b6dd667 --- /dev/null +++ b/ui/static/robots.txt @@ -0,0 +1,3 @@ +# allow crawling everything by default +User-agent: * +Disallow: diff --git a/ui/tsconfig.json b/ui/tsconfig.json new file mode 100644 index 0000000..2c2ed3c --- /dev/null +++ b/ui/tsconfig.json @@ -0,0 +1,20 @@ +{ + "extends": "./.svelte-kit/tsconfig.json", + "compilerOptions": { + "rewriteRelativeImportExtensions": true, + "allowJs": true, + "checkJs": true, + "esModuleInterop": true, + "forceConsistentCasingInFileNames": true, + "resolveJsonModule": true, + "skipLibCheck": true, + "sourceMap": true, + "strict": true, + "moduleResolution": "bundler" + } + // Path aliases are handled by https://svelte.dev/docs/kit/configuration#alias + // except $lib which is handled by https://svelte.dev/docs/kit/configuration#files + // + // To make changes to top-level options such as include and exclude, we recommend extending + // the generated config; see https://svelte.dev/docs/kit/configuration#typescript +} diff --git a/ui/vite.config.ts b/ui/vite.config.ts new file mode 100644 index 0000000..f7056fa --- /dev/null +++ b/ui/vite.config.ts @@ -0,0 +1,20 @@ +import tailwindcss from '@tailwindcss/vite'; +import adapter from '@sveltejs/adapter-static'; +import { sveltekit } from '@sveltejs/kit/vite'; +import { defineConfig } from 'vite'; + +export default defineConfig({ + server: { + fs: { allow: ['assets'] } + }, + plugins: [ + tailwindcss(), + sveltekit({ + compilerOptions: { + // Force runes mode for the project, except for libraries. Can be removed in svelte 6. + runes: ({ filename }) => filename.split(/[/\\]/).includes('node_modules') ? undefined : true + }, + adapter: adapter() + }) + ] +});